From 378a6cdd817eceb5e467a5df95661d4743bf2a68 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:11:49 -0400 Subject: [PATCH 01/94] [v7] feat: Remove references to @sentry/apm (#4845) Removes all references to `@sentry/apm`, a deprecated package we do not use anymore. --- packages/integrations/src/vue.ts | 58 ++++---------------- packages/react/src/profiler.tsx | 90 +++----------------------------- 2 files changed, 16 insertions(+), 132 deletions(-) diff --git a/packages/integrations/src/vue.ts b/packages/integrations/src/vue.ts index 1b1cf3caa63a..12c55f53df32 100644 --- a/packages/integrations/src/vue.ts +++ b/packages/integrations/src/vue.ts @@ -5,15 +5,6 @@ import { basename, getGlobalObject, logger, timestampWithMs } from '@sentry/util import { IS_DEBUG_BUILD } from './flags'; -/** - * Used to extract Tracing integration from the current client, - * without the need to import `Tracing` itself from the @sentry/apm package. - * @deprecated as @sentry/tracing should be used over @sentry/apm. - */ -const TRACING_GETTER = { - id: 'Tracing', -} as any as IntegrationClass; - /** * Used to extract BrowserTracing integration from @sentry/tracing */ @@ -150,7 +141,6 @@ export class Vue implements Integration { private readonly _componentsCache: { [key: string]: string } = {}; private _rootSpan?: Span; private _rootSpanTimer?: ReturnType; - private _tracingActivity?: number; /** * @inheritDoc @@ -260,30 +250,12 @@ export class Vue implements Integration { vm.$once(`hook:${hook}`, () => { // Create an activity on the first event call. There'll be no second call, as rootSpan will be in place, // thus new event handler won't be attached. - - // We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency. - // We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods. - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - // eslint-disable-next-line deprecation/deprecation - const tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER); - if (tracingIntegration) { - this._tracingActivity = (tracingIntegration as any).constructor.pushActivity('Vue Application Render'); - const transaction = (tracingIntegration as any).constructor.getTransaction(); - if (transaction) { - this._rootSpan = transaction.startChild({ - description: 'Application Render', - op: VUE_OP, - }); - } - // Use functionality from @sentry/tracing - } else { - const activeTransaction = getActiveTransaction(getCurrentHub()); - if (activeTransaction) { - this._rootSpan = activeTransaction.startChild({ - description: 'Application Render', - op: VUE_OP, - }); - } + const activeTransaction = getActiveTransaction(getCurrentHub()); + if (activeTransaction) { + this._rootSpan = activeTransaction.startChild({ + description: 'Application Render', + op: VUE_OP, + }); } /* eslint-enable @typescript-eslint/no-unsafe-member-access */ }); @@ -349,24 +321,13 @@ export class Vue implements Integration { }; /** Finish top-level span and activity with a debounce configured using `timeout` option */ - private _finishRootSpan(timestamp: number, getCurrentHub: () => Hub): void { + private _finishRootSpan(timestamp: number, _getCurrentHub: () => Hub): void { if (this._rootSpanTimer) { clearTimeout(this._rootSpanTimer); } this._rootSpanTimer = setTimeout(() => { - if (this._tracingActivity) { - // We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency. - // We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods. - // eslint-disable-next-line deprecation/deprecation - const tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER); - if (tracingIntegration) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - (tracingIntegration as any).constructor.popActivity(this._tracingActivity); - } - } - - // We should always finish the span, only should pop activity if using @sentry/apm + // We should always finish the span if (this._rootSpan) { this._rootSpan.finish(timestamp); } @@ -379,8 +340,7 @@ export class Vue implements Integration { this._options.Vue.mixin({ beforeCreate(this: ViewModel): void { - // eslint-disable-next-line deprecation/deprecation - if (getCurrentHub().getIntegration(TRACING_GETTER) || getCurrentHub().getIntegration(BROWSER_TRACING_GETTER)) { + if (getCurrentHub().getIntegration(BROWSER_TRACING_GETTER)) { // `this` points to currently rendered component applyTracingHooks(this, getCurrentHub); } else { diff --git a/packages/react/src/profiler.tsx b/packages/react/src/profiler.tsx index acf764347c69..c52d503eb92b 100644 --- a/packages/react/src/profiler.tsx +++ b/packages/react/src/profiler.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { getCurrentHub, Hub } from '@sentry/browser'; -import { Integration, IntegrationClass, Span, Transaction } from '@sentry/types'; +import { Span, Transaction } from '@sentry/types'; import { timestampWithMs } from '@sentry/utils'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; @@ -10,66 +10,6 @@ import { REACT_MOUNT_OP, REACT_RENDER_OP, REACT_UPDATE_OP } from './constants'; export const UNKNOWN_COMPONENT = 'unknown'; -const TRACING_GETTER = ({ - id: 'Tracing', -} as any) as IntegrationClass; - -let globalTracingIntegration: Integration | null = null; -/** @deprecated remove when @sentry/apm no longer used */ -const getTracingIntegration = (): Integration | null => { - if (globalTracingIntegration) { - return globalTracingIntegration; - } - - globalTracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER); - return globalTracingIntegration; -}; - -/** - * pushActivity creates an new react activity. - * Is a no-op if Tracing integration is not valid - * @param name displayName of component that started activity - * @deprecated remove when @sentry/apm no longer used - */ -function pushActivity(name: string, op: string): number | null { - if (globalTracingIntegration === null) { - return null; - } - - return (globalTracingIntegration as any).constructor.pushActivity(name, { - description: `<${name}>`, - op, - }); -} - -/** - * popActivity removes a React activity. - * Is a no-op if Tracing integration is not valid. - * @param activity id of activity that is being popped - * @deprecated remove when @sentry/apm no longer used - */ -function popActivity(activity: number | null): void { - if (activity === null || globalTracingIntegration === null) { - return; - } - - (globalTracingIntegration as any).constructor.popActivity(activity); -} - -/** - * Obtain a span given an activity id. - * Is a no-op if Tracing integration is not valid. - * @param activity activity id associated with obtained span - * @deprecated remove when @sentry/apm no longer used - */ -function getActivitySpan(activity: number | null): Span | undefined { - if (activity === null || globalTracingIntegration === null) { - return undefined; - } - - return (globalTracingIntegration as any).constructor.getActivitySpan(activity) as Span | undefined; -} - export type ProfilerProps = { // The name of the component being profiled. name: string; @@ -95,9 +35,6 @@ class Profiler extends React.Component { */ protected _mountSpan: Span | undefined = undefined; - // The activity representing how long it takes to mount a component. - private _mountActivity: number | null = null; - // eslint-disable-next-line @typescript-eslint/member-ordering public static defaultProps: Partial = { disabled: false, @@ -113,19 +50,12 @@ class Profiler extends React.Component { return; } - // If they are using @sentry/apm, we need to push/pop activities - // eslint-disable-next-line deprecation/deprecation - if (getTracingIntegration()) { - // eslint-disable-next-line deprecation/deprecation - this._mountActivity = pushActivity(name, REACT_MOUNT_OP); - } else { - const activeTransaction = getActiveTransaction(); - if (activeTransaction) { - this._mountSpan = activeTransaction.startChild({ - description: `<${name}>`, - op: REACT_MOUNT_OP, - }); - } + const activeTransaction = getActiveTransaction(); + if (activeTransaction) { + this._mountSpan = activeTransaction.startChild({ + description: `<${name}>`, + op: REACT_MOUNT_OP, + }); } } @@ -133,12 +63,6 @@ class Profiler extends React.Component { public componentDidMount(): void { if (this._mountSpan) { this._mountSpan.finish(); - } else { - // eslint-disable-next-line deprecation/deprecation - this._mountSpan = getActivitySpan(this._mountActivity); - // eslint-disable-next-line deprecation/deprecation - popActivity(this._mountActivity); - this._mountActivity = null; } } From 7e50a944bd083a1239a3878e40d33f19794685e1 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:12:47 -0400 Subject: [PATCH 02/94] [v7] feat(core): Delete API class (#4848) Removes the deprecated `API` class. --- packages/core/src/api.ts | 69 +----------------------------- packages/core/src/index.ts | 2 - packages/core/test/lib/api.test.ts | 39 +++++++++++------ 3 files changed, 26 insertions(+), 84 deletions(-) diff --git a/packages/core/src/api.ts b/packages/core/src/api.ts index bace0ad07591..8d76cb135400 100644 --- a/packages/core/src/api.ts +++ b/packages/core/src/api.ts @@ -17,73 +17,6 @@ export interface APIDetails { readonly tunnel?: string; } -/** - * Helper class to provide urls, headers and metadata that can be used to form - * different types of requests to Sentry endpoints. - * Supports both envelopes and regular event requests. - * - * @deprecated Please use APIDetails - **/ -export class API { - /** The DSN as passed to Sentry.init() */ - public dsn: DsnLike; - - /** Metadata about the SDK (name, version, etc) for inclusion in envelope headers */ - public metadata: SdkMetadata; - - /** The internally used Dsn object. */ - private readonly _dsnObject: DsnComponents; - - /** The envelope tunnel to use. */ - private readonly _tunnel?: string; - - /** Create a new instance of API */ - public constructor(dsn: DsnLike, metadata: SdkMetadata = {}, tunnel?: string) { - this.dsn = dsn; - this._dsnObject = makeDsn(dsn); - this.metadata = metadata; - this._tunnel = tunnel; - } - - /** Returns the Dsn object. */ - public getDsn(): DsnComponents { - return this._dsnObject; - } - - /** Does this transport force envelopes? */ - public forceEnvelope(): boolean { - return !!this._tunnel; - } - - /** Returns the prefix to construct Sentry ingestion API endpoints. */ - public getBaseApiEndpoint(): string { - return getBaseApiEndpoint(this._dsnObject); - } - - /** Returns the store endpoint URL. */ - public getStoreEndpoint(): string { - return getStoreEndpoint(this._dsnObject); - } - - /** - * Returns the store endpoint URL with auth in the query string. - * - * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. - */ - public getStoreEndpointWithUrlEncodedAuth(): string { - return getStoreEndpointWithUrlEncodedAuth(this._dsnObject); - } - - /** - * Returns the envelope endpoint URL with auth in the query string. - * - * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests. - */ - public getEnvelopeEndpointWithUrlEncodedAuth(): string { - return getEnvelopeEndpointWithUrlEncodedAuth(this._dsnObject, this._tunnel); - } -} - /** Initializes API Details */ export function initAPIDetails(dsn: DsnLike, metadata?: SdkMetadata, tunnel?: string): APIDetails { return { @@ -117,7 +50,7 @@ function _encodedAuth(dsn: DsnComponents): string { } /** Returns the store endpoint URL. */ -function getStoreEndpoint(dsn: DsnComponents): string { +export function getStoreEndpoint(dsn: DsnComponents): string { return _getIngestEndpoint(dsn, 'store'); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f09d804d3bed..b066724ce099 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -15,8 +15,6 @@ export { } from '@sentry/minimal'; export { addGlobalEventProcessor, getCurrentHub, getHubFromCarrier, Hub, makeMain, Scope, Session } from '@sentry/hub'; export { - // eslint-disable-next-line deprecation/deprecation - API, APIDetails, getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth, diff --git a/packages/core/test/lib/api.test.ts b/packages/core/test/lib/api.test.ts index 14b44aed9602..af3a7bfb8ca3 100644 --- a/packages/core/test/lib/api.test.ts +++ b/packages/core/test/lib/api.test.ts @@ -1,27 +1,38 @@ /* eslint-disable deprecation/deprecation */ import { makeDsn } from '@sentry/utils'; -import { API, getReportDialogEndpoint, getRequestHeaders } from '../../src/api'; +import { + getEnvelopeEndpointWithUrlEncodedAuth, + getReportDialogEndpoint, + getRequestHeaders, + getStoreEndpoint, + getStoreEndpointWithUrlEncodedAuth, + initAPIDetails, +} from '../../src/api'; const ingestDsn = 'https://abc@xxxx.ingest.sentry.io:1234/subpath/123'; const dsnPublic = 'https://abc@sentry.io:1234/subpath/123'; const legacyDsn = 'https://abc:123@sentry.io:1234/subpath/123'; const tunnel = 'https://hello.com/world'; +const ingestDsnAPI = initAPIDetails(ingestDsn); +const dsnPublicAPI = initAPIDetails(dsnPublic); + describe('API', () => { test('getStoreEndpoint', () => { - expect(new API(dsnPublic).getStoreEndpointWithUrlEncodedAuth()).toEqual( + expect(getStoreEndpointWithUrlEncodedAuth(dsnPublicAPI.dsn)).toEqual( 'https://sentry.io:1234/subpath/api/123/store/?sentry_key=abc&sentry_version=7', ); - expect(new API(dsnPublic).getStoreEndpoint()).toEqual('https://sentry.io:1234/subpath/api/123/store/'); - expect(new API(ingestDsn).getStoreEndpoint()).toEqual('https://xxxx.ingest.sentry.io:1234/subpath/api/123/store/'); + expect(getStoreEndpoint(dsnPublicAPI.dsn)).toEqual('https://sentry.io:1234/subpath/api/123/store/'); + expect(getStoreEndpoint(ingestDsnAPI.dsn)).toEqual('https://xxxx.ingest.sentry.io:1234/subpath/api/123/store/'); }); test('getEnvelopeEndpoint', () => { - expect(new API(dsnPublic).getEnvelopeEndpointWithUrlEncodedAuth()).toEqual( + expect(getEnvelopeEndpointWithUrlEncodedAuth(dsnPublicAPI.dsn)).toEqual( 'https://sentry.io:1234/subpath/api/123/envelope/?sentry_key=abc&sentry_version=7', ); - expect(new API(dsnPublic, {}, tunnel).getEnvelopeEndpointWithUrlEncodedAuth()).toEqual(tunnel); + const dsnPublicAPIWithTunnel = initAPIDetails(dsnPublic, {}, tunnel); + expect(getEnvelopeEndpointWithUrlEncodedAuth(dsnPublicAPIWithTunnel.dsn, tunnel)).toEqual(tunnel); }); test('getRequestHeaders', () => { @@ -118,13 +129,13 @@ describe('API', () => { ); }); - test('getDsn', () => { - expect(new API(dsnPublic).getDsn().host).toEqual(makeDsn(dsnPublic).host); - expect(new API(dsnPublic).getDsn().path).toEqual(makeDsn(dsnPublic).path); - expect(new API(dsnPublic).getDsn().pass).toEqual(makeDsn(dsnPublic).pass); - expect(new API(dsnPublic).getDsn().port).toEqual(makeDsn(dsnPublic).port); - expect(new API(dsnPublic).getDsn().protocol).toEqual(makeDsn(dsnPublic).protocol); - expect(new API(dsnPublic).getDsn().projectId).toEqual(makeDsn(dsnPublic).projectId); - expect(new API(dsnPublic).getDsn().publicKey).toEqual(makeDsn(dsnPublic).publicKey); + test('initAPIDetails dsn', () => { + expect(dsnPublicAPI.dsn.host).toEqual(makeDsn(dsnPublic).host); + expect(dsnPublicAPI.dsn.path).toEqual(makeDsn(dsnPublic).path); + expect(dsnPublicAPI.dsn.pass).toEqual(makeDsn(dsnPublic).pass); + expect(dsnPublicAPI.dsn.port).toEqual(makeDsn(dsnPublic).port); + expect(dsnPublicAPI.dsn.protocol).toEqual(makeDsn(dsnPublic).protocol); + expect(dsnPublicAPI.dsn.projectId).toEqual(makeDsn(dsnPublic).projectId); + expect(dsnPublicAPI.dsn.publicKey).toEqual(makeDsn(dsnPublic).publicKey); }); }); From d2fe51242e231469b8566122a6e8a0d6f2168df6 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:13:38 -0400 Subject: [PATCH 03/94] [v7] feat: Delete deprecated `startSpan` and `child` methods (#4849) Remove deprecated methods `startSpan` and `child`. These deprecated methods were removed in favour of `span.startChild`. --- packages/hub/src/hub.ts | 9 --------- packages/tracing/src/span.ts | 10 ---------- packages/types/src/hub.ts | 6 ------ packages/types/src/span.ts | 8 -------- 4 files changed, 33 deletions(-) diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index 67761953abfa..b6ebffc74866 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -14,8 +14,6 @@ import { Primitive, SessionContext, Severity, - Span, - SpanContext, Transaction, TransactionContext, User, @@ -385,13 +383,6 @@ export class Hub implements HubInterface { } } - /** - * @inheritDoc - */ - public startSpan(context: SpanContext): Span { - return this._callExtensionMethod('startSpan', context); - } - /** * @inheritDoc */ diff --git a/packages/tracing/src/span.ts b/packages/tracing/src/span.ts index 990f56ce981c..baece680f52c 100644 --- a/packages/tracing/src/span.ts +++ b/packages/tracing/src/span.ts @@ -149,16 +149,6 @@ export class Span implements SpanInterface { } } - /** - * @inheritDoc - * @deprecated - */ - public child( - spanContext?: Pick>, - ): Span { - return this.startChild(spanContext); - } - /** * @inheritDoc */ diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts index c80ea1b51686..49452266fe9f 100644 --- a/packages/types/src/hub.ts +++ b/packages/types/src/hub.ts @@ -7,7 +7,6 @@ import { Primitive } from './misc'; import { Scope } from './scope'; import { Session, SessionContext } from './session'; import { Severity } from './severity'; -import { Span, SpanContext } from './span'; import { CustomSamplingContext, Transaction, TransactionContext } from './transaction'; import { User } from './user'; @@ -180,11 +179,6 @@ export interface Hub { /** Returns all trace headers that are currently on the top scope. */ traceHeaders(): { [key: string]: string }; - /** - * @deprecated No longer does anything. Use use {@link Transaction.startChild} instead. - */ - startSpan(context: SpanContext): Span; - /** * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. * diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index 09b69454835e..d26887a93f2a 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -128,14 +128,6 @@ export interface Span extends SpanContext { */ setHttpStatus(httpStatus: number): this; - /** - * Use {@link startChild} - * @deprecated - */ - child( - spanContext?: Pick>, - ): Span; - /** * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`. * Also the `sampled` decision will be inherited. From 50395bd396e7a37becc9daea2475806384658665 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:14:07 -0400 Subject: [PATCH 04/94] feat(core): Remove whitelistUrls/blacklistUrls (#4850) --- packages/browser/src/backend.ts | 6 ----- .../core/src/integrations/inboundfilters.ts | 23 ++----------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/packages/browser/src/backend.ts b/packages/browser/src/backend.ts index 4cdef3d11047..89cf843d48ae 100644 --- a/packages/browser/src/backend.ts +++ b/packages/browser/src/backend.ts @@ -23,12 +23,6 @@ export interface BrowserOptions extends Options { * By default, all errors will be sent. */ denyUrls?: Array; - - /** @deprecated use {@link Options.allowUrls} instead. */ - whitelistUrls?: Array; - - /** @deprecated use {@link Options.denyUrls} instead. */ - blacklistUrls?: Array; } /** diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index ff6c616c442d..83d635ff3256 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -13,11 +13,6 @@ export interface InboundFiltersOptions { denyUrls: Array; ignoreErrors: Array; ignoreInternal: boolean; - - /** @deprecated use {@link InboundFiltersOptions.allowUrls} instead. */ - whitelistUrls: Array; - /** @deprecated use {@link InboundFiltersOptions.denyUrls} instead. */ - blacklistUrls: Array; } /** Inbound filters configurable by the user */ @@ -60,22 +55,8 @@ export function _mergeOptions( clientOptions: Partial = {}, ): Partial { return { - allowUrls: [ - // eslint-disable-next-line deprecation/deprecation - ...(internalOptions.whitelistUrls || []), - ...(internalOptions.allowUrls || []), - // eslint-disable-next-line deprecation/deprecation - ...(clientOptions.whitelistUrls || []), - ...(clientOptions.allowUrls || []), - ], - denyUrls: [ - // eslint-disable-next-line deprecation/deprecation - ...(internalOptions.blacklistUrls || []), - ...(internalOptions.denyUrls || []), - // eslint-disable-next-line deprecation/deprecation - ...(clientOptions.blacklistUrls || []), - ...(clientOptions.denyUrls || []), - ], + allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])], + denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])], ignoreErrors: [ ...(internalOptions.ignoreErrors || []), ...(clientOptions.ignoreErrors || []), From b12e864c1868e52084a6255124e05e58bb79f01e Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:14:50 -0400 Subject: [PATCH 05/94] feat(gatsby): Remove Sentry from window (#4857) --- packages/gatsby/gatsby-browser.js | 8 +++----- packages/gatsby/test/gatsby-browser.test.ts | 10 ---------- packages/gatsby/test/integration.test.tsx | 3 ++- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/gatsby/gatsby-browser.js b/packages/gatsby/gatsby-browser.js index 5cf1e3d26f80..598ce44ade08 100644 --- a/packages/gatsby/gatsby-browser.js +++ b/packages/gatsby/gatsby-browser.js @@ -6,12 +6,11 @@ exports.onClientEntry = function (_, pluginParams) { const areOptionsDefined = areSentryOptionsDefined(pluginParams); if (isIntialized) { - window.Sentry = Sentry; // For backwards compatibility if (areOptionsDefined) { console.warn( 'Sentry Logger [Warn]: The SDK was initialized in the Sentry config file, but options were found in the Gatsby config. ' + - 'These have been ignored, merge them to the Sentry config if you want to use them.\n' + - 'Learn more about the Gatsby SDK on https://docs.sentry.io/platforms/javascript/guides/gatsby/', + 'These have been ignored, merge them to the Sentry config if you want to use them.\n' + + 'Learn more about the Gatsby SDK on https://docs.sentry.io/platforms/javascript/guides/gatsby/', ); } return; @@ -20,7 +19,7 @@ exports.onClientEntry = function (_, pluginParams) { if (!areOptionsDefined) { console.error( 'Sentry Logger [Error]: No config for the Gatsby SDK was found.\n' + - 'Learn how to configure it on https://docs.sentry.io/platforms/javascript/guides/gatsby/', + 'Learn how to configure it on https://docs.sentry.io/platforms/javascript/guides/gatsby/', ); return; } @@ -32,7 +31,6 @@ exports.onClientEntry = function (_, pluginParams) { dsn: __SENTRY_DSN__, ...pluginParams, }); - window.Sentry = Sentry; // For backwards compatibility }; function isSentryInitialized() { diff --git a/packages/gatsby/test/gatsby-browser.test.ts b/packages/gatsby/test/gatsby-browser.test.ts index a3c98524a2fd..a2044dd2c8a9 100644 --- a/packages/gatsby/test/gatsby-browser.test.ts +++ b/packages/gatsby/test/gatsby-browser.test.ts @@ -36,10 +36,6 @@ describe('onClientEntry', () => { tracingAddExtensionMethods = jest.fn(); }); - afterEach(() => { - (window as any).Sentry = undefined; - }); - it.each([ [{}, ['dsn', 'release']], [{ key: 'value' }, ['dsn', 'release', 'key']], @@ -54,7 +50,6 @@ describe('onClientEntry', () => { describe('inits Sentry once', () => { afterEach(() => { - delete (window as any).Sentry; delete (window as any).__SENTRY__; (global.console.warn as jest.Mock).mockClear(); (global.console.error as jest.Mock).mockClear(); @@ -78,7 +73,6 @@ describe('onClientEntry', () => { // eslint-disable-next-line no-console expect(console.error).not.toHaveBeenCalled(); expect(sentryInit).not.toHaveBeenCalled(); - expect((window as any).Sentry).toBeDefined(); }); it('initialized in injected config, with pluginParams', () => { @@ -94,7 +88,6 @@ describe('onClientEntry', () => { // eslint-disable-next-line no-console expect(console.error).not.toHaveBeenCalled(); expect(sentryInit).not.toHaveBeenCalled(); - expect((window as any).Sentry).toBeDefined(); }); it('not initialized in injected config, without pluginParams', () => { @@ -108,7 +101,6 @@ describe('onClientEntry', () => { Learn how to configure it on https://docs.sentry.io/platforms/javascript/guides/gatsby/", ] `); - expect((window as any).Sentry).not.toBeDefined(); }); it('not initialized in injected config, with pluginParams', () => { @@ -125,7 +117,6 @@ describe('onClientEntry', () => { "release": "release", } `); - expect((window as any).Sentry).toBeDefined(); }); }); @@ -164,7 +155,6 @@ describe('onClientEntry', () => { it('does not run if plugin params are undefined', () => { onClientEntry(); expect(sentryInit).toHaveBeenCalledTimes(0); - expect((window as any).Sentry).toBeUndefined(); expect(tracingAddExtensionMethods).toHaveBeenCalledTimes(0); }); }); diff --git a/packages/gatsby/test/integration.test.tsx b/packages/gatsby/test/integration.test.tsx index e758aa90a79d..18c738ba2ac2 100644 --- a/packages/gatsby/test/integration.test.tsx +++ b/packages/gatsby/test/integration.test.tsx @@ -5,6 +5,7 @@ import { useEffect } from 'react'; import * as React from 'react'; import { onClientEntry } from '../gatsby-browser'; +import * as Sentry from '../src'; beforeAll(() => { (global as any).__SENTRY_RELEASE__ = '683f3a6ab819d47d23abfca9a914c81f0524d35b'; @@ -28,7 +29,7 @@ describe('useEffect', () => { function TestComponent() { useEffect(() => { const error = new Error('testing 123'); - (window as any).Sentry.captureException(error); + Sentry.captureException(error); }); return
Hello
; From 6623d43f6bd6783225ddeaf219d3e184180499b9 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:15:35 -0400 Subject: [PATCH 06/94] feat(hub): Remove getActiveDomain (#4858) Removes `getActiveDomain` function and corresponding type. --- packages/hub/src/hub.ts | 23 ----------------------- packages/hub/src/index.ts | 4 ---- 2 files changed, 27 deletions(-) diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index b6ebffc74866..94c8e3ea91fe 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -80,15 +80,6 @@ export interface Carrier { }; } -/** - * @hidden - * @deprecated Can be removed once `Hub.getActiveDomain` is removed. - */ -export interface DomainAsCarrier extends Carrier { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - members: { [key: string]: any }[]; -} - /** * @inheritDoc */ @@ -559,20 +550,6 @@ export function getCurrentHub(): Hub { return getHubFromCarrier(registry); } -/** - * Returns the active domain, if one exists - * @deprecated No longer used; remove in v7 - * @returns The domain, or undefined if there is no active domain - */ -// eslint-disable-next-line deprecation/deprecation -export function getActiveDomain(): DomainAsCarrier | undefined { - IS_DEBUG_BUILD && logger.warn('Function `getActiveDomain` is deprecated and will be removed in a future version.'); - - const sentry = getMainCarrier().__SENTRY__; - - return sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active; -} - /** * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist * @returns discovered hub diff --git a/packages/hub/src/index.ts b/packages/hub/src/index.ts index 9c0a77625dc2..3d3b97fa239b 100644 --- a/packages/hub/src/index.ts +++ b/packages/hub/src/index.ts @@ -2,8 +2,6 @@ export { addGlobalEventProcessor, Scope } from './scope'; export { Session } from './session'; export { SessionFlusher } from './sessionflusher'; export { - // eslint-disable-next-line deprecation/deprecation - getActiveDomain, getCurrentHub, getHubFromCarrier, getMainCarrier, @@ -11,7 +9,5 @@ export { makeMain, setHubOnCarrier, Carrier, - // eslint-disable-next-line deprecation/deprecation - DomainAsCarrier, Layer, } from './hub'; From 9094492d16b5f8396eb6ffc1c9666d9d79814ae5 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:17:36 -0400 Subject: [PATCH 07/94] feat(types): Remove deprecated user dsn field (#4864) The `user` dsn component was renamed to `publicKey`. This PR removes that from the dsn field. --- packages/types/src/dsn.ts | 2 -- packages/utils/src/dsn.ts | 6 ------ 2 files changed, 8 deletions(-) diff --git a/packages/types/src/dsn.ts b/packages/types/src/dsn.ts index b21130802903..761c52889caf 100644 --- a/packages/types/src/dsn.ts +++ b/packages/types/src/dsn.ts @@ -5,8 +5,6 @@ export type DsnProtocol = 'http' | 'https'; export interface DsnComponents { /** Protocol used to connect to Sentry. */ protocol: DsnProtocol; - /** Public authorization key (deprecated, renamed to publicKey). */ - user?: string; /** Public authorization key. */ publicKey?: string; /** Private authorization key (deprecated, optional). */ diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 0b58a7974821..5c500c5ec654 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -55,13 +55,7 @@ function dsnFromString(str: string): DsnComponents { } function dsnFromComponents(components: DsnComponents): DsnComponents { - // TODO this is for backwards compatibility, and can be removed in a future version - if ('user' in components && !('publicKey' in components)) { - components.publicKey = components.user; - } - return { - user: components.publicKey || '', protocol: components.protocol, publicKey: components.publicKey || '', pass: components.pass || '', From ffb8b169f2b6b743aad37682f7db42d7f001bbd0 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:18:08 -0400 Subject: [PATCH 08/94] feat(hub): Remove setTransaction scope method (#4865) --- packages/hub/src/scope.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 9243cd409b66..09dd244734ee 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -223,14 +223,6 @@ export class Scope implements ScopeInterface { return this; } - /** - * Can be removed in major version. - * @deprecated in favor of {@link this.setTransactionName} - */ - public setTransaction(name?: string): this { - return this.setTransactionName(name); - } - /** * @inheritDoc */ From 7ea63c7c7b4ba394fd22408d071b9d14ab75ccae Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:19:14 -0400 Subject: [PATCH 09/94] [v7] feat: Drop support for Node 6 (#4851) --- .github/workflows/build.yml | 2 +- packages/angular/package.json | 2 +- packages/browser/package.json | 2 +- packages/core/package.json | 2 +- packages/eslint-config-sdk/package.json | 2 +- packages/eslint-plugin-sdk/package.json | 2 +- packages/gatsby/package.json | 2 +- packages/hub/package.json | 2 +- packages/integrations/package.json | 2 +- packages/minimal/package.json | 2 +- packages/nextjs/package.json | 2 +- packages/node/package.json | 2 +- packages/node/test/integrations/http.test.ts | 4 +--- packages/react/package.json | 2 +- packages/tracing/package.json | 2 +- packages/types/package.json | 2 +- packages/utils/package.json | 2 +- packages/vue/package.json | 2 +- packages/wasm/package.json | 2 +- scripts/test.ts | 16 +--------------- 20 files changed, 20 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8f026b2729f..368412a4515c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -217,7 +217,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [6, 8, 10, 12, 14, 16] + node: [8, 10, 12, 14, 16] steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 diff --git a/packages/angular/package.json b/packages/angular/package.json index 58e11ebcdf0a..d1e1396acc10 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "dist/index.js", "module": "esm/index.js", diff --git a/packages/browser/package.json b/packages/browser/package.json index f87b9cd35a9d..5ba65a4c3b56 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/npm/dist/index.js", "module": "build/npm/esm/index.js", diff --git a/packages/core/package.json b/packages/core/package.json index 5db1a39a72ea..94093c3888f9 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index 4ae520a2c574..48606f73f334 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -12,7 +12,7 @@ "sentry" ], "engines": { - "node": ">=6" + "node": ">=8" }, "main": "src/index.js", "publishConfig": { diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index 8f2590530f13..4d44121da800 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -12,7 +12,7 @@ "sentry" ], "engines": { - "node": ">=6" + "node": ">=8" }, "main": "src/index.js", "publishConfig": { diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 8f9747d5c73b..4f1a814582d1 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -11,7 +11,7 @@ "gatsby-plugin" ], "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/hub/package.json b/packages/hub/package.json index 7c8c3a6f0a15..3325b6ea6b6d 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 277886f1288f..459fa6325107 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "publishConfig": { "access": "public" diff --git a/packages/minimal/package.json b/packages/minimal/package.json index df082f257383..7a303565e75e 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index d57ee16aa35a..51018abce6f0 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.server.js", "module": "build/esm/index.server.js", diff --git a/packages/node/package.json b/packages/node/package.json index 646a63662013..ba296a8fd672 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index c7a9c3e0a621..bc71b994c7a5 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -44,9 +44,7 @@ describe('tracing', () => { http.get('http://dogs.are.great/'); - // TODO: For some reason in node 6 two request spans are appearing. Once we stop testing against it, this can go - // back to being `toEqual()`. - expect(spans.length).toBeGreaterThanOrEqual(2); + expect(spans.length).toEqual(2); // our span is at index 1 because the transaction itself is at index 0 expect(spans[1].description).toEqual('GET http://dogs.are.great/'); diff --git a/packages/react/package.json b/packages/react/package.json index 29ad3a37651c..cfa931d6ed56 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/tracing/package.json b/packages/tracing/package.json index b79f4dc55268..2b75c54c3ff7 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/npm/dist/index.js", "module": "build/npm/esm/index.js", diff --git a/packages/types/package.json b/packages/types/package.json index da815e8c3aa8..7cf3960cbca7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/utils/package.json b/packages/utils/package.json index 8ac06877f541..ef9a398f99b2 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "BSD-3-Clause", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/vue/package.json b/packages/vue/package.json index 8c0711cba662..c36c8f688ab0 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/dist/index.js", "module": "build/esm/index.js", diff --git a/packages/wasm/package.json b/packages/wasm/package.json index caab3b56c8d8..babefffec6ba 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -7,7 +7,7 @@ "author": "Sentry", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" }, "main": "build/npm/dist/index.js", "module": "build/npm/esm/index.js", diff --git a/scripts/test.ts b/scripts/test.ts index 6c2efd8a1b68..51a1dc06245e 100644 --- a/scripts/test.ts +++ b/scripts/test.ts @@ -11,21 +11,7 @@ function run(cmd: string, cwd: string = '') { const nodeMajorVersion = parseInt(process.version.split('.')[0].replace('v', ''), 10); -// control which packages we test on each version of node -if (nodeMajorVersion <= 6) { - // install legacy versions of packages whose current versions don't support node 6 - // ignoring engines and scripts lets us get away with having incompatible things installed for packages we're not testing - run('yarn add --dev --ignore-engines --ignore-scripts nock@10.x', 'packages/node'); - run('yarn add --dev --ignore-engines --ignore-scripts jsdom@11.x', 'packages/tracing'); - run('yarn add --dev --ignore-engines --ignore-scripts jsdom@11.x', 'packages/utils'); - - // only test against @sentry/node and its dependencies - node 6 is too old for anything else to work - const scope = ['@sentry/core', '@sentry/hub', '@sentry/minimal', '@sentry/node', '@sentry/utils', '@sentry/tracing'] - .map(dep => `--scope="${dep}"`) - .join(' '); - - run(`yarn test ${scope}`); -} else if (nodeMajorVersion <= 8) { +if (nodeMajorVersion <= 8) { // install legacy versions of packages whose current versions don't support node 8 // ignoring engines and scripts lets us get away with having incompatible things installed for packages we're not testing run('yarn add --dev --ignore-engines --ignore-scripts jsdom@15.x', 'packages/tracing'); From 68317c47ea2ab8bd8a77bef60f3eae9b718c2de1 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 6 Apr 2022 21:16:08 -0400 Subject: [PATCH 10/94] [v7] feat(tracing): Rename registerRequestInstrumentation -> instrumentOutgoingRequests (#4859) --- packages/tracing/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/tracing/src/index.ts b/packages/tracing/src/index.ts index 89e3b3ba92d5..dcfea00f422a 100644 --- a/packages/tracing/src/index.ts +++ b/packages/tracing/src/index.ts @@ -26,8 +26,7 @@ export { Span, SpanStatusType, spanStatusfromHttpCode } from './span'; export { SpanStatus } from './spanstatus'; export { Transaction } from './transaction'; export { - // TODO deprecate old name in v7 - instrumentOutgoingRequests as registerRequestInstrumentation, + instrumentOutgoingRequests, RequestInstrumentationOptions, defaultRequestInstrumentationOptions, } from './browser'; From 780512bf9b82957ce4425d83513aaa699150bdf3 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 7 Apr 2022 14:26:42 +0200 Subject: [PATCH 11/94] fix(test): Increase MongoMemoryServer creation timeout (#4881) Increases the creation timeout of `MongoMemoryServer` to temporarily fix Node integration test flakiness --- .../suites/tracing/auto-instrument/mongodb/test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts index d118a03261a5..dd5f88f860ca 100644 --- a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts +++ b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts @@ -8,7 +8,7 @@ conditionalTest({ min: 12 })('MongoDB Test', () => { beforeAll(async () => { mongoServer = await MongoMemoryServer.create(); process.env.MONGO_URL = mongoServer.getUri(); - }, 30000); + }, 40000); afterAll(async () => { await mongoServer.stop(); From 7d3a3bfa2cf9de1289d42fa10ce565c7a8e6885a Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Thu, 7 Apr 2022 16:01:27 +0100 Subject: [PATCH 12/94] [v7] feat(node): Remove deprecated `frameContextLines` (#4884) This PR removes the previously deprecated `frameContextLines` from `NodeOptions`. --- packages/node/src/integrations/contextlines.ts | 13 ------------- packages/node/src/types.ts | 15 --------------- 2 files changed, 28 deletions(-) diff --git a/packages/node/src/integrations/contextlines.ts b/packages/node/src/integrations/contextlines.ts index e18768b2fe3d..cad196342f28 100644 --- a/packages/node/src/integrations/contextlines.ts +++ b/packages/node/src/integrations/contextlines.ts @@ -1,11 +1,8 @@ -import { getCurrentHub } from '@sentry/core'; import { Event, EventProcessor, Integration, StackFrame } from '@sentry/types'; import { addContextToFrame } from '@sentry/utils'; import { readFile } from 'fs'; import { LRUMap } from 'lru_map'; -import { NodeClient } from '../client'; - const FILE_CONTENT_CACHE = new LRUMap(100); const DEFAULT_LINES_OF_CONTEXT = 7; @@ -53,16 +50,6 @@ export class ContextLines implements Integration { /** Get's the number of context lines to add */ private get _contextLines(): number { - // This is only here to copy frameContextLines from init options if it hasn't - // been set via this integrations constructor. - // - // TODO: Remove on next major! - if (this._options.frameContextLines === undefined) { - const initOptions = getCurrentHub().getClient()?.getOptions(); - // eslint-disable-next-line deprecation/deprecation - this._options.frameContextLines = initOptions?.frameContextLines; - } - return this._options.frameContextLines !== undefined ? this._options.frameContextLines : DEFAULT_LINES_OF_CONTEXT; } diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 6c6651bc7b88..055006a47e9e 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -20,21 +20,6 @@ export interface NodeOptions extends Options { /** HTTPS proxy certificates path */ caCerts?: string; - /** - * Sets the number of context lines for each frame when loading a file. - * - * @deprecated Context lines configuration has moved to the `ContextLines` integration, and can be used like this: - * - * ``` - * init({ - * dsn: '__DSN__', - * integrations: [new ContextLines({ frameContextLines: 10 })] - * }) - * ``` - * - * */ - frameContextLines?: number; - /** Callback that is executed when a fatal global error occurs. */ onFatalError?(error: Error): void; } From 9d29071bff6d42c43a3831ecb53726e35153a635 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Thu, 7 Apr 2022 17:17:31 +0100 Subject: [PATCH 13/94] [v7] feat(browser): Remove top level eventbuilder exports (#4887) These exports were historically used in `@sentry/electron`, but are no longer being used by the Electron SDK or the React Native SDK, so they can be removed. --- packages/browser/src/exports.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 86ace0abbdd5..b4dd4374a7b3 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -44,6 +44,5 @@ export { export { BrowserOptions } from './backend'; export { BrowserClient } from './client'; export { injectReportDialog, ReportDialogOptions } from './helpers'; -export { eventFromException, eventFromMessage } from './eventbuilder'; export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close, wrap } from './sdk'; export { SDK_NAME } from './version'; From cbbc15da3f2060a391333cdc505afd3643722034 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 7 Apr 2022 16:20:52 -0700 Subject: [PATCH 14/94] ref(build): Update to TypeScript 3.8.3 (#4895) This updates the SDK to use Typescript 3.8.3, in order to be able to use type-only imports and exports[1]. (These are needed for us to turn on `isolatedModules`, which is in turn is needed for us to switch our build tool away from `tsc`[2], since no other tool understands the relationship between files.) As a result of this change, a few of the browser integration tests needed to be fixed so that all promises were explicitly awaited, a point about which the linter in 3.8 complains. This is a breaking change for anyone using TS 3.7.x (there's no one using TS < 3.7.x, since that's our current minimum). That said, though there are plenty of public projects on GH using TS 3.7 and `@sentry/xyz`, if you restrict it to projects using TS 3.7 and `@sentry/xyz` 6.x, all you get are forks of this very repo. Granted, this isn't every project ever, but it's likely decently representative of the fact that if you've upgraded our SDK, you've almost certainly upgraded TS as well. We're going to wait until v7 to release this change in any case, but that's an indication that it won't affect many people when we do. (See this commit's PR for links to searches demonstrating the points.) Note: Originally there was some thought of going farther, into TS 4.x, but we decided that for the foreseeable future, we're going to stick with 3.8.3. Though moving up to 4.x doesn't seem like it would affect many customers (repeating the same TS/sentry 6.x crossover search with TS 3.8 and 3.9 reveals a total of 5 projects), it does have the known side effect of replacing export statements which, after compilation, currently look like `exports.SdkInfo = types_1.SdkInfo;` with ones that look like `Object.defineProperty(exports, "SdkInfo", { enumerable: true, get: function () { return types_1.SdkInfo; } });`. (For those of you following along at home, that's a 3x character increase.) Though we might be able to engineer around this in order to avoid the inevitable substantial bundle size hit, attempting to do so is only worth it if there are features from 4.x that we desperately need. Given that we've agreed that right now there aren't, we'll stick with 3.8.3. [1] https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export [2] https://www.typescriptlang.org/tsconfig#isolatedModules --- package.json | 2 +- .../tracing/browsertracing/backgroundtab-pageload/test.ts | 2 +- .../suites/tracing/metrics/web-vitals-fid/test.ts | 4 ++-- .../suites/tracing/metrics/web-vitals-lcp/test.ts | 4 ++-- packages/typescript/package.json | 2 +- scripts/verify-packages-versions.js | 2 +- yarn.lock | 8 ++++---- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 14d73feddc03..e1f42542b33d 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "ts-node": "^8.10.2", "tslib": "^2.3.1", "typedoc": "^0.18.0", - "typescript": "3.7.5" + "typescript": "3.8.3" }, "resolutions": { "**/agent-base": "5", diff --git a/packages/integration-tests/suites/tracing/browsertracing/backgroundtab-pageload/test.ts b/packages/integration-tests/suites/tracing/browsertracing/backgroundtab-pageload/test.ts index 42787cbb4819..47f695b0440c 100644 --- a/packages/integration-tests/suites/tracing/browsertracing/backgroundtab-pageload/test.ts +++ b/packages/integration-tests/suites/tracing/browsertracing/backgroundtab-pageload/test.ts @@ -9,7 +9,7 @@ sentryTest('should finish pageload transaction when the page goes background', a await page.goto(url); - page.click('#go-background'); + void page.click('#go-background'); const pageloadTransaction = await getFirstSentryEnvelopeRequest(page); diff --git a/packages/integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts b/packages/integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts index ed3a86676867..0eaa60a75031 100644 --- a/packages/integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts +++ b/packages/integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts @@ -12,9 +12,9 @@ sentryTest('should capture a FID vital.', async ({ browserName, getLocalTestPath const url = await getLocalTestPath({ testDir: __dirname }); - page.goto(url); + await page.goto(url); // To trigger FID - page.click('#fid-btn'); + await page.click('#fid-btn'); const eventData = await getFirstSentryEnvelopeRequest(page); diff --git a/packages/integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts b/packages/integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts index 2eb554013280..32f86d3c54d1 100644 --- a/packages/integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts +++ b/packages/integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts @@ -14,10 +14,10 @@ sentryTest('should capture a LCP vital with element details.', async ({ browserN ); const url = await getLocalTestPath({ testDir: __dirname }); - page.goto(url); + await page.goto(url); // Force closure of LCP listener. - page.click('body'); + await page.click('body'); const eventData = await getFirstSentryEnvelopeRequest(page); expect(eventData.measurements).toBeDefined(); diff --git a/packages/typescript/package.json b/packages/typescript/package.json index f212b98752dc..c564c0c3e344 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -16,7 +16,7 @@ }, "peerDependencies": { "tslint": "5.16.0", - "typescript": "3.7.5" + "typescript": "3.8.3" }, "scripts": { "link:yarn": "yarn link", diff --git a/scripts/verify-packages-versions.js b/scripts/verify-packages-versions.js index fb6a6e95ec7f..e0efc39311bc 100644 --- a/scripts/verify-packages-versions.js +++ b/scripts/verify-packages-versions.js @@ -1,6 +1,6 @@ const pkg = require('../package.json'); -const TYPESCRIPT_VERSION = '3.7.5'; +const TYPESCRIPT_VERSION = '3.8.3'; if (pkg.devDependencies.typescript !== TYPESCRIPT_VERSION) { console.error(` diff --git a/yarn.lock b/yarn.lock index 81cd3f64044a..26947533ab88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21523,10 +21523,10 @@ typescript-memoize@^1.0.1: resolved "https://registry.yarnpkg.com/typescript-memoize/-/typescript-memoize-1.0.1.tgz#0a8199aa28f6fe18517f6e9308ef7bfbe9a98d59" integrity sha512-oJNge1qUrOK37d5Y6Ly2txKeuelYVsFtNF6U9kXIN7juudcQaHJQg2MxLOy0CqtkW65rVDYuTCOjnSIVPd8z3w== -typescript@3.7.5: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== +typescript@3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== typescript@^3.9.5, typescript@^3.9.7: version "3.9.9" From 14bb9ac928e8c87ccce2bc68e6e5670bc2ebead9 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 8 Apr 2022 15:01:10 +0200 Subject: [PATCH 15/94] build(bundles): Stop publishing CDN bundles on npm (#4901) --- .npmignore | 3 --- packages/wasm/package.json | 2 +- scripts/prepack.ts | 21 --------------------- 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/.npmignore b/.npmignore index 4ab7cc4f278f..facb3a101f90 100644 --- a/.npmignore +++ b/.npmignore @@ -3,9 +3,6 @@ * -# TODO remove bundles (which in the tarball are inside `build`) in v7 -!/build/**/* - !/dist/**/* !/esm/**/* !/types/**/* diff --git a/packages/wasm/package.json b/packages/wasm/package.json index babefffec6ba..775e80b8ec43 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -43,7 +43,7 @@ "build:es5:watch": "yarn build:cjs:watch # *** backwards compatibility - remove in v7 ***", "build:esm:watch": "tsc -p tsconfig.esm.json --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", - "build:npm": "ts-node ../../scripts/prepack.ts --bundles --skipBundleCopy && npm pack ./build/npm", + "build:npm": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", "circularDepCheck": "madge --circular src/index.ts", "clean": "rimraf dist esm build coverage *.js.map *.d.ts", "fix": "run-s fix:eslint fix:prettier", diff --git a/scripts/prepack.ts b/scripts/prepack.ts index bac7a544a2f5..a7609a8087bd 100644 --- a/scripts/prepack.ts +++ b/scripts/prepack.ts @@ -7,7 +7,6 @@ */ import * as fs from 'fs'; -import * as fse from 'fs-extra'; import * as path from 'path'; const NPM_BUILD_DIR = 'build/npm'; @@ -49,26 +48,6 @@ ASSETS.forEach(asset => { } }); -// TODO remove in v7! Until then: -// copy CDN bundles into npm dir to temporarily keep bundles in npm tarball -// inside the tarball, they are located in `build/` -// for now, copy it by default, unless explicitly forbidden via an command line arg -const tmpCopyBundles = packageWithBundles && !process.argv.includes('--skipBundleCopy'); -if (tmpCopyBundles) { - const npmTmpBundlesPath = path.resolve(buildDir, 'build'); - const cdnBundlesPath = path.resolve('build', 'bundles'); - try { - if (!fs.existsSync(npmTmpBundlesPath)) { - fs.mkdirSync(npmTmpBundlesPath); - } - void fse.copy(cdnBundlesPath, npmTmpBundlesPath); - } catch (error) { - console.error(`Error while tmp copying CDN bundles to ${buildDir}`); - process.exit(1); - } -} -// end remove - // package.json modifications const packageJsonPath = path.resolve(buildDir, 'package.json'); // eslint-disable-next-line @typescript-eslint/no-var-requires From 4bb3c649cdd303c09c07b81b1f96c67ad9805e0d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 8 Apr 2022 09:59:43 -0400 Subject: [PATCH 16/94] feat(types): Delete RequestSessionStatus enum (#4889) --- packages/types/src/requestsessionstatus.ts | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 packages/types/src/requestsessionstatus.ts diff --git a/packages/types/src/requestsessionstatus.ts b/packages/types/src/requestsessionstatus.ts deleted file mode 100644 index b6b7ab9ee659..000000000000 --- a/packages/types/src/requestsessionstatus.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** JSDoc - * @deprecated Use string literals - if you require type casting, cast to RequestSessionStatus type - */ -export enum RequestSessionStatus { - /** JSDoc */ - Ok = 'ok', - /** JSDoc */ - Errored = 'errored', - /** JSDoc */ - Crashed = 'crashed', -} From 2e1eaf36c9e23763bcf73f7d974d7405bc47cbbd Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 8 Apr 2022 10:00:02 -0400 Subject: [PATCH 17/94] [v7] feat(types): Delete Status enum (#4891) --- packages/types/src/status.ts | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 packages/types/src/status.ts diff --git a/packages/types/src/status.ts b/packages/types/src/status.ts deleted file mode 100644 index a80cd00b97e7..000000000000 --- a/packages/types/src/status.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** JSDoc - * @deprecated Use string literals - if you require type casting, cast to EventStatus type - */ -export enum Status { - /** The status could not be determined. */ - Unknown = 'unknown', - /** The event was skipped due to configuration or callbacks. */ - Skipped = 'skipped', - /** The event was sent to Sentry successfully. */ - Success = 'success', - /** The client is currently rate limited and will try again later. */ - RateLimit = 'rate_limit', - /** The event could not be processed. */ - Invalid = 'invalid', - /** A server-side error occurred during submission. */ - Failed = 'failed', -} From 899ed58a22462493118078901f610097b5c9d9de Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 8 Apr 2022 17:12:20 +0200 Subject: [PATCH 18/94] ref(build): Rename `dist` directories to `cjs` (#4900) rename the dist directories in all build dirs to cjs. Hence, also the tarballs' structure changes which is why this PR also introduces a breaking change. Additional change: cleanup `yarn clean` commands by removing no longer existing directories --- .eslintrc.js | 11 ++++- .github/workflows/build.yml | 2 +- .gitignore | 2 +- .npmignore | 2 +- .vscode/launch.json | 49 +++++++------------ packages/angular/.npmignore | 2 +- packages/angular/package.json | 4 +- packages/angular/tsconfig.cjs.json | 2 +- packages/browser/package.json | 2 +- packages/browser/test/package/test-code.js | 4 +- packages/browser/tsconfig.cjs.json | 2 +- packages/core/package.json | 4 +- packages/core/tsconfig.cjs.json | 2 +- packages/gatsby/.npmignore | 2 +- packages/gatsby/package.json | 4 +- packages/gatsby/tsconfig.cjs.json | 2 +- packages/hub/package.json | 4 +- packages/hub/tsconfig.cjs.json | 2 +- .../integration-tests/utils/generatePlugin.ts | 4 +- packages/integrations/package.json | 4 +- packages/integrations/tsconfig.cjs.json | 2 +- packages/minimal/package.json | 4 +- packages/minimal/tsconfig.cjs.json | 2 +- packages/nextjs/package.json | 6 +-- packages/nextjs/tsconfig.cjs.json | 2 +- .../vercel/install-sentry-from-branch.sh | 2 +- packages/node/package.json | 4 +- .../node/test/manual/apm-transaction/main.js | 2 +- .../manual/express-scope-separation/start.js | 2 +- .../test/manual/memory-leak/context-memory.js | 2 +- .../manual/memory-leak/express-patient.js | 2 +- .../aggregates-disable-single-session.js | 2 +- .../caught-exception-errored-session.js | 2 +- .../errors-in-session-capped-to-one.js | 2 +- .../single-session/healthy-session.js | 2 +- .../terminal-state-sessions-sent-once.js | 2 +- .../uncaught-exception-crashed-session.js | 2 +- .../unhandled-rejection-crashed-session.js | 2 +- .../node/test/manual/webpack-domain/index.js | 2 +- packages/node/tsconfig.cjs.json | 2 +- packages/react/package.json | 4 +- packages/react/tsconfig.cjs.json | 2 +- packages/serverless/README.md | 2 +- packages/serverless/package.json | 4 +- .../scripts/build-awslambda-layer.js | 2 +- packages/serverless/tsconfig.cjs.json | 2 +- packages/tracing/package.json | 6 +-- packages/tracing/tsconfig.cjs.json | 2 +- packages/types/package.json | 4 +- packages/types/tsconfig.cjs.json | 2 +- packages/utils/package.json | 4 +- packages/utils/test/types/index.js | 2 +- packages/utils/tsconfig.cjs.json | 2 +- packages/vue/package.json | 4 +- packages/vue/tsconfig.cjs.json | 2 +- packages/wasm/package.json | 4 +- packages/wasm/tsconfig.cjs.json | 2 +- tsconfig-templates/tsconfig.cjs.json | 2 +- typedoc.js | 2 +- 59 files changed, 105 insertions(+), 107 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index a081c38c7ade..da303c683c01 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,16 @@ module.exports = { ecmaVersion: 2018, }, extends: ['@sentry-internal/sdk'], - ignorePatterns: ['coverage/**', 'build/**', 'dist/**', 'esm/**', 'examples/**', 'test/manual/**', 'types/**'], + ignorePatterns: [ + 'coverage/**', + 'build/**', + 'dist/**', + 'cjs/**', + 'esm/**', + 'examples/**', + 'test/manual/**', + 'types/**', + ], overrides: [ { files: ['*.ts', '*.tsx', '*.d.ts'], diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 368412a4515c..aec9e06c66dc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ env: CACHED_BUILD_PATHS: | ${{ github.workspace }}/packages/**/build - ${{ github.workspace }}/packages/**/dist + ${{ github.workspace }}/packages/**/cjs ${{ github.workspace }}/packages/**/esm ${{ github.workspace }}/packages/ember/*.d.ts ${{ github.workspace }}/packages/ember/instance-initializers diff --git a/.gitignore b/.gitignore index 01098a94ef9f..4418a41432bc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ package-lock.json # build and test build/ -packages/*/dist/ +packages/*/cjs/ packages/*/esm/ coverage/ scratch/ diff --git a/.npmignore b/.npmignore index facb3a101f90..cb864514088e 100644 --- a/.npmignore +++ b/.npmignore @@ -3,6 +3,6 @@ * -!/dist/**/* +!/cjs/**/* !/esm/**/* !/types/**/* diff --git a/.vscode/launch.json b/.vscode/launch.json index 9670683310d6..bef12bd786af 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,16 +5,16 @@ "version": "0.2.0", "inputs": [ { - "id": "getPackageName", - "type": "command", - "command": "shellCommand.execute", - "args": { - "command": "echo '${file}' | sed s/'.*sentry-javascript\\/packages\\/'// | grep --extended-regexp --only-matching --max-count 1 '[^\\/]+' | head -1", - "cwd": "${workspaceFolder}" , - // normally `input` commands bring up a selector for the user, but given that there should only be one - // choice here, this lets us skip the prompt - "useSingleResult": true - } + "id": "getPackageName", + "type": "command", + "command": "shellCommand.execute", + "args": { + "command": "echo '${file}' | sed s/'.*sentry-javascript\\/packages\\/'// | grep --extended-regexp --only-matching --max-count 1 '[^\\/]+' | head -1", + "cwd": "${workspaceFolder}", + // normally `input` commands bring up a selector for the user, but given that there should only be one + // choice here, this lets us skip the prompt + "useSingleResult": true + } } ], "configurations": [ @@ -25,18 +25,9 @@ "cwd": "${workspaceFolder}/packages/${input:getPackageName}", "request": "launch", "runtimeExecutable": "yarn", - "runtimeArgs": [ - "rollup", - "-c", - "${file}" - ], - "skipFiles": [ - "/**" - ], - "outFiles": [ - "${workspaceFolder}/**/*.js", - "!**/node_modules/**" - ], + "runtimeArgs": ["rollup", "-c", "${file}"], + "skipFiles": ["/**"], + "outFiles": ["${workspaceFolder}/**/*.js", "!**/node_modules/**"], "sourceMaps": true, "smartStep": true, "internalConsoleOptions": "openOnSessionStart", @@ -67,14 +58,13 @@ ], "sourceMaps": true, "smartStep": true, - // otherwise it goes to the VSCode debug terminal, which prints the test output or console logs (depending on - // "outputCapture" option here; default is to show console logs), but not both + // otherwise it goes to the VSCode debug terminal, which prints the test output or console logs (depending on + // "outputCapture" option here; default is to show console logs), but not both "console": "integratedTerminal", // since we're not using it, don't automatically switch to it - "internalConsoleOptions": "neverOpen", + "internalConsoleOptions": "neverOpen" }, - // @sentry/nextjs - Run a specific integration test file // Must have test file in currently active tab when hitting the play button, and must already have run `yarn` in test app directory { @@ -105,18 +95,17 @@ // this controls which files are sourcemapped "outFiles": [ // our SDK code - "${workspaceFolder}/**/dist/**/*.js", + "${workspaceFolder}/**/cjs/**/*.js", // the built test app "${workspaceFolder}/packages/nextjs/test/integration/.next/**/*.js", "!**/node_modules/**" ], "resolveSourceMapLocations": [ - "${workspaceFolder}/**/dist/**", + "${workspaceFolder}/**/cjs/**", "${workspaceFolder}/packages/nextjs/test/integration/.next/**", "!**/node_modules/**" ], "internalConsoleOptions": "openOnSessionStart" - - }, + } ] } diff --git a/packages/angular/.npmignore b/packages/angular/.npmignore index 8904efca5aea..75ee79933841 100644 --- a/packages/angular/.npmignore +++ b/packages/angular/.npmignore @@ -1,4 +1,4 @@ * -!/dist/**/* +!/cjs/**/* !/esm/**/* !/build/types/**/* diff --git a/packages/angular/package.json b/packages/angular/package.json index d1e1396acc10..9db6f128eaf0 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "dist/index.js", + "main": "cjs/index.js", "module": "esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -47,7 +47,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "npm pack", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf cjs esm build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/angular/tsconfig.cjs.json b/packages/angular/tsconfig.cjs.json index abd80f77e1ff..4ec31d2ff68b 100644 --- a/packages/angular/tsconfig.cjs.json +++ b/packages/angular/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "dist" + "outDir": "cjs" } } diff --git a/packages/browser/package.json b/packages/browser/package.json index 5ba65a4c3b56..2c498962fb0a 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/npm/dist/index.js", + "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "publishConfig": { diff --git a/packages/browser/test/package/test-code.js b/packages/browser/test/package/test-code.js index e05a667db274..3a3811eebb89 100644 --- a/packages/browser/test/package/test-code.js +++ b/packages/browser/test/package/test-code.js @@ -1,6 +1,6 @@ /* eslint-disable no-console */ -const Sentry = require('../../build/npm/dist/index.js'); -const Integrations = require('../../../integrations/build/npm/dist/dedupe.js'); +const Sentry = require('../../build/npm/cjs/index.js'); +const Integrations = require('../../../integrations/build/npm/cjs/dedupe.js'); // Init Sentry.init({ diff --git a/packages/browser/tsconfig.cjs.json b/packages/browser/tsconfig.cjs.json index 6782dae5e453..0fa3132e7510 100644 --- a/packages/browser/tsconfig.cjs.json +++ b/packages/browser/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/npm/dist" + "outDir": "build/npm/cjs" } } diff --git a/packages/core/package.json b/packages/core/package.json index 94093c3888f9..c6422c4dab99 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -37,7 +37,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/core/tsconfig.cjs.json b/packages/core/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/core/tsconfig.cjs.json +++ b/packages/core/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/gatsby/.npmignore b/packages/gatsby/.npmignore index b8bb08da7374..66474694b223 100644 --- a/packages/gatsby/.npmignore +++ b/packages/gatsby/.npmignore @@ -3,7 +3,7 @@ * -!/dist/**/* +!/cjs/**/* !/esm/**/* !/types/**/* diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 4f1a814582d1..1789fe091a4f 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -13,7 +13,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -48,7 +48,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/gatsby/tsconfig.cjs.json b/packages/gatsby/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/gatsby/tsconfig.cjs.json +++ b/packages/gatsby/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/hub/package.json b/packages/hub/package.json index 3325b6ea6b6d..45408c158c39 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -35,7 +35,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/hub/tsconfig.cjs.json b/packages/hub/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/hub/tsconfig.cjs.json +++ b/packages/hub/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/integration-tests/utils/generatePlugin.ts b/packages/integration-tests/utils/generatePlugin.ts index 5163f81a668a..1a7ebefad0b7 100644 --- a/packages/integration-tests/utils/generatePlugin.ts +++ b/packages/integration-tests/utils/generatePlugin.ts @@ -17,7 +17,7 @@ const useBundle = bundleKey && !useCompiledModule; const BUNDLE_PATHS: Record> = { browser: { - cjs: 'build/npm/dist/index.js', + cjs: 'build/npm/cjs/index.js', esm: 'build/npm/esm/index.js', bundle_es5: 'build/bundles/bundle.js', bundle_es5_min: 'build/bundles/bundle.min.js', @@ -25,7 +25,7 @@ const BUNDLE_PATHS: Record> = { bundle_es6_min: 'build/bundles/bundle.es6.min.js', }, tracing: { - cjs: 'build/npm/dist/index.js', + cjs: 'build/npm/cjs/index.js', esm: 'build/npm/esm/index.js', bundle_es5: 'build/bundles/bundle.tracing.js', bundle_es5_min: 'build/bundles/bundle.tracing.min.js', diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 459fa6325107..ede4c816e00d 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -12,7 +12,7 @@ "publishConfig": { "access": "public" }, - "main": "build/npm/dist/index.js", + "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "dependencies": { @@ -40,7 +40,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage .rpt2_cache", + "clean": "rimraf build coverage .rpt2_cache", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/integrations/tsconfig.cjs.json b/packages/integrations/tsconfig.cjs.json index 6782dae5e453..0fa3132e7510 100644 --- a/packages/integrations/tsconfig.cjs.json +++ b/packages/integrations/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/npm/dist" + "outDir": "build/npm/cjs" } } diff --git a/packages/minimal/package.json b/packages/minimal/package.json index 7a303565e75e..4a8b6630cae0 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -35,7 +35,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/minimal/tsconfig.cjs.json b/packages/minimal/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/minimal/tsconfig.cjs.json +++ b/packages/minimal/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 51018abce6f0..cec39c72c4aa 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.server.js", + "main": "build/cjs/index.server.js", "module": "build/esm/index.server.js", "browser": "build/esm/index.client.js", "types": "build/types/index.server.d.ts", @@ -57,7 +57,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.client.ts && madge --circular --exclude 'config/types\\.ts' src/index.server.ts # see https://github.com/pahen/madge/issues/306", - "clean": "rimraf dist esm build coverage *.js *.js.map *.d.ts", + "clean": "rimraf build coverage *.js *.js.map *.d.ts", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", @@ -97,7 +97,7 @@ } }, "sideEffects": [ - "./dist/index.server.js", + "./cjs/index.server.js", "./esm/index.server.js", "./src/index.server.ts" ] diff --git a/packages/nextjs/tsconfig.cjs.json b/packages/nextjs/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/nextjs/tsconfig.cjs.json +++ b/packages/nextjs/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/nextjs/vercel/install-sentry-from-branch.sh b/packages/nextjs/vercel/install-sentry-from-branch.sh index af79d10ea04e..704601894308 100644 --- a/packages/nextjs/vercel/install-sentry-from-branch.sh +++ b/packages/nextjs/vercel/install-sentry-from-branch.sh @@ -28,7 +28,7 @@ yarn --prod false echo " " echo "BUILDING SDK" # We need to build es5 versions because `next.config.js` calls `require` on the SDK (to get `withSentryConfig`) and -# therefore it looks for `dist/index.js` +# therefore it looks for `cjs/index.js` yarn build:cjs # We need to build esm versions because that's what `next` actually uses when it builds the app yarn build:esm diff --git a/packages/node/package.json b/packages/node/package.json index ba296a8fd672..a9048c5b67a4 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -48,7 +48,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/node/test/manual/apm-transaction/main.js b/packages/node/test/manual/apm-transaction/main.js index e34088b4eaaf..0584177e8b10 100644 --- a/packages/node/test/manual/apm-transaction/main.js +++ b/packages/node/test/manual/apm-transaction/main.js @@ -1,7 +1,7 @@ const http = require('http'); const express = require('express'); const app = express(); -const Sentry = require('../../../build/dist'); +const Sentry = require('../../../build/cjs'); Sentry.init({ debug: true, diff --git a/packages/node/test/manual/express-scope-separation/start.js b/packages/node/test/manual/express-scope-separation/start.js index 2e89fa14f4ec..9146c3ab2eba 100644 --- a/packages/node/test/manual/express-scope-separation/start.js +++ b/packages/node/test/manual/express-scope-separation/start.js @@ -1,7 +1,7 @@ const http = require('http'); const express = require('express'); const app = express(); -const Sentry = require('../../../build/dist'); +const Sentry = require('../../../build/cjs'); function assertTags(actual, expected) { if (JSON.stringify(actual) !== JSON.stringify(expected)) { diff --git a/packages/node/test/manual/memory-leak/context-memory.js b/packages/node/test/manual/memory-leak/context-memory.js index 9c63343c1fd8..6c124d542ce5 100644 --- a/packages/node/test/manual/memory-leak/context-memory.js +++ b/packages/node/test/manual/memory-leak/context-memory.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../build/dist'); +const Sentry = require('../../../build/cjs'); Sentry.init({ dsn: 'https://public@app.getsentry.com/12345' }); diff --git a/packages/node/test/manual/memory-leak/express-patient.js b/packages/node/test/manual/memory-leak/express-patient.js index 90be8be575d4..7a677a442972 100644 --- a/packages/node/test/manual/memory-leak/express-patient.js +++ b/packages/node/test/manual/memory-leak/express-patient.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../build/dist'); +const Sentry = require('../../../build/cjs'); Sentry.init({ dsn: 'https://public@app.getsentry.com/12345' }); diff --git a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js index cedd795e9a57..0c536e0accae 100644 --- a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js +++ b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js @@ -1,7 +1,7 @@ const http = require('http'); const express = require('express'); const app = express(); -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, BaseDummyTransport } = require('../test-utils'); function cleanUpAndExitSuccessfully() { diff --git a/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js b/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js index 9f538a1ba993..db052b2bc508 100644 --- a/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js +++ b/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, diff --git a/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js b/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js index 65c2bf05ef7f..983f10e9b294 100644 --- a/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js +++ b/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, diff --git a/packages/node/test/manual/release-health/single-session/healthy-session.js b/packages/node/test/manual/release-health/single-session/healthy-session.js index 05712ae7dcc2..1906b8196bf5 100644 --- a/packages/node/test/manual/release-health/single-session/healthy-session.js +++ b/packages/node/test/manual/release-health/single-session/healthy-session.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, diff --git a/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js b/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js index 1fe58a972569..b2692957aa70 100644 --- a/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js +++ b/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, diff --git a/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js b/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js index 8007b7d0ea4c..eaf247aa080a 100644 --- a/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js +++ b/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, BaseDummyTransport } = require('../test-utils'); class DummyTransport extends BaseDummyTransport { diff --git a/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js b/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js index f24c557c878a..c5a1874024ba 100644 --- a/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js +++ b/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../../build/dist'); +const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, diff --git a/packages/node/test/manual/webpack-domain/index.js b/packages/node/test/manual/webpack-domain/index.js index e0479e0fec78..521699a6349a 100644 --- a/packages/node/test/manual/webpack-domain/index.js +++ b/packages/node/test/manual/webpack-domain/index.js @@ -1,4 +1,4 @@ -const Sentry = require('../../../build/dist'); +const Sentry = require('../../../build/cjs'); let remaining = 2; diff --git a/packages/node/tsconfig.cjs.json b/packages/node/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/node/tsconfig.cjs.json +++ b/packages/node/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/react/package.json b/packages/react/package.json index cfa931d6ed56..a92935e9c793 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -63,7 +63,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/react/tsconfig.cjs.json b/packages/react/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/react/tsconfig.cjs.json +++ b/packages/react/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/serverless/README.md b/packages/serverless/README.md index 4b99dde9b424..e6f819f0cf66 100644 --- a/packages/serverless/README.md +++ b/packages/serverless/README.md @@ -60,7 +60,7 @@ Another and much simpler way to integrate Sentry to your AWS Lambda function is 1. Choose Layers -> Add Layer. 2. Specify an ARN: `arn:aws:lambda:us-west-1:TODO:layer:TODO:VERSION`. 3. Go to Environment variables and add: - - `NODE_OPTIONS`: `-r @sentry/serverless/dist/awslambda-auto`. + - `NODE_OPTIONS`: `-r @sentry/serverless/cjs/awslambda-auto`. - `SENTRY_DSN`: `your dsn`. - `SENTRY_TRACES_SAMPLE_RATE`: a number between 0 and 1 representing the chance a transaction is sent to Sentry. For more information, see [docs](https://docs.sentry.io/platforms/node/guides/aws-lambda/configuration/options/#tracesSampleRate). diff --git a/packages/serverless/package.json b/packages/serverless/package.json index ae3d084758d6..39ce5479d2bb 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=10" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -54,7 +54,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build dist-awslambda-layer coverage", + "clean": "rimraf build dist-awslambda-layer coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/serverless/scripts/build-awslambda-layer.js b/packages/serverless/scripts/build-awslambda-layer.js index 674dba133c73..377abfbdf425 100644 --- a/packages/serverless/scripts/build-awslambda-layer.js +++ b/packages/serverless/scripts/build-awslambda-layer.js @@ -69,7 +69,7 @@ async function collectPackages(cwd, packages = {}) { async function main() { const workDir = path.resolve(__dirname, '..'); // packages/serverless directory - const distRequirements = path.resolve(workDir, 'build', 'dist'); + const distRequirements = path.resolve(workDir, 'build', 'cjs'); if (!fs.existsSync(distRequirements)) { console.log(`The path ${distRequirements} must exist.`); return; diff --git a/packages/serverless/tsconfig.cjs.json b/packages/serverless/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/serverless/tsconfig.cjs.json +++ b/packages/serverless/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 2b75c54c3ff7..1d99f2a3b564 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/npm/dist/index.js", + "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "publishConfig": { @@ -44,7 +44,7 @@ "build:esm:watch": "tsc -p tsconfig.esm.json --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf build coverage", "circularDepCheck": "madge --circular src/index.ts", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", @@ -80,7 +80,7 @@ } }, "sideEffects": [ - "./npm/dist/index.js", + "./npm/cjs/index.js", "./npm/esm/index.js", "./src/index.ts" ] diff --git a/packages/tracing/tsconfig.cjs.json b/packages/tracing/tsconfig.cjs.json index 6782dae5e453..0fa3132e7510 100644 --- a/packages/tracing/tsconfig.cjs.json +++ b/packages/tracing/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/npm/dist" + "outDir": "build/npm/cjs" } } diff --git a/packages/types/package.json b/packages/types/package.json index 7cf3960cbca7..aaf97dc1b6d7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -29,7 +29,7 @@ "build:esm:watch": "tsc -p tsconfig.esm.json --watch", "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", - "clean": "rimraf dist esm build", + "clean": "rimraf build", "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", diff --git a/packages/types/tsconfig.cjs.json b/packages/types/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/types/tsconfig.cjs.json +++ b/packages/types/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/utils/package.json b/packages/utils/package.json index ef9a398f99b2..39df57d9e1fa 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -38,7 +38,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage *.js *.js.map *.d.ts", + "clean": "rimraf build coverage *.js *.js.map *.d.ts", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/utils/test/types/index.js b/packages/utils/test/types/index.js index a8f9e9360b68..7b6936691197 100644 --- a/packages/utils/test/types/index.js +++ b/packages/utils/test/types/index.js @@ -3,7 +3,7 @@ const path = require('path'); const testStrings = ['/// ']; -const paths = [path.join('./build/dist'), path.join('./build/esm')]; +const paths = [path.join('./build/cjs'), path.join('./build/esm')]; paths.forEach(dir => { if (!fs.existsSync(dir)) { diff --git a/packages/utils/tsconfig.cjs.json b/packages/utils/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/utils/tsconfig.cjs.json +++ b/packages/utils/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/vue/package.json b/packages/vue/package.json index c36c8f688ab0..01610c1ad8ab 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/dist/index.js", + "main": "build/cjs/index.js", "module": "build/esm/index.js", "types": "build/types/index.d.ts", "publishConfig": { @@ -46,7 +46,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage", + "clean": "rimraf esm build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/vue/tsconfig.cjs.json b/packages/vue/tsconfig.cjs.json index e3a918fc70af..c1edc81a9657 100644 --- a/packages/vue/tsconfig.cjs.json +++ b/packages/vue/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/dist" + "outDir": "build/cjs" } } diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 775e80b8ec43..d2eaa28340d9 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -9,7 +9,7 @@ "engines": { "node": ">=8" }, - "main": "build/npm/dist/index.js", + "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "publishConfig": { @@ -45,7 +45,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf dist esm build coverage *.js.map *.d.ts", + "clean": "rimraf build coverage *.js.map *.d.ts", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/wasm/tsconfig.cjs.json b/packages/wasm/tsconfig.cjs.json index 6782dae5e453..0fa3132e7510 100644 --- a/packages/wasm/tsconfig.cjs.json +++ b/packages/wasm/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "build/npm/dist" + "outDir": "build/npm/cjs" } } diff --git a/tsconfig-templates/tsconfig.cjs.json b/tsconfig-templates/tsconfig.cjs.json index abd80f77e1ff..4ec31d2ff68b 100644 --- a/tsconfig-templates/tsconfig.cjs.json +++ b/tsconfig-templates/tsconfig.cjs.json @@ -3,6 +3,6 @@ "compilerOptions": { "module": "commonjs", - "outDir": "dist" + "outDir": "cjs" } } diff --git a/typedoc.js b/typedoc.js index f6e0a7e2a805..4b1843c33aad 100644 --- a/typedoc.js +++ b/typedoc.js @@ -6,7 +6,7 @@ module.exports = { exclude: [ '**/test/**/*', '**/*.js', - '**/dist/**/*', + '**/cjs/**/*', '**/esm/**/*', '**/build/**/*', '**/packages/typescript/**/*', From 780af570374708a6131042a1e5beb8d55c0be31a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 8 Apr 2022 12:35:26 -0400 Subject: [PATCH 19/94] feat(integrations): Remove old angular, ember, and vue integrations (#4893) --- packages/integrations/src/angular.ts | 129 --------- packages/integrations/src/ember.ts | 73 ----- packages/integrations/src/index.ts | 3 - packages/integrations/src/vue.ts | 417 --------------------------- 4 files changed, 622 deletions(-) delete mode 100644 packages/integrations/src/angular.ts delete mode 100644 packages/integrations/src/ember.ts delete mode 100644 packages/integrations/src/vue.ts diff --git a/packages/integrations/src/angular.ts b/packages/integrations/src/angular.ts deleted file mode 100644 index dc71042700ff..000000000000 --- a/packages/integrations/src/angular.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Event, EventProcessor, Hub, Integration } from '@sentry/types'; -import { getGlobalObject, logger } from '@sentry/utils'; - -import { IS_DEBUG_BUILD } from './flags'; - -// See https://github.com/angular/angular.js/blob/v1.4.7/src/minErr.js -const angularPattern = /^\[((?:[$a-zA-Z0-9]+:)?(?:[$a-zA-Z0-9]+))\] (.*?)\n?(\S+)$/; - -/** - * AngularJS integration - * - * Provides an $exceptionHandler for AngularJS - */ -export class Angular implements Integration { - /** - * @inheritDoc - */ - public static id: string = 'AngularJS'; - - /** - * moduleName used in Angular's DI resolution algorithm - */ - public static moduleName: string = 'ngSentry'; - - /** - * @inheritDoc - */ - public name: string = Angular.id; - - /** - * Angular's instance - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private readonly _angular: any; - - /** - * ngSentry module instance - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private readonly _module: any; - - /** - * Returns current hub. - */ - private _getCurrentHub?: () => Hub; - - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public constructor(options: { angular?: any } = {}) { - IS_DEBUG_BUILD && logger.log('You are still using the Angular integration, consider moving to @sentry/angular'); - - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access - this._angular = options.angular || getGlobalObject().angular; - - if (!this._angular) { - IS_DEBUG_BUILD && logger.error('AngularIntegration is missing an Angular instance'); - return; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - this._module = this._angular.module(Angular.moduleName, []); - } - - /** - * @inheritDoc - */ - public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - if (!this._module) { - return; - } - - this._getCurrentHub = getCurrentHub; - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - this._module.config([ - '$provide', - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ($provide: any): void => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - $provide.decorator('$exceptionHandler', ['$delegate', this._$exceptionHandlerDecorator.bind(this)]); - }, - ]); - } - - /** - * Angular's exceptionHandler for Sentry integration - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _$exceptionHandlerDecorator($delegate: any): any { - return (exception: Error, cause?: string): void => { - const hub = this._getCurrentHub && this._getCurrentHub(); - - if (hub && hub.getIntegration(Angular)) { - hub.withScope(scope => { - if (cause) { - scope.setExtra('cause', cause); - } - - scope.addEventProcessor((event: Event) => { - const ex = event.exception && event.exception.values && event.exception.values[0]; - - if (ex) { - const matches = angularPattern.exec(ex.value || ''); - - if (matches) { - // This type now becomes something like: $rootScope:inprog - ex.type = matches[1]; - ex.value = matches[2]; - event.message = `${ex.type}: ${ex.value}`; - // auto set a new tag specifically for the angular error url - event.extra = { - ...event.extra, - angularDocs: matches[3].substr(0, 250), - }; - } - } - - return event; - }); - - hub.captureException(exception); - }); - } - $delegate(exception, cause); - }; - } -} diff --git a/packages/integrations/src/ember.ts b/packages/integrations/src/ember.ts deleted file mode 100644 index 81bbd1a0036b..000000000000 --- a/packages/integrations/src/ember.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { EventProcessor, Hub, Integration } from '@sentry/types'; -import { getGlobalObject, isInstanceOf, logger } from '@sentry/utils'; - -import { IS_DEBUG_BUILD } from './flags'; - -/** JSDoc */ -export class Ember implements Integration { - /** - * @inheritDoc - */ - public static id: string = 'Ember'; - - /** - * @inheritDoc - */ - public name: string = Ember.id; - - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any - private readonly _Ember: any; - - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public constructor(options: { Ember?: any } = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access - this._Ember = options.Ember || getGlobalObject().Ember; - } - - /** - * @inheritDoc - */ - public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - if (!this._Ember) { - IS_DEBUG_BUILD && logger.error('EmberIntegration is missing an Ember instance'); - return; - } - - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - const oldOnError = this._Ember.onerror; - - this._Ember.onerror = (error: Error): void => { - if (getCurrentHub().getIntegration(Ember)) { - getCurrentHub().captureException(error, { originalException: error }); - } - - if (typeof oldOnError === 'function') { - oldOnError.call(this._Ember, error); - } else if (this._Ember.testing) { - throw error; - } - }; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this._Ember.RSVP.on('error', (reason: unknown): void => { - if (getCurrentHub().getIntegration(Ember)) { - getCurrentHub().withScope(scope => { - if (isInstanceOf(reason, Error)) { - scope.setExtra('context', 'Unhandled Promise error detected'); - getCurrentHub().captureException(reason, { originalException: reason as Error }); - } else { - scope.setExtra('reason', reason); - getCurrentHub().captureMessage('Unhandled Promise error detected'); - } - }); - } - }); - } - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ -} diff --git a/packages/integrations/src/index.ts b/packages/integrations/src/index.ts index f1ba52e92026..9a2573ee5a44 100644 --- a/packages/integrations/src/index.ts +++ b/packages/integrations/src/index.ts @@ -1,12 +1,9 @@ -export { Angular } from './angular'; export { CaptureConsole } from './captureconsole'; export { Debug } from './debug'; export { Dedupe } from './dedupe'; -export { Ember } from './ember'; export { ExtraErrorData } from './extraerrordata'; export { Offline } from './offline'; export { ReportingObserver } from './reportingobserver'; export { RewriteFrames } from './rewriteframes'; export { SessionTiming } from './sessiontiming'; export { Transaction } from './transaction'; -export { Vue } from './vue'; diff --git a/packages/integrations/src/vue.ts b/packages/integrations/src/vue.ts deleted file mode 100644 index 12c55f53df32..000000000000 --- a/packages/integrations/src/vue.ts +++ /dev/null @@ -1,417 +0,0 @@ -/* eslint-disable max-lines */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { EventProcessor, Hub, Integration, IntegrationClass, Scope, Span, Transaction } from '@sentry/types'; -import { basename, getGlobalObject, logger, timestampWithMs } from '@sentry/utils'; - -import { IS_DEBUG_BUILD } from './flags'; - -/** - * Used to extract BrowserTracing integration from @sentry/tracing - */ -const BROWSER_TRACING_GETTER = { - id: 'BrowserTracing', -} as any as IntegrationClass; - -const VUE_OP = 'ui.vue'; - -/** Global Vue object limited to the methods/attributes we require */ -interface VueInstance { - config: { - errorHandler?(error: Error, vm?: ViewModel, info?: string): void; - }; - util?: { - warn(...input: any): void; - }; - mixin(hooks: { [key: string]: () => void }): void; -} - -/** Representation of Vue component internals */ -interface ViewModel { - [key: string]: any; - // eslint-disable-next-line @typescript-eslint/ban-types - $root: object; - $options: { - [key: string]: any; - name?: string; - propsData?: { [key: string]: any }; - _componentTag?: string; - __file?: string; - $_sentryPerfHook?: boolean; - }; - $once(hook: string, cb: () => void): void; -} - -/** Vue Integration configuration */ -interface IntegrationOptions { - /** Vue instance to be used inside the integration */ - Vue: VueInstance; - - /** - * When set to `false`, Sentry will suppress reporting of all props data - * from your Vue components for privacy concerns. - */ - attachProps: boolean; - /** - * When set to `true`, original Vue's `logError` will be called as well. - * https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48 - */ - logErrors: boolean; - - /** - * When set to `true`, enables tracking of components lifecycle performance. - * It requires `Tracing` integration to be also enabled. - */ - tracing: boolean; - - /** {@link TracingOptions} */ - tracingOptions: TracingOptions; -} - -/** Vue specific configuration for Tracing Integration */ -interface TracingOptions { - /** - * Decides whether to track components by hooking into its lifecycle methods. - * Can be either set to `boolean` to enable/disable tracking for all of them. - * Or to an array of specific component names (case-sensitive). - */ - trackComponents: boolean | string[]; - /** How long to wait until the tracked root activity is marked as finished and sent of to Sentry */ - timeout: number; - /** - * List of hooks to keep track of during component lifecycle. - * Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'update' - * Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks - */ - hooks: Operation[]; -} - -/** Optional metadata attached to Sentry Event */ -interface Metadata { - [key: string]: any; - componentName?: string; - propsData?: { [key: string]: any }; - lifecycleHook?: string; -} - -// https://vuejs.org/v2/api/#Options-Lifecycle-Hooks -type Hook = - | 'activated' - | 'beforeCreate' - | 'beforeDestroy' - | 'beforeMount' - | 'beforeUpdate' - | 'created' - | 'deactivated' - | 'destroyed' - | 'mounted' - | 'updated'; - -type Operation = 'activate' | 'create' | 'destroy' | 'mount' | 'update'; - -// Mappings from operation to corresponding lifecycle hook. -const HOOKS: { [key in Operation]: Hook[] } = { - activate: ['activated', 'deactivated'], - create: ['beforeCreate', 'created'], - destroy: ['beforeDestroy', 'destroyed'], - mount: ['beforeMount', 'mounted'], - update: ['beforeUpdate', 'updated'], -}; - -const COMPONENT_NAME_REGEXP = /(?:^|[-_/])(\w)/g; -const ROOT_COMPONENT_NAME = 'root'; -const ANONYMOUS_COMPONENT_NAME = 'anonymous component'; - -/** JSDoc */ -export class Vue implements Integration { - /** - * @inheritDoc - */ - public static id: string = 'Vue'; - - /** - * @inheritDoc - */ - public name: string = Vue.id; - - private readonly _options: IntegrationOptions; - - /** - * Cache holding already processed component names - */ - private readonly _componentsCache: { [key: string]: string } = {}; - private _rootSpan?: Span; - private _rootSpanTimer?: ReturnType; - - /** - * @inheritDoc - */ - public constructor( - options: Partial & { tracingOptions: Partial }>, - ) { - IS_DEBUG_BUILD && logger.log('You are still using the Vue.js integration, consider moving to @sentry/vue'); - this._options = { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - Vue: getGlobalObject().Vue, - attachProps: true, - logErrors: false, - tracing: false, - ...options, - tracingOptions: { - hooks: ['mount', 'update'], - timeout: 2000, - trackComponents: false, - ...options.tracingOptions, - }, - }; - } - - /** - * @inheritDoc - */ - public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - if (!this._options.Vue) { - IS_DEBUG_BUILD && logger.error('Vue integration is missing a Vue instance'); - return; - } - - this._attachErrorHandler(getCurrentHub); - - if (this._options.tracing) { - this._startTracing(getCurrentHub); - } - } - - /** - * Extract component name from the ViewModel - */ - private _getComponentName(vm: ViewModel): string { - // Such level of granularity is most likely not necessary, but better safe than sorry. — Kamil - if (!vm) { - return ANONYMOUS_COMPONENT_NAME; - } - - if (vm.$root === vm) { - return ROOT_COMPONENT_NAME; - } - - if (!vm.$options) { - return ANONYMOUS_COMPONENT_NAME; - } - - if (vm.$options.name) { - return vm.$options.name; - } - - if (vm.$options._componentTag) { - return vm.$options._componentTag; - } - - // injected by vue-loader - if (vm.$options.__file) { - const unifiedFile = vm.$options.__file.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/'); - const filename = basename(unifiedFile, '.vue'); - return ( - this._componentsCache[filename] || - (this._componentsCache[filename] = filename.replace(COMPONENT_NAME_REGEXP, (_, c: string) => - c ? c.toUpperCase() : '', - )) - ); - } - - return ANONYMOUS_COMPONENT_NAME; - } - - /** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */ - // eslint-disable-next-line @typescript-eslint/typedef - private readonly _applyTracingHooks = (vm: ViewModel, getCurrentHub: () => Hub): void => { - // Don't attach twice, just in case - if (vm.$options.$_sentryPerfHook) { - return; - } - vm.$options.$_sentryPerfHook = true; - - const name = this._getComponentName(vm); - const rootMount = name === ROOT_COMPONENT_NAME; - const spans: { [key: string]: Span } = {}; - - // Render hook starts after once event is emitted, - // but it ends before the second event of the same type. - // - // Because of this, we start measuring inside the first event, - // but finish it before it triggers, to skip the event emitter timing itself. - const rootHandler = (hook: Hook): void => { - const now = timestampWithMs(); - - // On the first handler call (before), it'll be undefined, as `$once` will add it in the future. - // However, on the second call (after), it'll be already in place. - if (this._rootSpan) { - this._finishRootSpan(now, getCurrentHub); - } else { - vm.$once(`hook:${hook}`, () => { - // Create an activity on the first event call. There'll be no second call, as rootSpan will be in place, - // thus new event handler won't be attached. - const activeTransaction = getActiveTransaction(getCurrentHub()); - if (activeTransaction) { - this._rootSpan = activeTransaction.startChild({ - description: 'Application Render', - op: VUE_OP, - }); - } - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - }); - } - }; - - const childHandler = (hook: Hook, operation: Operation): void => { - // Skip components that we don't want to track to minimize the noise and give a more granular control to the user - const shouldTrack = Array.isArray(this._options.tracingOptions.trackComponents) - ? this._options.tracingOptions.trackComponents.indexOf(name) > -1 - : this._options.tracingOptions.trackComponents; - - if (!this._rootSpan || !shouldTrack) { - return; - } - - const now = timestampWithMs(); - const span = spans[operation]; - - // On the first handler call (before), it'll be undefined, as `$once` will add it in the future. - // However, on the second call (after), it'll be already in place. - if (span) { - span.finish(); - this._finishRootSpan(now, getCurrentHub); - } else { - vm.$once(`hook:${hook}`, () => { - if (this._rootSpan) { - spans[operation] = this._rootSpan.startChild({ - description: `Vue <${name}>`, - op: `${VUE_OP}.${operation}`, - }); - } - }); - } - }; - - // Each component has it's own scope, so all activities are only related to one of them - this._options.tracingOptions.hooks.forEach(operation => { - // Retrieve corresponding hooks from Vue lifecycle. - // eg. mount => ['beforeMount', 'mounted'] - const internalHooks = HOOKS[operation]; - - if (!internalHooks) { - IS_DEBUG_BUILD && logger.warn(`Unknown hook: ${operation}`); - return; - } - - internalHooks.forEach(internalHook => { - const handler = rootMount - ? rootHandler.bind(this, internalHook) - : childHandler.bind(this, internalHook, operation); - const currentValue = vm.$options[internalHook]; - - if (Array.isArray(currentValue)) { - vm.$options[internalHook] = [handler, ...currentValue]; - } else if (typeof currentValue === 'function') { - vm.$options[internalHook] = [handler, currentValue]; - } else { - vm.$options[internalHook] = [handler]; - } - }); - }); - }; - - /** Finish top-level span and activity with a debounce configured using `timeout` option */ - private _finishRootSpan(timestamp: number, _getCurrentHub: () => Hub): void { - if (this._rootSpanTimer) { - clearTimeout(this._rootSpanTimer); - } - - this._rootSpanTimer = setTimeout(() => { - // We should always finish the span - if (this._rootSpan) { - this._rootSpan.finish(timestamp); - } - }, this._options.tracingOptions.timeout); - } - - /** Inject configured tracing hooks into Vue's component lifecycles */ - private _startTracing(getCurrentHub: () => Hub): void { - const applyTracingHooks = this._applyTracingHooks; - - this._options.Vue.mixin({ - beforeCreate(this: ViewModel): void { - if (getCurrentHub().getIntegration(BROWSER_TRACING_GETTER)) { - // `this` points to currently rendered component - applyTracingHooks(this, getCurrentHub); - } else { - IS_DEBUG_BUILD && - logger.error('Vue integration has tracing enabled, but Tracing integration is not configured'); - } - }, - }); - } - - /** Inject Sentry's handler into owns Vue's error handler */ - private _attachErrorHandler(getCurrentHub: () => Hub): void { - // eslint-disable-next-line @typescript-eslint/unbound-method - const currentErrorHandler = this._options.Vue.config.errorHandler; - - this._options.Vue.config.errorHandler = (error: Error, vm?: ViewModel, info?: string): void => { - const metadata: Metadata = {}; - - if (vm) { - try { - metadata.componentName = this._getComponentName(vm); - - if (this._options.attachProps) { - metadata.propsData = vm.$options.propsData; - } - } catch (_oO) { - IS_DEBUG_BUILD && logger.warn('Unable to extract metadata from Vue component.'); - } - } - - if (info) { - metadata.lifecycleHook = info; - } - - if (getCurrentHub().getIntegration(Vue)) { - // Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time. - setTimeout(() => { - getCurrentHub().withScope(scope => { - scope.setContext('vue', metadata); - getCurrentHub().captureException(error); - }); - }); - } - - if (typeof currentErrorHandler === 'function') { - currentErrorHandler.call(this._options.Vue, error, vm, info); - } - - if (this._options.logErrors) { - if (this._options.Vue.util) { - this._options.Vue.util.warn(`Error in ${info}: "${error && error.toString()}"`, vm); - } - // eslint-disable-next-line no-console - console.error(error); - } - }; - } -} - -interface HubType extends Hub { - getScope?(): Scope | undefined; -} - -/** Grabs active transaction off scope */ -export function getActiveTransaction(hub: HubType): T | undefined { - if (hub && hub.getScope) { - const scope = hub.getScope() as Scope; - if (scope) { - return scope.getTransaction() as T | undefined; - } - } - - return undefined; -} From 2123da5323023d147ccfd555c9b56d188323ca77 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 8 Apr 2022 12:35:48 -0400 Subject: [PATCH 20/94] feat(types): Delete SessionStatus enum (#4890) --- packages/types/src/sessionstatus.ts | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 packages/types/src/sessionstatus.ts diff --git a/packages/types/src/sessionstatus.ts b/packages/types/src/sessionstatus.ts deleted file mode 100644 index 339b4ea2f5e6..000000000000 --- a/packages/types/src/sessionstatus.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** JSDoc - * @deprecated Use string literals - if you require type casting, cast to SessionStatus type - */ -export enum SessionStatus { - /** JSDoc */ - Ok = 'ok', - /** JSDoc */ - Exited = 'exited', - /** JSDoc */ - Crashed = 'crashed', - /** JSDoc */ - Abnormal = 'abnormal', -} From b2f361d6c8489eaaa061d5c0f32d66f6871f0e95 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Fri, 8 Apr 2022 14:04:04 -0400 Subject: [PATCH 21/94] meta: 7.0.0-alpha.0 changelog (#4892) --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e955904ea44..9a4fd090e149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 7.0.0-alpha.0 + +- **breaking** feat: Drop support for Node 6 (#4851) +- **breaking** feat: Remove references to @sentry/apm (#4845) +- **breaking** feat: Delete deprecated startSpan and child methods (#4849) +- **breaking** feat(bundles): Stop publishing CDN bundles on npm (#4901) +- **breaking** ref(build): Rename dist directories to cjs (#4900) +- **breaking** ref(build): Update to TypeScript 3.8.3 (#4895) +- **breaking** feat(browser): Remove top level eventbuilder exports (#4887) +- **breaking** feat(core): Delete API class (#4848) +- **breaking** feat(core): Remove whitelistUrls/blacklistUrls (#4850) +- **breaking** feat(gatsby): Remove Sentry from window (#4857) +- **breaking** feat(hub): Remove getActiveDomain (#4858) +- **breaking** feat(hub): Remove setTransaction scope method (#4865) +- **breaking** feat(integrations): Remove old angular, ember, and vue integrations (#4893) +- **breaking** feat(node): Remove deprecated frameContextLines (#4884) +- **breaking** feat(tracing): Rename registerRequestInstrumentation -> instrumentOutgoingRequests (#4859) +- **breaking** feat(types): Remove deprecated user dsn field (#4864) +- **breaking** feat(types): Delete RequestSessionStatus enum (#4889) +- **breaking** feat(types): Delete Status enum (#4891) +- **breaking** feat(types): Delete SessionStatus enum (#4890) + ## 6.19.6 - fix(typing): Fix typing API in CaptureConsle (#4879) From 381183e6f5f97926c92f40f918a44a0628e2bc0f Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sat, 9 Apr 2022 14:14:54 -0700 Subject: [PATCH 22/94] fix(build): Skip flags file when building integration bundles (#4906) In https://github.com/getsentry/sentry-javascript/pull/4842, a `flags.ts` file was added to each package to fix logger treeshaking when using webpack. Because of the way that webpack works, this file has to exist separately in each individual package, including in `@sentry/integrations`. It is not itself an integration, though, so we shouldn't be building a separate CDN bundle for it (let alone six versions of one). This fixes the build script so that we're no longer doing that. --- packages/integrations/scripts/buildBundles.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/integrations/scripts/buildBundles.sh b/packages/integrations/scripts/buildBundles.sh index 88c4887b0605..3e81a8e6e045 100644 --- a/packages/integrations/scripts/buildBundles.sh +++ b/packages/integrations/scripts/buildBundles.sh @@ -3,9 +3,10 @@ for filepath in ./src/*; do file=$(basename $filepath) - # the index file is only there for the purposes of npm builds - for the CDN we create a separate bundle for each - # integration - so we can skip it here - if [[ $file == "index.ts" ]]; then + # The index file is only there for the purposes of npm builds (for the CDN we create a separate bundle for each + # integration) and the flags file is just a helper for including or not including debug logging, whose contents gets + # incorporated into each of the individual integration bundles, so we can skip them both here. + if [[ $file == "index.ts" || $file == "flags.ts" ]]; then continue fi From 7fa3e8c13d5879e746d70b70261c836aeaab1b48 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 06:10:17 -0700 Subject: [PATCH 23/94] fix(dev): Standardize yarn `clean` scripts (#4909) Now that we have files like `rollup.config.js` and `jest.config.js` at the package root level, it's helpful if running `yarn clean` doesn't delete them. This fixes that problem, and also fixes a spot where the now-defunct package-top-level `esm` directory was still included in a `clean` script. --- packages/nextjs/package.json | 2 +- packages/utils/package.json | 2 +- packages/vue/package.json | 2 +- packages/wasm/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index cec39c72c4aa..30f7bb2ebac0 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -57,7 +57,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.client.ts && madge --circular --exclude 'config/types\\.ts' src/index.server.ts # see https://github.com/pahen/madge/issues/306", - "clean": "rimraf build coverage *.js *.js.map *.d.ts", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/utils/package.json b/packages/utils/package.json index 39df57d9e1fa..f192799b3cf1 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -38,7 +38,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf build coverage *.js *.js.map *.d.ts", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/vue/package.json b/packages/vue/package.json index 01610c1ad8ab..3ce551347efe 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -46,7 +46,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/wasm/package.json b/packages/wasm/package.json index d2eaa28340d9..5fc5425bfe1b 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -45,7 +45,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf build coverage *.js.map *.d.ts", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", From 05504b35e5ea24f7ed279329e9f9647bd4a7e2f4 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 06:11:39 -0700 Subject: [PATCH 24/94] chore(dev): Remove redundant `.gitignore` in `utils` package (#4905) The `.gitignore` file in the `utils` package isn't ignoring any current files which the main `.gitignore` (the one at the root level of the repo) isn't already ignoring, as evidenced by the fact that deleting the former doesn't cause anything to new to come to git's attention. What it will ignore, however, is future `.js` files (such as `rollup.config.js` and `jest.config.js`) which we don't want ignored (and which aren't ignored in any other package). This therefore removes the `.gitignore` in `utils`, in order to prevent that future problem. --- packages/utils/.gitignore | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 packages/utils/.gitignore diff --git a/packages/utils/.gitignore b/packages/utils/.gitignore deleted file mode 100644 index 5c5f1c199d85..000000000000 --- a/packages/utils/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.js.map -*.d.ts -*.js -!test/types/* -!.eslintrc.js From 4f0469b9f8e20e55b715495105d7628a097c1bef Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 06:49:41 -0700 Subject: [PATCH 25/94] ref(dev): Centralize jest config (#4907) Currently, we configure jest using a mix of `package.json` entries and `jest.config.js` files, and there's a great deal of repetition between configs. To make things DRYer and easier to update (as will happen in future PRs), this aims to fix that by creating a centralized jest config from which all others can inherit. To facilitate this inheritance, all config has been removed from `package.json` files and moved into `jest.config.js` files. This change was done in a few distinct stages: - Extracting the config which was identical across many packages into a central config file, and fixing a mistake they all contained, namely that they were using the regular tsconfig file rather than the test-specific one. - In the packages which were using exactly that config, creating a new `jest.config.js` file and inheriting directly from the central jest config with no changes. - In the packages whose config varied only slightly from the boilerplate config, creating a new `jest.config.js` file and inheriting from the central file with small changes. This also required adding `.tsx` files to the central config. - In the browser package, moving the existing `jest.config.js` for the unit tests to the repo root level and refactoring it to inherit from the central file. This also required specifying a coverage directory in the central config and modifying the browser package's yarn test commands. - In the node integration test package, refactoring the existing `jest.config.js` to inherit from the central file. This also required creating a test-specific tsconfig to match the one in other packages. - Finally, making a small optimization (narrowing the scope of where to look for tests) in the now universally-used central config. --- jest.config.js | 19 ++++++++++++++ packages/browser/jest.config.js | 7 +++++ packages/browser/package.json | 4 +-- packages/browser/test/unit/jest.config.js | 16 ------------ packages/core/jest.config.js | 1 + packages/core/package.json | 20 -------------- packages/gatsby/jest.config.js | 7 +++++ packages/gatsby/package.json | 26 ------------------- packages/hub/jest.config.js | 1 + packages/hub/package.json | 20 -------------- packages/integrations/jest.config.js | 1 + packages/integrations/package.json | 20 -------------- packages/minimal/jest.config.js | 1 + packages/minimal/package.json | 20 -------------- packages/nextjs/jest.config.js | 1 + packages/nextjs/package.json | 20 -------------- .../node-integration-tests/jest.config.js | 12 +++------ packages/node-integration-tests/tsconfig.json | 10 ++++--- .../node-integration-tests/tsconfig.test.json | 12 +++++++++ packages/node/jest.config.js | 1 + packages/node/package.json | 20 -------------- packages/react/jest.config.js | 6 +++++ packages/react/package.json | 23 ---------------- packages/serverless/jest.config.js | 1 + packages/serverless/package.json | 22 +--------------- packages/tracing/jest.config.js | 1 + packages/tracing/package.json | 20 -------------- packages/utils/jest.config.js | 1 + packages/utils/package.json | 20 -------------- packages/vue/jest.config.js | 6 +++++ packages/vue/package.json | 20 -------------- packages/wasm/jest.config.js | 3 +++ packages/wasm/package.json | 3 --- 33 files changed, 82 insertions(+), 283 deletions(-) create mode 100644 jest.config.js create mode 100644 packages/browser/jest.config.js delete mode 100644 packages/browser/test/unit/jest.config.js create mode 100644 packages/core/jest.config.js create mode 100644 packages/gatsby/jest.config.js create mode 100644 packages/hub/jest.config.js create mode 100644 packages/integrations/jest.config.js create mode 100644 packages/minimal/jest.config.js create mode 100644 packages/nextjs/jest.config.js create mode 100644 packages/node-integration-tests/tsconfig.test.json create mode 100644 packages/node/jest.config.js create mode 100644 packages/react/jest.config.js create mode 100644 packages/serverless/jest.config.js create mode 100644 packages/tracing/jest.config.js create mode 100644 packages/utils/jest.config.js create mode 100644 packages/vue/jest.config.js create mode 100644 packages/wasm/jest.config.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000000..411c1f269052 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,19 @@ +module.exports = { + rootDir: process.cwd(), + collectCoverage: true, + transform: { + '^.+\\.ts$': 'ts-jest', + '^.+\\.tsx$': 'ts-jest', + }, + coverageDirectory: '/coverage', + moduleFileExtensions: ['js', 'ts', 'tsx'], + testEnvironment: 'node', + testMatch: ['/**/*.test.ts', '/**/*.test.tsx'], + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.test.json', + diagnostics: false, + }, + }, + testPathIgnorePatterns: ['/build/', '/node_modules/'], +}; diff --git a/packages/browser/jest.config.js b/packages/browser/jest.config.js new file mode 100644 index 000000000000..06b833307dd8 --- /dev/null +++ b/packages/browser/jest.config.js @@ -0,0 +1,7 @@ +const baseConfig = require('../../jest.config.js'); + +module.exports = { + ...baseConfig, + testEnvironment: 'jsdom', + testMatch: ['/test/unit/**/*.test.ts'], +}; diff --git a/packages/browser/package.json b/packages/browser/package.json index 2c498962fb0a..4ce4782d8554 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -72,11 +72,11 @@ "size:check:es5": "cat build/bundles/bundle.min.js | gzip -9 | wc -c | awk '{$1=$1/1024; print \"ES5: \",$1,\"kB\";}'", "size:check:es6": "cat build/bundles/bundle.es6.min.js | gzip -9 | wc -c | awk '{$1=$1/1024; print \"ES6: \",$1,\"kB\";}'", "test": "run-s test:unit", - "test:unit": "jest --config test/unit/jest.config.js", + "test:unit": "jest", "test:integration": "test/integration/run.js", "test:integration:checkbrowsers": "node scripts/checkbrowsers.js", "test:package": "node test/package/npm-build.js && rm test/package/tmp.js", - "test:unit:watch": "jest --config test/unit/jest.config.js --watch", + "test:unit:watch": "jest --watch", "test:integration:watch": "test/integration/run.js --watch" }, "volta": { diff --git a/packages/browser/test/unit/jest.config.js b/packages/browser/test/unit/jest.config.js deleted file mode 100644 index 5495646bc33f..000000000000 --- a/packages/browser/test/unit/jest.config.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - transform: { - '^.+\\.ts$': 'ts-jest', - }, - collectCoverage: true, - coverageDirectory: '../../coverage', - moduleFileExtensions: ['js', 'ts'], - testEnvironment: 'jsdom', - testMatch: ['**/*.test.ts'], - globals: { - 'ts-jest': { - tsConfig: '../../tsconfig.json', - diagnostics: false, - }, - }, -}; diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/core/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/core/package.json b/packages/core/package.json index c6422c4dab99..7dca9d04abdb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -52,25 +52,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/gatsby/jest.config.js b/packages/gatsby/jest.config.js new file mode 100644 index 000000000000..6ea22d92d139 --- /dev/null +++ b/packages/gatsby/jest.config.js @@ -0,0 +1,7 @@ +const baseConfig = require('../../jest.config.js'); + +module.exports = { + ...baseConfig, + setupFiles: ['/test/setEnvVars.ts'], + testEnvironment: 'jsdom', +}; diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 1789fe091a4f..7bce4a987cef 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -62,31 +62,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest", - "^.+\\.tsx$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts", - "tsx" - ], - "testEnvironment": "jsdom", - "testMatch": [ - "**/*.test.ts", - "**/*.test.tsx" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - }, - "setupFiles": [ - "/test/setEnvVars.ts" - ] - }, "sideEffects": false } diff --git a/packages/hub/jest.config.js b/packages/hub/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/hub/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/hub/package.json b/packages/hub/package.json index 45408c158c39..f541c7bb7d1f 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -49,25 +49,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/integrations/jest.config.js b/packages/integrations/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/integrations/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/integrations/package.json b/packages/integrations/package.json index ede4c816e00d..8c42ddd7b90d 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -54,25 +54,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/minimal/jest.config.js b/packages/minimal/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/minimal/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/minimal/package.json b/packages/minimal/package.json index 4a8b6630cae0..6db5916eaeb0 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -49,25 +49,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/nextjs/jest.config.js b/packages/nextjs/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/nextjs/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 30f7bb2ebac0..af1c729c6622 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -76,26 +76,6 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": [ "./cjs/index.server.js", "./esm/index.server.js", diff --git a/packages/node-integration-tests/jest.config.js b/packages/node-integration-tests/jest.config.js index 8edea137a75b..617a25ea0817 100644 --- a/packages/node-integration-tests/jest.config.js +++ b/packages/node-integration-tests/jest.config.js @@ -1,10 +1,6 @@ -const config = { - transform: { - '^.+\\.ts$': 'ts-jest', - }, - testEnvironment: 'node', +const baseConfig = require('../../jest.config.js'); + +module.exports = { + ...baseConfig, testMatch: ['**/test.ts'], - moduleFileExtensions: ['js', 'ts'], }; - -module.exports = config; diff --git a/packages/node-integration-tests/tsconfig.json b/packages/node-integration-tests/tsconfig.json index 87d045dbc42d..c98602a3af23 100644 --- a/packages/node-integration-tests/tsconfig.json +++ b/packages/node-integration-tests/tsconfig.json @@ -1,9 +1,11 @@ { "extends": "../../tsconfig.json", + + "include": ["**/*.ts"], + "compilerOptions": { + // package-specific options "esModuleInterop": true, - "types": ["jest", "node"] - }, - "include": ["**/*.ts", "jest.config.js"], - "exclude": ["node_modules"] + "types": ["node"] + } } diff --git a/packages/node-integration-tests/tsconfig.test.json b/packages/node-integration-tests/tsconfig.test.json new file mode 100644 index 000000000000..b43ec254274b --- /dev/null +++ b/packages/node-integration-tests/tsconfig.test.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + + "include": ["**/*.ts"], + + "compilerOptions": { + // should include all types from `./tsconfig.json` plus types for all test frameworks used + "types": ["node", "jest"] + + // other package-specific, test-specific options + } +} diff --git a/packages/node/jest.config.js b/packages/node/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/node/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/node/package.json b/packages/node/package.json index a9048c5b67a4..43142e6c9208 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -65,25 +65,5 @@ }, "volta": { "extends": "../../package.json" - }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } } } diff --git a/packages/react/jest.config.js b/packages/react/jest.config.js new file mode 100644 index 000000000000..8baa8e01db0c --- /dev/null +++ b/packages/react/jest.config.js @@ -0,0 +1,6 @@ +const baseConfig = require('../../jest.config.js'); + +module.exports = { + ...baseConfig, + testEnvironment: 'jsdom', +}; diff --git a/packages/react/package.json b/packages/react/package.json index a92935e9c793..ff98dfe10a54 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -77,28 +77,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest", - "^.+\\.tsx$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts", - "tsx" - ], - "testEnvironment": "jsdom", - "testMatch": [ - "**/*.test.ts", - "**/*.test.tsx" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/serverless/jest.config.js b/packages/serverless/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/serverless/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/serverless/package.json b/packages/serverless/package.json index 39ce5479d2bb..91e86642d6c0 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -68,25 +68,5 @@ "volta": { "extends": "../../package.json" }, - "sideEffects": false, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - } + "sideEffects": false } diff --git a/packages/tracing/jest.config.js b/packages/tracing/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/tracing/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 1d99f2a3b564..a486fef99048 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -59,26 +59,6 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": [ "./npm/cjs/index.js", "./npm/esm/index.js", diff --git a/packages/utils/jest.config.js b/packages/utils/jest.config.js new file mode 100644 index 000000000000..58141f076dc4 --- /dev/null +++ b/packages/utils/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config.js'); diff --git a/packages/utils/package.json b/packages/utils/package.json index f192799b3cf1..2967d08ab553 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -53,25 +53,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "node", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/vue/jest.config.js b/packages/vue/jest.config.js new file mode 100644 index 000000000000..8baa8e01db0c --- /dev/null +++ b/packages/vue/jest.config.js @@ -0,0 +1,6 @@ +const baseConfig = require('../../jest.config.js'); + +module.exports = { + ...baseConfig, + testEnvironment: 'jsdom', +}; diff --git a/packages/vue/package.json b/packages/vue/package.json index 3ce551347efe..4aa5fb77d228 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -60,25 +60,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "collectCoverage": true, - "transform": { - "^.+\\.ts$": "ts-jest" - }, - "moduleFileExtensions": [ - "js", - "ts" - ], - "testEnvironment": "jsdom", - "testMatch": [ - "**/*.test.ts" - ], - "globals": { - "ts-jest": { - "tsConfig": "./tsconfig.json", - "diagnostics": false - } - } - }, "sideEffects": false } diff --git a/packages/wasm/jest.config.js b/packages/wasm/jest.config.js new file mode 100644 index 000000000000..2762fa4ef2ff --- /dev/null +++ b/packages/wasm/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: 'jest-puppeteer', +}; diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 5fc5425bfe1b..e5c19f7233b9 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -59,8 +59,5 @@ "volta": { "extends": "../../package.json" }, - "jest": { - "preset": "jest-puppeteer" - }, "sideEffects": false } From 66f63dec376f7bbb424473506777cd2a7e4ac13e Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 11 Apr 2022 13:54:26 +0000 Subject: [PATCH 26/94] release: 7.0.0-alpha.0 --- lerna.json | 2 +- packages/angular/package.json | 8 ++++---- packages/browser/package.json | 8 ++++---- packages/core/package.json | 10 +++++----- packages/core/src/version.ts | 2 +- packages/ember/package.json | 10 +++++----- packages/eslint-config-sdk/package.json | 6 +++--- packages/eslint-plugin-sdk/package.json | 2 +- packages/gatsby/package.json | 8 ++++---- packages/hub/package.json | 6 +++--- packages/integration-tests/package.json | 2 +- packages/integrations/package.json | 6 +++--- packages/minimal/package.json | 6 +++--- packages/nextjs/package.json | 18 +++++++++--------- packages/node-integration-tests/package.json | 2 +- packages/node/package.json | 10 +++++----- packages/react/package.json | 10 +++++----- packages/serverless/package.json | 12 ++++++------ packages/tracing/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/typescript/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/vue/package.json | 12 ++++++------ packages/wasm/package.json | 6 +++--- 24 files changed, 83 insertions(+), 83 deletions(-) diff --git a/lerna.json b/lerna.json index aaa9bac7e91b..ab5fdf259b84 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "3.4.0", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "packages": "packages/*", "npmClient": "yarn", "useWorkspaces": true diff --git a/packages/angular/package.json b/packages/angular/package.json index 9db6f128eaf0..e92a3235d969 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/angular", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Angular", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular", @@ -21,9 +21,9 @@ "@angular/router": "10.x || 11.x || 12.x || 13.x" }, "dependencies": { - "@sentry/browser": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "rxjs": "^6.6.0", "tslib": "^1.9.3" }, diff --git a/packages/browser/package.json b/packages/browser/package.json index 4ce4782d8554..d3a87d21d04a 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/browser", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for browsers", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser", @@ -16,9 +16,9 @@ "access": "public" }, "dependencies": { - "@sentry/core": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/core": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 7dca9d04abdb..23ee48723424 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/core", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Base implementation for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "6.19.6", - "@sentry/minimal": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/hub": "7.0.0-alpha.0", + "@sentry/minimal": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/core/src/version.ts b/packages/core/src/version.ts index 165438edb075..485119673c97 100644 --- a/packages/core/src/version.ts +++ b/packages/core/src/version.ts @@ -1 +1 @@ -export const SDK_VERSION = '6.19.6'; +export const SDK_VERSION = '7.0.0-alpha.0'; diff --git a/packages/ember/package.json b/packages/ember/package.json index 8a6af3c2eb33..3b22b69981b2 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/ember", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Ember.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember", @@ -29,10 +29,10 @@ }, "dependencies": { "@embroider/macros": "~0.47.2", - "@sentry/browser": "6.19.6", - "@sentry/tracing": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", + "@sentry/tracing": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "ember-auto-import": "~1.12.1 || ~2.2.0", "ember-cli-babel": "~7.26.6", "ember-cli-htmlbars": "^6.0.1", diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index 48606f73f334..45a42c8472d0 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-config-sdk", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK eslint config", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk", @@ -19,8 +19,8 @@ "access": "public" }, "dependencies": { - "@sentry-internal/eslint-plugin-sdk": "6.19.6", - "@sentry-internal/typescript": "6.19.6", + "@sentry-internal/eslint-plugin-sdk": "7.0.0-alpha.0", + "@sentry-internal/typescript": "7.0.0-alpha.0", "@typescript-eslint/eslint-plugin": "^3.9.0", "@typescript-eslint/parser": "^3.9.0", "eslint-config-prettier": "^6.11.0", diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index 4d44121da800..938815cb33a3 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-plugin-sdk", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK eslint plugin", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk", diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 7bce4a987cef..976ab9847663 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/gatsby", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Gatsby.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby", @@ -20,8 +20,8 @@ "access": "public" }, "dependencies": { - "@sentry/react": "6.19.6", - "@sentry/tracing": "6.19.6", + "@sentry/react": "7.0.0-alpha.0", + "@sentry/tracing": "7.0.0-alpha.0", "@sentry/webpack-plugin": "1.18.8" }, "peerDependencies": { @@ -29,7 +29,7 @@ "react": "15.x || 16.x || 17.x || 18.x" }, "devDependencies": { - "@sentry/types": "6.19.6", + "@sentry/types": "7.0.0-alpha.0", "@testing-library/react": "^13.0.0", "react": "^18.0.0" }, diff --git a/packages/hub/package.json b/packages/hub/package.json index f541c7bb7d1f..8bb57aab02e2 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/hub", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Sentry hub which handles global state managment.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/hub", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index af8e639c3d46..5456ef0e19be 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-integration-tests", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "main": "index.js", "license": "MIT", "engines": { diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 8c42ddd7b90d..52f2c23ea924 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/integrations", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Pluggable integrations that can be used to enhance JS SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/integrations", @@ -16,8 +16,8 @@ "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "dependencies": { - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "localforage": "^1.8.1", "tslib": "^1.9.3" }, diff --git a/packages/minimal/package.json b/packages/minimal/package.json index 6db5916eaeb0..4154add1ca3d 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/minimal", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Sentry minimal library that can be used in other packages", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/minimal", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "6.19.6", - "@sentry/types": "6.19.6", + "@sentry/hub": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index af1c729c6622..5674ffc46956 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nextjs", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Next.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs", @@ -17,18 +17,18 @@ "access": "public" }, "dependencies": { - "@sentry/core": "6.19.6", - "@sentry/hub": "6.19.6", - "@sentry/integrations": "6.19.6", - "@sentry/node": "6.19.6", - "@sentry/react": "6.19.6", - "@sentry/tracing": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/core": "7.0.0-alpha.0", + "@sentry/hub": "7.0.0-alpha.0", + "@sentry/integrations": "7.0.0-alpha.0", + "@sentry/node": "7.0.0-alpha.0", + "@sentry/react": "7.0.0-alpha.0", + "@sentry/tracing": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "@sentry/webpack-plugin": "1.18.8", "tslib": "^1.9.3" }, "devDependencies": { - "@sentry/types": "6.19.6", + "@sentry/types": "7.0.0-alpha.0", "@types/webpack": "^4.41.31", "next": "10.1.3" }, diff --git a/packages/node-integration-tests/package.json b/packages/node-integration-tests/package.json index 3e1baf31eb53..3f10098ba15b 100644 --- a/packages/node-integration-tests/package.json +++ b/packages/node-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/node-integration-tests", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "license": "MIT", "engines": { "node": ">=10" diff --git a/packages/node/package.json b/packages/node/package.json index 43142e6c9208..f7a19037a029 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/node", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Node.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/core": "6.19.6", - "@sentry/hub": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/core": "7.0.0-alpha.0", + "@sentry/hub": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "cookie": "^0.4.1", "https-proxy-agent": "^5.0.0", "lru_map": "^0.3.3", diff --git a/packages/react/package.json b/packages/react/package.json index ff98dfe10a54..534283e00d07 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/react", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for React.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "6.19.6", - "@sentry/minimal": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", + "@sentry/minimal": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "hoist-non-react-statics": "^3.3.2", "tslib": "^1.9.3" }, diff --git a/packages/serverless/package.json b/packages/serverless/package.json index 91e86642d6c0..ac3374862764 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/serverless", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for various serverless solutions", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/serverless", @@ -16,11 +16,11 @@ "access": "public" }, "dependencies": { - "@sentry/minimal": "6.19.6", - "@sentry/node": "6.19.6", - "@sentry/tracing": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/minimal": "7.0.0-alpha.0", + "@sentry/node": "7.0.0-alpha.0", + "@sentry/tracing": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "@types/aws-lambda": "^8.10.62", "@types/express": "^4.17.2", "tslib": "^1.9.3" diff --git a/packages/tracing/package.json b/packages/tracing/package.json index a486fef99048..6998ba95ba9e 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/tracing", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Extensions for Sentry AM", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tracing", @@ -16,14 +16,14 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "6.19.6", - "@sentry/minimal": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/hub": "7.0.0-alpha.0", + "@sentry/minimal": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "devDependencies": { - "@sentry/browser": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", "@types/express": "^4.17.1", "@types/jsdom": "^16.2.3", "jsdom": "^16.2.2" diff --git a/packages/types/package.json b/packages/types/package.json index aaf97dc1b6d7..2fc59e9a1535 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/types", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Types for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types", diff --git a/packages/typescript/package.json b/packages/typescript/package.json index c564c0c3e344..338ab3906aef 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/typescript", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Typescript configuration used at Sentry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript", diff --git a/packages/utils/package.json b/packages/utils/package.json index 2967d08ab553..6d62d5602180 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/utils", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/utils", @@ -16,7 +16,7 @@ "access": "public" }, "dependencies": { - "@sentry/types": "6.19.6", + "@sentry/types": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/packages/vue/package.json b/packages/vue/package.json index 4aa5fb77d228..fea81ff573a8 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vue", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Official Sentry SDK for Vue.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue", @@ -16,11 +16,11 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "6.19.6", - "@sentry/core": "6.19.6", - "@sentry/minimal": "6.19.6", - "@sentry/types": "6.19.6", - "@sentry/utils": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", + "@sentry/core": "7.0.0-alpha.0", + "@sentry/minimal": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", + "@sentry/utils": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "peerDependencies": { diff --git a/packages/wasm/package.json b/packages/wasm/package.json index e5c19f7233b9..6cdf354f1f5e 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/wasm", - "version": "6.19.6", + "version": "7.0.0-alpha.0", "description": "Support for WASM.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "6.19.6", - "@sentry/types": "6.19.6", + "@sentry/browser": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.0", "tslib": "^1.9.3" }, "devDependencies": { From de739c9f64cd02a74aa253f65d1c7f7933721fef Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 11 Apr 2022 20:19:29 +0200 Subject: [PATCH 27/94] Add migration guide for v7 (#4910) Documents: - ES6 for CJS files - Dropping Support for Node v6 - Removing Platform Integrations - New npm package structure - Deleting deprecations --- MIGRATION.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index b3acaa6695e8..5307b44a7597 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,3 +1,91 @@ +## Upgrading from 6.x to 7.x + +The main goal of version 7 is to reduce bundle size. This version is breaking because we removed deprecated APIs, upgraded our build tooling, and restructured npm package contents. +Below we will outline all the breaking changes you should consider when upgrading. + +### Dropping Support for Node.js v6 + +Node.js version 6 has reached end of life in April 2019. For Sentry JavaScript SDK version 7, we will no longer be supporting version 6 of Node.js. + +As far as SDK development goes, dropping support means no longer running integration tests for Node.js version 6, and also no longer handling edge cases specific to version 6. +Running the new SDK version on Node.js v6 is therefore highly discouraged. + +### Removal Of Old Platform Integrations From `@sentry/integrations` Package + +The following classes will be removed from the `@sentry/integrations` package and can no longer be used: + +- `Angular` +- `Ember` +- `Vue` + +These classes have been superseded and were moved into their own packages, `@sentry/angular`, `@sentry/ember`, and `@sentry/vue` in a previous version. +Refer to those packages if you want to integrate Sentry into your Angular, Ember, or Vue application. + +### Moving To ES6 For CommonJS Files + +From version 7 onwards, the CommonJS files in Sentry JavaScript SDK packages will use ES6. + +If you need to support Internet Explorer 11 or old Node.js versions, we recommend using a preprocessing tool like [Babel](https://babeljs.io/) to convert Sentry packages to ES5. + +### Restructuring Of Package Content + +Up until v6.x, we have published our packages on npm with the following structure: + +- `build` folder contained CDN bundles +- `dist` folder contained CommonJS files and TypeScript declarations +- `esm` folder contained ESM files and TypeScript declarations + +Moving forward the JavaScript SDK packages will generally have the following structure: + +- `cjs` folder contains CommonJS files +- `esm` folder contains ESM files +- `types` folder contains TypeScript declarations + +**CDN bundles of version 7 or higher will no longer be distributed through our npm package.** +This means that most third-party CDNs like [unpkg](https://unpkg.com/) or [jsDelivr](https://www.jsdelivr.com/) will also not provide them. + +If you depend on any specific files in a Sentry JavaScript npm package, you will most likely need to update their references. +For example, imports on `@sentry/browser/dist/client` will become `@sentry/browser/cjs/client`. +However, directly importing from specific files is discouraged. + +### Removing the `API` class from `@sentry/core` + +The internal `API` class was removed in favor of the `initAPIDetails` function and the `APIDetails` type. More details can be found in the [PR that deprecated this class](https://github.com/getsentry/sentry-javascript/pull/4281). To migrate, see the following example. + +```js +// New in v7: +import { + initAPIDetails, + getEnvelopeEndpointWithUrlEncodedAuth, + getStoreEndpointWithUrlEncodedAuth, +} from '@sentry/core'; + +const dsn = initAPIDetails(dsn, metadata, tunnel); +const dsn = api.dsn; +const storeEndpoint = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); +const envelopeEndpoint = getStoreEndpointWithUrlEncodedAuth(api.dsn); + +// Before: +import { API } from '@sentry/core'; + +const api = new API(dsn, metadata, tunnel); +const dsn = api.getDsn(); +const storeEndpoint = api.getStoreEndpointWithUrlEncodedAuth(); +const envelopeEndpoint = api.getEnvelopeEndpointWithUrlEncodedAuth(); +``` + +### General API Changes + +For our efforts to reduce bundle size of the SDK we had to remove and refactor parts of the package which introduced a few changes to the API: + +- Remove support for deprecated `@sentry/apm` package. `@sentry/tracing` should be used instead. +- Remove deprecated `user` field from DSN. `publicKey` should be used instead. +- Remove deprecated `whitelistUrls` and `blacklistUrls` options from `Sentry.init`. They have been superseded by `allowUrls` and `denyUrls` specifically. See [our docs page on inclusive language](https://develop.sentry.dev/inclusion/) for more details. +- Gatsby SDK: Remove `Sentry` from `window` object. +- Remove deprecated `Status`, `SessionStatus`, and `RequestSessionStatus` enums. These were only part of an internal API. If you are using these enums, we encourage you to to look at [b177690d](https://github.com/getsentry/sentry-javascript/commit/b177690d89640aef2587039113c614672c07d2be), [5fc3147d](https://github.com/getsentry/sentry-javascript/commit/5fc3147dfaaf1a856d5923e4ba409479e87273be), and [f99bdd16](https://github.com/getsentry/sentry-javascript/commit/f99bdd16539bf6fac14eccf1a974a4988d586b28) to to see the changes we've made to our code as result. We generally recommend using string literals instead of the removed enums. +- Remove deprecated `getActiveDomain` method and `DomainAsCarrier` type from `@sentry/hub`. +- Rename `registerRequestInstrumentation` to `instrumentOutgoingRequests` in `@sentry/tracing`. + # Upgrading from 6.17.x to 6.18.0 Version 6.18.0 deprecates the `frameContextLines` top-level option for the Node SDK. This option will be removed in an upcoming major version. To migrate off of the top-level option, pass it instead to the new `ContextLines` integration. From 144bec3bca966417ccaf5c32711467950c661295 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 13:30:26 -0700 Subject: [PATCH 28/94] feat(browser): Add debugging hints to browser integration tests (#4914) Our old browser integration tests are difficult to debug. This adds a file of (hard-won) debugging tips to the test directory, to hopefully make it easier on the next person. While it's true that it contains a lot of very specific references (to functions, files, etc) and is therefore much more susceptible to becoming out of date, these tests aren't something we change often, and the consequences of such staleness are small. --- .../browser/test/integration/debugging.md | 29 +++++++++++++++++++ .../browser/test/integration/suites/shell.js | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 packages/browser/test/integration/debugging.md diff --git a/packages/browser/test/integration/debugging.md b/packages/browser/test/integration/debugging.md new file mode 100644 index 000000000000..eb4849a48493 --- /dev/null +++ b/packages/browser/test/integration/debugging.md @@ -0,0 +1,29 @@ +### Debugging Hints + +These tests are hard to debug, because the testing system is somewhat complex, straightforward debugging doesn't work (see below), and the output of most `console.log` calls gets swallowed. Here, future debugger, are some tips to make it easier, to hopefully save you the hour(s) of trial and error it took to figure them out. + +- `suites/shell.js`: + - Remove the loader options from the `variants` array. + - Delete all of the placeholders of the form `{{ suites/something.js }}` except for the one you're interested in. It's not enough to comment them out, because they'll still exist in the file and get replaced by the test runner. Don't forget the one at the bottom of the file. + +- `suites/helpers.js`: + - Add `sandbox.contentWindow.console.log = (...args) => console.log(...args);` just before the return in `createSandbox()`. This will make it so that `console.log` statements come through to the terminal. (Yes, Karma theoretically has settings for that, but they don't seem to work. See https://github.com/karma-runner/karma-mocha/issues/47.) + +- `suites.yourTestFile.js`: + - Use `it.only` to only run the single test you're interested in. + +- Repo-level `rollup.config.js`: + - Comment out all bundle variants except whichever one `run.js` is turning into `artifacts/sdk.js`. + +- Browser-package-level `rollup.config.js`: + - Build only one of `es5` and `es6`. + +- Run `build:bundle:watch` in a separate terminal tab, so that when you add `console.log`s to the SDK, they get picked up. + +- Don't bother trying to copy one of our standard VSCode debug profiles, because it won't work, except to debug the testing system itself. (It will pause the node process running the tests, not the headless browser in which the tests themselves run.) + +- To make karma do verbose logging, run `export DEBUG=1`. To turn it off, run `unset DEBUG`. + +- To make the testing system do verbose logging, run `yarn test:integration --debug`. + +- To see exactly the files which are being run, comment out `rmdir('artifacts');` near the bottom of `run.js`. diff --git a/packages/browser/test/integration/suites/shell.js b/packages/browser/test/integration/suites/shell.js index 0b594f3d2eff..2ba7e2bd8c79 100644 --- a/packages/browser/test/integration/suites/shell.js +++ b/packages/browser/test/integration/suites/shell.js @@ -20,7 +20,7 @@ function runVariant(variant) { }); /** - * This part will be replaced by the test runner + * The test runner will replace each of these placeholders with the contents of the corresponding file. */ {{ suites/config.js }} // prettier-ignore {{ suites/api.js }} // prettier-ignore From 2ecf1e5ca359d27c60a6c5288d68ad33a324e8e4 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Tue, 12 Apr 2022 00:11:39 +0100 Subject: [PATCH 29/94] feat: Remove usage of deprecated `event.stacktrace` (#4885) Removes usage of deprecated `event.stacktrace` and updated the event interface to remove the deprecated property. --- packages/browser/src/eventbuilder.ts | 7 +- packages/browser/src/integrations/dedupe.ts | 2 - .../browser/test/integration/suites/api.js | 4 +- .../test/integration/suites/breadcrumbs.js | 13 --- .../core/src/integrations/inboundfilters.ts | 3 - .../lib/integrations/inboundfilters.test.ts | 84 ++++++++++++------- packages/integrations/src/dedupe.ts | 2 - packages/integrations/src/rewriteframes.ts | 16 ---- packages/integrations/test/dedupe.test.ts | 40 +++++---- .../integrations/test/rewriteframes.test.ts | 26 ------ packages/node/src/eventbuilder.ts | 9 +- packages/types/src/event.ts | 2 - packages/wasm/src/index.ts | 3 - 13 files changed, 94 insertions(+), 117 deletions(-) diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index f999eb2854ca..d8acd41c12c0 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -74,7 +74,8 @@ export function eventFromPlainObject( if (syntheticException) { const frames = parseStackFrames(syntheticException); if (frames.length) { - event.stacktrace = { frames }; + // event.exception.values[0] has been set above + (event.exception as { values: Exception[] }).values[0].stacktrace = { frames }; } } @@ -273,7 +274,9 @@ export function eventFromString(input: string, syntheticException?: Error, attac if (attachStacktrace && syntheticException) { const frames = parseStackFrames(syntheticException); if (frames.length) { - event.stacktrace = { frames }; + event.exception = { + values: [{ value: input, stacktrace: { frames } }], + }; } } diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index 24e01d2f1226..c486c84c815e 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -198,8 +198,6 @@ function _getFramesFromEvent(event: Event): StackFrame[] | undefined { } catch (_oO) { return undefined; } - } else if (event.stacktrace) { - return event.stacktrace.frames; } return undefined; } diff --git a/packages/browser/test/integration/suites/api.js b/packages/browser/test/integration/suites/api.js index f51928c5bed5..be5de29abd0e 100644 --- a/packages/browser/test/integration/suites/api.js +++ b/packages/browser/test/integration/suites/api.js @@ -65,8 +65,8 @@ describe('API', function () { return runInSandbox(sandbox, function () { throwNonError(); }).then(function (summary) { - assert.isAtLeast(summary.events[0].stacktrace.frames.length, 1); - assert.isAtMost(summary.events[0].stacktrace.frames.length, 3); + assert.isAtLeast(summary.events[0].exception.values[0].stacktrace.frames.length, 1); + assert.isAtMost(summary.events[0].exception.values[0].stacktrace.frames.length, 3); }); }); diff --git a/packages/browser/test/integration/suites/breadcrumbs.js b/packages/browser/test/integration/suites/breadcrumbs.js index 434bcacc8b4a..5e5c2973efc7 100644 --- a/packages/browser/test/integration/suites/breadcrumbs.js +++ b/packages/browser/test/integration/suites/breadcrumbs.js @@ -234,8 +234,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbHints.length, 1); assert.equal(summary.breadcrumbHints[0].name, 'click'); assert.equal(summary.breadcrumbHints[0].event.target.tagName, 'INPUT'); - // There should be no expection, if there is one it means we threw it - assert.isUndefined(summary.events[0].exception); } }); }); @@ -265,9 +263,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbs[1].category, 'ui.input'); assert.equal(summary.breadcrumbs[1].message, 'body > form#foo-form > input[name="foo"]'); - - // There should be no expection, if there is one it means we threw it - assert.isUndefined(summary.events[0].exception); } }); }); @@ -288,8 +283,6 @@ describe('breadcrumbs', function () { // The async loader doesn't wrap event listeners, but we should receive the event without breadcrumbs assert.lengthOf(summary.events, 1); } else { - // There should be no expection, if there is one it means we threw it - assert.isUndefined(summary.events[0].exception); assert.equal(summary.breadcrumbs.length, 0); } }); @@ -309,8 +302,6 @@ describe('breadcrumbs', function () { // The async loader doesn't wrap event listeners, but we should receive the event without breadcrumbs assert.lengthOf(summary.events, 1); } else { - // There should be no expection, if there is one it means we threw it - assert.isUndefined(summary.events[0].exception); assert.equal(summary.breadcrumbs.length, 0); } }); @@ -472,7 +463,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbs[0].message, 'body > form#foo-form > input[name="foo"]'); assert.equal(summary.breadcrumbHints[0].global, false); assert.equal(summary.breadcrumbHints[1].global, false); - assert.isUndefined(summary.events[0].exception); } }); }); @@ -507,7 +497,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbs[0].message, 'body > form#foo-form > input[name="foo"]'); assert.equal(summary.breadcrumbHints[0].global, false); assert.equal(summary.breadcrumbHints[1].global, false); - assert.isUndefined(summary.events[0].exception); } }); }); @@ -538,7 +527,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbs[1].message, 'body > form#foo-form > div.contenteditable'); assert.equal(summary.breadcrumbHints[0].global, false); assert.equal(summary.breadcrumbHints[1].global, false); - assert.isUndefined(summary.events[0].exception); } }); }); @@ -706,7 +694,6 @@ describe('breadcrumbs', function () { assert.equal(summary.breadcrumbs.length, 2); assert.equal(summary.breadcrumbHints[0].global, true); assert.equal(summary.breadcrumbHints[1].global, true); - assert.isUndefined(summary.events[0].exception); } }); }); diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 83d635ff3256..6151e32e5bbd 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -170,9 +170,6 @@ function _getLastValidUrl(frames: StackFrame[] = []): string | null { function _getEventFilterUrl(event: Event): string | null { try { - if (event.stacktrace) { - return _getLastValidUrl(event.stacktrace.frames); - } let frames; try { // @ts-ignore we only care about frames if the whole thing here is defined diff --git a/packages/core/test/lib/integrations/inboundfilters.test.ts b/packages/core/test/lib/integrations/inboundfilters.test.ts index fd6530cd75e3..74672a3f56e5 100644 --- a/packages/core/test/lib/integrations/inboundfilters.test.ts +++ b/packages/core/test/lib/integrations/inboundfilters.test.ts @@ -1,4 +1,4 @@ -import { EventProcessor } from '@sentry/types'; +import { Event, EventProcessor } from '@sentry/types'; import { InboundFilters, InboundFiltersOptions } from '../../../src/integrations/inboundfilters'; @@ -52,50 +52,68 @@ function createInboundFiltersEventProcessor( // Fixtures -const MESSAGE_EVENT = { +const MESSAGE_EVENT: Event = { message: 'captureMessage', }; -const MESSAGE_EVENT_2 = { +const MESSAGE_EVENT_2: Event = { message: 'captureMessageSomething', }; -const MESSAGE_EVENT_WITH_STACKTRACE = { +const MESSAGE_EVENT_WITH_STACKTRACE: Event = { message: 'wat', - stacktrace: { - // Frames are always in the reverse order, as this is how Sentry expect them to come. - // Frame that crashed is the last one, the one from awesome-analytics - frames: [ - { filename: 'https://our-side.com/js/bundle.js' }, - { filename: 'https://our-side.com/js/bundle.js' }, - { filename: 'https://awesome-analytics.io/some/file.js' }, + exception: { + values: [ + { + stacktrace: { + // Frames are always in the reverse order, as this is how Sentry expect them to come. + // Frame that crashed is the last one, the one from awesome-analytics + frames: [ + { filename: 'https://our-side.com/js/bundle.js' }, + { filename: 'https://our-side.com/js/bundle.js' }, + { filename: 'https://awesome-analytics.io/some/file.js' }, + ], + }, + }, ], }, }; -const MESSAGE_EVENT_WITH_ANON_LAST_FRAME = { +const MESSAGE_EVENT_WITH_ANON_LAST_FRAME: Event = { message: 'any', - stacktrace: { - frames: [ - { filename: 'https://our-side.com/js/bundle.js' }, - { filename: 'https://awesome-analytics.io/some/file.js' }, - { filename: '' }, + exception: { + values: [ + { + stacktrace: { + frames: [ + { filename: 'https://our-side.com/js/bundle.js' }, + { filename: 'https://awesome-analytics.io/some/file.js' }, + { filename: '' }, + ], + }, + }, ], }, }; -const MESSAGE_EVENT_WITH_NATIVE_LAST_FRAME = { +const MESSAGE_EVENT_WITH_NATIVE_LAST_FRAME: Event = { message: 'any', - stacktrace: { - frames: [ - { filename: 'https://our-side.com/js/bundle.js' }, - { filename: 'https://awesome-analytics.io/some/file.js' }, - { filename: '[native code]' }, + exception: { + values: [ + { + stacktrace: { + frames: [ + { filename: 'https://our-side.com/js/bundle.js' }, + { filename: 'https://awesome-analytics.io/some/file.js' }, + { filename: '[native code]' }, + ], + }, + }, ], }, }; -const EXCEPTION_EVENT = { +const EXCEPTION_EVENT: Event = { exception: { values: [ { @@ -106,7 +124,7 @@ const EXCEPTION_EVENT = { }, }; -const EXCEPTION_EVENT_WITH_FRAMES = { +const EXCEPTION_EVENT_WITH_FRAMES: Event = { exception: { values: [ { @@ -124,7 +142,7 @@ const EXCEPTION_EVENT_WITH_FRAMES = { }, }; -const SENTRY_EVENT = { +const SENTRY_EVENT: Event = { exception: { values: [ { @@ -135,7 +153,7 @@ const SENTRY_EVENT = { }, }; -const SCRIPT_ERROR_EVENT = { +const SCRIPT_ERROR_EVENT: Event = { exception: { values: [ { @@ -146,9 +164,15 @@ const SCRIPT_ERROR_EVENT = { }, }; -const MALFORMED_EVENT = { - stacktrace: { - frames: undefined, +const MALFORMED_EVENT: Event = { + exception: { + values: [ + { + stacktrace: { + frames: undefined, + }, + }, + ], }, }; diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 2ce72a6b636c..644f3d41cd62 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -198,8 +198,6 @@ function _getFramesFromEvent(event: Event): StackFrame[] | undefined { } catch (_oO) { return undefined; } - } else if (event.stacktrace) { - return event.stacktrace.frames; } return undefined; } diff --git a/packages/integrations/src/rewriteframes.ts b/packages/integrations/src/rewriteframes.ts index 9eb95e54f6d3..7b1129e45032 100644 --- a/packages/integrations/src/rewriteframes.ts +++ b/packages/integrations/src/rewriteframes.ts @@ -61,10 +61,6 @@ export class RewriteFrames implements Integration { processedEvent = this._processExceptionsEvent(processedEvent); } - if (originalEvent.stacktrace) { - processedEvent = this._processStacktraceEvent(processedEvent); - } - return processedEvent; } @@ -110,18 +106,6 @@ export class RewriteFrames implements Integration { } } - /** JSDoc */ - private _processStacktraceEvent(event: Event): Event { - try { - return { - ...event, - stacktrace: this._processStacktrace(event.stacktrace), - }; - } catch (_oO) { - return event; - } - } - /** JSDoc */ private _processStacktrace(stacktrace?: Stacktrace): Stacktrace { return { diff --git a/packages/integrations/test/dedupe.test.ts b/packages/integrations/test/dedupe.test.ts index 46cac4d06320..c56ab59d5b82 100644 --- a/packages/integrations/test/dedupe.test.ts +++ b/packages/integrations/test/dedupe.test.ts @@ -1,3 +1,5 @@ +import { Event } from '@sentry/types'; + import { _shouldDropEvent } from '../src/dedupe'; /** JSDoc */ @@ -5,27 +7,34 @@ function clone(data: T): T { return JSON.parse(JSON.stringify(data)); } -const messageEvent = { +const messageEvent: Event = { fingerprint: ['MrSnuffles'], message: 'PickleRick', - stacktrace: { - frames: [ - { - colno: 1, - filename: 'filename.js', - function: 'function', - lineno: 1, - }, + exception: { + values: [ { - colno: 2, - filename: 'filename.js', - function: 'function', - lineno: 2, + value: 'PickleRick', + stacktrace: { + frames: [ + { + colno: 1, + filename: 'filename.js', + function: 'function', + lineno: 1, + }, + { + colno: 2, + filename: 'filename.js', + function: 'function', + lineno: 2, + }, + ], + }, }, ], }, }; -const exceptionEvent = { +const exceptionEvent: Event = { exception: { values: [ { @@ -64,13 +73,14 @@ describe('Dedupe', () => { const eventA = clone(messageEvent); const eventB = clone(messageEvent); eventB.message = 'EvilMorty'; + eventB.exception.values[0].value = 'EvilMorty'; expect(_shouldDropEvent(eventA, eventB)).toBe(false); }); it('should not drop if events have same messages, but different stacktraces', () => { const eventA = clone(messageEvent); const eventB = clone(messageEvent); - eventB.stacktrace.frames[0].colno = 1337; + eventB.exception.values[0].stacktrace.frames[0].colno = 1337; expect(_shouldDropEvent(eventA, eventB)).toBe(false); }); diff --git a/packages/integrations/test/rewriteframes.test.ts b/packages/integrations/test/rewriteframes.test.ts index 92346d99ebcb..ff18e16f753d 100644 --- a/packages/integrations/test/rewriteframes.test.ts +++ b/packages/integrations/test/rewriteframes.test.ts @@ -65,12 +65,6 @@ describe('RewriteFrames', () => { rewriteFrames = new RewriteFrames(); }); - it('transforms messageEvent frames', () => { - const event = rewriteFrames.process(messageEvent); - expect(event.stacktrace!.frames![0].filename).toEqual('app:///file1.js'); - expect(event.stacktrace!.frames![1].filename).toEqual('app:///file2.js'); - }); - it('transforms exceptionEvent frames', () => { const event = rewriteFrames.process(exceptionEvent); expect(event.exception!.values![0].stacktrace!.frames![0].filename).toEqual('app:///file1.js'); @@ -85,12 +79,6 @@ describe('RewriteFrames', () => { }); }); - it('transforms messageEvent frames', () => { - const event = rewriteFrames.process(messageEvent); - expect(event.stacktrace!.frames![0].filename).toEqual('foobar/file1.js'); - expect(event.stacktrace!.frames![1].filename).toEqual('foobar/file2.js'); - }); - it('transforms exceptionEvent frames', () => { const event = rewriteFrames.process(exceptionEvent); expect(event.exception!.values![0].stacktrace!.frames![0].filename).toEqual('foobar/file1.js'); @@ -117,12 +105,6 @@ describe('RewriteFrames', () => { }); }); - it('transforms messageEvent frames', () => { - const event = rewriteFrames.process(messageEvent); - expect(event.stacktrace!.frames![0].filename).toEqual('app:///src/app/file1.js'); - expect(event.stacktrace!.frames![1].filename).toEqual('app:///src/app/mo\\dule/file2.js'); - }); - it('transforms exceptionEvent frames', () => { const event = rewriteFrames.process(exceptionEvent); expect(event.exception!.values![0].stacktrace!.frames![0].filename).toEqual('app:///src/app/file1.js'); @@ -146,14 +128,6 @@ describe('RewriteFrames', () => { }); }); - it('transforms messageEvent frames', () => { - const event = rewriteFrames.process(messageEvent); - expect(event.stacktrace!.frames![0].filename).toEqual('/www/src/app/file1.js'); - expect(event.stacktrace!.frames![0].function).toEqual('whoops'); - expect(event.stacktrace!.frames![1].filename).toEqual('/www/src/app/mo\\dule/file2.js'); - expect(event.stacktrace!.frames![1].function).toEqual('whoops'); - }); - it('transforms exceptionEvent frames', () => { const event = rewriteFrames.process(exceptionEvent); expect(event.exception!.values![0].stacktrace!.frames![0].filename).toEqual('/www/src/app/file1.js'); diff --git a/packages/node/src/eventbuilder.ts b/packages/node/src/eventbuilder.ts index 0376f21a59c8..1287f2a47f48 100644 --- a/packages/node/src/eventbuilder.ts +++ b/packages/node/src/eventbuilder.ts @@ -105,7 +105,14 @@ export function eventFromMessage( if (attachStacktrace && hint && hint.syntheticException) { const frames = parseStackFrames(hint.syntheticException); if (frames.length) { - event.stacktrace = { frames }; + event.exception = { + values: [ + { + value: message, + stacktrace: { frames }, + }, + ], + }; } } diff --git a/packages/types/src/event.ts b/packages/types/src/event.ts index 0aa146f43848..6711322baab4 100644 --- a/packages/types/src/event.ts +++ b/packages/types/src/event.ts @@ -9,7 +9,6 @@ import { CaptureContext } from './scope'; import { SdkInfo } from './sdkinfo'; import { Severity } from './severity'; import { Span } from './span'; -import { Stacktrace } from './stacktrace'; import { Measurements } from './transaction'; import { User } from './user'; @@ -34,7 +33,6 @@ export interface Event { exception?: { values?: Exception[]; }; - stacktrace?: Stacktrace; breadcrumbs?: Breadcrumb[]; contexts?: Contexts; tags?: { [key: string]: Primitive }; diff --git a/packages/wasm/src/index.ts b/packages/wasm/src/index.ts index 14252305fa76..cc5e678ee123 100644 --- a/packages/wasm/src/index.ts +++ b/packages/wasm/src/index.ts @@ -58,9 +58,6 @@ export class Wasm implements Integration { } }); } - if (event.stacktrace?.frames) { - haveWasm = haveWasm || patchFrames(event.stacktrace.frames); - } if (haveWasm) { event.debug_meta = event.debug_meta || {}; From af7abc02db9c9e88e0cbb554cff52336ddb07a94 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 16:47:44 -0700 Subject: [PATCH 30/94] chore(dev): Update `jest` and friends (#4897) This updates `jest`, `ts-jest`, and `jest-environment-node` to the latest versions, in order to facilitate code transformations during `ts-jest`'s on-the-fly compilation that will become necessary once we move to ES6. (More detail on this to come in the PR which actually introduces said transformation, but TL;DR the way we use and extend `global` is fine if it's a `var` (which it is in ES5 Land) but less fine if it's a `const` (which it becomes under ES6), and we need to fix that for tests to run.) It also updates `jsdom`. Together these updates meant that a larger number of packages needed to be downgraded in order for tests to run in node 8 and 10. This therefore also reworks the test script a bit to account for those changes. Finally, this removes the test environment from our main jest config, as its value has become the default in latest version of jest. --- .github/workflows/build.yml | 2 + jest.config.js | 1 - package.json | 10 +- packages/browser/package.json | 1 - packages/react/package.json | 1 - packages/tracing/package.json | 4 +- packages/utils/package.json | 3 +- packages/vue/package.json | 3 - scripts/test.ts | 69 +- yarn.lock | 1928 +++++++++++++++++++++------------ 10 files changed, 1304 insertions(+), 718 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aec9e06c66dc..21d0fd5685f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -410,6 +410,8 @@ jobs: uses: actions/checkout@v2 - name: Set up Node uses: actions/setup-node@v1 + with: + node-version: '16' - name: Check dependency cache uses: actions/cache@v2 with: diff --git a/jest.config.js b/jest.config.js index 411c1f269052..208a643187f4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -7,7 +7,6 @@ module.exports = { }, coverageDirectory: '/coverage', moduleFileExtensions: ['js', 'ts', 'tsx'], - testEnvironment: 'node', testMatch: ['/**/*.test.ts', '/**/*.test.tsx'], globals: { 'ts-jest': { diff --git a/package.json b/package.json index e1f42542b33d..7075a4f5f6fd 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "@strictsoftware/typedoc-plugin-monorepo": "^0.3.1", "@types/chai": "^4.1.3", "@types/jest": "^24.0.11", + "@types/jsdom": "^16.2.3", "@types/mocha": "^5.2.0", "@types/node": "~10.17.0", "@types/sinon": "^7.0.11", @@ -69,7 +70,9 @@ "codecov": "^3.6.5", "deepmerge": "^4.2.2", "eslint": "7.32.0", - "jest": "^24.9.0", + "jest": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jsdom": "^19.0.0", "karma-browserstack-launcher": "^1.5.1", "karma-firefox-launcher": "^1.1.0", "lerna": "3.13.4", @@ -85,15 +88,14 @@ "rollup-plugin-typescript2": "^0.31.2", "sinon": "^7.3.2", "size-limit": "^4.5.5", - "ts-jest": "^24.3.0", + "ts-jest": "^27.1.4", "ts-node": "^8.10.2", "tslib": "^2.3.1", "typedoc": "^0.18.0", "typescript": "3.8.3" }, "resolutions": { - "**/agent-base": "5", - "**/jest-environment-node": "24" + "**/agent-base": "5" }, "version": "0.0.0", "dependencies": {} diff --git a/packages/browser/package.json b/packages/browser/package.json index d3a87d21d04a..7f1c79235b59 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -26,7 +26,6 @@ "btoa": "^1.2.1", "chai": "^4.1.2", "chokidar": "^3.0.2", - "jsdom": "^15.0.0", "karma": "^6.3.16", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^2.2.0", diff --git a/packages/react/package.json b/packages/react/package.json index 534283e00d07..7835071eccdc 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -40,7 +40,6 @@ "eslint-plugin-react-hooks": "^4.0.8", "history-4": "npm:history@4.6.0", "history-5": "npm:history@4.9.0", - "jsdom": "^16.2.2", "react": "^18.0.0", "react-dom": "^18.0.0", "react-router-3": "npm:react-router@3.2.0", diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 6998ba95ba9e..5100e610ef8a 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -24,9 +24,7 @@ }, "devDependencies": { "@sentry/browser": "7.0.0-alpha.0", - "@types/express": "^4.17.1", - "@types/jsdom": "^16.2.3", - "jsdom": "^16.2.2" + "@types/express": "^4.17.1" }, "scripts": { "build": "run-p build:cjs build:esm build:types build:bundle && ts-node ../../scripts/prepack.ts #necessary for integration tests", diff --git a/packages/utils/package.json b/packages/utils/package.json index 6d62d5602180..ddce3d7933aa 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -20,8 +20,7 @@ "tslib": "^1.9.3" }, "devDependencies": { - "chai": "^4.1.2", - "jsdom": "^16.2.2" + "chai": "^4.1.2" }, "scripts": { "build": "run-p build:cjs build:esm build:types", diff --git a/packages/vue/package.json b/packages/vue/package.json index fea81ff573a8..b49beced0934 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -26,9 +26,6 @@ "peerDependencies": { "vue": "2.x || 3.x" }, - "devDependencies": { - "jsdom": "^16.2.2" - }, "scripts": { "build": "run-p build:cjs build:esm build:types", "build:bundle": "rollup --config", diff --git a/scripts/test.ts b/scripts/test.ts index 51a1dc06245e..02f440af1af9 100644 --- a/scripts/test.ts +++ b/scripts/test.ts @@ -11,28 +11,55 @@ function run(cmd: string, cwd: string = '') { const nodeMajorVersion = parseInt(process.version.split('.')[0].replace('v', ''), 10); -if (nodeMajorVersion <= 8) { - // install legacy versions of packages whose current versions don't support node 8 +// Ember tests require dependency changes for each set of tests, making them quite slow. To compensate for this, in CI +// we run them in a separate, parallel job. +let ignorePackages = ['@sentry/ember']; + +// install legacy versions of third-party packages whose current versions don't support node 8 or 10, and skip testing +// our own packages which don't support node 8 for various syntax or dependency reasons +if (nodeMajorVersion <= 10) { + let legacyDependencies; + + if (nodeMajorVersion === 8) { + legacyDependencies = [ + 'jsdom@15.x', + 'jest@25.x', + 'jest-environment-jsdom@25.x', + 'jest-environment-node@25.x', + 'ts-jest@25.x', + ]; + + ignorePackages = [ + ...ignorePackages, + '@sentry-internal/eslint-plugin-sdk', + '@sentry/react', + '@sentry/wasm', + '@sentry/gatsby', + '@sentry/serverless', + '@sentry/nextjs', + ]; + + // This is a hack, to deal the fact that the browser-based tests fail under Node 8, because of a conflict buried + // somewhere in the interaction between our current overall set of dependencies and the older versions of a small + // subset we're about to install below. Since they're browser-based, these tests are never going to be running in a + // node 8 environment in any case, so it's fine to skip them here. (In the long run, we should only run such tests + // against a single version of node, but in the short run, this at least allows us to not be blocked by the + // failures.) + run('rm -rf packages/tracing/test/browser'); + } + // Node 10 + else { + legacyDependencies = ['jsdom@16.x']; + } + + const legacyDepStr = legacyDependencies.join(' '); + // ignoring engines and scripts lets us get away with having incompatible things installed for packages we're not testing - run('yarn add --dev --ignore-engines --ignore-scripts jsdom@15.x', 'packages/tracing'); - run('yarn add --dev --ignore-engines --ignore-scripts jsdom@15.x', 'packages/utils'); - - // ember tests happen separately, and the rest fail on node 8 for various syntax or dependency reasons - const ignore = [ - '@sentry/ember', - '@sentry-internal/eslint-plugin-sdk', - '@sentry/react', - '@sentry/wasm', - '@sentry/gatsby', - '@sentry/serverless', - '@sentry/nextjs', - ] - .map(dep => `--ignore="${dep}"`) - .join(' '); - - run(`yarn test ${ignore}`); -} else { - run('yarn test --ignore="@sentry/ember"'); + run(`yarn add --dev --ignore-engines --ignore-scripts --ignore-workspace-root-check ${legacyDepStr}`); } +const ignoreFlags = ignorePackages.map(dep => `--ignore="${dep}"`).join(' '); + +run(`yarn test ${ignoreFlags}`); + process.exit(0); diff --git a/yarn.lock b/yarn.lock index 26947533ab88..7a8d5c41fb37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + "@angular/common@^10.0.3": version "10.2.4" resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.4.tgz#fb1772ea5780c96e00411900c54457f0cbcf401b" @@ -61,6 +68,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa" integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew== +"@babel/compat-data@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" + integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== + "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.12.0", "@babel/core@^7.3.4": version "7.13.14" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06" @@ -82,6 +94,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" + integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.9" + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.9" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.9" + "@babel/types" "^7.17.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/core@^7.12.9": version "7.15.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.5.tgz#f8ed9ace730722544609f90c9bb49162dc3bf5b9" @@ -151,6 +184,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.17.9", "@babel/generator@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" + integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" @@ -200,6 +242,16 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" + integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.5.5": version "7.13.11" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" @@ -299,6 +351,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" + integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== + dependencies: + "@babel/template" "^7.16.7" + "@babel/types" "^7.17.0" + "@babel/helper-get-function-arity@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" @@ -376,6 +436,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz#962cc629a7f7f9a082dd62d0307fa75fe8788d7c" @@ -404,6 +471,20 @@ "@babel/traverse" "^7.16.0" "@babel/types" "^7.16.0" +"@babel/helper-module-transforms@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" + integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + "@babel/helper-optimise-call-expression@^7.12.13", "@babel/helper-optimise-call-expression@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" @@ -489,6 +570,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-simple-access@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" + integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== + dependencies: + "@babel/types" "^7.17.0" + "@babel/helper-skip-transparent-expression-wrappers@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" @@ -577,6 +665,15 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" +"@babel/helpers@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" + integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.9" + "@babel/types" "^7.17.0" + "@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" @@ -609,6 +706,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746" integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ== +"@babel/parser@^7.14.7", "@babel/parser@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" + integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== + "@babel/parser@^7.15.4", "@babel/parser@^7.15.5": version "7.15.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.6.tgz#043b9aa3c303c0722e5377fef9197f4cf1796549" @@ -833,7 +935,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.13": +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -861,6 +970,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" @@ -868,7 +984,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -882,14 +998,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.10.4": +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -924,6 +1040,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-typescript@^7.12.13", "@babel/plugin-syntax-typescript@^7.2.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" @@ -938,7 +1061,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.16.7": +"@babel/plugin-syntax-typescript@^7.16.7", "@babel/plugin-syntax-typescript@^7.7.2": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== @@ -1417,7 +1540,7 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/template@^7.16.7": +"@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== @@ -1426,7 +1549,7 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg== @@ -1486,6 +1609,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" + integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.9" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.9" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -1528,6 +1667,19 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.17.0", "@babel/types@^7.3.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1953,7 +2105,23 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@jest/console@^24.7.1", "@jest/console@^24.9.0": +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== @@ -1962,39 +2130,51 @@ chalk "^2.0.1" slash "^2.0.0" -"@jest/core@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" - integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.9.0" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-resolve-dependencies "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - jest-watcher "^24.9.0" - micromatch "^3.1.10" - p-each-series "^1.0.0" - realpath-native "^1.1.0" - rimraf "^2.5.4" - slash "^2.0.0" - strip-ansi "^5.0.0" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" "@jest/environment@^24.9.0": version "24.9.0" @@ -2006,6 +2186,16 @@ "@jest/types" "^24.9.0" jest-mock "^24.9.0" +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + "@jest/fake-timers@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" @@ -2015,34 +2205,59 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" -"@jest/reporters@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" - integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== dependencies: - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.2.6" - jest-haste-map "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - node-notifier "^5.4.2" - slash "^2.0.0" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" source-map "^0.6.0" - string-length "^2.0.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" -"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": +"@jest/source-map@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== @@ -2051,6 +2266,15 @@ graceful-fs "^4.1.15" source-map "^0.6.0" +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + "@jest/test-result@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" @@ -2060,15 +2284,25 @@ "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-sequencer@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" - integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== dependencies: - "@jest/test-result" "^24.9.0" - jest-haste-map "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" "@jest/transform@^24.9.0": version "24.9.0" @@ -2092,6 +2326,27 @@ source-map "^0.6.1" write-file-atomic "2.4.1" +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@>=24 <=26": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -2123,6 +2378,35 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@lerna/add@3.13.3": version "3.13.3" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.3.tgz#f4c1674839780e458f0426d4f7b6d0a77b9a2ae9" @@ -3173,6 +3457,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/formatio@^3.2.1": version "3.2.2" resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" @@ -3287,6 +3578,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@ts-type/package-dts@^1.0.58": version "1.0.58" resolved "https://registry.yarnpkg.com/@ts-type/package-dts/-/package-dts-1.0.58.tgz#75f6fdf5f1e8f262a5081b90346439b4c4bc8d01" @@ -3305,10 +3601,10 @@ resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.73.tgz#77773c9accb2cec26fcb7c6b510a555805604a53" integrity sha512-P+a6TRQbRnVQOIjWkmw6F23wiJcF+4Uniasbzx7NAXjLQCVGx/Z4VoMfit81/pxlmcXNxAMGuYPugn6CrJLilQ== -"@types/babel__core@^7.1.0": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" - integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -3338,6 +3634,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/babel__traverse@^7.0.4": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + "@types/body-parser@*": version "1.19.0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" @@ -3663,6 +3966,13 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + "@types/history-4@npm:@types/history@4.7.8", "@types/history-5@npm:@types/history@4.7.8", "@types/history@*": name "@types/history-4" version "4.7.8" @@ -3697,6 +4007,11 @@ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== +"@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + "@types/istanbul-lib-report@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" @@ -3857,6 +4172,11 @@ pg-protocol "*" pg-types "^2.2.0" +"@types/prettier@^2.1.5": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" + integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== + "@types/prop-types@*": version "15.7.3" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" @@ -4464,7 +4784,7 @@ JSONStream@^1.0.4, JSONStream@^1.3.4: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.0, abab@^2.0.3, abab@^2.0.5: +abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== @@ -4502,14 +4822,6 @@ accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^4.1.0, acorn-globals@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -4528,7 +4840,7 @@ acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== -acorn-walk@^6.0.1, acorn-walk@^6.1.1: +acorn-walk@^6.1.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== @@ -4543,26 +4855,26 @@ acorn-walk@^8.0.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== -acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== - -acorn@^6.0.1, acorn@^6.0.5, acorn@^6.4.1: +acorn@^6.0.5, acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.1.0: +acorn@^8.0.4: version "8.1.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== +acorn@^8.2.4, acorn@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + acorn@^8.4.1: version "8.6.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" @@ -4662,7 +4974,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: +ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -4760,7 +5072,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.0, anymatch@~3.1.1: +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -5022,11 +5334,6 @@ ast-types@0.13.3: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.3.tgz#50da3f28d17bdbc7969a3a2d83a0e4a72ae755a7" integrity sha512-XTZ7xGML849LkQP86sWdQzfhwbt3YwIO6MqbX9mUNYY98VKaaVZP7YNNm70IpwecbkkxmfC5IYAzOQ/2p29zRA== -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -5063,11 +5370,6 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - async-mutex@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.2.tgz#1485eda5bda1b0ec7c8df1ac2e815757ad1831df" @@ -5342,18 +5644,19 @@ babel-import-util@^0.2.0: resolved "https://registry.yarnpkg.com/babel-import-util/-/babel-import-util-0.2.0.tgz#b468bb679919601a3570f9e317536c54f2862e23" integrity sha512-CtWYYHU/MgK88rxMrLfkD356dApswtR/kWZ/c6JifG1m10e7tBBrs/366dFzWMAoqYmG5/JSh+94tUSpIwh+ag== -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" babel-loader@^8.0.6: version "8.2.2" @@ -5486,11 +5789,25 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" babel-plugin-module-resolver@^3.2.0: @@ -5796,6 +6113,24 @@ babel-polyfill@^6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + babel-preset-env@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" @@ -5832,13 +6167,13 @@ babel-preset-env@^1.7.0: invariant "^2.2.2" semver "^5.3.0" -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" babel-register@^6.26.0: version "6.26.0" @@ -6892,7 +7227,7 @@ buffer-equal-constant-time@1.0.1: resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= -buffer-from@1.x, buffer-from@^1.0.0: +buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -7262,6 +7597,11 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -7335,6 +7675,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + ci-job-number@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-1.2.2.tgz#f4e5918fcaeeda95b604f214be7d7d4a961fe0c0" @@ -7348,6 +7693,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -7550,6 +7900,11 @@ codecov@^3.6.5: teeny-request "6.0.1" urlgrey "0.4.4" +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -7631,7 +7986,7 @@ combine-source-map@^0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -8122,7 +8477,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -8353,24 +8708,22 @@ csso@^4.0.2: dependencies: css-tree "^1.1.2" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssom@^0.4.1, cssom@^0.4.4: +cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== - dependencies: - cssom "0.3.x" +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.0.0, cssstyle@^2.3.0: +cssstyle@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== @@ -8431,15 +8784,6 @@ data-uri-to-buffer@3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== -data-urls@^1.0.0, data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -8449,6 +8793,15 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +data-urls@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" + integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + date-and-time@^0.14.2: version "0.14.2" resolved "https://registry.yarnpkg.com/date-and-time/-/date-and-time-0.14.2.tgz#a4266c3dead460f6c231fe9674e585908dac354e" @@ -8561,6 +8914,11 @@ decimal.js@^10.2.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== +decimal.js@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -8724,16 +9082,11 @@ detect-indent@^6.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== -detect-newline@3.1.0: +detect-newline@3.1.0, detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - detective-amd@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-3.1.0.tgz#92daee3214a0ca4522646cf333cac90a3fca6373" @@ -8849,6 +9202,11 @@ diff-sequences@^27.4.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + diff@3.5.0, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -8969,13 +9327,6 @@ domelementtype@^2.2.0: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - domexception@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" @@ -8983,6 +9334,13 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + domhandler@^4.0.0, domhandler@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" @@ -9823,6 +10181,11 @@ emit-function@0.0.2: resolved "https://registry.yarnpkg.com/emit-function/-/emit-function-0.0.2.tgz#e3a50b3d61be1bf8ca88b924bf713157a5bec124" integrity sha1-46ULPWG+G/jKiLkkv3ExV6W+wSQ= +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -10117,18 +10480,6 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" -escodegen@^1.11.1, escodegen@^1.9.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - escodegen@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" @@ -10390,7 +10741,7 @@ estraverse@^1.9.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -10514,6 +10865,21 @@ execa@^4.0.0, execa@^4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exists-sync@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/exists-sync/-/exists-sync-0.0.4.tgz#9744c2c428cc03b01060db454d4b12f0ef3c8879" @@ -10573,17 +10939,15 @@ expect@=27.2.5: jest-message-util "^27.2.5" jest-regex-util "^27.0.6" -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" express@^4.10.7, express@^4.16.4, express@^4.17.1: version "4.17.1" @@ -11190,6 +11554,24 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -11398,7 +11780,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.3.1, fsevents@~2.3.2: +fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -11513,6 +11895,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -11967,6 +12354,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" @@ -12346,13 +12738,6 @@ html-comment-regex@^1.1.0: resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -12360,6 +12745,13 @@ html-encoding-sniffer@^2.0.1: dependencies: whatwg-encoding "^1.0.5" +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -12460,7 +12852,7 @@ http-proxy-agent@^2.1.0: agent-base "4" debug "3.1.0" -http-proxy-agent@^4.0.0: +http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== @@ -12469,6 +12861,15 @@ http-proxy-agent@^4.0.0: agent-base "6" debug "4" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + http-proxy@^1.13.1, http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" @@ -12526,6 +12927,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -12540,6 +12946,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + iconv-lite@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" @@ -12618,13 +13031,13 @@ import-local@^1.0.0: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" @@ -12805,11 +13218,6 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - ip@1.1.5, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -13144,10 +13552,10 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-potential-custom-element-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" - integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-redirect@^1.0.0: version "1.0.0" @@ -13389,12 +13797,17 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: +istanbul-lib-coverage@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== @@ -13407,32 +13820,42 @@ istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: istanbul-lib-coverage "^2.0.5" semver "^6.0.0" -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" istanbul@0.4.5, istanbul@^0.4.0: version "0.4.5" @@ -13480,56 +13903,87 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" exit "^0.1.2" - import-local "^2.0.0" - is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" + yargs "^16.2.0" -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" jest-dev-server@^4.4.0: version "4.4.0" @@ -13544,7 +13998,7 @@ jest-dev-server@^4.4.0: tree-kill "^1.2.2" wait-on "^3.3.0" -jest-diff@^24.3.0, jest-diff@^24.9.0: +jest-diff@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== @@ -13564,37 +14018,48 @@ jest-diff@^27.2.5, jest-diff@^27.4.2: jest-get-type "^27.4.0" pretty-format "^27.4.2" -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== dependencies: - detect-newline "^2.1.0" + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" + detect-newline "^3.0.0" -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" -jest-environment-node@24, "jest-environment-node@>=24 <=26", jest-environment-node@^24.9.0: +"jest-environment-node@>=24 <=26": version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== @@ -13605,6 +14070,18 @@ jest-environment-node@24, "jest-environment-node@>=24 <=26", jest-environment-no jest-mock "^24.9.0" jest-util "^24.9.0" +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jest-environment-puppeteer@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.0.tgz#d82a37e0e0c51b63cc6b15dea101d53967508860" @@ -13625,6 +14102,11 @@ jest-get-type@^27.0.6, jest-get-type@^27.4.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -13644,35 +14126,56 @@ jest-haste-map@^24.9.0: optionalDependencies: fsevents "^1.2.7" -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" co "^4.6.0" - expect "^24.9.0" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" jest-matcher-utils@=27.2.5: version "27.2.5" @@ -13684,16 +14187,6 @@ jest-matcher-utils@=27.2.5: jest-get-type "^27.0.6" pretty-format "^27.2.5" -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - jest-matcher-utils@^27.2.5: version "27.4.2" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" @@ -13704,6 +14197,16 @@ jest-matcher-utils@^27.2.5: jest-get-type "^27.4.0" pretty-format "^27.4.2" +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + jest-message-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" @@ -13733,6 +14236,21 @@ jest-message-util@^27.2.5: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -13740,7 +14258,15 @@ jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-pnp-resolver@^1.2.1: +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== @@ -13753,7 +14279,7 @@ jest-puppeteer@^4.4.0: expect-puppeteer "^4.4.0" jest-environment-puppeteer "^4.4.0" -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: +jest-regex-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== @@ -13763,103 +14289,131 @@ jest-regex-util@^27.0.6: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== - dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-resolve@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" - integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== dependencies: - "@jest/types" "^24.9.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" source-map-support "^0.5.6" - throat "^4.0.0" + throat "^6.0.1" -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" - exit "^0.1.2" +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" jest-serializer@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" + pretty-format "^27.5.1" + semver "^7.3.2" jest-util@^24.9.0: version "24.9.0" @@ -13879,30 +14433,42 @@ jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" leven "^3.1.0" - pretty-format "^24.9.0" + pretty-format "^27.5.1" -jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" jest-worker@27.0.0-next.5: version "27.0.0-next.5" @@ -13913,7 +14479,7 @@ jest-worker@27.0.0-next.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^24.6.0, jest-worker@^24.9.0: +jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== @@ -13939,13 +14505,23 @@ jest-worker@^27.0.6: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" jmespath@0.15.0: version "0.15.0" @@ -14016,77 +14592,13 @@ jsdoctypeparser@^9.0.0: resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz#8c97e2fb69315eb274b0f01377eaa5c940bd7b26" integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" - -jsdom@^15.0.0: - version "15.2.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" - integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== - dependencies: - abab "^2.0.0" - acorn "^7.1.0" - acorn-globals "^4.3.2" - array-equal "^1.0.0" - cssom "^0.4.1" - cssstyle "^2.0.0" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.1" - html-encoding-sniffer "^1.0.2" - nwsapi "^2.2.0" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.7" - saxes "^3.1.9" - symbol-tree "^3.2.2" - tough-cookie "^3.0.1" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^7.0.0" - xml-name-validator "^3.0.0" - -jsdom@^16.2.2: - version "16.5.2" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.2.tgz#583fac89a0aea31dbf6237e7e4bedccd9beab472" - integrity sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg== +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" cssstyle "^2.3.0" @@ -14094,12 +14606,13 @@ jsdom@^16.2.2: decimal.js "^10.2.1" domexception "^2.0.1" escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" parse5 "6.0.1" - request "^2.88.2" - request-promise-native "^1.0.9" saxes "^5.0.1" symbol-tree "^3.2.4" tough-cookie "^4.0.0" @@ -14109,9 +14622,42 @@ jsdom@^16.2.2: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.4" + ws "^7.4.6" xml-name-validator "^3.0.0" +jsdom@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a" + integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A== + dependencies: + abab "^2.0.5" + acorn "^8.5.0" + acorn-globals "^6.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.1" + decimal.js "^10.3.1" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + ws "^8.2.3" + xml-name-validator "^4.0.0" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -14205,6 +14751,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -14528,11 +15079,6 @@ leek@0.0.24: lodash.assign "^3.2.0" rsvp "^3.0.21" -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - lerna@3.13.4: version "3.13.4" resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.13.4.tgz#03026c11c5643f341fda42e4fb1882e2df35e6cb" @@ -15086,6 +15632,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.4.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.8.0.tgz#649aaeb294a56297b5cbc5d70f198dcc5ebe5747" + integrity sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg== + lru_map@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" @@ -15148,7 +15699,7 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" -make-dir@^2.0.0, make-dir@^2.1.0: +make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -15679,7 +16230,7 @@ mkdirp@0.5.4: dependencies: minimist "^1.2.5" -mkdirp@0.5.x, mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -16165,17 +16716,6 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.4.2: - version "5.4.5" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.5.tgz#0cbc1a2b0f658493b4025775a13ad938e96091ef" - integrity sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - node-notifier@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-9.0.1.tgz#cea837f4c5e733936c7b9005e6545cea825d1af4" @@ -16390,7 +16930,7 @@ npm-run-path@^3.0.0: dependencies: path-key "^3.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -16431,7 +16971,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.0.7, nwsapi@^2.2.0: +nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -16587,7 +17127,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -16729,13 +17269,6 @@ p-defer@^3.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" integrity sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw== -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" - p-event@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" @@ -16988,7 +17521,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -17033,16 +17566,6 @@ parse-url@^5.0.0: parse-path "^4.0.0" protocols "^1.4.0" -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parse5@6.0.1, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -17342,6 +17865,11 @@ pirates@^4.0.1: dependencies: node-modules-regexp "^1.0.0" +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + pixelmatch@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.2.1.tgz#9e4e4f4aa59648208a31310306a5bed5522b0d65" @@ -17440,11 +17968,6 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - pngjs@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-4.0.1.tgz#f803869bb2fc1bfe1bf99aa4ec21c108117cfdbe" @@ -17910,7 +18433,7 @@ pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^27.0.2: +pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -18896,23 +19419,7 @@ replace-in-file@^4.0.0: glob "^7.1.6" yargs "^15.0.2" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5, request-promise-native@^1.0.7, request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.87.0, request@^2.88.0, request@^2.88.2: +request@^2.87.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -19003,6 +19510,13 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-dependency-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz#11700e340717b865d216c66cabeb4a2a3c696736" @@ -19034,6 +19548,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-package-path@^1.0.11, resolve-package-path@^1.2.2, resolve-package-path@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-1.2.7.tgz#2a7bc37ad96865e239330e3102c31322847e652e" @@ -19088,19 +19607,16 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@1.1.7, resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - resolve@^1.1.6: version "1.21.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" @@ -19110,6 +19626,14 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + resolve@^2.0.0-next.3: version "2.0.0-next.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" @@ -19370,18 +19894,11 @@ sax@1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= -sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: +sax@>=0.6.0, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== - dependencies: - xmlchars "^2.1.1" - saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -19432,7 +19949,7 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -19449,6 +19966,13 @@ semver@7.3.4: dependencies: lru-cache "^6.0.0" +semver@7.x: + version "7.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b" + integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w== + dependencies: + lru-cache "^7.4.0" + semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -19648,6 +20172,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.0, silent-error@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.1.1.tgz#f72af5b0d73682a2ba1778b7e32cd8aa7c2d8662" @@ -20255,11 +20784,6 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-browserify@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" @@ -20366,13 +20890,13 @@ string-hash@1.1.3: resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-template@~0.2.1: version "0.2.1" @@ -20707,6 +21231,14 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -20736,7 +21268,7 @@ symbol-observable@^1.2.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -symbol-tree@^3.2.2, symbol-tree@^3.2.4: +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== @@ -20897,6 +21429,14 @@ temp@~0.4.0: resolved "https://registry.yarnpkg.com/temp/-/temp-0.4.0.tgz#671ad63d57be0fe9d7294664b3fc400636678a60" integrity sha1-ZxrWPVe+D+nXKUZks/xABjZnimA= +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + terser-webpack-plugin@^1.4.3: version "1.4.5" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" @@ -20951,6 +21491,15 @@ test-exclude@^5.2.3: read-pkg-up "^4.0.0" require-main-filename "^2.0.0" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + testem@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/testem/-/testem-3.4.0.tgz#48ab6b98e96085eeddac1fb46337872b13e9e06c" @@ -21001,10 +21550,10 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.6.0.tgz#d7e4ab13fe54e32e08873be40d51b74229b00fc4" integrity sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ== -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== through2@3.0.0: version "3.0.0" @@ -21199,23 +21748,6 @@ totalist@^1.0.0: resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -21225,6 +21757,14 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -21239,6 +21779,13 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -21296,21 +21843,19 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -ts-jest@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" - integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== +ts-jest@^27.1.4: + version "27.1.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" + integrity sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ== dependencies: bs-logger "0.x" - buffer-from "1.x" fast-json-stable-stringify "2.x" + jest-util "^27.0.0" json5 "2.x" lodash.memoize "4.x" make-error "1.x" - mkdirp "0.x" - resolve "1.x" - semver "^5.5" - yargs-parser "10.x" + semver "7.x" + yargs-parser "20.x" ts-node@^8.10.2: version "8.10.2" @@ -21882,6 +22427,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -21946,22 +22500,13 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: +w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== - dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" - xml-name-validator "^3.0.0" - w3c-xmlserializer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" @@ -21969,6 +22514,13 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +w3c-xmlserializer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" + integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== + dependencies: + xml-name-validator "^4.0.0" + wait-on@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082" @@ -22114,6 +22666,11 @@ webidl-conversions@^6.1.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + webpack-bundle-analyzer@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.0.tgz#74013106e7e2b07cbd64f3a5ae847f7e814802c7" @@ -22215,23 +22772,43 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + whatwg-fetch@>=0.10.0: version "3.6.2" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" + integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -22240,15 +22817,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" @@ -22296,7 +22864,7 @@ which-typed-array@^1.1.2: has-symbols "^1.0.1" is-typed-array "^1.1.3" -which@1, which@1.3.1, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@1, which@1.3.1, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -22460,14 +23028,7 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" -ws@^5.2.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" - integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== - dependencies: - async-limiter "~1.0.0" - -ws@^7.0.0, ws@^7.2.3, ws@^7.3.1, ws@^7.4.4, ws@~7.4.2: +ws@^7.2.3, ws@^7.3.1, ws@~7.4.2: version "7.4.4" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== @@ -22477,6 +23038,11 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== +ws@^8.2.3: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + ws@~8.2.3: version "8.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" @@ -22492,6 +23058,11 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + xml2js@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" @@ -22505,7 +23076,7 @@ xmlbuilder@~9.0.1: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmlchars@^2.1.1, xmlchars@^2.2.0: +xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== @@ -22553,13 +23124,6 @@ yam@^1.0.0: fs-extra "^4.0.2" lodash.merge "^4.6.0" -yargs-parser@10.x: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - yargs-parser@13.1.2, yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -22568,6 +23132,11 @@ yargs-parser@13.1.2, yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@20.x, yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" @@ -22584,11 +23153,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-parser@^20.2.3: version "20.2.7" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" @@ -22654,7 +23218,7 @@ yargs@^15.0.2, yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.1.1: +yargs@^16.1.1, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== From f2c8cee62165a879a0f10a0ec04ba6ef84ce88d3 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 11 Apr 2022 17:03:23 -0700 Subject: [PATCH 31/94] fix(dev): Fix unit test debugging configuration (#4915) In https://github.com/getsentry/sentry-javascript/pull/4907, all of our jest config was pulled out of `package.json` and put into `jest.config.js` files. This fixes our VSCode debug profile for unit tests to point to the new config. --- .vscode/launch.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index bef12bd786af..2a1d7141b53c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -47,9 +47,6 @@ // this runs one test at a time, rather than running them in parallel (necessary for debugging so that you know // you're hitting a single test's breakpoints, in order) "--runInBand", - // TODO: when we unify jest config, we may need to change this - "--config", - "${workspaceFolder}/packages/${input:getPackageName}/package.json", // coverage messes up the source maps "--coverage", "false", From 7079520518f324ca4b782b03413f2dc8ba04f8e9 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 12 Apr 2022 10:12:48 +0200 Subject: [PATCH 32/94] ref(backend): Port functionality from Backend to Client (#4911) port all the functionality from the Backend classes to the Client classes. This includes: * Backend (interface) * BaseBackend * BrowserBackend * NodeBackend * TestBackend Additionally, fix the unit and integration tests in Core to spy on TestClient instead of TestBackend. --- packages/browser/src/backend.ts | 2 + packages/browser/src/client.ts | 60 ++++++++- packages/browser/src/exports.ts | 1 + packages/browser/test/unit/backend.test.ts | 2 + packages/browser/test/unit/index.test.ts | 6 +- .../unit/integrations/linkederrors.test.ts | 3 + packages/core/src/baseclient.ts | 106 ++++++++++++++-- packages/core/src/index.ts | 1 + packages/core/test/lib/base.test.ts | 116 ++++++++++-------- packages/core/test/mocks/backend.ts | 9 +- packages/core/test/mocks/client.ts | 68 +++++++++- packages/node/src/client.ts | 67 +++++++++- packages/node/src/index.ts | 1 + packages/node/test/index.test.ts | 11 +- .../test/integrations/linkederrors.test.ts | 5 + packages/types/src/client.ts | 20 ++- 16 files changed, 394 insertions(+), 84 deletions(-) diff --git a/packages/browser/src/backend.ts b/packages/browser/src/backend.ts index 89cf843d48ae..2543c6ae99ad 100644 --- a/packages/browser/src/backend.ts +++ b/packages/browser/src/backend.ts @@ -8,6 +8,8 @@ import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTranspor /** * Configuration options for the Sentry Browser SDK. * @see BrowserClient for more information. + * + * TODO(v7): move to client */ export interface BrowserOptions extends Options { /** diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 75aab49db77b..b64997c0a23b 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,17 +1,20 @@ -import { BaseClient, Scope, SDK_VERSION } from '@sentry/core'; -import { Event, EventHint } from '@sentry/types'; -import { getGlobalObject, logger } from '@sentry/utils'; +import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; +import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; +import { getGlobalObject, logger, supportsFetch } from '@sentry/utils'; import { BrowserBackend, BrowserOptions } from './backend'; +import { eventFromException, eventFromMessage } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; import { injectReportDialog, ReportDialogOptions } from './helpers'; import { Breadcrumbs } from './integrations'; +import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTransport } from './transports'; /** * The Sentry Browser SDK Client. * * @see BrowserOptions for documentation on configuration options. * @see SentryClient for usage documentation. + * TODO(v7): remove BrowserBackend */ export class BrowserClient extends BaseClient { /** @@ -32,6 +35,7 @@ export class BrowserClient extends BaseClient { version: SDK_VERSION, }; + // TODO(v7): remove BrowserBackend param super(BrowserBackend, options); } @@ -58,6 +62,20 @@ export class BrowserClient extends BaseClient { }); } + /** + * @inheritDoc + */ + public eventFromException(exception: unknown, hint?: EventHint): PromiseLike { + return eventFromException(exception, hint, this._options.attachStacktrace); + } + + /** + * @inheritDoc + */ + public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { + return eventFromMessage(message, level, hint, this._options.attachStacktrace); + } + /** * @inheritDoc */ @@ -76,4 +94,40 @@ export class BrowserClient extends BaseClient { } super._sendEvent(event); } + + /** + * @inheritDoc + */ + protected _setupTransport(): Transport { + if (!this._options.dsn) { + // We return the noop transport here in case there is no Dsn. + return super._setupTransport(); + } + + const transportOptions: TransportOptions = { + ...this._options.transportOptions, + dsn: this._options.dsn, + tunnel: this._options.tunnel, + sendClientReports: this._options.sendClientReports, + _metadata: this._options._metadata, + }; + + const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); + const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); + + if (this._options.transport) { + return new this._options.transport(transportOptions); + } + if (supportsFetch()) { + const requestOptions: RequestInit = { ...transportOptions.fetchParameters }; + this._newTransport = makeNewFetchTransport({ requestOptions, url }); + return new FetchTransport(transportOptions); + } + + this._newTransport = makeNewXHRTransport({ + url, + headers: transportOptions.headers, + }); + return new XHRTransport(transportOptions); + } } diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index b4dd4374a7b3..2a62e8e46fbe 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -41,6 +41,7 @@ export { withScope, } from '@sentry/core'; +// TODO(v7): refactor to use client here! export { BrowserOptions } from './backend'; export { BrowserClient } from './client'; export { injectReportDialog, ReportDialogOptions } from './helpers'; diff --git a/packages/browser/test/unit/backend.test.ts b/packages/browser/test/unit/backend.test.ts index 71ffec4d75b1..83f95307a8c7 100644 --- a/packages/browser/test/unit/backend.test.ts +++ b/packages/browser/test/unit/backend.test.ts @@ -2,6 +2,8 @@ import { BrowserBackend } from '../../src/backend'; let backend: BrowserBackend; +// TODO(v7): remove when deleting Backend + describe('BrowserBackend', () => { describe('sendEvent()', () => { it('should use NoopTransport', () => { diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 83c0053d3b66..707354fe7d1d 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -246,7 +246,7 @@ describe('SentryBrowser initialization', () => { it('should set SDK data when Sentry.init() is called', () => { init({ dsn }); - const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toBe('sentry.javascript.browser'); expect(sdkData.packages[0].name).toBe('npm:@sentry/browser'); @@ -257,7 +257,7 @@ describe('SentryBrowser initialization', () => { it('should set SDK data when instantiating a client directly', () => { const client = new BrowserClient({ dsn }); - const sdkData = (client as any)._backend._transport._api.metadata?.sdk; + const sdkData = (client as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toBe('sentry.javascript.browser'); expect(sdkData.packages[0].name).toBe('npm:@sentry/browser'); @@ -285,7 +285,7 @@ describe('SentryBrowser initialization', () => { }, }); - const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toBe('sentry.javascript.angular'); expect(sdkData.packages[0].name).toBe('npm:@sentry/angular'); diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 1531aa6f77ed..35f54f4b2d87 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -34,6 +34,7 @@ describe('LinkedErrors', () => { one.cause = two; const originalException = one; + // TODO(v7): refactor to use client here! const backend = new BrowserBackend({}); return backend.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('cause', 5, event, { @@ -65,6 +66,7 @@ describe('LinkedErrors', () => { const originalException = one; const backend = new BrowserBackend({}); + // TODO(v7): refactor to use client here! return backend.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('reason', 5, event, { originalException, @@ -92,6 +94,7 @@ describe('LinkedErrors', () => { const backend = new BrowserBackend({}); const originalException = one; + // TODO(v7): refactor to use client here! return backend.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('cause', 2, event, { originalException, diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index b7fef7f2164f..59145508ca9d 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -28,15 +28,21 @@ import { uuid4, } from '@sentry/utils'; +import { initAPIDetails } from './api'; import { Backend, BackendClass } from './basebackend'; import { IS_DEBUG_BUILD } from './flags'; import { IntegrationIndex, setupIntegrations } from './integration'; +import { createEventEnvelope, createSessionEnvelope } from './request'; +import { NewTransport } from './transports/base'; +import { NoopTransport } from './transports/noop'; const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; /** * Base implementation for all JavaScript SDK clients. * + * TODO(v7): refactor doc w.r.t. Backend + * * Call the constructor with the corresponding backend constructor and options * specific to the client subclass. To access these options later, use * {@link Client.getOptions}. Also, the Backend instance is available via @@ -71,6 +77,7 @@ export abstract class BaseClient implement * The backend used to physically interact in the environment. Usually, this * will correspond to the client. When composing SDKs, however, the Backend * from the root SDK will be used. + * TODO(v7): DELETE */ protected readonly _backend: B; @@ -86,6 +93,12 @@ export abstract class BaseClient implement /** Number of calls being processed */ protected _numProcessing: number = 0; + /** Cached transport used internally. */ + protected _transport: Transport; + + /** New v7 Transport that is initialized alongside the old one */ + protected _newTransport?: NewTransport; + /** * Initializes this client instance. * @@ -93,12 +106,17 @@ export abstract class BaseClient implement * @param options Options for the client. */ protected constructor(backendClass: BackendClass, options: O) { + // TODO(v7): Delete this._backend = new backendClass(options); this._options = options; if (options.dsn) { this._dsn = makeDsn(options.dsn); + } else { + IS_DEBUG_BUILD && logger.warn('No DSN provided, client will not do anything.'); } + + this._transport = this._setupTransport(); } /** @@ -115,8 +133,7 @@ export abstract class BaseClient implement let eventId: string | undefined = hint && hint.event_id; this._process( - this._getBackend() - .eventFromException(exception, hint) + this.eventFromException(exception, hint) .then(event => this._captureEvent(event, hint, scope)) .then(result => { eventId = result; @@ -133,8 +150,8 @@ export abstract class BaseClient implement let eventId: string | undefined = hint && hint.event_id; const promisedEvent = isPrimitive(message) - ? this._getBackend().eventFromMessage(String(message), level, hint) - : this._getBackend().eventFromException(message, hint); + ? this.eventFromMessage(String(message), level, hint) + : this.eventFromException(message, hint); this._process( promisedEvent @@ -204,7 +221,7 @@ export abstract class BaseClient implement * @inheritDoc */ public getTransport(): Transport { - return this._getBackend().getTransport(); + return this._transport; } /** @@ -249,6 +266,57 @@ export abstract class BaseClient implement } } + /** + * @inheritDoc + */ + public sendEvent(event: Event): void { + // TODO(v7): Remove the if-else + if ( + this._newTransport && + this._options.dsn && + this._options._experiments && + this._options._experiments.newTransport + ) { + const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); + const env = createEventEnvelope(event, api); + void this._newTransport.send(env).then(null, reason => { + IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); + }); + } else { + void this._transport.sendEvent(event).then(null, reason => { + IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); + }); + } + } + + /** + * @inheritDoc + */ + public sendSession(session: Session): void { + if (!this._transport.sendSession) { + IS_DEBUG_BUILD && logger.warn("Dropping session because custom transport doesn't implement sendSession"); + return; + } + + // TODO(v7): Remove the if-else + if ( + this._newTransport && + this._options.dsn && + this._options._experiments && + this._options._experiments.newTransport + ) { + const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); + const [env] = createSessionEnvelope(session, api); + void this._newTransport.send(env).then(null, reason => { + IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); + }); + } else { + void this._transport.sendSession(session).then(null, reason => { + IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); + }); + } + } + /** Updates existing session based on the provided event */ protected _updateSessionFromEvent(session: Session, event: Event): void { let crashed = false; @@ -283,8 +351,9 @@ export abstract class BaseClient implement } /** Deliver captured session to Sentry */ + // TODO(v7): should this be deleted? protected _sendSession(session: Session): void { - this._getBackend().sendSession(session); + this.sendSession(session); } /** @@ -317,7 +386,9 @@ export abstract class BaseClient implement }); } - /** Returns the current backend. */ + /** Returns the current backend. + * TODO(v7): DELETE + */ protected _getBackend(): B { return this._backend; } @@ -490,8 +561,9 @@ export abstract class BaseClient implement * Tells the backend to send this event * @param event The Sentry event to send */ + // TODO(v7): refactor: get rid of method? protected _sendEvent(event: Event): void { - this._getBackend().sendEvent(event); + this.sendEvent(event); } /** @@ -618,6 +690,24 @@ export abstract class BaseClient implement }, ); } + + /** + * Sets up the transport so it can be used later to send requests. + */ + protected _setupTransport(): Transport { + return new NoopTransport(); + } + + /** + * @inheritDoc + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + public abstract eventFromException(_exception: any, _hint?: EventHint): PromiseLike; + + /** + * @inheritDoc + */ + public abstract eventFromMessage(_message: string, _level?: Severity, _hint?: EventHint): PromiseLike; } /** diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b066724ce099..77018c2b4437 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -23,6 +23,7 @@ export { getReportDialogEndpoint, } from './api'; export { BaseClient } from './baseclient'; +// TODO(v7): Delete! export { BackendClass, BaseBackend } from './basebackend'; export { eventToSentryRequest, sessionToSentryRequest } from './request'; export { initAndBind, ClientClass } from './sdk'; diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 5c978b0ee530..8a26bd51f116 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -3,7 +3,7 @@ import { Event, Span, Transport } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import * as integrationModule from '../../src/integration'; -import { TestBackend } from '../mocks/backend'; +import { NoopTransport } from '../../src/transports/noop'; import { TestClient } from '../mocks/client'; import { TestIntegration } from '../mocks/integration'; import { FakeTransport } from '../mocks/transport'; @@ -12,7 +12,7 @@ const PUBLIC_DSN = 'https://username@domain/123'; // eslint-disable-next-line no-var declare var global: any; -const backendEventFromException = jest.spyOn(TestBackend.prototype, 'eventFromException'); +const clientEventFromException = jest.spyOn(TestClient.prototype, 'eventFromException'); const clientProcess = jest.spyOn(TestClient.prototype as any, '_process'); jest.mock('@sentry/utils', () => { @@ -55,8 +55,8 @@ jest.mock('@sentry/utils', () => { describe('BaseClient', () => { beforeEach(() => { - TestBackend.sendEventCalled = undefined; - TestBackend.instance = undefined; + TestClient.sendEventCalled = undefined; + TestClient.instance = undefined; }); afterEach(() => { @@ -98,14 +98,24 @@ describe('BaseClient', () => { }); describe('getTransport()', () => { - test('returns the transport from backend', () => { + test('returns the transport from client', () => { expect.assertions(2); const options = { dsn: PUBLIC_DSN, transport: FakeTransport }; const client = new TestClient(options); expect(client.getTransport()).toBeInstanceOf(FakeTransport); - expect(TestBackend.instance!.getTransport()).toBe(client.getTransport()); + expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); + }); + + test('retruns NoopTransport when no transport is passed', () => { + expect.assertions(2); + + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options); + + expect(client.getTransport()).toBeInstanceOf(NoopTransport); + expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); }); }); @@ -223,7 +233,7 @@ describe('BaseClient', () => { client.captureException(new Error('test exception')); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -257,7 +267,7 @@ describe('BaseClient', () => { scope, ); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ extra: { bar: 'wat', @@ -284,7 +294,7 @@ describe('BaseClient', () => { scope, ); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ extra: { bar: 'wat', @@ -309,12 +319,12 @@ describe('BaseClient', () => { client.captureException(thrown); expect(thrown.__sentry_captured__).toBe(true); - expect(backendEventFromException).toHaveBeenCalledTimes(1); + expect(clientEventFromException).toHaveBeenCalledTimes(1); client.captureException(thrown); // `captureException` should bail right away this second time around and not get as far as calling this again - expect(backendEventFromException).toHaveBeenCalledTimes(1); + expect(clientEventFromException).toHaveBeenCalledTimes(1); }); }); @@ -324,7 +334,7 @@ describe('BaseClient', () => { client.captureMessage('test message'); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -337,7 +347,7 @@ describe('BaseClient', () => { test('should call eventFromException if input to captureMessage is not a primitive', () => { const client = new TestClient({ dsn: PUBLIC_DSN }); - const spy = jest.spyOn(TestBackend.instance!, 'eventFromException'); + const spy = jest.spyOn(TestClient.instance!, 'eventFromException'); client.captureMessage('foo'); client.captureMessage(null as any); @@ -371,7 +381,7 @@ describe('BaseClient', () => { scope, ); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ extra: { bar: 'wat', @@ -392,7 +402,7 @@ describe('BaseClient', () => { client.captureEvent({}, undefined, scope); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); }); test('skips without a Dsn', () => { @@ -403,7 +413,7 @@ describe('BaseClient', () => { client.captureEvent({}, undefined, scope); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); }); test.each([ @@ -443,8 +453,8 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!.message).toBe('message'); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event!.message).toBe('message'); + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -462,8 +472,8 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message', timestamp: 1234 }, undefined, scope); - expect(TestBackend.instance!.event!.message).toBe('message'); - expect(TestBackend.instance!.event).toEqual( + expect(TestClient.instance!.event!.message).toBe('message'); + expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -481,7 +491,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', event_id: 'wat', @@ -501,7 +511,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -522,7 +532,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'env', event_id: '42', @@ -543,7 +553,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: undefined, event_id: '42', @@ -564,7 +574,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -584,10 +594,10 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toHaveProperty('event_id', '42'); - expect(TestBackend.instance!.event!).toHaveProperty('message', 'message'); - expect(TestBackend.instance!.event!).toHaveProperty('breadcrumbs'); - expect(TestBackend.instance!.event!.breadcrumbs![0]).toHaveProperty('message', 'breadcrumb'); + expect(TestClient.instance!.event!).toHaveProperty('event_id', '42'); + expect(TestClient.instance!.event!).toHaveProperty('message', 'message'); + expect(TestClient.instance!.event!).toHaveProperty('breadcrumbs'); + expect(TestClient.instance!.event!.breadcrumbs![0]).toHaveProperty('message', 'breadcrumb'); }); test('limits previously saved breadcrumbs', () => { @@ -601,8 +611,8 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!.breadcrumbs).toHaveLength(1); - expect(TestBackend.instance!.event!.breadcrumbs![0].message).toEqual('2'); + expect(TestClient.instance!.event!.breadcrumbs).toHaveLength(1); + expect(TestClient.instance!.event!.breadcrumbs![0].message).toEqual('2'); }); test('adds context data', () => { @@ -616,7 +626,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -638,7 +648,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', event_id: '42', @@ -655,7 +665,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }); - expect(TestBackend.instance!.event!.sdk).toEqual({ + expect(TestClient.instance!.event!.sdk).toEqual({ integrations: ['TestIntegration'], }); }); @@ -698,7 +708,7 @@ describe('BaseClient', () => { user: fourLevelsObject, }); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ breadcrumbs: [normalizedBreadcrumb, normalizedBreadcrumb, normalizedBreadcrumb], contexts: normalizedObject, @@ -749,7 +759,7 @@ describe('BaseClient', () => { user: fourLevelsObject, }); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ breadcrumbs: [normalizedBreadcrumb, normalizedBreadcrumb, normalizedBreadcrumb], contexts: normalizedObject, @@ -805,7 +815,7 @@ describe('BaseClient', () => { user: fourLevelsObject, }); - expect(TestBackend.instance!.event!).toEqual( + expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ breadcrumbs: [normalizedBreadcrumb, normalizedBreadcrumb, normalizedBreadcrumb], contexts: normalizedObject, @@ -871,7 +881,7 @@ describe('BaseClient', () => { // event. The code can be restored to its original form (the commented-out line below) once that hack is // removed. See https://github.com/getsentry/sentry-javascript/pull/4425 and // https://github.com/getsentry/sentry-javascript/pull/4574 - const capturedEvent = TestBackend.instance!.event!; + const capturedEvent = TestClient.instance!.event!; if (capturedEvent.sdkProcessingMetadata?.normalizeDepth) { if (Object.keys(capturedEvent.sdkProcessingMetadata).length === 1) { delete capturedEvent.sdkProcessingMetadata; @@ -899,7 +909,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); - expect(TestBackend.instance!.event!.message).toBe('hello'); + expect(TestClient.instance!.event!.message).toBe('hello'); }); test('calls beforeSend and uses the new one', () => { @@ -910,7 +920,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); - expect(TestBackend.instance!.event!.message).toBe('changed1'); + expect(TestClient.instance!.event!.message).toBe('changed1'); }); test('calls beforeSend and discards the event', () => { @@ -923,7 +933,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); expect(captureExceptionSpy).not.toBeCalled(); expect(loggerErrorSpy).toBeCalledWith(new SentryError('`beforeSend` returned `null`, will not send event.')); }); @@ -940,7 +950,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); expect(loggerErrorSpy).toBeCalledWith( new SentryError('`beforeSend` method has to return `null` or a valid event.'), ); @@ -964,7 +974,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); - TestBackend.sendEventCalled = (event: Event) => { + TestClient.sendEventCalled = (event: Event) => { expect(event.message).toBe('hello'); }; @@ -992,7 +1002,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); - TestBackend.sendEventCalled = (event: Event) => { + TestClient.sendEventCalled = (event: Event) => { expect(event.message).toBe('changed2'); }; @@ -1020,7 +1030,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }); jest.runAllTimers(); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); }); test('beforeSend gets access to a hint as a second argument', () => { @@ -1031,8 +1041,8 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }, { data: 'someRandomThing' }); - expect(TestBackend.instance!.event!.message).toBe('hello'); - expect((TestBackend.instance!.event! as any).data).toBe('someRandomThing'); + expect(TestClient.instance!.event!.message).toBe('hello'); + expect((TestClient.instance!.event! as any).data).toBe('someRandomThing'); }); test('beforeSend records dropped events', () => { @@ -1068,7 +1078,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }, {}, scope); - expect(TestBackend.instance!.event).toBeUndefined(); + expect(TestClient.instance!.event).toBeUndefined(); expect(captureExceptionSpy).not.toBeCalled(); expect(loggerErrorSpy).toBeCalledWith(new SentryError('An event processor returned null, will not send event.')); }); @@ -1108,7 +1118,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'hello' }, {}, scope); - expect(TestBackend.instance!.event!.exception!.values![0]).toStrictEqual({ type: 'Error', value: 'sorry' }); + expect(TestClient.instance!.event!.exception!.values![0]).toStrictEqual({ type: 'Error', value: 'sorry' }); expect(captureExceptionSpy).toBeCalledWith(exception, { data: { __sentry__: true, @@ -1249,7 +1259,7 @@ describe('BaseClient', () => { }); const delay = 300; - const spy = jest.spyOn(TestBackend.instance!, 'eventFromMessage'); + const spy = jest.spyOn(TestClient.instance!, 'eventFromMessage'); spy.mockImplementationOnce( (message, level) => new SyncPromise(resolve => { @@ -1317,7 +1327,7 @@ describe('BaseClient', () => { }); describe('captureSession()', () => { - test('sends sessions to the backend', () => { + test('sends sessions to the client', () => { expect.assertions(1); const client = new TestClient({ dsn: PUBLIC_DSN }); @@ -1325,7 +1335,7 @@ describe('BaseClient', () => { client.captureSession(session); - expect(TestBackend.instance!.session).toEqual(session); + expect(TestClient.instance!.session).toEqual(session); }); test('skips when disabled', () => { @@ -1336,7 +1346,7 @@ describe('BaseClient', () => { client.captureSession(session); - expect(TestBackend.instance!.session).toBeUndefined(); + expect(TestClient.instance!.session).toBeUndefined(); }); }); }); diff --git a/packages/core/test/mocks/backend.ts b/packages/core/test/mocks/backend.ts index 48ddb0d9cc0c..a201bc8c0b68 100644 --- a/packages/core/test/mocks/backend.ts +++ b/packages/core/test/mocks/backend.ts @@ -1,14 +1,11 @@ import { Session } from '@sentry/hub'; -import { Event, Options, Severity, Transport } from '@sentry/types'; +import { Event, Severity, Transport } from '@sentry/types'; import { resolvedSyncPromise } from '@sentry/utils'; import { BaseBackend } from '../../src/basebackend'; +import { TestOptions } from './client'; -export interface TestOptions extends Options { - test?: boolean; - mockInstallFailure?: boolean; - enableSend?: boolean; -} +// TODO: Delete whole file (?) export class TestBackend extends BaseBackend { public static instance?: TestBackend; diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 810328818eae..8c02ca30f5f3 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,14 +1,80 @@ +import { Session } from '@sentry/hub'; +import { Event, Options, Severity, Transport } from '@sentry/types'; +import { resolvedSyncPromise } from '@sentry/utils'; + import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; -import { TestBackend, TestOptions } from './backend'; +import { TestBackend } from './backend'; +export interface TestOptions extends Options { + test?: boolean; + mockInstallFailure?: boolean; + enableSend?: boolean; +} +// TODO(v7): remove TestBackend export class TestClient extends BaseClient { public static instance?: TestClient; + public static sendEventCalled?: (event: Event) => void; + + public event?: Event; + public session?: Session; public constructor(options: TestOptions) { + // TODO(v7): remove TestBackend param super(TestBackend, options); TestClient.instance = this; } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + public eventFromException(exception: any): PromiseLike { + return resolvedSyncPromise({ + exception: { + values: [ + { + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + type: exception.name, + value: exception.message, + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + }, + ], + }, + }); + } + + public eventFromMessage(message: string, level: Severity = Severity.Info): PromiseLike { + return resolvedSyncPromise({ message, level }); + } + + public sendEvent(event: Event): void { + this.event = event; + if (this._options.enableSend) { + super.sendEvent(event); + return; + } + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + TestClient.sendEventCalled && TestClient.sendEventCalled(event); + } + + public sendSession(session: Session): void { + this.session = session; + } + + protected _setupTransport(): Transport { + if (!this._options.dsn) { + // We return the noop transport here in case there is no Dsn. + return super._setupTransport(); + } + + const transportOptions = this._options.transportOptions + ? this._options.transportOptions + : { dsn: this._options.dsn }; + + if (this._options.transport) { + return new this._options.transport(transportOptions); + } + + return super._setupTransport(); + } } export function init(options: TestOptions): void { diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index dde7f8941b74..0b2b585edc5d 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,10 +1,12 @@ -import { BaseClient, Scope, SDK_VERSION } from '@sentry/core'; +import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; -import { Event, EventHint } from '@sentry/types'; -import { logger } from '@sentry/utils'; +import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; +import { logger, makeDsn, resolvedSyncPromise } from '@sentry/utils'; import { NodeBackend } from './backend'; +import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; +import { HTTPSTransport, HTTPTransport, makeNodeTransport } from './transports'; import { NodeOptions } from './types'; /** @@ -12,6 +14,8 @@ import { NodeOptions } from './types'; * * @see NodeOptions for documentation on configuration options. * @see SentryClient for usage documentation. + * + * TODO(v7): remove NodeBackend */ export class NodeClient extends BaseClient { protected _sessionFlusher: SessionFlusher | undefined; @@ -33,6 +37,7 @@ export class NodeClient extends BaseClient { version: SDK_VERSION, }; + // TODO(v7): remove NodeBackend param super(NodeBackend, options); } @@ -106,6 +111,21 @@ export class NodeClient extends BaseClient { } } + /** + * @inheritDoc + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types + public eventFromException(exception: any, hint?: EventHint): PromiseLike { + return resolvedSyncPromise(eventFromUnknownInput(exception, hint)); + } + + /** + * @inheritDoc + */ + public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { + return resolvedSyncPromise(eventFromMessage(message, level, hint, this._options.attachStacktrace)); + } + /** * @inheritDoc */ @@ -128,4 +148,45 @@ export class NodeClient extends BaseClient { this._sessionFlusher.incrementSessionStatusCount(); } } + + /** + * @inheritDoc + */ + protected _setupTransport(): Transport { + if (!this._options.dsn) { + // We return the noop transport here in case there is no Dsn. + return super._setupTransport(); + } + + const dsn = makeDsn(this._options.dsn); + + const transportOptions: TransportOptions = { + ...this._options.transportOptions, + ...(this._options.httpProxy && { httpProxy: this._options.httpProxy }), + ...(this._options.httpsProxy && { httpsProxy: this._options.httpsProxy }), + ...(this._options.caCerts && { caCerts: this._options.caCerts }), + dsn: this._options.dsn, + tunnel: this._options.tunnel, + _metadata: this._options._metadata, + }; + + if (this._options.transport) { + return new this._options.transport(transportOptions); + } + + const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); + const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); + + this._newTransport = makeNodeTransport({ + url, + headers: transportOptions.headers, + proxy: transportOptions.httpProxy, + caCerts: transportOptions.caCerts, + }); + + if (dsn.protocol === 'http') { + return new HTTPTransport(transportOptions); + } + return new HTTPSTransport(transportOptions); + } } diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 9f65c3f1a1a8..48bb88a24872 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -42,6 +42,7 @@ export { } from '@sentry/core'; export { NodeOptions } from './types'; +// TODO(v7): delete! export { NodeBackend } from './backend'; export { NodeClient } from './client'; export { defaultIntegrations, init, lastEventId, flush, close, getSentryRelease } from './sdk'; diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index 0af38dae80fb..687465802a94 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -15,7 +15,6 @@ import { NodeClient, Scope, } from '../src'; -import { NodeBackend } from '../src/backend'; import { ContextLines, LinkedErrors } from '../src/integrations'; jest.mock('@sentry/core', () => { @@ -78,7 +77,7 @@ describe('SentryNode', () => { let s: jest.SpyInstance; beforeEach(() => { - s = jest.spyOn(NodeBackend.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 })); + s = jest.spyOn(NodeClient.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 })); }); afterEach(() => { @@ -107,7 +106,7 @@ describe('SentryNode', () => { let s: jest.SpyInstance; beforeEach(() => { - s = jest.spyOn(NodeBackend.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 })); + s = jest.spyOn(NodeClient.prototype, 'sendEvent').mockImplementation(async () => Promise.resolve({ code: 200 })); }); afterEach(() => { @@ -360,7 +359,7 @@ describe('SentryNode initialization', () => { init({ dsn }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toEqual('sentry.javascript.node'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/node'); @@ -372,7 +371,7 @@ describe('SentryNode initialization', () => { const client = new NodeClient({ dsn }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (client as any)._backend._transport._api.metadata?.sdk; + const sdkData = (client as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toEqual('sentry.javascript.node'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/node'); @@ -401,7 +400,7 @@ describe('SentryNode initialization', () => { }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; expect(sdkData.name).toEqual('sentry.javascript.serverless'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/serverless'); diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 7dcaf077e4c6..8363bd177359 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -28,6 +28,7 @@ describe('LinkedErrors', () => { expect.assertions(2); const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); + // TODO(v7): refactor to use client here! const backend = new NodeBackend({}); let event: Event | undefined; return backend @@ -52,6 +53,7 @@ describe('LinkedErrors', () => { ); const one = new Error('originalException'); const backend = new NodeBackend({}); + // TODO(v7): refactor to use client here! return backend.eventFromException(one).then(event => linkedErrors ._handler(event, { @@ -72,6 +74,7 @@ describe('LinkedErrors', () => { two.cause = three; const backend = new NodeBackend({}); + // TODO(v7): refactor to use client here! return backend.eventFromException(one).then(event => linkedErrors ._handler(event, { @@ -105,6 +108,7 @@ describe('LinkedErrors', () => { two.reason = three; const backend = new NodeBackend({}); + // TODO(v7): refactor to use client here! return backend.eventFromException(one).then(event => linkedErrors ._handler(event, { @@ -138,6 +142,7 @@ describe('LinkedErrors', () => { two.cause = three; const backend = new NodeBackend({}); + // TODO(v7): refactor to use client here! return backend.eventFromException(one).then(event => linkedErrors ._handler(event, { diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index 69f7298105b2..e11950487fa1 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -60,7 +60,12 @@ export interface Client { /** Returns the current options. */ getOptions(): O; - /** Returns clients transport. */ + /** + * Returns the transport that is used by the client. + * Please note that the transport gets lazy initialized so it will only be there once the first event has been sent. + * + * @returns The transport. + */ getTransport?(): Transport; /** @@ -88,4 +93,17 @@ export interface Client { /** This is an internal function to setup all integrations that should run on the client */ setupIntegrations(): void; + + /** Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`. */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + eventFromException(exception: any, hint?: EventHint): PromiseLike; + + /** Creates an {@link Event} from primitive inputs to `captureMessage`. */ + eventFromMessage(message: string, level?: Severity, hint?: EventHint): PromiseLike; + + /** Submits the event to Sentry */ + sendEvent(event: Event): void; + + /** Submits the session to Sentry */ + sendSession(session: Session): void; } From 58b9c4e89d9b5645cc1f3f9f4be2910ec8bf3c42 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 12 Apr 2022 10:54:43 +0200 Subject: [PATCH 33/94] docs(migration): Add section for renaming of CDN bundles (#4918) Co-authored-by: Lukas Stracke --- MIGRATION.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 5307b44a7597..4e5de472634d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -27,6 +27,12 @@ From version 7 onwards, the CommonJS files in Sentry JavaScript SDK packages wil If you need to support Internet Explorer 11 or old Node.js versions, we recommend using a preprocessing tool like [Babel](https://babeljs.io/) to convert Sentry packages to ES5. +### Renaming Of CDN Bundles + +CDN bundles will be ES6 by default. Files that followed the naming scheme `bundle.es6.min.js` were renamed to `bundle.min.js` and any bundles using ES5 (files without `.es6`) turned into `bundle.es5.min.js`. + +See our [docs on CDN bundles](https://docs.sentry.io/platforms/javascript/install/cdn/) for more information. + ### Restructuring Of Package Content Up until v6.x, we have published our packages on npm with the following structure: From 3f59f9db448fdc17aeadf9cdd95b057e43b696e3 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 12 Apr 2022 13:35:33 +0200 Subject: [PATCH 34/94] ref(backend): Delete Backend classes (#4919) Delete the Backend classes. Specifically the following classes and files are removed: * `Backend (interface)` * `BaseBackend`* * `BrowserBackend` * `NodeBackend` * `TestBackend`* *`Options` interfaces in these files were moved to the respective Client files Additionally, * delete (the previously ported) `NoopTransport` test in packages/browser/test/unit/backend.test.ts. * adjust a few remaining Backend references in tests to use Client classes * adjust `BaseBackend` documentation to no longer include Backend information --- packages/browser/src/backend.ts | 83 --------- packages/browser/src/client.ts | 29 +++- packages/browser/src/exports.ts | 4 +- packages/browser/src/sdk.ts | 3 +- packages/browser/test/unit/backend.test.ts | 14 -- .../unit/integrations/linkederrors.test.ts | 17 +- packages/core/src/basebackend.ts | 161 ------------------ packages/core/src/baseclient.ts | 38 +---- packages/core/src/index.ts | 2 - packages/core/test/lib/base.test.ts | 2 +- packages/core/test/mocks/backend.ts | 72 -------- packages/core/test/mocks/client.ts | 7 +- packages/node/src/backend.ts | 69 -------- packages/node/src/client.ts | 8 +- packages/node/src/index.ts | 2 - .../test/integrations/linkederrors.test.ts | 28 ++- 16 files changed, 56 insertions(+), 483 deletions(-) delete mode 100644 packages/browser/src/backend.ts delete mode 100644 packages/browser/test/unit/backend.test.ts delete mode 100644 packages/core/src/basebackend.ts delete mode 100644 packages/core/test/mocks/backend.ts delete mode 100644 packages/node/src/backend.ts diff --git a/packages/browser/src/backend.ts b/packages/browser/src/backend.ts deleted file mode 100644 index 2543c6ae99ad..000000000000 --- a/packages/browser/src/backend.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { BaseBackend, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails } from '@sentry/core'; -import { Event, EventHint, Options, Severity, Transport, TransportOptions } from '@sentry/types'; -import { supportsFetch } from '@sentry/utils'; - -import { eventFromException, eventFromMessage } from './eventbuilder'; -import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTransport } from './transports'; - -/** - * Configuration options for the Sentry Browser SDK. - * @see BrowserClient for more information. - * - * TODO(v7): move to client - */ -export interface BrowserOptions extends Options { - /** - * A pattern for error URLs which should exclusively be sent to Sentry. - * This is the opposite of {@link Options.denyUrls}. - * By default, all errors will be sent. - */ - allowUrls?: Array; - - /** - * A pattern for error URLs which should not be sent to Sentry. - * To allow certain errors instead, use {@link Options.allowUrls}. - * By default, all errors will be sent. - */ - denyUrls?: Array; -} - -/** - * The Sentry Browser SDK Backend. - * @hidden - */ -export class BrowserBackend extends BaseBackend { - /** - * @inheritDoc - */ - public eventFromException(exception: unknown, hint?: EventHint): PromiseLike { - return eventFromException(exception, hint, this._options.attachStacktrace); - } - /** - * @inheritDoc - */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { - return eventFromMessage(message, level, hint, this._options.attachStacktrace); - } - - /** - * @inheritDoc - */ - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } - - const transportOptions: TransportOptions = { - ...this._options.transportOptions, - dsn: this._options.dsn, - tunnel: this._options.tunnel, - sendClientReports: this._options.sendClientReports, - _metadata: this._options._metadata, - }; - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - if (supportsFetch()) { - const requestOptions: RequestInit = { ...transportOptions.fetchParameters }; - this._newTransport = makeNewFetchTransport({ requestOptions, url }); - return new FetchTransport(transportOptions); - } - - this._newTransport = makeNewXHRTransport({ - url, - headers: transportOptions.headers, - }); - return new XHRTransport(transportOptions); - } -} diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index b64997c0a23b..8265889e4967 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,22 +1,40 @@ import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; -import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; +import { Event, EventHint, Options, Severity, Transport, TransportOptions } from '@sentry/types'; import { getGlobalObject, logger, supportsFetch } from '@sentry/utils'; -import { BrowserBackend, BrowserOptions } from './backend'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; import { injectReportDialog, ReportDialogOptions } from './helpers'; import { Breadcrumbs } from './integrations'; import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTransport } from './transports'; +/** + * Configuration options for the Sentry Browser SDK. + * @see BrowserClient for more information. + */ +export interface BrowserOptions extends Options { + /** + * A pattern for error URLs which should exclusively be sent to Sentry. + * This is the opposite of {@link Options.denyUrls}. + * By default, all errors will be sent. + */ + allowUrls?: Array; + + /** + * A pattern for error URLs which should not be sent to Sentry. + * To allow certain errors instead, use {@link Options.allowUrls}. + * By default, all errors will be sent. + */ + denyUrls?: Array; +} + /** * The Sentry Browser SDK Client. * * @see BrowserOptions for documentation on configuration options. * @see SentryClient for usage documentation. - * TODO(v7): remove BrowserBackend */ -export class BrowserClient extends BaseClient { +export class BrowserClient extends BaseClient { /** * Creates a new Browser SDK instance. * @@ -35,8 +53,7 @@ export class BrowserClient extends BaseClient { version: SDK_VERSION, }; - // TODO(v7): remove BrowserBackend param - super(BrowserBackend, options); + super(options); } /** diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 2a62e8e46fbe..6204a25f614e 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -41,9 +41,7 @@ export { withScope, } from '@sentry/core'; -// TODO(v7): refactor to use client here! -export { BrowserOptions } from './backend'; -export { BrowserClient } from './client'; +export { BrowserClient, BrowserOptions } from './client'; export { injectReportDialog, ReportDialogOptions } from './helpers'; export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close, wrap } from './sdk'; export { SDK_NAME } from './version'; diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 3f05a646c96f..44d66add18c3 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -2,8 +2,7 @@ import { getCurrentHub, initAndBind, Integrations as CoreIntegrations } from '@s import { Hub } from '@sentry/types'; import { addInstrumentationHandler, getGlobalObject, logger, resolvedSyncPromise } from '@sentry/utils'; -import { BrowserOptions } from './backend'; -import { BrowserClient } from './client'; +import { BrowserClient, BrowserOptions } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { ReportDialogOptions, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, LinkedErrors, TryCatch, UserAgent } from './integrations'; diff --git a/packages/browser/test/unit/backend.test.ts b/packages/browser/test/unit/backend.test.ts deleted file mode 100644 index 83f95307a8c7..000000000000 --- a/packages/browser/test/unit/backend.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { BrowserBackend } from '../../src/backend'; - -let backend: BrowserBackend; - -// TODO(v7): remove when deleting Backend - -describe('BrowserBackend', () => { - describe('sendEvent()', () => { - it('should use NoopTransport', () => { - backend = new BrowserBackend({}); - expect(backend.getTransport().constructor.name).toBe('NoopTransport'); - }); - }); -}); diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 35f54f4b2d87..8178741d1210 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -1,6 +1,6 @@ import { ExtendedError } from '@sentry/types'; -import { BrowserBackend } from '../../../src/backend'; +import { BrowserClient } from '../../../src/client'; import * as LinkedErrorsModule from '../../../src/integrations/linkederrors'; describe('LinkedErrors', () => { @@ -34,9 +34,8 @@ describe('LinkedErrors', () => { one.cause = two; const originalException = one; - // TODO(v7): refactor to use client here! - const backend = new BrowserBackend({}); - return backend.eventFromException(originalException).then(event => { + const client = new BrowserClient({}); + return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('cause', 5, event, { originalException, }); @@ -65,9 +64,8 @@ describe('LinkedErrors', () => { one.reason = two; const originalException = one; - const backend = new BrowserBackend({}); - // TODO(v7): refactor to use client here! - return backend.eventFromException(originalException).then(event => { + const client = new BrowserClient({}); + return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('reason', 5, event, { originalException, }); @@ -92,10 +90,9 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const backend = new BrowserBackend({}); + const client = new BrowserClient({}); const originalException = one; - // TODO(v7): refactor to use client here! - return backend.eventFromException(originalException).then(event => { + return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler('cause', 2, event, { originalException, }); diff --git a/packages/core/src/basebackend.ts b/packages/core/src/basebackend.ts deleted file mode 100644 index 92bdd4e7f65c..000000000000 --- a/packages/core/src/basebackend.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { Event, EventHint, Options, Session, Severity, Transport } from '@sentry/types'; -import { logger, SentryError } from '@sentry/utils'; - -import { initAPIDetails } from './api'; -import { IS_DEBUG_BUILD } from './flags'; -import { createEventEnvelope, createSessionEnvelope } from './request'; -import { NewTransport } from './transports/base'; -import { NoopTransport } from './transports/noop'; - -/** - * Internal platform-dependent Sentry SDK Backend. - * - * While {@link Client} contains business logic specific to an SDK, the - * Backend offers platform specific implementations for low-level operations. - * These are persisting and loading information, sending events, and hooking - * into the environment. - * - * Backends receive a handle to the Client in their constructor. When a - * Backend automatically generates events, it must pass them to - * the Client for validation and processing first. - * - * Usually, the Client will be of corresponding type, e.g. NodeBackend - * receives NodeClient. However, higher-level SDKs can choose to instantiate - * multiple Backends and delegate tasks between them. In this case, an event - * generated by one backend might very well be sent by another one. - * - * The client also provides access to options via {@link Client.getOptions}. - * @hidden - */ -export interface Backend { - /** Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`. */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - eventFromException(exception: any, hint?: EventHint): PromiseLike; - - /** Creates an {@link Event} from primitive inputs to `captureMessage`. */ - eventFromMessage(message: string, level?: Severity, hint?: EventHint): PromiseLike; - - /** Submits the event to Sentry */ - sendEvent(event: Event): void; - - /** Submits the session to Sentry */ - sendSession(session: Session): void; - - /** - * Returns the transport that is used by the backend. - * Please note that the transport gets lazy initialized so it will only be there once the first event has been sent. - * - * @returns The transport. - */ - getTransport(): Transport; -} - -/** - * A class object that can instantiate Backend objects. - * @hidden - */ -export type BackendClass = new (options: O) => B; - -/** - * This is the base implemention of a Backend. - * @hidden - */ -export abstract class BaseBackend implements Backend { - /** Options passed to the SDK. */ - protected readonly _options: O; - - /** Cached transport used internally. */ - protected _transport: Transport; - - /** New v7 Transport that is initialized alongside the old one */ - protected _newTransport?: NewTransport; - - /** Creates a new backend instance. */ - public constructor(options: O) { - this._options = options; - if (!this._options.dsn) { - IS_DEBUG_BUILD && logger.warn('No DSN provided, backend will not do anything.'); - } - this._transport = this._setupTransport(); - } - - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - public eventFromException(_exception: any, _hint?: EventHint): PromiseLike { - throw new SentryError('Backend has to implement `eventFromException` method'); - } - - /** - * @inheritDoc - */ - public eventFromMessage(_message: string, _level?: Severity, _hint?: EventHint): PromiseLike { - throw new SentryError('Backend has to implement `eventFromMessage` method'); - } - - /** - * @inheritDoc - */ - public sendEvent(event: Event): void { - // TODO(v7): Remove the if-else - if ( - this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport - ) { - const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - const env = createEventEnvelope(event, api); - void this._newTransport.send(env).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); - }); - } else { - void this._transport.sendEvent(event).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); - }); - } - } - - /** - * @inheritDoc - */ - public sendSession(session: Session): void { - if (!this._transport.sendSession) { - IS_DEBUG_BUILD && logger.warn("Dropping session because custom transport doesn't implement sendSession"); - return; - } - - // TODO(v7): Remove the if-else - if ( - this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport - ) { - const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - const [env] = createSessionEnvelope(session, api); - void this._newTransport.send(env).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); - }); - } else { - void this._transport.sendSession(session).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); - }); - } - } - - /** - * @inheritDoc - */ - public getTransport(): Transport { - return this._transport; - } - - /** - * Sets up the transport so it can be used later to send requests. - */ - protected _setupTransport(): Transport { - return new NoopTransport(); - } -} diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 59145508ca9d..75712f62479b 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -29,7 +29,6 @@ import { } from '@sentry/utils'; import { initAPIDetails } from './api'; -import { Backend, BackendClass } from './basebackend'; import { IS_DEBUG_BUILD } from './flags'; import { IntegrationIndex, setupIntegrations } from './integration'; import { createEventEnvelope, createSessionEnvelope } from './request'; @@ -41,19 +40,16 @@ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been ca /** * Base implementation for all JavaScript SDK clients. * - * TODO(v7): refactor doc w.r.t. Backend - * - * Call the constructor with the corresponding backend constructor and options + * Call the constructor with the corresponding options * specific to the client subclass. To access these options later, use - * {@link Client.getOptions}. Also, the Backend instance is available via - * {@link Client.getBackend}. + * {@link Client.getOptions}. * * If a Dsn is specified in the options, it will be parsed and stored. Use * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is * invalid, the constructor will throw a {@link SentryException}. Note that * without a valid Dsn, the SDK will not send any events to Sentry. * - * Before sending an event via the backend, it is passed through + * Before sending an event, it is passed through * {@link BaseClient._prepareEvent} to add SDK information and scope data * (breadcrumbs and context). To add more custom information, override this * method and extend the resulting prepared event. @@ -64,23 +60,15 @@ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been ca * {@link Client.addBreadcrumb}. * * @example - * class NodeClient extends BaseClient { + * class NodeClient extends BaseClient { * public constructor(options: NodeOptions) { - * super(NodeBackend, options); + * super(options); * } * * // ... * } */ -export abstract class BaseClient implements Client { - /** - * The backend used to physically interact in the environment. Usually, this - * will correspond to the client. When composing SDKs, however, the Backend - * from the root SDK will be used. - * TODO(v7): DELETE - */ - protected readonly _backend: B; - +export abstract class BaseClient implements Client { /** Options passed to the SDK. */ protected readonly _options: O; @@ -102,12 +90,9 @@ export abstract class BaseClient implement /** * Initializes this client instance. * - * @param backendClass A constructor function to create the backend. * @param options Options for the client. */ - protected constructor(backendClass: BackendClass, options: O) { - // TODO(v7): Delete - this._backend = new backendClass(options); + protected constructor(options: O) { this._options = options; if (options.dsn) { @@ -386,13 +371,6 @@ export abstract class BaseClient implement }); } - /** Returns the current backend. - * TODO(v7): DELETE - */ - protected _getBackend(): B { - return this._backend; - } - /** Determines whether this SDK is enabled and a valid Dsn is present. */ protected _isEnabled(): boolean { return this.getOptions().enabled !== false && this._dsn !== undefined; @@ -558,7 +536,7 @@ export abstract class BaseClient implement } /** - * Tells the backend to send this event + * Sends the passed event * @param event The Sentry event to send */ // TODO(v7): refactor: get rid of method? diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 77018c2b4437..e4143f098e4a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -23,8 +23,6 @@ export { getReportDialogEndpoint, } from './api'; export { BaseClient } from './baseclient'; -// TODO(v7): Delete! -export { BackendClass, BaseBackend } from './basebackend'; export { eventToSentryRequest, sessionToSentryRequest } from './request'; export { initAndBind, ClientClass } from './sdk'; export { NoopTransport } from './transports/noop'; diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 8a26bd51f116..6bb72ed99f16 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -898,7 +898,7 @@ describe('BaseClient', () => { } expect(capturedEvent).toEqual(normalizedTransaction); - // expect(TestBackend.instance!.event!).toEqual(normalizedTransaction); + // expect(TestClient.instance!.event!).toEqual(normalizedTransaction); }); test('calls beforeSend and uses original event without any changes', () => { diff --git a/packages/core/test/mocks/backend.ts b/packages/core/test/mocks/backend.ts deleted file mode 100644 index a201bc8c0b68..000000000000 --- a/packages/core/test/mocks/backend.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Session } from '@sentry/hub'; -import { Event, Severity, Transport } from '@sentry/types'; -import { resolvedSyncPromise } from '@sentry/utils'; - -import { BaseBackend } from '../../src/basebackend'; -import { TestOptions } from './client'; - -// TODO: Delete whole file (?) - -export class TestBackend extends BaseBackend { - public static instance?: TestBackend; - public static sendEventCalled?: (event: Event) => void; - - public event?: Event; - public session?: Session; - - public constructor(protected readonly _options: TestOptions) { - super(_options); - TestBackend.instance = this; - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - public eventFromException(exception: any): PromiseLike { - return resolvedSyncPromise({ - exception: { - values: [ - { - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - type: exception.name, - value: exception.message, - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - }, - ], - }, - }); - } - - public eventFromMessage(message: string, level: Severity = Severity.Info): PromiseLike { - return resolvedSyncPromise({ message, level }); - } - - public sendEvent(event: Event): void { - this.event = event; - if (this._options.enableSend) { - super.sendEvent(event); - return; - } - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - TestBackend.sendEventCalled && TestBackend.sendEventCalled(event); - } - - public sendSession(session: Session): void { - this.session = session; - } - - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } - - const transportOptions = this._options.transportOptions - ? this._options.transportOptions - : { dsn: this._options.dsn }; - - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - - return super._setupTransport(); - } -} diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 8c02ca30f5f3..f399c6018122 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -4,15 +4,13 @@ import { resolvedSyncPromise } from '@sentry/utils'; import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; -import { TestBackend } from './backend'; export interface TestOptions extends Options { test?: boolean; mockInstallFailure?: boolean; enableSend?: boolean; } -// TODO(v7): remove TestBackend -export class TestClient extends BaseClient { +export class TestClient extends BaseClient { public static instance?: TestClient; public static sendEventCalled?: (event: Event) => void; @@ -20,8 +18,7 @@ export class TestClient extends BaseClient { public session?: Session; public constructor(options: TestOptions) { - // TODO(v7): remove TestBackend param - super(TestBackend, options); + super(options); TestClient.instance = this; } diff --git a/packages/node/src/backend.ts b/packages/node/src/backend.ts deleted file mode 100644 index f319673ebc18..000000000000 --- a/packages/node/src/backend.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { BaseBackend, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails } from '@sentry/core'; -import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; -import { makeDsn, resolvedSyncPromise } from '@sentry/utils'; - -import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; -import { HTTPSTransport, HTTPTransport, makeNodeTransport } from './transports'; -import { NodeOptions } from './types'; - -/** - * The Sentry Node SDK Backend. - * @hidden - */ -export class NodeBackend extends BaseBackend { - /** - * @inheritDoc - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types - public eventFromException(exception: any, hint?: EventHint): PromiseLike { - return resolvedSyncPromise(eventFromUnknownInput(exception, hint)); - } - - /** - * @inheritDoc - */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { - return resolvedSyncPromise(eventFromMessage(message, level, hint, this._options.attachStacktrace)); - } - - /** - * @inheritDoc - */ - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } - - const dsn = makeDsn(this._options.dsn); - - const transportOptions: TransportOptions = { - ...this._options.transportOptions, - ...(this._options.httpProxy && { httpProxy: this._options.httpProxy }), - ...(this._options.httpsProxy && { httpsProxy: this._options.httpsProxy }), - ...(this._options.caCerts && { caCerts: this._options.caCerts }), - dsn: this._options.dsn, - tunnel: this._options.tunnel, - _metadata: this._options._metadata, - }; - - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - this._newTransport = makeNodeTransport({ - url, - headers: transportOptions.headers, - proxy: transportOptions.httpProxy, - caCerts: transportOptions.caCerts, - }); - - if (dsn.protocol === 'http') { - return new HTTPTransport(transportOptions); - } - return new HTTPSTransport(transportOptions); - } -} diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 0b2b585edc5d..4401f4016520 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -3,7 +3,6 @@ import { SessionFlusher } from '@sentry/hub'; import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; import { logger, makeDsn, resolvedSyncPromise } from '@sentry/utils'; -import { NodeBackend } from './backend'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; import { HTTPSTransport, HTTPTransport, makeNodeTransport } from './transports'; @@ -14,10 +13,8 @@ import { NodeOptions } from './types'; * * @see NodeOptions for documentation on configuration options. * @see SentryClient for usage documentation. - * - * TODO(v7): remove NodeBackend */ -export class NodeClient extends BaseClient { +export class NodeClient extends BaseClient { protected _sessionFlusher: SessionFlusher | undefined; /** @@ -37,8 +34,7 @@ export class NodeClient extends BaseClient { version: SDK_VERSION, }; - // TODO(v7): remove NodeBackend param - super(NodeBackend, options); + super(options); } /** diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 48bb88a24872..591fd4ad911d 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -42,8 +42,6 @@ export { } from '@sentry/core'; export { NodeOptions } from './types'; -// TODO(v7): delete! -export { NodeBackend } from './backend'; export { NodeClient } from './client'; export { defaultIntegrations, init, lastEventId, flush, close, getSentryRelease } from './sdk'; export { deepReadDirSync } from './utils'; diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 8363bd177359..47249d129716 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -1,7 +1,6 @@ import { ExtendedError } from '@sentry/types'; -import { Event } from '../../src'; -import { NodeBackend } from '../../src/backend'; +import { Event, NodeClient } from '../../src'; import { LinkedErrors } from '../../src/integrations/linkederrors'; let linkedErrors: any; @@ -28,10 +27,9 @@ describe('LinkedErrors', () => { expect.assertions(2); const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); - // TODO(v7): refactor to use client here! - const backend = new NodeBackend({}); + const client = new NodeClient({}); let event: Event | undefined; - return backend + return client .eventFromException(one) .then(eventFromException => { event = eventFromException; @@ -52,9 +50,8 @@ describe('LinkedErrors', () => { }), ); const one = new Error('originalException'); - const backend = new NodeBackend({}); - // TODO(v7): refactor to use client here! - return backend.eventFromException(one).then(event => + const client = new NodeClient({}); + return client.eventFromException(one).then(event => linkedErrors ._handler(event, { originalException: one, @@ -73,9 +70,8 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const backend = new NodeBackend({}); - // TODO(v7): refactor to use client here! - return backend.eventFromException(one).then(event => + const client = new NodeClient({}); + return client.eventFromException(one).then(event => linkedErrors ._handler(event, { originalException: one, @@ -107,9 +103,8 @@ describe('LinkedErrors', () => { one.reason = two; two.reason = three; - const backend = new NodeBackend({}); - // TODO(v7): refactor to use client here! - return backend.eventFromException(one).then(event => + const client = new NodeClient({}); + return client.eventFromException(one).then(event => linkedErrors ._handler(event, { originalException: one, @@ -141,9 +136,8 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const backend = new NodeBackend({}); - // TODO(v7): refactor to use client here! - return backend.eventFromException(one).then(event => + const client = new NodeClient({}); + return client.eventFromException(one).then(event => linkedErrors ._handler(event, { originalException: one, From 0f1035894f564c81bb6d6ab75c9198766da6288c Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Tue, 12 Apr 2022 06:44:15 -0700 Subject: [PATCH 35/94] fix(wasm): Ensure wasm bundle exists before running wasm tests (#4916) The `@sentry/wasm` test suite requires both the browser bundle and the wasm bundle. Currently, before running the tests, we check to make sure the browser bundle exists, and build it if it's missing. We don't do the same for the wasm bundle, however. This fixes that, so that both bundles are guaranteed to exist before we try to run tests. --- packages/wasm/package.json | 2 +- .../{ensure-browser-bundle.js => ensure-bundles.js} | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) rename packages/wasm/test/scripts/{ensure-browser-bundle.js => ensure-bundles.js} (65%) diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 6cdf354f1f5e..b8d70d1bd924 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -53,7 +53,7 @@ "lint": "run-s lint:prettier lint:eslint", "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "lint:prettier": "prettier --check \"{src,test,scripts}/**/*.ts\"", - "test": "node test/scripts/ensure-browser-bundle.js && cross-env PORT=1337 jest", + "test": "node test/scripts/ensure-bundles.js && cross-env PORT=1337 jest", "test:watch": "jest --watch" }, "volta": { diff --git a/packages/wasm/test/scripts/ensure-browser-bundle.js b/packages/wasm/test/scripts/ensure-bundles.js similarity index 65% rename from packages/wasm/test/scripts/ensure-browser-bundle.js rename to packages/wasm/test/scripts/ensure-bundles.js index 2261eccaf84a..baa4f1e2a41c 100644 --- a/packages/wasm/test/scripts/ensure-browser-bundle.js +++ b/packages/wasm/test/scripts/ensure-bundles.js @@ -11,4 +11,13 @@ function ensureBrowserBundle() { } } +function ensureWasmBundle() { + if (!fs.existsSync('build/bundles/wasm.js')) { + // eslint-disable-next-line no-console + console.warn('\nWARNING: Missing wasm bundle. Bundle will be created before running wasm integration tests.'); + execSync('yarn build:bundle'); + } +} + ensureBrowserBundle(); +ensureWasmBundle(); From f3e9384795840f121653cbf1354f75766a8d5891 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Tue, 12 Apr 2022 16:23:17 +0100 Subject: [PATCH 36/94] ref: Expose configurable stack parser (#4902) Adds a `stackParser` option to `Options`: ```ts /** * A stack parser implementation or an array of stack line parsers * By default, a stack parser is supplied for all supported browsers */ stackParser?: StackParser | StackLineParser[]; ``` Whenever we want access to a `StackParser` to use with the functions in `eventbuilder` we call `stackParserFromOptions(options)`. This converts `StackLineParser[]` to `StackParser` and saves it back in the options so this conversion only occurs once. ### Added Exports `@sentry/node` - `nodeStackParser` `@sentry/browser` - `chromeStackParser` - `geckoStackParser` - `opera10StackParser` - `opera11StackParser` - `winjsStackParser` - `defaultStackParsers` --- packages/browser/src/client.ts | 12 +++- packages/browser/src/eventbuilder.ts | 65 +++++++++---------- packages/browser/src/exports.ts | 9 +++ .../src/integrations/globalhandlers.ts | 22 ++++--- .../browser/src/integrations/linkederrors.ts | 32 ++++++--- packages/browser/src/sdk.ts | 4 ++ packages/browser/src/stack-parsers.ts | 11 +++- .../unit/integrations/linkederrors.test.ts | 20 +++--- .../test/unit/tracekit/chromium.test.ts | 29 +++++---- .../test/unit/tracekit/firefox.test.ts | 23 ++++--- .../browser/test/unit/tracekit/ie.test.ts | 11 +++- .../browser/test/unit/tracekit/misc.test.ts | 7 +- .../browser/test/unit/tracekit/opera.test.ts | 13 ++-- .../test/unit/tracekit/react-native.test.ts | 15 +++-- .../browser/test/unit/tracekit/react.test.ts | 11 +++- .../browser/test/unit/tracekit/safari.test.ts | 25 ++++--- packages/node/src/client.ts | 8 ++- packages/node/src/eventbuilder.ts | 20 +++--- packages/node/src/index.ts | 1 + .../node/src/integrations/linkederrors.ts | 31 +++++---- packages/node/src/sdk.ts | 5 ++ packages/node/src/stack-parser.ts | 3 +- packages/node/test/context-lines.test.ts | 12 ++-- packages/node/test/index.test.ts | 13 ++++ .../test/integrations/linkederrors.test.ts | 26 ++++---- packages/node/test/stacktrace.test.ts | 33 ++++++---- packages/types/src/index.ts | 2 +- packages/types/src/options.ts | 7 ++ packages/types/src/stacktrace.ts | 4 ++ packages/utils/src/stacktrace.ts | 29 +++++++-- 30 files changed, 330 insertions(+), 173 deletions(-) diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 8265889e4967..4ee24f0ceadf 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,6 +1,6 @@ import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; import { Event, EventHint, Options, Severity, Transport, TransportOptions } from '@sentry/types'; -import { getGlobalObject, logger, supportsFetch } from '@sentry/utils'; +import { getGlobalObject, logger, stackParserFromOptions, supportsFetch } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; @@ -83,14 +83,20 @@ export class BrowserClient extends BaseClient { * @inheritDoc */ public eventFromException(exception: unknown, hint?: EventHint): PromiseLike { - return eventFromException(exception, hint, this._options.attachStacktrace); + return eventFromException(stackParserFromOptions(this._options), exception, hint, this._options.attachStacktrace); } /** * @inheritDoc */ public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { - return eventFromMessage(message, level, hint, this._options.attachStacktrace); + return eventFromMessage( + stackParserFromOptions(this._options), + message, + level, + hint, + this._options.attachStacktrace, + ); } /** diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index d8acd41c12c0..6ed5181eefa1 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -1,8 +1,7 @@ -import { Event, EventHint, Exception, Severity, StackFrame } from '@sentry/types'; +import { Event, EventHint, Exception, Severity, StackFrame, StackParser } from '@sentry/types'; import { addExceptionMechanism, addExceptionTypeValue, - createStackParser, extractExceptionKeysForMessage, isDOMError, isDOMException, @@ -14,22 +13,12 @@ import { resolvedSyncPromise, } from '@sentry/utils'; -import { - chromeStackParser, - geckoStackParser, - opera10StackParser, - opera11StackParser, - winjsStackParser, -} from './stack-parsers'; - /** * This function creates an exception from an TraceKitStackTrace - * @param stacktrace TraceKitStackTrace that will be converted to an exception - * @hidden */ -export function exceptionFromError(ex: Error): Exception { +export function exceptionFromError(stackParser: StackParser, ex: Error): Exception { // Get the frames first since Opera can lose the stack if we touch anything else first - const frames = parseStackFrames(ex); + const frames = parseStackFrames(stackParser, ex); const exception: Exception = { type: ex && ex.name, @@ -51,6 +40,7 @@ export function exceptionFromError(ex: Error): Exception { * @hidden */ export function eventFromPlainObject( + stackParser: StackParser, exception: Record, syntheticException?: Error, isUnhandledRejection?: boolean, @@ -72,7 +62,7 @@ export function eventFromPlainObject( }; if (syntheticException) { - const frames = parseStackFrames(syntheticException); + const frames = parseStackFrames(stackParser, syntheticException); if (frames.length) { // event.exception.values[0] has been set above (event.exception as { values: Exception[] }).values[0].stacktrace = { frames }; @@ -85,16 +75,19 @@ export function eventFromPlainObject( /** * @hidden */ -export function eventFromError(ex: Error): Event { +export function eventFromError(stackParser: StackParser, ex: Error): Event { return { exception: { - values: [exceptionFromError(ex)], + values: [exceptionFromError(stackParser, ex)], }, }; } /** Parses stack frames from an error */ -export function parseStackFrames(ex: Error & { framesToPop?: number; stacktrace?: string }): StackFrame[] { +export function parseStackFrames( + stackParser: StackParser, + ex: Error & { framesToPop?: number; stacktrace?: string }, +): StackFrame[] { // Access and store the stacktrace property before doing ANYTHING // else to it because Opera is not very good at providing it // reliably in other circumstances. @@ -103,13 +96,7 @@ export function parseStackFrames(ex: Error & { framesToPop?: number; stacktrace? const popSize = getPopSize(ex); try { - return createStackParser( - opera10StackParser, - opera11StackParser, - chromeStackParser, - winjsStackParser, - geckoStackParser, - )(stacktrace, popSize); + return stackParser(stacktrace, popSize); } catch (e) { // no-empty } @@ -155,12 +142,13 @@ function extractMessage(ex: Error & { message: { error?: Error } }): string { * @hidden */ export function eventFromException( + stackParser: StackParser, exception: unknown, hint?: EventHint, attachStacktrace?: boolean, ): PromiseLike { const syntheticException = (hint && hint.syntheticException) || undefined; - const event = eventFromUnknownInput(exception, syntheticException, attachStacktrace); + const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace); addExceptionMechanism(event); // defaults to { type: 'generic', handled: true } event.level = Severity.Error; if (hint && hint.event_id) { @@ -174,13 +162,14 @@ export function eventFromException( * @hidden */ export function eventFromMessage( + stackParser: StackParser, message: string, level: Severity = Severity.Info, hint?: EventHint, attachStacktrace?: boolean, ): PromiseLike { const syntheticException = (hint && hint.syntheticException) || undefined; - const event = eventFromString(message, syntheticException, attachStacktrace); + const event = eventFromString(stackParser, message, syntheticException, attachStacktrace); event.level = level; if (hint && hint.event_id) { event.event_id = hint.event_id; @@ -192,6 +181,7 @@ export function eventFromMessage( * @hidden */ export function eventFromUnknownInput( + stackParser: StackParser, exception: unknown, syntheticException?: Error, attachStacktrace?: boolean, @@ -202,7 +192,7 @@ export function eventFromUnknownInput( if (isErrorEvent(exception as ErrorEvent) && (exception as ErrorEvent).error) { // If it is an ErrorEvent with `error` property, extract it to get actual Error const errorEvent = exception as ErrorEvent; - return eventFromError(errorEvent.error as Error); + return eventFromError(stackParser, errorEvent.error as Error); } // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name @@ -216,11 +206,11 @@ export function eventFromUnknownInput( const domException = exception as DOMException; if ('stack' in (exception as Error)) { - event = eventFromError(exception as Error); + event = eventFromError(stackParser, exception as Error); } else { const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException'); const message = domException.message ? `${name}: ${domException.message}` : name; - event = eventFromString(message, syntheticException, attachStacktrace); + event = eventFromString(stackParser, message, syntheticException, attachStacktrace); addExceptionTypeValue(event, message); } if ('code' in domException) { @@ -231,14 +221,14 @@ export function eventFromUnknownInput( } if (isError(exception)) { // we have a real Error object, do nothing - return eventFromError(exception); + return eventFromError(stackParser, exception); } if (isPlainObject(exception) || isEvent(exception)) { // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize // it manually. This will allow us to group events based on top-level keys which is much better than creating a new // group on any key/value change. const objectException = exception as Record; - event = eventFromPlainObject(objectException, syntheticException, isUnhandledRejection); + event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection); addExceptionMechanism(event, { synthetic: true, }); @@ -254,7 +244,7 @@ export function eventFromUnknownInput( // - a plain Object // // So bail out and capture it as a simple message: - event = eventFromString(exception as string, syntheticException, attachStacktrace); + event = eventFromString(stackParser, exception as string, syntheticException, attachStacktrace); addExceptionTypeValue(event, `${exception}`, undefined); addExceptionMechanism(event, { synthetic: true, @@ -266,13 +256,18 @@ export function eventFromUnknownInput( /** * @hidden */ -export function eventFromString(input: string, syntheticException?: Error, attachStacktrace?: boolean): Event { +export function eventFromString( + stackParser: StackParser, + input: string, + syntheticException?: Error, + attachStacktrace?: boolean, +): Event { const event: Event = { message: input, }; if (attachStacktrace && syntheticException) { - const frames = parseStackFrames(syntheticException); + const frames = parseStackFrames(stackParser, syntheticException); if (frames.length) { event.exception = { values: [{ value: input, stacktrace: { frames } }], diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 6204a25f614e..704096fae520 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -42,6 +42,15 @@ export { } from '@sentry/core'; export { BrowserClient, BrowserOptions } from './client'; + +export { + defaultStackParsers, + chromeStackParser, + geckoStackParser, + opera10StackParser, + opera11StackParser, + winjsStackParser, +} from './stack-parsers'; export { injectReportDialog, ReportDialogOptions } from './helpers'; export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close, wrap } from './sdk'; export { SDK_NAME } from './version'; diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 19ee594afaf3..70966e4f7ec5 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { getCurrentHub } from '@sentry/core'; -import { Event, EventHint, Hub, Integration, Primitive, Severity } from '@sentry/types'; +import { Event, EventHint, Hub, Integration, Primitive, Severity, StackParser } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -9,8 +9,10 @@ import { isPrimitive, isString, logger, + stackParserFromOptions, } from '@sentry/utils'; +import { BrowserClient } from '../client'; import { eventFromUnknownInput } from '../eventbuilder'; import { IS_DEBUG_BUILD } from '../flags'; import { shouldIgnoreOnError } from '../helpers'; @@ -79,7 +81,7 @@ function _installGlobalOnErrorHandler(): void { 'error', // eslint-disable-next-line @typescript-eslint/no-explicit-any (data: { msg: any; url: any; line: any; column: any; error: any }) => { - const [hub, attachStacktrace] = getHubAndAttachStacktrace(); + const [hub, stackParser, attachStacktrace] = getHubAndOptions(); if (!hub.getIntegration(GlobalHandlers)) { return; } @@ -92,7 +94,7 @@ function _installGlobalOnErrorHandler(): void { error === undefined && isString(msg) ? _eventFromIncompleteOnError(msg, url, line, column) : _enhanceEventWithInitialFrame( - eventFromUnknownInput(error || msg, undefined, attachStacktrace, false), + eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false), url, line, column, @@ -111,7 +113,7 @@ function _installGlobalOnUnhandledRejectionHandler(): void { 'unhandledrejection', // eslint-disable-next-line @typescript-eslint/no-explicit-any (e: any) => { - const [hub, attachStacktrace] = getHubAndAttachStacktrace(); + const [hub, stackParser, attachStacktrace] = getHubAndOptions(); if (!hub.getIntegration(GlobalHandlers)) { return; } @@ -142,7 +144,7 @@ function _installGlobalOnUnhandledRejectionHandler(): void { const event = isPrimitive(error) ? _eventFromRejectionWithPrimitive(error) - : eventFromUnknownInput(error, undefined, attachStacktrace, true); + : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true); event.level = Severity.Error; @@ -250,9 +252,11 @@ function addMechanismAndCapture(hub: Hub, error: EventHint['originalException'], }); } -function getHubAndAttachStacktrace(): [Hub, boolean | undefined] { +function getHubAndOptions(): [Hub, StackParser, boolean | undefined] { const hub = getCurrentHub(); - const client = hub.getClient(); - const attachStacktrace = client && client.getOptions().attachStacktrace; - return [hub, attachStacktrace]; + const client = hub.getClient(); + const options = client?.getOptions(); + const parser = stackParserFromOptions(options); + const attachStacktrace = options?.attachStacktrace; + return [hub, parser, attachStacktrace]; } diff --git a/packages/browser/src/integrations/linkederrors.ts b/packages/browser/src/integrations/linkederrors.ts index fa197b48e681..1cc30c182950 100644 --- a/packages/browser/src/integrations/linkederrors.ts +++ b/packages/browser/src/integrations/linkederrors.ts @@ -1,7 +1,8 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core'; -import { Event, EventHint, Exception, ExtendedError, Integration } from '@sentry/types'; -import { isInstanceOf } from '@sentry/utils'; +import { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types'; +import { isInstanceOf, stackParserFromOptions } from '@sentry/utils'; +import { BrowserClient } from '../client'; import { exceptionFromError } from '../eventbuilder'; const DEFAULT_KEY = 'cause'; @@ -46,9 +47,12 @@ export class LinkedErrors implements Integration { * @inheritDoc */ public setupOnce(): void { + const options = getCurrentHub().getClient()?.getOptions(); + const parser = stackParserFromOptions(options); + addGlobalEventProcessor((event: Event, hint?: EventHint) => { const self = getCurrentHub().getIntegration(LinkedErrors); - return self ? _handler(self._key, self._limit, event, hint) : event; + return self ? _handler(parser, self._key, self._limit, event, hint) : event; }); } } @@ -56,11 +60,17 @@ export class LinkedErrors implements Integration { /** * @inheritDoc */ -export function _handler(key: string, limit: number, event: Event, hint?: EventHint): Event | null { +export function _handler( + parser: StackParser, + key: string, + limit: number, + event: Event, + hint?: EventHint, +): Event | null { if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) { return event; } - const linkedErrors = _walkErrorTree(limit, hint.originalException as ExtendedError, key); + const linkedErrors = _walkErrorTree(parser, limit, hint.originalException as ExtendedError, key); event.exception.values = [...linkedErrors, ...event.exception.values]; return event; } @@ -68,10 +78,16 @@ export function _handler(key: string, limit: number, event: Event, hint?: EventH /** * JSDOC */ -export function _walkErrorTree(limit: number, error: ExtendedError, key: string, stack: Exception[] = []): Exception[] { +export function _walkErrorTree( + parser: StackParser, + limit: number, + error: ExtendedError, + key: string, + stack: Exception[] = [], +): Exception[] { if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) { return stack; } - const exception = exceptionFromError(error[key]); - return _walkErrorTree(limit, error[key], key, [exception, ...stack]); + const exception = exceptionFromError(parser, error[key]); + return _walkErrorTree(parser, limit, error[key], key, [exception, ...stack]); } diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 44d66add18c3..60c53b364e9c 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -6,6 +6,7 @@ import { BrowserClient, BrowserOptions } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { ReportDialogOptions, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, LinkedErrors, TryCatch, UserAgent } from './integrations'; +import { defaultStackParsers } from './stack-parsers'; export const defaultIntegrations = [ new CoreIntegrations.InboundFilters(), @@ -92,6 +93,9 @@ export function init(options: BrowserOptions = {}): void { if (options.sendClientReports === undefined) { options.sendClientReports = true; } + if (options.stackParser === undefined) { + options.stackParser = defaultStackParsers; + } initAndBind(BrowserClient, options); diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index f54c1df803e9..5ee652001854 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -1,5 +1,4 @@ -import { StackFrame } from '@sentry/types'; -import { StackLineParser, StackLineParserFn } from '@sentry/utils'; +import { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/types'; // global reference to slice const UNKNOWN_FUNCTION = '?'; @@ -131,6 +130,14 @@ const opera11: StackLineParserFn = line => { export const opera11StackParser: StackLineParser = [OPERA11_PRIORITY, opera11]; +export const defaultStackParsers = [ + chromeStackParser, + geckoStackParser, + opera10StackParser, + opera11StackParser, + winjsStackParser, +]; + /** * Safari web extensions, starting version unknown, can produce "frames-only" stacktraces. * What it means, is that instead of format like: diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 8178741d1210..2589487dbcac 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -1,7 +1,11 @@ import { ExtendedError } from '@sentry/types'; +import { createStackParser } from '@sentry/utils'; import { BrowserClient } from '../../../src/client'; import * as LinkedErrorsModule from '../../../src/integrations/linkederrors'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('LinkedErrors', () => { describe('handler', () => { @@ -9,7 +13,7 @@ describe('LinkedErrors', () => { const event = { message: 'foo', }; - const result = LinkedErrorsModule._handler('cause', 5, event); + const result = LinkedErrorsModule._handler(parser, 'cause', 5, event); expect(result).toEqual(event); }); @@ -20,7 +24,7 @@ describe('LinkedErrors', () => { }, message: 'foo', }; - const result = LinkedErrorsModule._handler('cause', 5, event); + const result = LinkedErrorsModule._handler(parser, 'cause', 5, event); expect(result).toEqual(event); }); @@ -34,9 +38,9 @@ describe('LinkedErrors', () => { one.cause = two; const originalException = one; - const client = new BrowserClient({}); + const client = new BrowserClient({ stackParser: parser }); return client.eventFromException(originalException).then(event => { - const result = LinkedErrorsModule._handler('cause', 5, event, { + const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { originalException, }); @@ -64,9 +68,9 @@ describe('LinkedErrors', () => { one.reason = two; const originalException = one; - const client = new BrowserClient({}); + const client = new BrowserClient({ stackParser: parser }); return client.eventFromException(originalException).then(event => { - const result = LinkedErrorsModule._handler('reason', 5, event, { + const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { originalException, }); @@ -90,10 +94,10 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new BrowserClient({}); + const client = new BrowserClient({ stackParser: parser }); const originalException = one; return client.eventFromException(originalException).then(event => { - const result = LinkedErrorsModule._handler('cause', 2, event, { + const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, { originalException, }); diff --git a/packages/browser/test/unit/tracekit/chromium.test.ts b/packages/browser/test/unit/tracekit/chromium.test.ts index e40abffd8d1f..67189984563a 100644 --- a/packages/browser/test/unit/tracekit/chromium.test.ts +++ b/packages/browser/test/unit/tracekit/chromium.test.ts @@ -1,9 +1,14 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - Chrome Tests', () => { it('should parse Chrome error with no location', () => { const NO_LOCATION = { message: 'foo', name: 'bar', stack: 'error\n at Array.forEach (native)' }; - const ex = exceptionFromError(NO_LOCATION); + const ex = exceptionFromError(parser, NO_LOCATION); expect(ex).toEqual({ value: 'foo', @@ -25,7 +30,7 @@ describe('Tracekit - Chrome Tests', () => { ' at http://path/to/file.js:24:4', }; - const ex = exceptionFromError(CHROME_15); + const ex = exceptionFromError(parser, CHROME_15); expect(ex).toEqual({ value: "Object # has no method 'undef'", @@ -52,7 +57,7 @@ describe('Tracekit - Chrome Tests', () => { ' at I.e.fn.(anonymous function) [as index] (http://localhost:8080/file.js:10:3651)', }; - const ex = exceptionFromError(CHROME_36); + const ex = exceptionFromError(parser, CHROME_36); expect(ex).toEqual({ value: 'Default error', @@ -98,7 +103,7 @@ describe('Tracekit - Chrome Tests', () => { ' at TESTTESTTEST.proxiedMethod(webpack:///./~/react-proxy/modules/createPrototypeProxy.js?:44:30)', }; - const ex = exceptionFromError(CHROME_XX_WEBPACK); + const ex = exceptionFromError(parser, CHROME_XX_WEBPACK); expect(ex).toEqual({ value: "Cannot read property 'error' of undefined", @@ -151,7 +156,7 @@ describe('Tracekit - Chrome Tests', () => { 'at http://localhost:8080/file.js:31:13\n', }; - const ex = exceptionFromError(CHROME_48_EVAL); + const ex = exceptionFromError(parser, CHROME_48_EVAL); expect(ex).toEqual({ value: 'message string', @@ -183,7 +188,7 @@ describe('Tracekit - Chrome Tests', () => { ' at n.handle (blob:http%3A//localhost%3A8080/abfc40e9-4742-44ed-9dcd-af8f99a29379:7:2863)', }; - const ex = exceptionFromError(CHROME_48_BLOB); + const ex = exceptionFromError(parser, CHROME_48_BLOB); expect(ex).toEqual({ value: 'Error: test', @@ -246,7 +251,7 @@ describe('Tracekit - Chrome Tests', () => { at examplescheme://examplehost/cd351f7250857e22ceaa.worker.js:70179:15`, }; - const ex = exceptionFromError(CHROMIUM_EMBEDDED_FRAMEWORK_CUSTOM_SCHEME); + const ex = exceptionFromError(parser, CHROMIUM_EMBEDDED_FRAMEWORK_CUSTOM_SCHEME); expect(ex).toEqual({ value: 'message string', @@ -276,7 +281,7 @@ describe('Tracekit - Chrome Tests', () => { at http://localhost:5000/test:24:7`, }; - const ex = exceptionFromError(CHROME73_NATIVE_CODE_EXCEPTION); + const ex = exceptionFromError(parser, CHROME73_NATIVE_CODE_EXCEPTION); expect(ex).toEqual({ value: 'test', @@ -309,7 +314,7 @@ describe('Tracekit - Chrome Tests', () => { at http://localhost:5000/:50:19`, }; - const ex = exceptionFromError(CHROME73_EVAL_EXCEPTION); + const ex = exceptionFromError(parser, CHROME73_EVAL_EXCEPTION); expect(ex).toEqual({ value: 'bad', @@ -342,7 +347,7 @@ describe('Tracekit - Chrome Tests', () => { at Global code (http://localhost:5000/test:24:7)`, }; - const ex = exceptionFromError(EDGE44_NATIVE_CODE_EXCEPTION); + const ex = exceptionFromError(parser, EDGE44_NATIVE_CODE_EXCEPTION); expect(ex).toEqual({ value: 'test', @@ -375,7 +380,7 @@ describe('Tracekit - Chrome Tests', () => { at Anonymous function (http://localhost:5000/:50:8)`, }; - const ex = exceptionFromError(EDGE44_EVAL_EXCEPTION); + const ex = exceptionFromError(parser, EDGE44_EVAL_EXCEPTION); expect(ex).toEqual({ value: 'aha', @@ -411,7 +416,7 @@ describe('Tracekit - Chrome Tests', () => { at TESTTESTTEST.someMethod (C:\\Users\\user\\path\\to\\file.js:295:108)`, }; - const ex = exceptionFromError(CHROME_ELECTRON_RENDERER); + const ex = exceptionFromError(parser, CHROME_ELECTRON_RENDERER); expect(ex).toEqual({ value: "Cannot read property 'error' of undefined", diff --git a/packages/browser/test/unit/tracekit/firefox.test.ts b/packages/browser/test/unit/tracekit/firefox.test.ts index a14fae1e38cc..87929568c857 100644 --- a/packages/browser/test/unit/tracekit/firefox.test.ts +++ b/packages/browser/test/unit/tracekit/firefox.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - Firefox Tests', () => { it('should parse Firefox 3 error', () => { @@ -18,7 +23,7 @@ describe('Tracekit - Firefox Tests', () => { '', }; - const ex = exceptionFromError(FIREFOX_3); + const ex = exceptionFromError(parser, FIREFOX_3); expect(ex).toEqual({ value: 'this.undef is not a function', @@ -54,7 +59,7 @@ describe('Tracekit - Firefox Tests', () => { '', }; - const ex = exceptionFromError(FIREFOX_7); + const ex = exceptionFromError(parser, FIREFOX_7); expect(ex).toEqual({ value: 'bar', @@ -86,7 +91,7 @@ describe('Tracekit - Firefox Tests', () => { lineNumber: 48, }; - const ex = exceptionFromError(FIREFOX_14); + const ex = exceptionFromError(parser, FIREFOX_14); expect(ex).toEqual({ value: 'x is null', @@ -115,7 +120,7 @@ describe('Tracekit - Firefox Tests', () => { columnNumber: 12, }; - const ex = exceptionFromError(FIREFOX_31); + const ex = exceptionFromError(parser, FIREFOX_31); expect(ex).toEqual({ value: 'Default error', @@ -150,7 +155,7 @@ describe('Tracekit - Firefox Tests', () => { result: 2147500037, }; - const ex = exceptionFromError(FIREFOX_44_NS_EXCEPTION); + const ex = exceptionFromError(parser, FIREFOX_44_NS_EXCEPTION); expect(ex).toEqual({ value: 'No error message', @@ -185,7 +190,7 @@ describe('Tracekit - Firefox Tests', () => { name: 'TypeError', }; - const ex = exceptionFromError(FIREFOX_50_RESOURCE_URL); + const ex = exceptionFromError(parser, FIREFOX_50_RESOURCE_URL); expect(ex).toEqual({ value: 'this.props.raw[this.state.dataSource].rows is undefined', @@ -233,7 +238,7 @@ describe('Tracekit - Firefox Tests', () => { '@http://localhost:8080/file.js:33:9', }; - const ex = exceptionFromError(FIREFOX_43_EVAL); + const ex = exceptionFromError(parser, FIREFOX_43_EVAL); expect(ex).toEqual({ value: 'message string', @@ -259,7 +264,7 @@ describe('Tracekit - Firefox Tests', () => { @http://localhost:5000/test:24:7`, }; - const stacktrace = exceptionFromError(FIREFOX66_NATIVE_CODE_EXCEPTION); + const stacktrace = exceptionFromError(parser, FIREFOX66_NATIVE_CODE_EXCEPTION); expect(stacktrace).toEqual({ value: 'test', @@ -289,7 +294,7 @@ describe('Tracekit - Firefox Tests', () => { @http://localhost:5000/:50:19`, }; - const stacktrace = exceptionFromError(FIREFOX66_EVAL_EXCEPTION); + const stacktrace = exceptionFromError(parser, FIREFOX66_EVAL_EXCEPTION); expect(stacktrace).toEqual({ value: 'aha', diff --git a/packages/browser/test/unit/tracekit/ie.test.ts b/packages/browser/test/unit/tracekit/ie.test.ts index cfd60ab2e6c4..9a796060f1cc 100644 --- a/packages/browser/test/unit/tracekit/ie.test.ts +++ b/packages/browser/test/unit/tracekit/ie.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - IE Tests', () => { it('should parse IE 10 error', () => { @@ -14,7 +19,7 @@ describe('Tracekit - IE Tests', () => { number: -2146823281, }; - const ex = exceptionFromError(IE_10); + const ex = exceptionFromError(parser, IE_10); // TODO: func should be normalized expect(ex).toEqual({ @@ -43,7 +48,7 @@ describe('Tracekit - IE Tests', () => { number: -2146823281, }; - const ex = exceptionFromError(IE_11); + const ex = exceptionFromError(parser, IE_11); // TODO: func should be normalized expect(ex).toEqual({ @@ -72,7 +77,7 @@ describe('Tracekit - IE Tests', () => { number: -2146823279, }; - const ex = exceptionFromError(IE_11_EVAL); + const ex = exceptionFromError(parser, IE_11_EVAL); expect(ex).toEqual({ value: "'getExceptionProps' is undefined", diff --git a/packages/browser/test/unit/tracekit/misc.test.ts b/packages/browser/test/unit/tracekit/misc.test.ts index 3aa59754cc9a..976f39e2449e 100644 --- a/packages/browser/test/unit/tracekit/misc.test.ts +++ b/packages/browser/test/unit/tracekit/misc.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - Misc Tests', () => { it('should parse PhantomJS 1.19 error', () => { @@ -11,7 +16,7 @@ describe('Tracekit - Misc Tests', () => { ' at foo (http://path/to/file.js:4283)\n' + ' at http://path/to/file.js:4287', }; - const ex = exceptionFromError(PHANTOMJS_1_19); + const ex = exceptionFromError(parser, PHANTOMJS_1_19); expect(ex).toEqual({ value: 'bar', diff --git a/packages/browser/test/unit/tracekit/opera.test.ts b/packages/browser/test/unit/tracekit/opera.test.ts index 472c4a55e2ca..a97675824e18 100644 --- a/packages/browser/test/unit/tracekit/opera.test.ts +++ b/packages/browser/test/unit/tracekit/opera.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - Opera Tests', () => { it('should parse Opera 10 error', () => { @@ -24,7 +29,7 @@ describe('Tracekit - Opera Tests', () => { '', }; - const ex = exceptionFromError(OPERA_10); + const ex = exceptionFromError(parser, OPERA_10); expect(ex).toEqual({ value: 'Statement on line 42: Type mismatch (usually non-object value supplied where object required)', @@ -70,7 +75,7 @@ describe('Tracekit - Opera Tests', () => { ' foo();', }; - const ex = exceptionFromError(OPERA_11); + const ex = exceptionFromError(parser, OPERA_11); expect(ex).toEqual({ value: "'this.undef' is not a function", @@ -107,7 +112,7 @@ describe('Tracekit - Opera Tests', () => { ' dumpException3();', }; - const ex = exceptionFromError(OPERA_12); + const ex = exceptionFromError(parser, OPERA_12); expect(ex).toEqual({ value: "Cannot convert 'x' to object", @@ -151,7 +156,7 @@ describe('Tracekit - Opera Tests', () => { ' at bar (http://path/to/file.js:108:168)', }; - const ex = exceptionFromError(OPERA_25); + const ex = exceptionFromError(parser, OPERA_25); expect(ex).toEqual({ value: "Cannot read property 'undef' of null", diff --git a/packages/browser/test/unit/tracekit/react-native.test.ts b/packages/browser/test/unit/tracekit/react-native.test.ts index 6935acd615fd..ac469a92246a 100644 --- a/packages/browser/test/unit/tracekit/react-native.test.ts +++ b/packages/browser/test/unit/tracekit/react-native.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - React Native Tests', () => { it('should parse exceptions for react-native-v8', () => { @@ -14,7 +19,7 @@ describe('Tracekit - React Native Tests', () => { at Object.y(index.android.bundle:93:571) at P(index.android.bundle:93:714)`, }; - const stacktrace = exceptionFromError(REACT_NATIVE_V8_EXCEPTION); + const stacktrace = exceptionFromError(parser, REACT_NATIVE_V8_EXCEPTION); expect(stacktrace).toEqual({ value: 'Manually triggered crash to test Sentry reporting', @@ -61,7 +66,7 @@ describe('Tracekit - React Native Tests', () => { p@/data/user/0/com.sentrytest/files/.expo-internal/bundle-613EDD44F3305B9D75D4679663900F2BCDDDC326F247CA3202A3A4219FD412D3:96:385 forEach@[native code]`, }; - const stacktrace = exceptionFromError(REACT_NATIVE_EXPO_EXCEPTION); + const stacktrace = exceptionFromError(parser, REACT_NATIVE_EXPO_EXCEPTION); expect(stacktrace).toEqual({ value: 'Test Error Expo', @@ -122,7 +127,7 @@ describe('Tracekit - React Native Tests', () => { 'at this(/home/username/sample-workspace/sampleapp.collect.react/node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBaseComponent.js:74:41)\n', }; - const ex = exceptionFromError(ANDROID_REACT_NATIVE); + const ex = exceptionFromError(parser, ANDROID_REACT_NATIVE); expect(ex).toEqual({ value: 'Error: test', @@ -241,7 +246,7 @@ describe('Tracekit - React Native Tests', () => { '[native code]', }; - const ex = exceptionFromError(ANDROID_REACT_NATIVE_PROD); + const ex = exceptionFromError(parser, ANDROID_REACT_NATIVE_PROD); expect(ex).toEqual({ value: 'Error: test', @@ -352,7 +357,7 @@ describe('Tracekit - React Native Tests', () => { 'at value (address at index.android.bundle:1:32776)\n' + 'at value (address at index.android.bundle:1:31561)', }; - const ex = exceptionFromError(ANDROID_REACT_NATIVE_HERMES); + const ex = exceptionFromError(parser, ANDROID_REACT_NATIVE_HERMES); expect(ex).toEqual({ value: 'Error: lets throw!', diff --git a/packages/browser/test/unit/tracekit/react.test.ts b/packages/browser/test/unit/tracekit/react.test.ts index dba60cceab4f..55229b333403 100644 --- a/packages/browser/test/unit/tracekit/react.test.ts +++ b/packages/browser/test/unit/tracekit/react.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - React Tests', () => { it('should correctly parse Invariant Violation errors and use framesToPop to drop info message', () => { @@ -14,7 +19,7 @@ describe('Tracekit - React Tests', () => { at f (http://localhost:5000/:1:980)`, }; - const ex = exceptionFromError(REACT_INVARIANT_VIOLATION_EXCEPTION); + const ex = exceptionFromError(parser, REACT_INVARIANT_VIOLATION_EXCEPTION); expect(ex).toEqual({ value: @@ -61,7 +66,7 @@ describe('Tracekit - React Tests', () => { at f (http://localhost:5000/:1:980)`, }; - const ex = exceptionFromError(REACT_PRODUCTION_ERROR); + const ex = exceptionFromError(parser, REACT_PRODUCTION_ERROR); expect(ex).toEqual({ value: @@ -109,7 +114,7 @@ describe('Tracekit - React Tests', () => { at f (http://localhost:5000/:1:980)`, }; - const ex = exceptionFromError(REACT_PRODUCTION_ERROR); + const ex = exceptionFromError(parser, REACT_PRODUCTION_ERROR); expect(ex).toEqual({ value: diff --git a/packages/browser/test/unit/tracekit/safari.test.ts b/packages/browser/test/unit/tracekit/safari.test.ts index 6342899e1ca4..beff492a6c1d 100644 --- a/packages/browser/test/unit/tracekit/safari.test.ts +++ b/packages/browser/test/unit/tracekit/safari.test.ts @@ -1,4 +1,9 @@ +import { createStackParser } from '@sentry/utils'; + import { exceptionFromError } from '../../../src/eventbuilder'; +import { defaultStackParsers } from '../../../src/stack-parsers'; + +const parser = createStackParser(...defaultStackParsers); describe('Tracekit - Safari Tests', () => { it('should parse Safari 6 error', () => { @@ -14,7 +19,7 @@ describe('Tracekit - Safari Tests', () => { sourceURL: 'http://path/to/file.js', }; - const stackFrames = exceptionFromError(SAFARI_6); + const stackFrames = exceptionFromError(parser, SAFARI_6); expect(stackFrames).toEqual({ value: "'null' is not an object (evaluating 'x.undef')", @@ -40,7 +45,7 @@ describe('Tracekit - Safari Tests', () => { sourceURL: 'http://path/to/file.js', }; - const stackFrames = exceptionFromError(SAFARI_7); + const stackFrames = exceptionFromError(parser, SAFARI_7); expect(stackFrames).toEqual({ value: "'null' is not an object (evaluating 'x.undef')", @@ -66,7 +71,7 @@ describe('Tracekit - Safari Tests', () => { sourceURL: 'http://path/to/file.js', }; - const stackFrames = exceptionFromError(SAFARI_8); + const stackFrames = exceptionFromError(parser, SAFARI_8); expect(stackFrames).toEqual({ value: "null is not an object (evaluating 'x.undef')", @@ -96,7 +101,7 @@ describe('Tracekit - Safari Tests', () => { column: 18, }; - const stackFrames = exceptionFromError(SAFARI_8_EVAL); + const stackFrames = exceptionFromError(parser, SAFARI_8_EVAL); expect(stackFrames).toEqual({ value: "Can't find variable: getExceptionProps", @@ -121,7 +126,7 @@ describe('Tracekit - Safari Tests', () => { at safari-extension:(//3284871F-A480-4FFC-8BC4-3F362C752446/2665fee0/topee-content.js:3313:26)`, }; - const ex = exceptionFromError(SAFARI_EXTENSION_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI_EXTENSION_EXCEPTION); expect(ex).toEqual({ value: 'wat', @@ -155,7 +160,7 @@ describe('Tracekit - Safari Tests', () => { safari-extension://com.grammarly.safari.extension.ext2-W8F64X92K3/ee7759dd/Grammarly.js:2:1588410 promiseReactionJob@[native code]`, }; - const ex = exceptionFromError(SAFARI_EXTENSION_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI_EXTENSION_EXCEPTION); expect(ex).toEqual({ value: "undefined is not an object (evaluating 'e.groups.includes')", @@ -191,7 +196,7 @@ describe('Tracekit - Safari Tests', () => { at safari-web-extension:(//3284871F-A480-4FFC-8BC4-3F362C752446/2665fee0/topee-content.js:3313:26)`, }; - const ex = exceptionFromError(SAFARI_WEB_EXTENSION_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI_WEB_EXTENSION_EXCEPTION); expect(ex).toEqual({ value: 'wat', @@ -225,7 +230,7 @@ describe('Tracekit - Safari Tests', () => { safari-web-extension://46434E60-F5BD-48A4-80C8-A422C5D16897/scripts/content-script.js:29:56027 promiseReactionJob@[native code]`, }; - const ex = exceptionFromError(SAFARI_EXTENSION_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI_EXTENSION_EXCEPTION); expect(ex).toEqual({ value: "undefined is not an object (evaluating 'e.groups.includes')", @@ -263,7 +268,7 @@ describe('Tracekit - Safari Tests', () => { global code@http://localhost:5000/test:24:10`, }; - const ex = exceptionFromError(SAFARI12_NATIVE_CODE_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI12_NATIVE_CODE_EXCEPTION); expect(ex).toEqual({ value: 'test', @@ -297,7 +302,7 @@ describe('Tracekit - Safari Tests', () => { http://localhost:5000/:50:29`, }; - const ex = exceptionFromError(SAFARI12_EVAL_EXCEPTION); + const ex = exceptionFromError(parser, SAFARI12_EVAL_EXCEPTION); expect(ex).toEqual({ value: 'aha', diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 4401f4016520..81f808f5ef56 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,7 +1,7 @@ import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; -import { logger, makeDsn, resolvedSyncPromise } from '@sentry/utils'; +import { logger, makeDsn, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; @@ -112,14 +112,16 @@ export class NodeClient extends BaseClient { */ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types public eventFromException(exception: any, hint?: EventHint): PromiseLike { - return resolvedSyncPromise(eventFromUnknownInput(exception, hint)); + return resolvedSyncPromise(eventFromUnknownInput(stackParserFromOptions(this._options), exception, hint)); } /** * @inheritDoc */ public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { - return resolvedSyncPromise(eventFromMessage(message, level, hint, this._options.attachStacktrace)); + return resolvedSyncPromise( + eventFromMessage(stackParserFromOptions(this._options), message, level, hint, this._options.attachStacktrace), + ); } /** diff --git a/packages/node/src/eventbuilder.ts b/packages/node/src/eventbuilder.ts index 1287f2a47f48..e0b6b16261f0 100644 --- a/packages/node/src/eventbuilder.ts +++ b/packages/node/src/eventbuilder.ts @@ -1,34 +1,31 @@ import { getCurrentHub } from '@sentry/hub'; -import { Event, EventHint, Exception, Mechanism, Severity, StackFrame } from '@sentry/types'; +import { Event, EventHint, Exception, Mechanism, Severity, StackFrame, StackParser } from '@sentry/types'; import { addExceptionMechanism, addExceptionTypeValue, - createStackParser, extractExceptionKeysForMessage, isError, isPlainObject, normalizeToSize, } from '@sentry/utils'; -import { nodeStackParser } from './stack-parser'; - /** * Extracts stack frames from the error.stack string */ -export function parseStackFrames(error: Error): StackFrame[] { - return createStackParser(nodeStackParser)(error.stack || '', 1); +export function parseStackFrames(stackParser: StackParser, error: Error): StackFrame[] { + return stackParser(error.stack || '', 1); } /** * Extracts stack frames from the error and builds a Sentry Exception */ -export function exceptionFromError(error: Error): Exception { +export function exceptionFromError(stackParser: StackParser, error: Error): Exception { const exception: Exception = { type: error.name || error.constructor.name, value: error.message, }; - const frames = parseStackFrames(error); + const frames = parseStackFrames(stackParser, error); if (frames.length) { exception.stacktrace = { frames }; } @@ -40,7 +37,7 @@ export function exceptionFromError(error: Error): Exception { * Builds and Event from a Exception * @hidden */ -export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Event { +export function eventFromUnknownInput(stackParser: StackParser, exception: unknown, hint?: EventHint): Event { // eslint-disable-next-line @typescript-eslint/no-explicit-any let ex: unknown = exception; const providedMechanism: Mechanism | undefined = @@ -73,7 +70,7 @@ export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Eve const event = { exception: { - values: [exceptionFromError(ex as Error)], + values: [exceptionFromError(stackParser, ex as Error)], }, }; @@ -91,6 +88,7 @@ export function eventFromUnknownInput(exception: unknown, hint?: EventHint): Eve * @hidden */ export function eventFromMessage( + stackParser: StackParser, message: string, level: Severity = Severity.Info, hint?: EventHint, @@ -103,7 +101,7 @@ export function eventFromMessage( }; if (attachStacktrace && hint && hint.syntheticException) { - const frames = parseStackFrames(hint.syntheticException); + const frames = parseStackFrames(stackParser, hint.syntheticException); if (frames.length) { event.exception = { values: [ diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 591fd4ad911d..d6a924a04c2e 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -46,6 +46,7 @@ export { NodeClient } from './client'; export { defaultIntegrations, init, lastEventId, flush, close, getSentryRelease } from './sdk'; export { deepReadDirSync } from './utils'; export { SDK_NAME } from './version'; +export { nodeStackParser } from './stack-parser'; import { Integrations as CoreIntegrations } from '@sentry/core'; import { getMainCarrier } from '@sentry/hub'; diff --git a/packages/node/src/integrations/linkederrors.ts b/packages/node/src/integrations/linkederrors.ts index 701400594971..c1dfd285db84 100644 --- a/packages/node/src/integrations/linkederrors.ts +++ b/packages/node/src/integrations/linkederrors.ts @@ -1,7 +1,8 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core'; -import { Event, EventHint, Exception, ExtendedError, Integration } from '@sentry/types'; -import { isInstanceOf, resolvedSyncPromise, SyncPromise } from '@sentry/utils'; +import { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types'; +import { isInstanceOf, resolvedSyncPromise, stackParserFromOptions, SyncPromise } from '@sentry/utils'; +import { NodeClient } from '../client'; import { exceptionFromError } from '../eventbuilder'; import { ContextLines } from './contextlines'; @@ -42,12 +43,15 @@ export class LinkedErrors implements Integration { * @inheritDoc */ public setupOnce(): void { - addGlobalEventProcessor((event: Event, hint?: EventHint) => { - const self = getCurrentHub().getIntegration(LinkedErrors); + addGlobalEventProcessor(async (event: Event, hint?: EventHint) => { + const hub = getCurrentHub(); + const self = hub.getIntegration(LinkedErrors); + const stackParser = stackParserFromOptions(hub.getClient()?.getOptions()); + if (self) { - const handler = self._handler && self._handler.bind(self); - return typeof handler === 'function' ? handler(event, hint) : event; + await self._handler(stackParser, event, hint); } + return event; }); } @@ -55,13 +59,13 @@ export class LinkedErrors implements Integration { /** * @inheritDoc */ - private _handler(event: Event, hint?: EventHint): PromiseLike { + private _handler(stackParser: StackParser, event: Event, hint?: EventHint): PromiseLike { if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) { return resolvedSyncPromise(event); } return new SyncPromise(resolve => { - void this._walkErrorTree(hint.originalException as Error, this._key) + void this._walkErrorTree(stackParser, hint.originalException as Error, this._key) .then((linkedErrors: Exception[]) => { if (event && event.exception && event.exception.values) { event.exception.values = [...linkedErrors, ...event.exception.values]; @@ -77,12 +81,17 @@ export class LinkedErrors implements Integration { /** * @inheritDoc */ - private async _walkErrorTree(error: ExtendedError, key: string, stack: Exception[] = []): Promise { + private async _walkErrorTree( + stackParser: StackParser, + error: ExtendedError, + key: string, + stack: Exception[] = [], + ): Promise { if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) { return Promise.resolve(stack); } - const exception = exceptionFromError(error[key]); + const exception = exceptionFromError(stackParser, error[key]); // If the ContextLines integration is enabled, we add source code context to linked errors // because we can't guarantee the order that integrations are run. @@ -92,7 +101,7 @@ export class LinkedErrors implements Integration { } return new Promise((resolve, reject) => { - void this._walkErrorTree(error[key], key, [exception, ...stack]) + void this._walkErrorTree(stackParser, error[key], key, [exception, ...stack]) .then(resolve) .then(null, () => { reject(); diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index 7dd660a44048..095bd3114144 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -7,6 +7,7 @@ import * as domain from 'domain'; import { NodeClient } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations'; +import { nodeStackParser } from './stack-parser'; import { NodeOptions } from './types'; export const defaultIntegrations = [ @@ -120,6 +121,10 @@ export function init(options: NodeOptions = {}): void { options.autoSessionTracking = true; } + if (options.stackParser === undefined) { + options.stackParser = [nodeStackParser]; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any if ((domain as any).active) { setHubOnCarrier(carrier, getCurrentHub()); diff --git a/packages/node/src/stack-parser.ts b/packages/node/src/stack-parser.ts index a37e38001da3..79a86e9018ee 100644 --- a/packages/node/src/stack-parser.ts +++ b/packages/node/src/stack-parser.ts @@ -1,4 +1,5 @@ -import { basename, dirname, StackLineParser, StackLineParserFn } from '@sentry/utils'; +import { StackLineParser, StackLineParserFn } from '@sentry/types'; +import { basename, dirname } from '@sentry/utils'; /** Gets the module */ function getModule(filename: string | undefined): string | undefined { diff --git a/packages/node/test/context-lines.test.ts b/packages/node/test/context-lines.test.ts index 821c95d7b6b0..55dce7be1615 100644 --- a/packages/node/test/context-lines.test.ts +++ b/packages/node/test/context-lines.test.ts @@ -1,10 +1,14 @@ import { StackFrame } from '@sentry/types'; +import { createStackParser } from '@sentry/utils'; import * as fs from 'fs'; import { parseStackFrames } from '../src/eventbuilder'; import { ContextLines, resetFileContentCache } from '../src/integrations/contextlines'; +import { nodeStackParser } from '../src/stack-parser'; import { getError } from './helper/error'; +const parser = createStackParser(nodeStackParser); + describe('ContextLines', () => { let readFileSpy: jest.SpyInstance; let contextLines: ContextLines; @@ -27,7 +31,7 @@ describe('ContextLines', () => { test('parseStack with same file', async () => { expect.assertions(1); - const frames = parseStackFrames(new Error('test')); + const frames = parseStackFrames(parser, new Error('test')); await addContext(Array.from(frames)); @@ -57,12 +61,12 @@ describe('ContextLines', () => { test('parseStack with adding different file', async () => { expect.assertions(1); - const frames = parseStackFrames(new Error('test')); + const frames = parseStackFrames(parser, new Error('test')); await addContext(frames); const numCalls = readFileSpy.mock.calls.length; - const parsedFrames = parseStackFrames(getError()); + const parsedFrames = parseStackFrames(parser, getError()); await addContext(parsedFrames); const newErrorCalls = readFileSpy.mock.calls.length; @@ -100,7 +104,7 @@ describe('ContextLines', () => { contextLines = new ContextLines({ frameContextLines: 0 }); expect.assertions(1); - const frames = parseStackFrames(new Error('test')); + const frames = parseStackFrames(parser, new Error('test')); await addContext(frames); expect(readFileSpy).toHaveBeenCalledTimes(0); diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index 687465802a94..af12a4b35994 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -1,6 +1,7 @@ import { initAndBind, SDK_VERSION } from '@sentry/core'; import { getMainCarrier } from '@sentry/hub'; import { Integration } from '@sentry/types'; +import { createStackParser } from '@sentry/utils'; import * as domain from 'domain'; import { @@ -16,6 +17,9 @@ import { Scope, } from '../src'; import { ContextLines, LinkedErrors } from '../src/integrations'; +import { nodeStackParser } from '../src/stack-parser'; + +const stackParser = createStackParser(nodeStackParser); jest.mock('@sentry/core', () => { const original = jest.requireActual('@sentry/core'); @@ -86,6 +90,7 @@ describe('SentryNode', () => { test('record auto breadcrumbs', done => { const client = new NodeClient({ + stackParser, beforeSend: (event: Event) => { // TODO: It should be 3, but we don't capture a breadcrumb // for our own captureMessage/captureException calls yet @@ -117,6 +122,7 @@ describe('SentryNode', () => { expect.assertions(6); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); expect(event.exception).not.toBeUndefined(); @@ -144,6 +150,7 @@ describe('SentryNode', () => { expect.assertions(6); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); expect(event.exception).not.toBeUndefined(); @@ -171,6 +178,7 @@ describe('SentryNode', () => { expect.assertions(10); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); expect(event.exception).not.toBeUndefined(); @@ -202,6 +210,7 @@ describe('SentryNode', () => { expect.assertions(15); getCurrentHub().bindClient( new NodeClient({ + stackParser, integrations: [new ContextLines(), new LinkedErrors()], beforeSend: (event: Event) => { expect(event.exception).not.toBeUndefined(); @@ -242,6 +251,7 @@ describe('SentryNode', () => { expect.assertions(2); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test'); expect(event.exception).toBeUndefined(); @@ -258,6 +268,7 @@ describe('SentryNode', () => { expect.assertions(2); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test event'); expect(event.exception).toBeUndefined(); @@ -274,6 +285,7 @@ describe('SentryNode', () => { const d = domain.create(); const client = new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test domain'); expect(event.exception).toBeUndefined(); @@ -294,6 +306,7 @@ describe('SentryNode', () => { expect.assertions(1); getCurrentHub().bindClient( new NodeClient({ + stackParser, beforeSend: (event: Event) => { expect( event.exception!.values![0].stacktrace!.frames![ diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 47249d129716..296384a5f222 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -1,7 +1,11 @@ import { ExtendedError } from '@sentry/types'; +import { createStackParser } from '@sentry/utils'; import { Event, NodeClient } from '../../src'; import { LinkedErrors } from '../../src/integrations/linkederrors'; +import { nodeStackParser } from '../../src/stack-parser'; + +const stackParser = createStackParser(nodeStackParser); let linkedErrors: any; @@ -17,7 +21,7 @@ describe('LinkedErrors', () => { const event = { message: 'foo', }; - return linkedErrors._handler(event).then((result: any) => { + return linkedErrors._handler(stackParser, event).then((result: any) => { expect(spy.mock.calls.length).toEqual(0); expect(result).toEqual(event); }); @@ -27,13 +31,13 @@ describe('LinkedErrors', () => { expect.assertions(2); const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); - const client = new NodeClient({}); + const client = new NodeClient({ stackParser }); let event: Event | undefined; return client .eventFromException(one) .then(eventFromException => { event = eventFromException; - return linkedErrors._handler(eventFromException); + return linkedErrors._handler(stackParser, eventFromException); }) .then(result => { expect(spy.mock.calls.length).toEqual(0); @@ -50,10 +54,10 @@ describe('LinkedErrors', () => { }), ); const one = new Error('originalException'); - const client = new NodeClient({}); + const client = new NodeClient({ stackParser }); return client.eventFromException(one).then(event => linkedErrors - ._handler(event, { + ._handler(stackParser, event, { originalException: one, }) .then((_: any) => { @@ -70,10 +74,10 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new NodeClient({}); + const client = new NodeClient({ stackParser }); return client.eventFromException(one).then(event => linkedErrors - ._handler(event, { + ._handler(stackParser, event, { originalException: one, }) .then((result: any) => { @@ -103,10 +107,10 @@ describe('LinkedErrors', () => { one.reason = two; two.reason = three; - const client = new NodeClient({}); + const client = new NodeClient({ stackParser }); return client.eventFromException(one).then(event => linkedErrors - ._handler(event, { + ._handler(stackParser, event, { originalException: one, }) .then((result: any) => { @@ -136,10 +140,10 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new NodeClient({}); + const client = new NodeClient({ stackParser }); return client.eventFromException(one).then(event => linkedErrors - ._handler(event, { + ._handler(stackParser, event, { originalException: one, }) .then((result: any) => { diff --git a/packages/node/test/stacktrace.test.ts b/packages/node/test/stacktrace.test.ts index 656ba1a69a9b..ec5ef8b94800 100644 --- a/packages/node/test/stacktrace.test.ts +++ b/packages/node/test/stacktrace.test.ts @@ -10,7 +10,12 @@ * @license MIT */ +import { createStackParser } from '@sentry/utils'; + import { parseStackFrames } from '../src/eventbuilder'; +import { nodeStackParser } from '../src/stack-parser'; + +const stackParser = createStackParser(nodeStackParser); function testBasic() { return new Error('something went wrong'); @@ -26,17 +31,17 @@ function evalWrapper() { describe('Stack parsing', () => { test('test basic error', () => { - const frames = parseStackFrames(testBasic()); + const frames = parseStackFrames(stackParser, testBasic()); const last = frames.length - 1; expect(frames[last].filename).toEqual(__filename); expect(frames[last].function).toEqual('testBasic'); - expect(frames[last].lineno).toEqual(16); + expect(frames[last].lineno).toEqual(21); expect(frames[last].colno).toEqual(10); }); test('test error with wrapper', () => { - const frames = parseStackFrames(testWrapper()); + const frames = parseStackFrames(stackParser, testWrapper()); const last = frames.length - 1; expect(frames[last].function).toEqual('testBasic'); @@ -44,7 +49,7 @@ describe('Stack parsing', () => { }); test('test error with eval wrapper', () => { - const frames = parseStackFrames(evalWrapper()); + const frames = parseStackFrames(stackParser, evalWrapper()); const last = frames.length - 1; expect(frames[last].function).toEqual('testBasic'); @@ -59,7 +64,7 @@ describe('Stack parsing', () => { ' at [object Object].global.every [as _onTimeout] (/Users/hoitz/develop/test.coffee:36:3)\n' + ' at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)\n'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -83,7 +88,7 @@ describe('Stack parsing', () => { test('parses undefined stack', () => { const err = { stack: undefined }; - const trace = parseStackFrames(err as Error); + const trace = parseStackFrames(stackParser, err as Error); expect(trace).toEqual([]); }); @@ -97,7 +102,7 @@ describe('Stack parsing', () => { 'oh no' + ' at TestCase.run (/Users/felix/code/node-fast-or-slow/lib/test_case.js:61:8)\n'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -126,7 +131,7 @@ describe('Stack parsing', () => { ' at Test.fn (/Users/felix/code/node-fast-or-slow/test/fast/example/test-example.js:6)\n' + ' at Test.run (/Users/felix/code/node-fast-or-slow/lib/test.js:45)'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -157,7 +162,7 @@ describe('Stack parsing', () => { ' at Array.0 (native)\n' + ' at EventEmitter._tickCallback (node.js:126:26)'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -212,7 +217,7 @@ describe('Stack parsing', () => { const err = new Error(); err.stack = 'AssertionError: true == false\n' + ' at /Users/felix/code/node-fast-or-slow/lib/test_case.js:80:10'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -232,7 +237,7 @@ describe('Stack parsing', () => { 'AssertionError: true == false\nAnd some more shit\n' + ' at /Users/felix/code/node-fast-or-slow/lib/test_case.js:80:10'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -252,7 +257,7 @@ describe('Stack parsing', () => { 'AssertionError: expected [] to be arguments\n' + ' at Assertion.prop.(anonymous function) (/Users/den/Projects/should.js/lib/should.js:60:14)\n'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -273,7 +278,7 @@ describe('Stack parsing', () => { ' at Test.run (/Users/felix (something)/code/node-fast-or-slow/lib/test.js:45:10)\n' + ' at TestCase.run (/Users/felix (something)/code/node-fast-or-slow/lib/test_case.js:61:8)\n'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { @@ -309,7 +314,7 @@ describe('Stack parsing', () => { ' at async onBatch (/code/node_modules/kafkajs/src/consumer/runner.js:326:9)\n' + ' at async /code/node_modules/kafkajs/src/consumer/runner.js:376:15\n'; - const frames = parseStackFrames(err); + const frames = parseStackFrames(stackParser, err); expect(frames).toEqual([ { diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 13651b7cd78e..20856f52aa64 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -50,7 +50,7 @@ export { Severity } from './severity'; export { SeverityLevel, SeverityLevels } from './severity'; export { Span, SpanContext } from './span'; export { StackFrame } from './stackframe'; -export { Stacktrace } from './stacktrace'; +export { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; export { CustomSamplingContext, Measurements, diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 3fefd41ca137..a7306acdd76f 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -3,6 +3,7 @@ import { Event, EventHint } from './event'; import { Integration } from './integration'; import { CaptureContext } from './scope'; import { SdkMetadata } from './sdkmetadata'; +import { StackLineParser, StackParser } from './stacktrace'; import { SamplingContext } from './transaction'; import { Transport, TransportClass, TransportOptions } from './transport'; @@ -149,6 +150,12 @@ export interface Options { */ initialScope?: CaptureContext; + /** + * A stack parser implementation or an array of stack line parsers + * By default, a stack parser is supplied for all supported browsers + */ + stackParser?: StackParser | StackLineParser[]; + /** * Set of metadata about the SDK that can be internally used to enhance envelopes and events, * and provide additional data about every request. diff --git a/packages/types/src/stacktrace.ts b/packages/types/src/stacktrace.ts index 120a1b471af6..ae2f350f716b 100644 --- a/packages/types/src/stacktrace.ts +++ b/packages/types/src/stacktrace.ts @@ -5,3 +5,7 @@ export interface Stacktrace { frames?: StackFrame[]; frames_omitted?: [number, number]; } + +export type StackParser = (stack: string, skipFirst?: number) => StackFrame[]; +export type StackLineParserFn = (line: string) => StackFrame | undefined; +export type StackLineParser = [number, StackLineParserFn]; diff --git a/packages/utils/src/stacktrace.ts b/packages/utils/src/stacktrace.ts index 7c9dddeee298..15c5401c09bd 100644 --- a/packages/utils/src/stacktrace.ts +++ b/packages/utils/src/stacktrace.ts @@ -1,11 +1,7 @@ -import { StackFrame } from '@sentry/types'; +import { StackFrame, StackLineParser, StackParser } from '@sentry/types'; const STACKTRACE_LIMIT = 50; -export type StackParser = (stack: string, skipFirst?: number) => StackFrame[]; -export type StackLineParserFn = (line: string) => StackFrame | undefined; -export type StackLineParser = [number, StackLineParserFn]; - /** * Creates a stack parser with the supplied line parsers * @@ -34,6 +30,29 @@ export function createStackParser(...parsers: StackLineParser[]): StackParser { }; } +interface StackParserOptions { + stackParser?: StackParser | StackLineParser[]; +} + +/** + * Gets a stack parser implementation from options + * + * If options contains an array of line parsers, it is converted into a parser + */ +export function stackParserFromOptions(options: StackParserOptions | undefined): StackParser { + if (options) { + if (Array.isArray(options.stackParser)) { + options.stackParser = createStackParser(...options.stackParser); + } + + if (typeof options.stackParser === 'function') { + return options.stackParser; + } + } + + return _ => []; +} + /** * @hidden */ From 6445db25b3ec16c514269078d9462224405bd147 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Tue, 12 Apr 2022 20:45:21 +0100 Subject: [PATCH 37/94] feat: Remove stack parser support for Opera pre v15 (#4923) Opera v15 was released in 2013 and was based on Chromium. This PR removes the two Opera specific stack parsers that cater for versions before this from the defaults. Anyone still wanting to support these ancient browser versions can do the following: ```ts import { init, defaultStackParsers, opera10StackParser, opera11StackParser } from '@sentry/browser'; init({ dsn: '__DSN__', stackParser: [...defaultStackParsers, opera10StackParser, opera11StackParser] }) ``` --- packages/browser/src/stack-parsers.ts | 8 +------- packages/browser/test/unit/tracekit/opera.test.ts | 13 +++++++------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 5ee652001854..5d58e9865cd4 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -130,13 +130,7 @@ const opera11: StackLineParserFn = line => { export const opera11StackParser: StackLineParser = [OPERA11_PRIORITY, opera11]; -export const defaultStackParsers = [ - chromeStackParser, - geckoStackParser, - opera10StackParser, - opera11StackParser, - winjsStackParser, -]; +export const defaultStackParsers = [chromeStackParser, geckoStackParser, winjsStackParser]; /** * Safari web extensions, starting version unknown, can produce "frames-only" stacktraces. diff --git a/packages/browser/test/unit/tracekit/opera.test.ts b/packages/browser/test/unit/tracekit/opera.test.ts index a97675824e18..9084447d4e29 100644 --- a/packages/browser/test/unit/tracekit/opera.test.ts +++ b/packages/browser/test/unit/tracekit/opera.test.ts @@ -1,9 +1,10 @@ import { createStackParser } from '@sentry/utils'; import { exceptionFromError } from '../../../src/eventbuilder'; -import { defaultStackParsers } from '../../../src/stack-parsers'; +import { defaultStackParsers, opera10StackParser, opera11StackParser } from '../../../src/stack-parsers'; -const parser = createStackParser(...defaultStackParsers); +const operaParser = createStackParser(opera10StackParser, opera11StackParser); +const chromiumParser = createStackParser(...defaultStackParsers); describe('Tracekit - Opera Tests', () => { it('should parse Opera 10 error', () => { @@ -29,7 +30,7 @@ describe('Tracekit - Opera Tests', () => { '', }; - const ex = exceptionFromError(parser, OPERA_10); + const ex = exceptionFromError(operaParser, OPERA_10); expect(ex).toEqual({ value: 'Statement on line 42: Type mismatch (usually non-object value supplied where object required)', @@ -75,7 +76,7 @@ describe('Tracekit - Opera Tests', () => { ' foo();', }; - const ex = exceptionFromError(parser, OPERA_11); + const ex = exceptionFromError(operaParser, OPERA_11); expect(ex).toEqual({ value: "'this.undef' is not a function", @@ -112,7 +113,7 @@ describe('Tracekit - Opera Tests', () => { ' dumpException3();', }; - const ex = exceptionFromError(parser, OPERA_12); + const ex = exceptionFromError(operaParser, OPERA_12); expect(ex).toEqual({ value: "Cannot convert 'x' to object", @@ -156,7 +157,7 @@ describe('Tracekit - Opera Tests', () => { ' at bar (http://path/to/file.js:108:168)', }; - const ex = exceptionFromError(parser, OPERA_25); + const ex = exceptionFromError(chromiumParser, OPERA_25); expect(ex).toEqual({ value: "Cannot read property 'undef' of null", From 20b8c525163b9bc28b0cc4077279d24e1ca75c46 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 15:31:56 +0200 Subject: [PATCH 38/94] ref(measurements): Update `setMeasurements` to only set a single measurement (#4920) --- .../setMeasurement/subject.js | 8 ++++ .../startTransaction/setMeasurement/test.ts | 18 ++++++++ packages/tracing/src/browser/metrics.ts | 43 ++++++++++++------- packages/tracing/src/transaction.ts | 10 +++-- packages/types/src/transaction.ts | 2 +- 5 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 packages/integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js create mode 100644 packages/integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts diff --git a/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js b/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js new file mode 100644 index 000000000000..036e86201b18 --- /dev/null +++ b/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/subject.js @@ -0,0 +1,8 @@ +const transaction = Sentry.startTransaction({ name: 'some_transaction' }); + +transaction.setMeasurement('metric.foo', 42, 'ms'); +transaction.setMeasurement('metric.bar', 1337, 'nanoseconds'); +transaction.setMeasurement('metric.baz', 99, 's'); +transaction.setMeasurement('metric.baz', 1); + +transaction.finish(); diff --git a/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts b/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts new file mode 100644 index 000000000000..e91231093bf3 --- /dev/null +++ b/packages/integration-tests/suites/public-api/startTransaction/setMeasurement/test.ts @@ -0,0 +1,18 @@ +import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; + +import { sentryTest } from '../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; + +sentryTest('should attach measurement to transaction', async ({ getLocalTestPath, page }) => { + const url = await getLocalTestPath({ testDir: __dirname }); + const event = await getFirstSentryEnvelopeRequest(page, url); + + expect(event.measurements?.['metric.foo'].value).toBe(42); + expect(event.measurements?.['metric.bar'].value).toBe(1337); + expect(event.measurements?.['metric.baz'].value).toBe(1); + + expect(event.measurements?.['metric.foo'].unit).toBe('ms'); + expect(event.measurements?.['metric.bar'].unit).toBe('nanoseconds'); + expect(event.measurements?.['metric.baz'].unit).toBe(''); +}); diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 8386b608f247..dffc39abb088 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -79,14 +79,14 @@ export class MetricsInstrumentation { if (entry.name === 'first-paint' && shouldRecord) { IS_DEBUG_BUILD && logger.log('[Measurements] Adding FP'); - this._measurements['fp'] = { value: entry.startTime }; - this._measurements['mark.fp'] = { value: startTimestamp }; + this._measurements['fp'] = { value: entry.startTime, unit: 'millisecond' }; + this._measurements['mark.fp'] = { value: startTimestamp, unit: 'second' }; } if (entry.name === 'first-contentful-paint' && shouldRecord) { IS_DEBUG_BUILD && logger.log('[Measurements] Adding FCP'); - this._measurements['fcp'] = { value: entry.startTime }; - this._measurements['mark.fcp'] = { value: startTimestamp }; + this._measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' }; + this._measurements['mark.fcp'] = { value: startTimestamp, unit: 'second' }; } break; @@ -115,12 +115,18 @@ export class MetricsInstrumentation { // start of the response in milliseconds if (typeof responseStartTimestamp === 'number') { IS_DEBUG_BUILD && logger.log('[Measurements] Adding TTFB'); - this._measurements['ttfb'] = { value: (responseStartTimestamp - transaction.startTimestamp) * 1000 }; + this._measurements['ttfb'] = { + value: (responseStartTimestamp - transaction.startTimestamp) * 1000, + unit: 'millisecond', + }; if (typeof requestStartTimestamp === 'number' && requestStartTimestamp <= responseStartTimestamp) { // Capture the time spent making the request and receiving the first byte of the response. // This is the time between the start of the request and the start of the response in milliseconds. - this._measurements['ttfb.requestTime'] = { value: (responseStartTimestamp - requestStartTimestamp) * 1000 }; + this._measurements['ttfb.requestTime'] = { + value: (responseStartTimestamp - requestStartTimestamp) * 1000, + unit: 'second', + }; } } @@ -162,7 +168,14 @@ export class MetricsInstrumentation { delete this._measurements.cls; } - transaction.setMeasurements(this._measurements); + Object.keys(this._measurements).forEach(measurementName => { + transaction.setMeasurement( + measurementName, + this._measurements[measurementName].value, + this._measurements[measurementName].unit, + ); + }); + tagMetricInfo(transaction, this._lcpEntry, this._clsEntry); transaction.setTag('sentry_reportAllChanges', this._reportAllChanges); } @@ -189,11 +202,11 @@ export class MetricsInstrumentation { } if (isMeasurementValue(connection.rtt)) { - this._measurements['connection.rtt'] = { value: connection.rtt as number }; + this._measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' }; } if (isMeasurementValue(connection.downlink)) { - this._measurements['connection.downlink'] = { value: connection.downlink as number }; + this._measurements['connection.downlink'] = { value: connection.downlink, unit: '' }; // unit is empty string for now, while relay doesn't support download speed units } } @@ -218,7 +231,7 @@ export class MetricsInstrumentation { } IS_DEBUG_BUILD && logger.log('[Measurements] Adding CLS'); - this._measurements['cls'] = { value: metric.value }; + this._measurements['cls'] = { value: metric.value, unit: 'millisecond' }; this._clsEntry = entry as LayoutShift; }); } @@ -234,8 +247,8 @@ export class MetricsInstrumentation { const timeOrigin = msToSec(browserPerformanceTimeOrigin as number); const startTime = msToSec(entry.startTime); IS_DEBUG_BUILD && logger.log('[Measurements] Adding LCP'); - this._measurements['lcp'] = { value: metric.value }; - this._measurements['mark.lcp'] = { value: timeOrigin + startTime }; + this._measurements['lcp'] = { value: metric.value, unit: 'millisecond' }; + this._measurements['mark.lcp'] = { value: timeOrigin + startTime, unit: 'second' }; this._lcpEntry = entry as LargestContentfulPaint; }, this._reportAllChanges); } @@ -251,8 +264,8 @@ export class MetricsInstrumentation { const timeOrigin = msToSec(browserPerformanceTimeOrigin as number); const startTime = msToSec(entry.startTime); IS_DEBUG_BUILD && logger.log('[Measurements] Adding FID'); - this._measurements['fid'] = { value: metric.value }; - this._measurements['mark.fid'] = { value: timeOrigin + startTime }; + this._measurements['fid'] = { value: metric.value, unit: 'millisecond' }; + this._measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' }; }); } } @@ -392,7 +405,7 @@ export function _startChild(transaction: Transaction, { startTimestamp, ...ctx } /** * Checks if a given value is a valid measurement value. */ -function isMeasurementValue(value: any): boolean { +function isMeasurementValue(value: unknown): value is number { return typeof value === 'number' && isFinite(value); } diff --git a/packages/tracing/src/transaction.ts b/packages/tracing/src/transaction.ts index 6cbda0e04223..5384f15a6105 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/tracing/src/transaction.ts @@ -68,11 +68,15 @@ export class Transaction extends SpanClass implements TransactionInterface { } /** - * Set observed measurements for this transaction. + * Set observed measurement for this transaction. + * + * @param name Name of the measurement + * @param value Value of the measurement + * @param unit Unit of the measurement. (Defaults to an empty string) * @hidden */ - public setMeasurements(measurements: Measurements): void { - this._measurements = { ...measurements }; + public setMeasurement(name: string, value: number, unit: string = ''): void { + this._measurements[name] = { value, unit }; } /** diff --git a/packages/types/src/transaction.ts b/packages/types/src/transaction.ts index d2a8744cd335..0367eafbb941 100644 --- a/packages/types/src/transaction.ts +++ b/packages/types/src/transaction.ts @@ -115,7 +115,7 @@ export interface SamplingContext extends CustomSamplingContext { request?: ExtractedNodeRequestData; } -export type Measurements = Record; +export type Measurements = Record; export type TransactionSamplingMethod = 'explicitly_set' | 'client_sampler' | 'client_rate' | 'inheritance'; From b5fd785a91fcdb655b099aa0aa57ccb206fd26ba Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 16:45:14 +0200 Subject: [PATCH 39/94] ref(measurements): Make `setMeasurement` public API (#4933) --- packages/tracing/src/transaction.ts | 7 +------ packages/types/src/transaction.ts | 9 +++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/tracing/src/transaction.ts b/packages/tracing/src/transaction.ts index 5384f15a6105..91fa4d3c435b 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/tracing/src/transaction.ts @@ -68,12 +68,7 @@ export class Transaction extends SpanClass implements TransactionInterface { } /** - * Set observed measurement for this transaction. - * - * @param name Name of the measurement - * @param value Value of the measurement - * @param unit Unit of the measurement. (Defaults to an empty string) - * @hidden + * @inheritDoc */ public setMeasurement(name: string, value: number, unit: string = ''): void { this._measurements[name] = { value, unit }; diff --git a/packages/types/src/transaction.ts b/packages/types/src/transaction.ts index 0367eafbb941..95f8b447e19a 100644 --- a/packages/types/src/transaction.ts +++ b/packages/types/src/transaction.ts @@ -73,6 +73,15 @@ export interface Transaction extends TransactionContext, Span { */ setName(name: string): void; + /** + * Set observed measurement for this transaction. + * + * @param name Name of the measurement + * @param value Value of the measurement + * @param unit Unit of the measurement. (Defaults to an empty string) + */ + setMeasurement(name: string, value: number, unit: string): void; + /** Returns the current transaction properties as a `TransactionContext` */ toContext(): TransactionContext; From 292075f2056c005112e87aed445bd635f37c5497 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 13 Apr 2022 17:32:27 -0700 Subject: [PATCH 40/94] ref(types): Stop using `Severity` enum (#4926) Note: This and https://github.com/getsentry/sentry-javascript/pull/4896 are together a (slightly updated) repeat of https://github.com/getsentry/sentry-javascript/pull/4497, to get it onto the main v7 branch. Our original v7 plan called for deprecating and then removing the `Severity` enum which lives in `@sentry/types`, because enums transpile to a two-way lookup function with a fairly hefty footprint (see this SO answer[1] from one of the maintainers of TS). We therefore added a new `SeverityLevel` type, which is the union of all of `Severity`'s underlying values, and directed people to use that instead. Though we subsequently decided not to remove `Severity` (at least in v7), we agreed that we should stop using it internally. This implements that change. Key Changes: - `Severity` and `severityFromString` have been redeprecated. - The original plan to have `SeverityLevel` live in `@sentry/utils` has been reverted, and it now lives only in `@sentry/types`. - The internal `SeverityLevels` array on which we were basing `SeverityLevel` has been removed. While we lose the elegance of the derived type, we gain the ability to truly only export types from `@sentry/types`. - Wherever we accept a `Severity` value, we now also accept a `SeverityLevel`. - All internal uses of `Severity` values have been replaced with the equivalent string constants. - A new `severityLevelFromString` function has been introduced, and is now used in place of `SeverityFromString`. - The tests for `severityFromString` have been cleaned up and replaced with equivalent tests for `SeverityLevelFromString`. [1] https://stackoverflow.com/a/28818850 --- packages/browser/src/client.ts | 9 +++- packages/browser/src/eventbuilder.ts | 7 ++-- packages/browser/src/exports.ts | 4 +- .../browser/src/integrations/breadcrumbs.ts | 8 ++-- .../src/integrations/globalhandlers.ts | 6 +-- packages/core/src/baseclient.ts | 16 ++++++- packages/core/test/mocks/client.ts | 8 +++- packages/hub/src/hub.ts | 8 +++- packages/hub/src/scope.ts | 9 +++- packages/hub/test/scope.test.ts | 22 +++++----- packages/integrations/src/captureconsole.ts | 4 +- packages/minimal/src/index.ts | 7 +++- packages/minimal/test/lib/minimal.test.ts | 13 +++--- .../multiple_breadcrumbs/scenario.ts | 2 +- .../simple_breadcrumb/scenario.ts | 2 +- .../captureMessage/with_level/scenario.ts | 14 +++---- packages/node/src/client.ts | 9 +++- packages/node/src/eventbuilder.ts | 14 ++++++- packages/node/src/index.ts | 4 +- packages/node/src/integrations/console.ts | 4 +- .../src/integrations/onuncaughtexception.ts | 4 +- packages/serverless/src/awslambda.ts | 2 +- packages/tracing/src/index.bundle.ts | 4 +- packages/types/src/breadcrumb.ts | 5 ++- packages/types/src/client.ts | 17 ++++++-- packages/types/src/event.ts | 5 ++- packages/types/src/hub.ts | 9 +++- packages/types/src/index.ts | 4 +- packages/types/src/scope.ts | 12 ++++-- packages/types/src/severity.ts | 10 ++--- packages/utils/src/enums.ts | 2 - packages/utils/src/index.ts | 1 - packages/utils/src/severity.ts | 42 +++++++++++++------ packages/utils/test/severity.test.ts | 28 +++++-------- packages/vue/src/index.bundle.ts | 3 +- 35 files changed, 199 insertions(+), 119 deletions(-) delete mode 100644 packages/utils/src/enums.ts diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 4ee24f0ceadf..5116df6104d1 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,5 +1,5 @@ import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; -import { Event, EventHint, Options, Severity, Transport, TransportOptions } from '@sentry/types'; +import { Event, EventHint, Options, Severity, SeverityLevel, Transport, TransportOptions } from '@sentry/types'; import { getGlobalObject, logger, stackParserFromOptions, supportsFetch } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; @@ -89,7 +89,12 @@ export class BrowserClient extends BaseClient { /** * @inheritDoc */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { + public eventFromMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel = 'info', + hint?: EventHint, + ): PromiseLike { return eventFromMessage( stackParserFromOptions(this._options), message, diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index 6ed5181eefa1..c3052c41dd48 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -1,4 +1,4 @@ -import { Event, EventHint, Exception, Severity, StackFrame, StackParser } from '@sentry/types'; +import { Event, EventHint, Exception, Severity, SeverityLevel, StackFrame, StackParser } from '@sentry/types'; import { addExceptionMechanism, addExceptionTypeValue, @@ -150,7 +150,7 @@ export function eventFromException( const syntheticException = (hint && hint.syntheticException) || undefined; const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace); addExceptionMechanism(event); // defaults to { type: 'generic', handled: true } - event.level = Severity.Error; + event.level = 'error'; if (hint && hint.event_id) { event.event_id = hint.event_id; } @@ -164,7 +164,8 @@ export function eventFromException( export function eventFromMessage( stackParser: StackParser, message: string, - level: Severity = Severity.Info, + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel = 'info', hint?: EventHint, attachStacktrace?: boolean, ): PromiseLike { diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 704096fae520..1ee859e354d6 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -8,15 +8,15 @@ export { EventStatus, Exception, Response, + // eslint-disable-next-line deprecation/deprecation Severity, + SeverityLevel, StackFrame, Stacktrace, Thread, User, } from '@sentry/types'; -export { SeverityLevel } from '@sentry/utils'; - export { addGlobalEventProcessor, addBreadcrumb, diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index 15237f599b15..3cca50248458 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable max-lines */ import { getCurrentHub } from '@sentry/core'; -import { Event, Integration, Severity } from '@sentry/types'; +import { Event, Integration } from '@sentry/types'; import { addInstrumentationHandler, getEventDescription, @@ -9,7 +9,7 @@ import { htmlTreeAsString, parseUrl, safeJoin, - severityFromString, + severityLevelFromString, } from '@sentry/utils'; /** JSDoc */ @@ -157,7 +157,7 @@ function _consoleBreadcrumb(handlerData: { [key: string]: any }): void { arguments: handlerData.args, logger: 'console', }, - level: severityFromString(handlerData.level), + level: severityLevelFromString(handlerData.level), message: safeJoin(handlerData.args, ' '), }; @@ -230,7 +230,7 @@ function _fetchBreadcrumb(handlerData: { [key: string]: any }): void { { category: 'fetch', data: handlerData.fetchData, - level: Severity.Error, + level: 'error', type: 'http', }, { diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 70966e4f7ec5..61e56a533629 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { getCurrentHub } from '@sentry/core'; -import { Event, EventHint, Hub, Integration, Primitive, Severity, StackParser } from '@sentry/types'; +import { Event, EventHint, Hub, Integration, Primitive, StackParser } from '@sentry/types'; import { addExceptionMechanism, addInstrumentationHandler, @@ -100,7 +100,7 @@ function _installGlobalOnErrorHandler(): void { column, ); - event.level = Severity.Error; + event.level = 'error'; addMechanismAndCapture(hub, error, event, 'onerror'); }, @@ -146,7 +146,7 @@ function _installGlobalOnUnhandledRejectionHandler(): void { ? _eventFromRejectionWithPrimitive(error) : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true); - event.level = Severity.Error; + event.level = 'error'; addMechanismAndCapture(hub, error, event, 'onunhandledrejection'); return; diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 75712f62479b..8486d5e03b9c 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -9,6 +9,7 @@ import { IntegrationClass, Options, Severity, + SeverityLevel, Transport, } from '@sentry/types'; import { @@ -131,7 +132,13 @@ export abstract class BaseClient implements Client { /** * @inheritDoc */ - public captureMessage(message: string, level?: Severity, hint?: EventHint, scope?: Scope): string | undefined { + public captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel, + hint?: EventHint, + scope?: Scope, + ): string | undefined { let eventId: string | undefined = hint && hint.event_id; const promisedEvent = isPrimitive(message) @@ -685,7 +692,12 @@ export abstract class BaseClient implements Client { /** * @inheritDoc */ - public abstract eventFromMessage(_message: string, _level?: Severity, _hint?: EventHint): PromiseLike; + public abstract eventFromMessage( + _message: string, + // eslint-disable-next-line deprecation/deprecation + _level?: Severity | SeverityLevel, + _hint?: EventHint, + ): PromiseLike; } /** diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index f399c6018122..36f053429e7f 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,5 +1,5 @@ import { Session } from '@sentry/hub'; -import { Event, Options, Severity, Transport } from '@sentry/types'; +import { Event, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; import { resolvedSyncPromise } from '@sentry/utils'; import { BaseClient } from '../../src/baseclient'; @@ -38,7 +38,11 @@ export class TestClient extends BaseClient { }); } - public eventFromMessage(message: string, level: Severity = Severity.Info): PromiseLike { + public eventFromMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel = 'info', + ): PromiseLike { return resolvedSyncPromise({ message, level }); } diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index 94c8e3ea91fe..74a810fafeea 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -14,6 +14,7 @@ import { Primitive, SessionContext, Severity, + SeverityLevel, Transaction, TransactionContext, User, @@ -213,7 +214,12 @@ export class Hub implements HubInterface { /** * @inheritDoc */ - public captureMessage(message: string, level?: Severity, hint?: EventHint): string { + public captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel, + hint?: EventHint, + ): string { const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4()); let finalHint = hint; diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 09dd244734ee..1733cf7f826f 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -14,6 +14,7 @@ import { Scope as ScopeInterface, ScopeContext, Severity, + SeverityLevel, Span, Transaction, User, @@ -61,7 +62,8 @@ export class Scope implements ScopeInterface { protected _fingerprint?: string[]; /** Severity */ - protected _level?: Severity; + // eslint-disable-next-line deprecation/deprecation + protected _level?: Severity | SeverityLevel; /** Transaction Name */ protected _transactionName?: string; @@ -208,7 +210,10 @@ export class Scope implements ScopeInterface { /** * @inheritDoc */ - public setLevel(level: Severity): this { + public setLevel( + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel, + ): this { this._level = level; this._notifyScopeListeners(); return this; diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index 62f2e112f7fe..7cca748fb6f8 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -1,4 +1,4 @@ -import { Event, EventHint, Severity } from '@sentry/types'; +import { Event, EventHint } from '@sentry/types'; import { getGlobalObject } from '@sentry/utils'; import { addGlobalEventProcessor, Scope } from '../src'; @@ -85,8 +85,8 @@ describe('Scope', () => { test('setLevel', () => { const scope = new Scope(); - scope.setLevel(Severity.Critical); - expect((scope as any)._level).toEqual(Severity.Critical); + scope.setLevel('critical'); + expect((scope as any)._level).toEqual('critical'); }); test('setTransactionName', () => { @@ -137,8 +137,8 @@ describe('Scope', () => { test('chaining', () => { const scope = new Scope(); - scope.setLevel(Severity.Critical).setUser({ id: '1' }); - expect((scope as any)._level).toEqual(Severity.Critical); + scope.setLevel('critical').setUser({ id: '1' }); + expect((scope as any)._level).toEqual('critical'); expect((scope as any)._user).toEqual({ id: '1' }); }); }); @@ -202,7 +202,7 @@ describe('Scope', () => { scope.setTag('a', 'b'); scope.setUser({ id: '1' }); scope.setFingerprint(['abcd']); - scope.setLevel(Severity.Warning); + scope.setLevel('warning'); scope.setTransactionName('/abc'); scope.addBreadcrumb({ message: 'test' }); scope.setContext('os', { id: '1' }); @@ -294,11 +294,11 @@ describe('Scope', () => { test('scope level should have priority over event level', () => { expect.assertions(1); const scope = new Scope(); - scope.setLevel(Severity.Warning); + scope.setLevel('warning'); const event: Event = {}; - event.level = Severity.Critical; + event.level = 'critical'; return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.level).toEqual(Severity.Warning); + expect(processedEvent!.level).toEqual('warning'); }); }); @@ -410,7 +410,7 @@ describe('Scope', () => { scope.setContext('foo', { id: '1' }); scope.setContext('bar', { id: '2' }); scope.setUser({ id: '1337' }); - scope.setLevel(Severity.Info); + scope.setLevel('info'); scope.setFingerprint(['foo']); scope.setRequestSession({ status: 'ok' }); }); @@ -458,7 +458,7 @@ describe('Scope', () => { localScope.setContext('bar', { id: '3' }); localScope.setContext('baz', { id: '4' }); localScope.setUser({ id: '42' }); - localScope.setLevel(Severity.Warning); + localScope.setLevel('warning'); localScope.setFingerprint(['bar']); (localScope as any)._requestSession = { status: 'ok' }; diff --git a/packages/integrations/src/captureconsole.ts b/packages/integrations/src/captureconsole.ts index 7224df50f286..7243520c0661 100644 --- a/packages/integrations/src/captureconsole.ts +++ b/packages/integrations/src/captureconsole.ts @@ -1,5 +1,5 @@ import { EventProcessor, Hub, Integration } from '@sentry/types'; -import { CONSOLE_LEVELS, fill, getGlobalObject, safeJoin, severityFromString } from '@sentry/utils'; +import { CONSOLE_LEVELS, fill, getGlobalObject, safeJoin, severityLevelFromString } from '@sentry/utils'; const global = getGlobalObject(); @@ -48,7 +48,7 @@ export class CaptureConsole implements Integration { if (hub.getIntegration(CaptureConsole)) { hub.withScope(scope => { - scope.setLevel(severityFromString(level)); + scope.setLevel(severityLevelFromString(level)); scope.setExtra('arguments', args); scope.addEventProcessor(event => { event.logger = 'console'; diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 00a1cdd91d44..7cb0271786ab 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -8,6 +8,7 @@ import { Extras, Primitive, Severity, + SeverityLevel, Transaction, TransactionContext, User, @@ -52,7 +53,11 @@ export function captureException(exception: any, captureContext?: CaptureContext * @param Severity Define the level of the message. * @returns The generated eventId. */ -export function captureMessage(message: string, captureContext?: CaptureContext | Severity): string { +export function captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + captureContext?: CaptureContext | Severity | SeverityLevel, +): string { const syntheticException = new Error(message); // This is necessary to provide explicit scopes upgrade, without changing the original diff --git a/packages/minimal/test/lib/minimal.test.ts b/packages/minimal/test/lib/minimal.test.ts index 911c19ad1f68..48a117cd5c5d 100644 --- a/packages/minimal/test/lib/minimal.test.ts +++ b/packages/minimal/test/lib/minimal.test.ts @@ -1,5 +1,4 @@ import { getCurrentHub, getHubFromCarrier, Scope } from '@sentry/hub'; -import { Severity } from '@sentry/types'; import { _callOnClient, @@ -165,8 +164,8 @@ describe('Minimal', () => { const client: any = new TestClient({}); const scope = getCurrentHub().pushScope(); getCurrentHub().bindClient(client); - scope.setLevel(Severity.Warning); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual(Severity.Warning); + scope.setLevel('warning'); + expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); }); }); @@ -245,16 +244,16 @@ describe('Minimal', () => { test('withScope', () => { withScope(scope => { - scope.setLevel(Severity.Warning); + scope.setLevel('warning'); scope.setFingerprint(['1']); withScope(scope2 => { - scope2.setLevel(Severity.Info); + scope2.setLevel('info'); scope2.setFingerprint(['2']); withScope(scope3 => { scope3.clear(); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual(Severity.Warning); + expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['1']); - expect(global.__SENTRY__.hub._stack[2].scope._level).toEqual(Severity.Info); + expect(global.__SENTRY__.hub._stack[2].scope._level).toEqual('info'); expect(global.__SENTRY__.hub._stack[2].scope._fingerprint).toEqual(['2']); expect(global.__SENTRY__.hub._stack[3].scope._level).toBeUndefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/scenario.ts b/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/scenario.ts index a94acf718b4b..993049500b08 100644 --- a/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/scenario.ts +++ b/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/scenario.ts @@ -8,7 +8,7 @@ Sentry.init({ Sentry.addBreadcrumb({ category: 'foo', message: 'bar', - level: Sentry.Severity.Critical, + level: 'critical', }); Sentry.addBreadcrumb({ diff --git a/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/scenario.ts b/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/scenario.ts index 108b79c26963..a31b33c68d54 100644 --- a/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/scenario.ts +++ b/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/scenario.ts @@ -8,7 +8,7 @@ Sentry.init({ Sentry.addBreadcrumb({ category: 'foo', message: 'bar', - level: Sentry.Severity.Critical, + level: 'critical', }); Sentry.captureMessage('test_simple'); diff --git a/packages/node-integration-tests/suites/public-api/captureMessage/with_level/scenario.ts b/packages/node-integration-tests/suites/public-api/captureMessage/with_level/scenario.ts index 61f8e2532ee6..32d46fa171fe 100644 --- a/packages/node-integration-tests/suites/public-api/captureMessage/with_level/scenario.ts +++ b/packages/node-integration-tests/suites/public-api/captureMessage/with_level/scenario.ts @@ -5,10 +5,10 @@ Sentry.init({ release: '1.0', }); -Sentry.captureMessage('debug_message', Sentry.Severity.Debug); -Sentry.captureMessage('info_message', Sentry.Severity.Info); -Sentry.captureMessage('warning_message', Sentry.Severity.Warning); -Sentry.captureMessage('error_message', Sentry.Severity.Error); -Sentry.captureMessage('fatal_message', Sentry.Severity.Fatal); -Sentry.captureMessage('critical_message', Sentry.Severity.Critical); -Sentry.captureMessage('log_message', Sentry.Severity.Log); +Sentry.captureMessage('debug_message', 'debug'); +Sentry.captureMessage('info_message', 'info'); +Sentry.captureMessage('warning_message', 'warning'); +Sentry.captureMessage('error_message', 'error'); +Sentry.captureMessage('fatal_message', 'fatal'); +Sentry.captureMessage('critical_message', 'critical'); +Sentry.captureMessage('log_message', 'log'); diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 81f808f5ef56..6c4812b65980 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,6 +1,6 @@ import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; -import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry/types'; +import { Event, EventHint, Severity, SeverityLevel, Transport, TransportOptions } from '@sentry/types'; import { logger, makeDsn, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; @@ -118,7 +118,12 @@ export class NodeClient extends BaseClient { /** * @inheritDoc */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { + public eventFromMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel = 'info', + hint?: EventHint, + ): PromiseLike { return resolvedSyncPromise( eventFromMessage(stackParserFromOptions(this._options), message, level, hint, this._options.attachStacktrace), ); diff --git a/packages/node/src/eventbuilder.ts b/packages/node/src/eventbuilder.ts index e0b6b16261f0..eead089793a0 100644 --- a/packages/node/src/eventbuilder.ts +++ b/packages/node/src/eventbuilder.ts @@ -1,5 +1,14 @@ import { getCurrentHub } from '@sentry/hub'; -import { Event, EventHint, Exception, Mechanism, Severity, StackFrame, StackParser } from '@sentry/types'; +import { + Event, + EventHint, + Exception, + Mechanism, + Severity, + SeverityLevel, + StackFrame, + StackParser, +} from '@sentry/types'; import { addExceptionMechanism, addExceptionTypeValue, @@ -90,7 +99,8 @@ export function eventFromUnknownInput(stackParser: StackParser, exception: unkno export function eventFromMessage( stackParser: StackParser, message: string, - level: Severity = Severity.Info, + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel = 'info', hint?: EventHint, attachStacktrace?: boolean, ): Event { diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index d6a924a04c2e..cb83bd07cdcf 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -8,15 +8,15 @@ export { EventStatus, Exception, Response, + // eslint-disable-next-line deprecation/deprecation Severity, + SeverityLevel, StackFrame, Stacktrace, Thread, User, } from '@sentry/types'; -export { SeverityLevel } from '@sentry/utils'; - export { addGlobalEventProcessor, addBreadcrumb, diff --git a/packages/node/src/integrations/console.ts b/packages/node/src/integrations/console.ts index a9542837fbcc..9b032c75cced 100644 --- a/packages/node/src/integrations/console.ts +++ b/packages/node/src/integrations/console.ts @@ -1,6 +1,6 @@ import { getCurrentHub } from '@sentry/core'; import { Integration } from '@sentry/types'; -import { fill, severityFromString } from '@sentry/utils'; +import { fill, severityLevelFromString } from '@sentry/utils'; import * as util from 'util'; /** Console module integration */ @@ -30,7 +30,7 @@ export class Console implements Integration { */ function createConsoleWrapper(level: string): (originalConsoleMethod: () => void) => void { return function consoleWrapper(originalConsoleMethod: () => void): () => void { - const sentryLevel = severityFromString(level); + const sentryLevel = severityLevelFromString(level); /* eslint-disable prefer-rest-params */ return function (this: typeof console): void { diff --git a/packages/node/src/integrations/onuncaughtexception.ts b/packages/node/src/integrations/onuncaughtexception.ts index 9c8d33913315..dfff26fa0675 100644 --- a/packages/node/src/integrations/onuncaughtexception.ts +++ b/packages/node/src/integrations/onuncaughtexception.ts @@ -1,5 +1,5 @@ import { getCurrentHub, Scope } from '@sentry/core'; -import { Integration, Severity } from '@sentry/types'; +import { Integration } from '@sentry/types'; import { logger } from '@sentry/utils'; import { NodeClient } from '../client'; @@ -78,7 +78,7 @@ export class OnUncaughtException implements Integration { if (hub.getIntegration(OnUncaughtException)) { hub.withScope((scope: Scope) => { - scope.setLevel(Severity.Fatal); + scope.setLevel('fatal'); hub.captureException(error, { originalException: error, data: { mechanism: { handled: false, type: 'onuncaughtexception' } }, diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index 3702ffc6a1fd..0b86f560a820 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -277,7 +277,7 @@ export function wrapHandler( timeoutWarningTimer = setTimeout(() => { withScope(scope => { scope.setTag('timeout', humanReadableTimeout); - captureMessage(`Possible function timeout: ${context.functionName}`, Sentry.Severity.Warning); + captureMessage(`Possible function timeout: ${context.functionName}`, 'warning'); }); }, timeoutWarningDelay); } diff --git a/packages/tracing/src/index.bundle.ts b/packages/tracing/src/index.bundle.ts index 3349dfbd06da..72ce4f3c19db 100644 --- a/packages/tracing/src/index.bundle.ts +++ b/packages/tracing/src/index.bundle.ts @@ -6,15 +6,15 @@ export { EventStatus, Exception, Response, + // eslint-disable-next-line deprecation/deprecation Severity, + SeverityLevel, StackFrame, Stacktrace, Thread, User, } from '@sentry/types'; -export { SeverityLevel } from '@sentry/utils'; - export { addGlobalEventProcessor, addBreadcrumb, diff --git a/packages/types/src/breadcrumb.ts b/packages/types/src/breadcrumb.ts index cab5ac68b3e1..34fe2dfcd16a 100644 --- a/packages/types/src/breadcrumb.ts +++ b/packages/types/src/breadcrumb.ts @@ -1,9 +1,10 @@ -import { Severity } from './severity'; +import { Severity, SeverityLevel } from './severity'; /** JSDoc */ export interface Breadcrumb { type?: string; - level?: Severity; + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel; event_id?: string; category?: string; message?: string; diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index e11950487fa1..c3f2a9920258 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -4,7 +4,7 @@ import { Integration, IntegrationClass } from './integration'; import { Options } from './options'; import { Scope } from './scope'; import { Session } from './session'; -import { Severity } from './severity'; +import { Severity, SeverityLevel } from './severity'; import { Transport } from './transport'; /** @@ -36,7 +36,13 @@ export interface Client { * @param scope An optional scope containing event metadata. * @returns The event id */ - captureMessage(message: string, level?: Severity, hint?: EventHint, scope?: Scope): string | undefined; + captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel, + hint?: EventHint, + scope?: Scope, + ): string | undefined; /** * Captures a manually created event and sends it to Sentry. @@ -99,7 +105,12 @@ export interface Client { eventFromException(exception: any, hint?: EventHint): PromiseLike; /** Creates an {@link Event} from primitive inputs to `captureMessage`. */ - eventFromMessage(message: string, level?: Severity, hint?: EventHint): PromiseLike; + eventFromMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel, + hint?: EventHint, + ): PromiseLike; /** Submits the event to Sentry */ sendEvent(event: Event): void; diff --git a/packages/types/src/event.ts b/packages/types/src/event.ts index 6711322baab4..7cb3047ed4d5 100644 --- a/packages/types/src/event.ts +++ b/packages/types/src/event.ts @@ -7,7 +7,7 @@ import { Primitive } from './misc'; import { Request } from './request'; import { CaptureContext } from './scope'; import { SdkInfo } from './sdkinfo'; -import { Severity } from './severity'; +import { Severity, SeverityLevel } from './severity'; import { Span } from './span'; import { Measurements } from './transaction'; import { User } from './user'; @@ -18,7 +18,8 @@ export interface Event { message?: string; timestamp?: number; start_timestamp?: number; - level?: Severity; + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel; platform?: string; logger?: string; server_name?: string; diff --git a/packages/types/src/hub.ts b/packages/types/src/hub.ts index 49452266fe9f..9a67968a4fc1 100644 --- a/packages/types/src/hub.ts +++ b/packages/types/src/hub.ts @@ -6,7 +6,7 @@ import { Integration, IntegrationClass } from './integration'; import { Primitive } from './misc'; import { Scope } from './scope'; import { Session, SessionContext } from './session'; -import { Severity } from './severity'; +import { Severity, SeverityLevel } from './severity'; import { CustomSamplingContext, Transaction, TransactionContext } from './transaction'; import { User } from './user'; @@ -87,7 +87,12 @@ export interface Hub { * @param hint May contain additional information about the original exception. * @returns The generated eventId. */ - captureMessage(message: string, level?: Severity, hint?: EventHint): string; + captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + level?: Severity | SeverityLevel, + hint?: EventHint, + ): string; /** * Captures a manually created event and sends it to Sentry. diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 20856f52aa64..b104f2e85930 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -46,8 +46,8 @@ export { SessionFlusherLike, } from './session'; -export { Severity } from './severity'; -export { SeverityLevel, SeverityLevels } from './severity'; +// eslint-disable-next-line deprecation/deprecation +export { Severity, SeverityLevel } from './severity'; export { Span, SpanContext } from './span'; export { StackFrame } from './stackframe'; export { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; diff --git a/packages/types/src/scope.ts b/packages/types/src/scope.ts index b46c47ce0759..c3ee56a2a763 100644 --- a/packages/types/src/scope.ts +++ b/packages/types/src/scope.ts @@ -4,7 +4,7 @@ import { EventProcessor } from './eventprocessor'; import { Extra, Extras } from './extra'; import { Primitive } from './misc'; import { RequestSession, Session } from './session'; -import { Severity } from './severity'; +import { Severity, SeverityLevel } from './severity'; import { Span } from './span'; import { Transaction } from './transaction'; import { User } from './user'; @@ -15,7 +15,8 @@ export type CaptureContext = Scope | Partial | ((scope: Scope) => /** JSDocs */ export interface ScopeContext { user: User; - level: Severity; + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel; extra: Extras; contexts: Contexts; tags: { [key: string]: Primitive }; @@ -79,9 +80,12 @@ export interface Scope { /** * Sets the level on the scope for future events. - * @param level string {@link Severity} + * @param level string {@link SeverityLevel} */ - setLevel(level: Severity): this; + setLevel( + // eslint-disable-next-line deprecation/deprecation + level: Severity | SeverityLevel, + ): this; /** * Sets the transaction name on the scope for future events. diff --git a/packages/types/src/severity.ts b/packages/types/src/severity.ts index 513c63c7dadb..ad96231cb013 100644 --- a/packages/types/src/severity.ts +++ b/packages/types/src/severity.ts @@ -1,5 +1,6 @@ /** - * TODO(v7): Remove this enum and replace with SeverityLevel + * @deprecated Please use a `SeverityLevel` string instead of the `Severity` enum. Acceptable values are 'fatal', + * 'critical', 'error', 'warning', 'log', 'info', and 'debug'. */ export enum Severity { /** JSDoc */ @@ -18,7 +19,6 @@ export enum Severity { Critical = 'critical', } -// TODO: in v7, these can disappear, because they now also exist in `@sentry/utils`. (Having them there rather than here -// is nice because then it enforces the idea that only types are exported from `@sentry/types`.) -export const SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'] as const; -export type SeverityLevel = typeof SeverityLevels[number]; +// Note: If this is ever changed, the `validSeverityLevels` array in `@sentry/utils` needs to be changed, also. (See +// note there for why we can't derive one from the other.) +export type SeverityLevel = 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug' | 'critical'; diff --git a/packages/utils/src/enums.ts b/packages/utils/src/enums.ts deleted file mode 100644 index 998540a6677f..000000000000 --- a/packages/utils/src/enums.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const SeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'] as const; -export type SeverityLevel = typeof SeverityLevels[number]; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index e4567790f7d3..4d33eeab55e3 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,7 +1,6 @@ export * from './async'; export * from './browser'; export * from './dsn'; -export * from './enums'; export * from './error'; export * from './global'; export * from './instrument'; diff --git a/packages/utils/src/severity.ts b/packages/utils/src/severity.ts index 034f7dcbeb99..ba2ad2822851 100644 --- a/packages/utils/src/severity.ts +++ b/packages/utils/src/severity.ts @@ -1,20 +1,36 @@ -import { Severity } from '@sentry/types'; +/* eslint-disable deprecation/deprecation */ +import { Severity, SeverityLevel } from '@sentry/types'; -import { SeverityLevel, SeverityLevels } from './enums'; +// Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either +// +// a) moving `validSeverityLevels` to `@sentry/types`, +// b) moving the`SeverityLevel` type here, or +// c) importing `validSeverityLevels` from here into `@sentry/types`. +// +// Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would +// create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the +// type, reminding anyone who changes it to change this list also, will have to do. + +export const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical']; -function isSupportedSeverity(level: string): level is Severity { - return SeverityLevels.indexOf(level as SeverityLevel) !== -1; -} /** - * Converts a string-based level into a {@link Severity}. + * Converts a string-based level into a member of the deprecated {@link Severity} enum. * - * @param level string representation of Severity + * @deprecated `severityFromString` is deprecated. Please use `severityLevelFromString` instead. + * + * @param level String representation of Severity * @returns Severity */ -export function severityFromString(level: SeverityLevel | string): Severity { - if (level === 'warn') return Severity.Warning; - if (isSupportedSeverity(level)) { - return level; - } - return Severity.Log; +export function severityFromString(level: Severity | SeverityLevel | string): Severity { + return severityLevelFromString(level) as Severity; +} + +/** + * Converts a string-based level into a `SeverityLevel`, normalizing it along the way. + * + * @param level String representation of desired `SeverityLevel`. + * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level. + */ +export function severityLevelFromString(level: SeverityLevel | string): SeverityLevel { + return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') as SeverityLevel; } diff --git a/packages/utils/test/severity.test.ts b/packages/utils/test/severity.test.ts index 7b41c92a2082..51f66e815288 100644 --- a/packages/utils/test/severity.test.ts +++ b/packages/utils/test/severity.test.ts @@ -1,23 +1,17 @@ -import { SeverityLevels } from '../src/enums'; -import { severityFromString } from '../src/severity'; +import { severityLevelFromString, validSeverityLevels } from '../src/severity'; -describe('severityFromString()', () => { - describe('normalize warn and warning', () => { - test('handles warn and warning', () => { - expect(severityFromString('warn')).toBe('warning'); - expect(severityFromString('warning')).toBe('warning'); - }); - test('handles warn and warning', () => { - expect(severityFromString('warn')).toBe('warning'); - expect(severityFromString('warning')).toBe('warning'); - }); +describe('severityLevelFromString()', () => { + test("converts 'warn' to 'warning'", () => { + expect(severityLevelFromString('warn')).toBe('warning'); }); - describe('default to log', () => { - expect(severityFromString('foo')).toBe('log'); + + test('defaults to log', () => { + expect(severityLevelFromString('foo')).toBe('log'); }); - describe('allows ', () => { - for (const level of SeverityLevels) { - expect(severityFromString(level)).toBe(level); + + test('acts as a pass-through for valid level strings', () => { + for (const level of validSeverityLevels) { + expect(severityLevelFromString(level)).toBe(level); } }); }); diff --git a/packages/vue/src/index.bundle.ts b/packages/vue/src/index.bundle.ts index 3b1c401a9af9..232ec67cd0c1 100644 --- a/packages/vue/src/index.bundle.ts +++ b/packages/vue/src/index.bundle.ts @@ -6,14 +6,13 @@ export { EventStatus, Exception, Response, + SeverityLevel, StackFrame, Stacktrace, Thread, User, } from '@sentry/types'; -export { SeverityLevel } from '@sentry/utils'; - export { BrowserClient, BrowserOptions, From 5fa71bb41d661e76199d6b506f09a18b4a1fc8ac Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 13 Apr 2022 18:49:57 -0700 Subject: [PATCH 41/94] ref(build): Turn on `isolatedModules` TS option (#4896) Note: This and https://github.com/getsentry/sentry-javascript/pull/4926 are together a (slightly updated) repeat of https://github.com/getsentry/sentry-javascript/pull/4497, to get it onto the main v7 branch. This applies [the TypeScript `isolatedModules` setting[1] to all packages in the repo, which is necessary in order for us to use any compiler other than `tsc`. (All other compilers handle each file separately, without understanding the relationships between them the way `tsc` does, so we need TS to warn us if we're doing anything which would make that a problem). It also makes the second of two code changes necessary in order to be compatible with the `isolatedModules` flag: all re-exported types and interfaces (anything that will get stripped away when compiling from TS to JS) are now exported using `export type`. This lets non-`tsc` compilers know that the exported types are eligible for stripping, in spite of the fact that said compilers can't follow the export path backwards to see the types' implementation. (The other code change, eliminating our usage of the `Severity` enum, was split off into the PR linked above.) [1] https://www.typescriptlang.org/tsconfig#isolatedModules --- packages/angular/src/index.ts | 4 +- packages/browser/src/exports.ts | 10 +-- packages/core/src/index.ts | 22 +++--- packages/hub/src/index.ts | 13 +--- packages/nextjs/src/index.server.ts | 2 +- packages/node/src/index.ts | 5 +- packages/node/src/transports/index.ts | 4 +- .../serverless/src/gcpfunction/general.ts | 2 +- packages/tracing/src/browser/index.ts | 8 +-- packages/tracing/src/index.bundle.ts | 7 +- packages/tracing/src/index.ts | 11 ++- packages/types/src/index.ts | 70 +++++++++---------- packages/typescript/tsconfig.json | 1 + packages/vue/src/index.bundle.ts | 6 +- 14 files changed, 83 insertions(+), 82 deletions(-) diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index 4b282610a16c..b6f188a35d14 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -1,7 +1,9 @@ +export type { ErrorHandlerOptions } from './errorhandler'; + export * from '@sentry/browser'; export { init } from './sdk'; -export { createErrorHandler, ErrorHandlerOptions, SentryErrorHandler } from './errorhandler'; +export { createErrorHandler, SentryErrorHandler } from './errorhandler'; export { getActiveTransaction, // TODO `instrumentAngularRouting` is just an alias for `routingInstrumentation`; deprecate the latter at some point diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 1ee859e354d6..1af8a7d8aaf5 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -1,4 +1,4 @@ -export { +export type { Breadcrumb, BreadcrumbHint, Request, @@ -17,6 +17,9 @@ export { User, } from '@sentry/types'; +export type { BrowserOptions } from './client'; +export type { ReportDialogOptions } from './helpers'; + export { addGlobalEventProcessor, addBreadcrumb, @@ -41,8 +44,7 @@ export { withScope, } from '@sentry/core'; -export { BrowserClient, BrowserOptions } from './client'; - +export { BrowserClient } from './client'; export { defaultStackParsers, chromeStackParser, @@ -51,6 +53,6 @@ export { opera11StackParser, winjsStackParser, } from './stack-parsers'; -export { injectReportDialog, ReportDialogOptions } from './helpers'; +export { injectReportDialog } from './helpers'; export { defaultIntegrations, forceLoad, init, lastEventId, onLoad, showReportDialog, flush, close, wrap } from './sdk'; export { SDK_NAME } from './version'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e4143f098e4a..ccf2aa519775 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,3 +1,13 @@ +export type { APIDetails } from './api'; +export type { ClientClass } from './sdk'; +export type { + BaseTransportOptions, + NewTransport, + TransportMakeRequestResponse, + TransportRequest, + TransportRequestExecutor, +} from './transports/base'; + export { addBreadcrumb, captureException, @@ -15,7 +25,6 @@ export { } from '@sentry/minimal'; export { addGlobalEventProcessor, getCurrentHub, getHubFromCarrier, Hub, makeMain, Scope, Session } from '@sentry/hub'; export { - APIDetails, getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth, getRequestHeaders, @@ -24,16 +33,9 @@ export { } from './api'; export { BaseClient } from './baseclient'; export { eventToSentryRequest, sessionToSentryRequest } from './request'; -export { initAndBind, ClientClass } from './sdk'; +export { initAndBind } from './sdk'; export { NoopTransport } from './transports/noop'; -export { - BaseTransportOptions, - createTransport, - NewTransport, - TransportMakeRequestResponse, - TransportRequest, - TransportRequestExecutor, -} from './transports/base'; +export { createTransport } from './transports/base'; export { SDK_VERSION } from './version'; import * as Integrations from './integrations'; diff --git a/packages/hub/src/index.ts b/packages/hub/src/index.ts index 3d3b97fa239b..16c99ec7bc89 100644 --- a/packages/hub/src/index.ts +++ b/packages/hub/src/index.ts @@ -1,13 +1,6 @@ +export type { Carrier, Layer } from './hub'; + export { addGlobalEventProcessor, Scope } from './scope'; export { Session } from './session'; export { SessionFlusher } from './sessionflusher'; -export { - getCurrentHub, - getHubFromCarrier, - getMainCarrier, - Hub, - makeMain, - setHubOnCarrier, - Carrier, - Layer, -} from './hub'; +export { getCurrentHub, getHubFromCarrier, getMainCarrier, Hub, makeMain, setHubOnCarrier } from './hub'; diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index a57ee89443a5..35ef814d97cd 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -135,8 +135,8 @@ function filterTransactions(event: Event): Event | null { return event.type === 'transaction' && event.transaction === '/404' ? null : event; } +export type { SentryWebpackPluginOptions } from './config/types'; export { withSentryConfig } from './config'; -export { SentryWebpackPluginOptions } from './config/types'; export { withSentry } from './utils/withSentry'; // Wrap various server methods to enable error monitoring and tracing. (Note: This only happens for non-Vercel diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index cb83bd07cdcf..0e8febd8a92a 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -1,4 +1,4 @@ -export { +export type { Breadcrumb, BreadcrumbHint, Request, @@ -17,6 +17,8 @@ export { User, } from '@sentry/types'; +export type { NodeOptions } from './types'; + export { addGlobalEventProcessor, addBreadcrumb, @@ -41,7 +43,6 @@ export { withScope, } from '@sentry/core'; -export { NodeOptions } from './types'; export { NodeClient } from './client'; export { defaultIntegrations, init, lastEventId, flush, close, getSentryRelease } from './sdk'; export { deepReadDirSync } from './utils'; diff --git a/packages/node/src/transports/index.ts b/packages/node/src/transports/index.ts index 2cabeee08d5f..958562933321 100644 --- a/packages/node/src/transports/index.ts +++ b/packages/node/src/transports/index.ts @@ -1,4 +1,6 @@ +export type { NodeTransportOptions } from './new'; + export { BaseTransport } from './base'; export { HTTPTransport } from './http'; export { HTTPSTransport } from './https'; -export { makeNodeTransport, NodeTransportOptions } from './new'; +export { makeNodeTransport } from './new'; diff --git a/packages/serverless/src/gcpfunction/general.ts b/packages/serverless/src/gcpfunction/general.ts index becad86b5b0f..4ba794958ec4 100644 --- a/packages/serverless/src/gcpfunction/general.ts +++ b/packages/serverless/src/gcpfunction/general.ts @@ -62,4 +62,4 @@ export function configureScopeWithContext(scope: Scope, context: Context): void scope.setContext('gcp.function.context', { ...context } as SentryContext); } -export { Request, Response }; +export type { Request, Response }; diff --git a/packages/tracing/src/browser/index.ts b/packages/tracing/src/browser/index.ts index dd022fe2b8ec..2f7a3fe0d522 100644 --- a/packages/tracing/src/browser/index.ts +++ b/packages/tracing/src/browser/index.ts @@ -1,6 +1,4 @@ +export type { RequestInstrumentationOptions } from './request'; + export { BrowserTracing } from './browsertracing'; -export { - instrumentOutgoingRequests, - RequestInstrumentationOptions, - defaultRequestInstrumentationOptions, -} from './request'; +export { instrumentOutgoingRequests, defaultRequestInstrumentationOptions } from './request'; diff --git a/packages/tracing/src/index.bundle.ts b/packages/tracing/src/index.bundle.ts index 72ce4f3c19db..56e35e0ceaaa 100644 --- a/packages/tracing/src/index.bundle.ts +++ b/packages/tracing/src/index.bundle.ts @@ -1,4 +1,4 @@ -export { +export type { Breadcrumb, Request, SdkInfo, @@ -15,6 +15,8 @@ export { User, } from '@sentry/types'; +export type { BrowserOptions, ReportDialogOptions } from '@sentry/browser'; + export { addGlobalEventProcessor, addBreadcrumb, @@ -37,8 +39,7 @@ export { withScope, } from '@sentry/browser'; -export { BrowserOptions } from '@sentry/browser'; -export { BrowserClient, ReportDialogOptions } from '@sentry/browser'; +export { BrowserClient } from '@sentry/browser'; export { defaultIntegrations, forceLoad, diff --git a/packages/tracing/src/index.ts b/packages/tracing/src/index.ts index dcfea00f422a..0085ad5f6b0a 100644 --- a/packages/tracing/src/index.ts +++ b/packages/tracing/src/index.ts @@ -1,6 +1,9 @@ import { addExtensionMethods } from './hubextensions'; import * as Integrations from './integrations'; +export type { RequestInstrumentationOptions } from './browser'; +export type { SpanStatusType } from './span'; + export { Integrations }; // This is already exported as part of `Integrations` above (and for the moment will remain so for @@ -21,15 +24,11 @@ export { Integrations }; // For an example of of the new usage of BrowserTracing, see @sentry/nextjs index.client.ts export { BrowserTracing } from './browser'; -export { Span, SpanStatusType, spanStatusfromHttpCode } from './span'; +export { Span, spanStatusfromHttpCode } from './span'; // eslint-disable-next-line deprecation/deprecation export { SpanStatus } from './spanstatus'; export { Transaction } from './transaction'; -export { - instrumentOutgoingRequests, - RequestInstrumentationOptions, - defaultRequestInstrumentationOptions, -} from './browser'; +export { instrumentOutgoingRequests, defaultRequestInstrumentationOptions } from './browser'; export { IdleTransaction } from './idletransaction'; export { startIdleTransaction } from './hubextensions'; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index b104f2e85930..84430c1d3976 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,10 +1,10 @@ -export { Breadcrumb, BreadcrumbHint } from './breadcrumb'; -export { Client } from './client'; -export { ClientReport } from './clientreport'; -export { Context, Contexts } from './context'; -export { DsnComponents, DsnLike, DsnProtocol } from './dsn'; -export { DebugImage, DebugImageType, DebugMeta } from './debugMeta'; -export { +export type { Breadcrumb, BreadcrumbHint } from './breadcrumb'; +export type { Client } from './client'; +export type { ClientReport } from './clientreport'; +export type { Context, Contexts } from './context'; +export type { DsnComponents, DsnLike, DsnProtocol } from './dsn'; +export type { DebugImage, DebugImageType, DebugMeta } from './debugMeta'; +export type { AttachmentItem, BaseEnvelopeHeaders, BaseEnvelopeItemHeaders, @@ -17,25 +17,25 @@ export { SessionItem, UserFeedbackItem, } from './envelope'; -export { ExtendedError } from './error'; -export { Event, EventHint } from './event'; -export { EventStatus } from './eventstatus'; -export { EventProcessor } from './eventprocessor'; -export { Exception } from './exception'; -export { Extra, Extras } from './extra'; -export { Hub } from './hub'; -export { Integration, IntegrationClass } from './integration'; -export { Mechanism } from './mechanism'; -export { ExtractedNodeRequestData, Primitive, WorkerLocation } from './misc'; -export { Options } from './options'; -export { Package } from './package'; -export { QueryParams, Request, SentryRequest, SentryRequestType } from './request'; -export { Response } from './response'; -export { Runtime } from './runtime'; -export { CaptureContext, Scope, ScopeContext } from './scope'; -export { SdkInfo } from './sdkinfo'; -export { SdkMetadata } from './sdkmetadata'; -export { +export type { ExtendedError } from './error'; +export type { Event, EventHint } from './event'; +export type { EventStatus } from './eventstatus'; +export type { EventProcessor } from './eventprocessor'; +export type { Exception } from './exception'; +export type { Extra, Extras } from './extra'; +export type { Hub } from './hub'; +export type { Integration, IntegrationClass } from './integration'; +export type { Mechanism } from './mechanism'; +export type { ExtractedNodeRequestData, Primitive, WorkerLocation } from './misc'; +export type { Options } from './options'; +export type { Package } from './package'; +export type { QueryParams, Request, SentryRequest, SentryRequestType } from './request'; +export type { Response } from './response'; +export type { Runtime } from './runtime'; +export type { CaptureContext, Scope, ScopeContext } from './scope'; +export type { SdkInfo } from './sdkinfo'; +export type { SdkMetadata } from './sdkmetadata'; +export type { SessionAggregates, AggregationCounts, Session, @@ -47,11 +47,11 @@ export { } from './session'; // eslint-disable-next-line deprecation/deprecation -export { Severity, SeverityLevel } from './severity'; -export { Span, SpanContext } from './span'; -export { StackFrame } from './stackframe'; -export { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; -export { +export type { Severity, SeverityLevel } from './severity'; +export type { Span, SpanContext } from './span'; +export type { StackFrame } from './stackframe'; +export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; +export type { CustomSamplingContext, Measurements, SamplingContext, @@ -61,7 +61,7 @@ export { TransactionMetadata, TransactionSamplingMethod, } from './transaction'; -export { Thread } from './thread'; -export { Outcome, Transport, TransportOptions, TransportClass } from './transport'; -export { User, UserFeedback } from './user'; -export { WrappedFunction } from './wrappedfunction'; +export type { Thread } from './thread'; +export type { Outcome, Transport, TransportOptions, TransportClass } from './transport'; +export type { User, UserFeedback } from './user'; +export type { WrappedFunction } from './wrappedfunction'; diff --git a/packages/typescript/tsconfig.json b/packages/typescript/tsconfig.json index d6858094b969..3a427cc596c9 100644 --- a/packages/typescript/tsconfig.json +++ b/packages/typescript/tsconfig.json @@ -6,6 +6,7 @@ "downlevelIteration": true, "importHelpers": true, "inlineSources": true, + "isolatedModules": true, "lib": ["es6", "dom"], // "module": "commonjs", // implied by "target" : "es5" "moduleResolution": "node", diff --git a/packages/vue/src/index.bundle.ts b/packages/vue/src/index.bundle.ts index 232ec67cd0c1..c2b744280372 100644 --- a/packages/vue/src/index.bundle.ts +++ b/packages/vue/src/index.bundle.ts @@ -1,4 +1,4 @@ -export { +export type { Breadcrumb, Request, SdkInfo, @@ -13,9 +13,10 @@ export { User, } from '@sentry/types'; +export type { BrowserOptions, ReportDialogOptions } from '@sentry/browser'; + export { BrowserClient, - BrowserOptions, defaultIntegrations, forceLoad, lastEventId, @@ -24,7 +25,6 @@ export { flush, close, wrap, - ReportDialogOptions, addGlobalEventProcessor, addBreadcrumb, captureException, From 96d1e0599f2579d2f1ee08373f5e9fd1dfb5e027 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 13 Apr 2022 18:55:43 -0700 Subject: [PATCH 42/94] chore(types): Update `@types/jest` (#4929) This updates `@types/jest` to the latest version, a change which was missed in the recent jest update. --- package.json | 2 +- yarn.lock | 67 +++++++++++++++------------------------------------- 2 files changed, 20 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 7075a4f5f6fd..bf91547479aa 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@size-limit/preset-small-lib": "^4.5.5", "@strictsoftware/typedoc-plugin-monorepo": "^0.3.1", "@types/chai": "^4.1.3", - "@types/jest": "^24.0.11", + "@types/jest": "^27.4.1", "@types/jsdom": "^16.2.3", "@types/mocha": "^5.2.0", "@types/node": "~10.17.0", diff --git a/yarn.lock b/yarn.lock index 7a8d5c41fb37..482f2369ee5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4043,12 +4043,13 @@ "@types/puppeteer" "*" jest-environment-node ">=24 <=26" -"@types/jest@^24.0.11": - version "24.9.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" - integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== +"@types/jest@^27.4.1": + version "27.4.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" + integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== dependencies: - jest-diff "^24.3.0" + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" "@types/jquery@*": version "3.5.5" @@ -5001,7 +5002,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.0.0, ansi-regex@^4.1.0: +ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -9192,11 +9193,6 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== - diff-sequences@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" @@ -13998,16 +13994,6 @@ jest-dev-server@^4.4.0: tree-kill "^1.2.2" wait-on "^3.3.0" -jest-diff@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - jest-diff@^27.2.5, jest-diff@^27.4.2: version "27.4.2" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" @@ -14092,11 +14078,6 @@ jest-environment-puppeteer@^4.4.0: jest-dev-server "^4.4.0" merge-deep "^3.0.2" -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - jest-get-type@^27.0.6, jest-get-type@^27.4.0: version "27.4.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" @@ -14187,6 +14168,16 @@ jest-matcher-utils@=27.2.5: jest-get-type "^27.0.6" pretty-format "^27.2.5" +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + jest-matcher-utils@^27.2.5: version "27.4.2" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" @@ -14197,16 +14188,6 @@ jest-matcher-utils@^27.2.5: jest-get-type "^27.4.0" pretty-format "^27.4.2" -jest-matcher-utils@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - jest-message-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" @@ -18423,17 +18404,7 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== - dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" - -pretty-format@^27.0.2, pretty-format@^27.5.1: +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -18918,7 +18889,7 @@ react-error-boundary@^3.1.0: dependencies: "@babel/runtime" "^7.12.5" -react-is@16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: +react-is@16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== From 71d1abaeb199a3bc2dff3c919bbc5d7947f4a446 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 14 Apr 2022 13:12:36 +0200 Subject: [PATCH 43/94] ref(client): Inject Transports into Client (#4921) Changes the way we initialize Transports. Previously, the Transport was initialized within the Client constructor (by calling setupTransport()). Change this so that the Transport is initialized beforehand and then injected into the client. This is currently (i.e. with this PR) happening via two additional arguments in the Client class constructors. The reason for two arguments is that we're still using both, the old `Transport` classes and the `NewTransport` interface. In the future, `NewTransport` will replace `Transport` and (once the old Transport is removed) the transport is then passed into the Client constructor as a property of the options object. * add the injection logic * initialize the transports in Browser and Node and pass them to the `Browser/NodeClient` initialization * add client-external transport setup functions (extracted from setupTransport()) * add basic tests for these transport setup functions * delete the client-internal setupTransport methods * fixe a bunch of tests that are initializing clients --- packages/browser/src/client.ts | 47 +--- packages/browser/src/sdk.ts | 4 +- packages/browser/src/transports/index.ts | 2 + packages/browser/src/transports/setup.ts | 68 +++++ packages/browser/test/unit/index.test.ts | 97 ++++--- .../unit/integrations/linkederrors.test.ts | 10 +- .../test/unit/transports/setup.test.ts | 98 +++++++ packages/core/src/baseclient.ts | 25 +- packages/core/src/sdk.ts | 19 +- packages/core/src/transports/base.ts | 9 - packages/core/test/lib/base.test.ts | 248 +++++++++++------- packages/core/test/lib/sdk.test.ts | 20 +- packages/core/test/mocks/client.ts | 39 +-- packages/node/src/client.ts | 52 +--- packages/node/src/sdk.ts | 4 +- packages/node/src/transports/index.ts | 1 + packages/node/src/transports/setup.ts | 52 ++++ packages/node/test/client.test.ts | 39 ++- packages/node/test/handlers.test.ts | 31 ++- packages/node/test/index.test.ts | 244 +++++++++-------- packages/node/test/integrations/http.test.ts | 37 ++- .../test/integrations/linkederrors.test.ts | 16 +- packages/node/test/transports/setup.test.ts | 61 +++++ .../test/browser/backgroundtab.test.ts | 4 +- .../test/browser/browsertracing.test.ts | 10 +- packages/tracing/test/browser/request.test.ts | 4 +- packages/tracing/test/errors.test.ts | 4 +- packages/tracing/test/hub.test.ts | 132 ++++++---- packages/tracing/test/idletransaction.test.ts | 3 +- packages/tracing/test/span.test.ts | 24 +- 30 files changed, 889 insertions(+), 515 deletions(-) create mode 100644 packages/browser/src/transports/setup.ts create mode 100644 packages/browser/test/unit/transports/setup.test.ts create mode 100644 packages/node/src/transports/setup.ts create mode 100644 packages/node/test/transports/setup.test.ts diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 5116df6104d1..8666eaebe8d5 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,12 +1,11 @@ -import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; -import { Event, EventHint, Options, Severity, SeverityLevel, Transport, TransportOptions } from '@sentry/types'; -import { getGlobalObject, logger, stackParserFromOptions, supportsFetch } from '@sentry/utils'; +import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; +import { Event, EventHint, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { getGlobalObject, logger, stackParserFromOptions } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; import { injectReportDialog, ReportDialogOptions } from './helpers'; import { Breadcrumbs } from './integrations'; -import { FetchTransport, makeNewFetchTransport, makeNewXHRTransport, XHRTransport } from './transports'; /** * Configuration options for the Sentry Browser SDK. @@ -40,7 +39,7 @@ export class BrowserClient extends BaseClient { * * @param options Configuration options for this SDK. */ - public constructor(options: BrowserOptions = {}) { + public constructor(options: BrowserOptions = {}, transport: Transport, newTransport?: NewTransport) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.browser', @@ -53,7 +52,7 @@ export class BrowserClient extends BaseClient { version: SDK_VERSION, }; - super(options); + super(options, transport, newTransport); } /** @@ -122,40 +121,4 @@ export class BrowserClient extends BaseClient { } super._sendEvent(event); } - - /** - * @inheritDoc - */ - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } - - const transportOptions: TransportOptions = { - ...this._options.transportOptions, - dsn: this._options.dsn, - tunnel: this._options.tunnel, - sendClientReports: this._options.sendClientReports, - _metadata: this._options._metadata, - }; - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - if (supportsFetch()) { - const requestOptions: RequestInit = { ...transportOptions.fetchParameters }; - this._newTransport = makeNewFetchTransport({ requestOptions, url }); - return new FetchTransport(transportOptions); - } - - this._newTransport = makeNewXHRTransport({ - url, - headers: transportOptions.headers, - }); - return new XHRTransport(transportOptions); - } } diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 60c53b364e9c..94ec87cb4279 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -7,6 +7,7 @@ import { IS_DEBUG_BUILD } from './flags'; import { ReportDialogOptions, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, LinkedErrors, TryCatch, UserAgent } from './integrations'; import { defaultStackParsers } from './stack-parsers'; +import { setupBrowserTransport } from './transports/setup'; export const defaultIntegrations = [ new CoreIntegrations.InboundFilters(), @@ -97,7 +98,8 @@ export function init(options: BrowserOptions = {}): void { options.stackParser = defaultStackParsers; } - initAndBind(BrowserClient, options); + const { transport, newTransport } = setupBrowserTransport(options); + initAndBind(BrowserClient, options, transport, newTransport); if (options.autoSessionTracking) { startSessionTracking(); diff --git a/packages/browser/src/transports/index.ts b/packages/browser/src/transports/index.ts index 287e14e0ac50..31871a76d01c 100644 --- a/packages/browser/src/transports/index.ts +++ b/packages/browser/src/transports/index.ts @@ -4,3 +4,5 @@ export { XHRTransport } from './xhr'; export { makeNewFetchTransport } from './new-fetch'; export { makeNewXHRTransport } from './new-xhr'; + +export { setupBrowserTransport } from './setup'; diff --git a/packages/browser/src/transports/setup.ts b/packages/browser/src/transports/setup.ts new file mode 100644 index 000000000000..0af6aad90676 --- /dev/null +++ b/packages/browser/src/transports/setup.ts @@ -0,0 +1,68 @@ +import { + BaseTransportOptions, + getEnvelopeEndpointWithUrlEncodedAuth, + initAPIDetails, + NewTransport, + NoopTransport, +} from '@sentry/core'; +import { Transport, TransportOptions } from '@sentry/types'; +import { supportsFetch } from '@sentry/utils'; + +import { BrowserOptions } from '../client'; +import { FetchTransport } from './fetch'; +import { makeNewFetchTransport } from './new-fetch'; +import { makeNewXHRTransport } from './new-xhr'; +import { XHRTransport } from './xhr'; + +export interface BrowserTransportOptions extends BaseTransportOptions { + // options to pass into fetch request + fetchParams: Record; + headers?: Record; + sendClientReports?: boolean; +} + +/** + * Sets up Browser transports based on the passed `options`. If available, the returned + * transport will use the fetch API. In case fetch is not supported, an XMLHttpRequest + * based transport is created. + * + * @returns an object currently still containing both, the old `Transport` and + * `NewTransport` which will eventually replace `Transport`. Once this is replaced, + * this function will return a ready to use `NewTransport`. + */ +// TODO(v7): Adjust return value when NewTransport is the default +export function setupBrowserTransport(options: BrowserOptions): { transport: Transport; newTransport?: NewTransport } { + if (!options.dsn) { + // We return the noop transport here in case there is no Dsn. + return { transport: new NoopTransport() }; + } + + const transportOptions: TransportOptions = { + ...options.transportOptions, + dsn: options.dsn, + tunnel: options.tunnel, + sendClientReports: options.sendClientReports, + _metadata: options._metadata, + }; + + const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); + const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); + + if (options.transport) { + return { transport: new options.transport(transportOptions) }; + } + + if (supportsFetch()) { + const requestOptions: RequestInit = { ...transportOptions.fetchParameters }; + const newTransport = makeNewFetchTransport({ requestOptions, url }); + const fetchTransport = new FetchTransport(transportOptions); + return { transport: fetchTransport, newTransport }; + } + + const newTransport = makeNewXHRTransport({ + url, + headers: transportOptions.headers, + }); + const transport = new XHRTransport(transportOptions); + return { transport, newTransport }; +} diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 707354fe7d1d..9371e60073c1 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -75,7 +75,7 @@ describe('SentryBrowser', () => { describe('showReportDialog', () => { describe('user', () => { const EX_USER = { email: 'test@example.com' }; - const client = new BrowserClient({ dsn }); + const client = new BrowserClient({ dsn }, new SimpleTransport({ dsn })); const reportDialogSpy = jest.spyOn(client, 'showReportDialog'); beforeEach(() => { @@ -140,30 +140,36 @@ describe('SentryBrowser', () => { it('should capture a message', done => { getCurrentHub().bindClient( - new BrowserClient({ - beforeSend: (event: Event): Event | null => { - expect(event.message).toBe('test'); - expect(event.exception).toBeUndefined(); - done(); - return event; + new BrowserClient( + { + beforeSend: (event: Event): Event | null => { + expect(event.message).toBe('test'); + expect(event.exception).toBeUndefined(); + done(); + return event; + }, + dsn, }, - dsn, - }), + new SimpleTransport({ dsn }), + ), ); captureMessage('test'); }); it('should capture an event', done => { getCurrentHub().bindClient( - new BrowserClient({ - beforeSend: (event: Event): Event | null => { - expect(event.message).toBe('event'); - expect(event.exception).toBeUndefined(); - done(); - return event; + new BrowserClient( + { + beforeSend: (event: Event): Event | null => { + expect(event.message).toBe('event'); + expect(event.exception).toBeUndefined(); + done(); + return event; + }, + dsn, }, - dsn, - }), + new SimpleTransport({ dsn }), + ), ); captureEvent({ message: 'event' }); }); @@ -171,11 +177,14 @@ describe('SentryBrowser', () => { it('should not dedupe an event on bound client', async () => { const localBeforeSend = jest.fn(); getCurrentHub().bindClient( - new BrowserClient({ - beforeSend: localBeforeSend, - dsn, - integrations: [], - }), + new BrowserClient( + { + beforeSend: localBeforeSend, + dsn, + integrations: [], + }, + new SimpleTransport({ dsn }), + ), ); captureMessage('event222'); @@ -189,11 +198,14 @@ describe('SentryBrowser', () => { it('should use inboundfilter rules of bound client', async () => { const localBeforeSend = jest.fn(); getCurrentHub().bindClient( - new BrowserClient({ - beforeSend: localBeforeSend, - dsn, - integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], - }), + new BrowserClient( + { + beforeSend: localBeforeSend, + dsn, + integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], + }, + new SimpleTransport({ dsn }), + ), ); captureMessage('capture'); @@ -248,16 +260,16 @@ describe('SentryBrowser initialization', () => { const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; - expect(sdkData.name).toBe('sentry.javascript.browser'); - expect(sdkData.packages[0].name).toBe('npm:@sentry/browser'); - expect(sdkData.packages[0].version).toBe(SDK_VERSION); - expect(sdkData.version).toBe(SDK_VERSION); + expect(sdkData?.name).toBe('sentry.javascript.browser'); + expect(sdkData?.packages[0].name).toBe('npm:@sentry/browser'); + expect(sdkData?.packages[0].version).toBe(SDK_VERSION); + expect(sdkData?.version).toBe(SDK_VERSION); }); it('should set SDK data when instantiating a client directly', () => { - const client = new BrowserClient({ dsn }); + const client = new BrowserClient({ dsn }, new SimpleTransport({ dsn })); - const sdkData = (client as any).getTransport()._api.metadata?.sdk; + const sdkData = (client.getTransport() as any)._api.metadata?.sdk; expect(sdkData.name).toBe('sentry.javascript.browser'); expect(sdkData.packages[0].name).toBe('npm:@sentry/browser'); @@ -298,15 +310,18 @@ describe('SentryBrowser initialization', () => { describe('wrap()', () => { it('should wrap and call function while capturing error', done => { getCurrentHub().bindClient( - new BrowserClient({ - beforeSend: (event: Event): Event | null => { - expect(event.exception!.values![0].type).toBe('TypeError'); - expect(event.exception!.values![0].value).toBe('mkey'); - done(); - return null; + new BrowserClient( + { + beforeSend: (event: Event): Event | null => { + expect(event.exception!.values![0].type).toBe('TypeError'); + expect(event.exception!.values![0].value).toBe('mkey'); + done(); + return null; + }, + dsn, }, - dsn, - }), + new SimpleTransport({ dsn }), + ), ); try { diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 2589487dbcac..6650877ff39b 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -4,6 +4,7 @@ import { createStackParser } from '@sentry/utils'; import { BrowserClient } from '../../../src/client'; import * as LinkedErrorsModule from '../../../src/integrations/linkederrors'; import { defaultStackParsers } from '../../../src/stack-parsers'; +import { setupBrowserTransport } from '../../../src/transports'; const parser = createStackParser(...defaultStackParsers); @@ -38,7 +39,8 @@ describe('LinkedErrors', () => { one.cause = two; const originalException = one; - const client = new BrowserClient({ stackParser: parser }); + const options = { stackParser: parser }; + const client = new BrowserClient(options, setupBrowserTransport(options).transport); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { originalException, @@ -68,7 +70,8 @@ describe('LinkedErrors', () => { one.reason = two; const originalException = one; - const client = new BrowserClient({ stackParser: parser }); + const options = { stackParser: parser }; + const client = new BrowserClient(options, setupBrowserTransport(options).transport); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { originalException, @@ -94,7 +97,8 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new BrowserClient({ stackParser: parser }); + const options = { stackParser: parser }; + const client = new BrowserClient(options, setupBrowserTransport(options).transport); const originalException = one; return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, { diff --git a/packages/browser/test/unit/transports/setup.test.ts b/packages/browser/test/unit/transports/setup.test.ts new file mode 100644 index 000000000000..2683a0619aea --- /dev/null +++ b/packages/browser/test/unit/transports/setup.test.ts @@ -0,0 +1,98 @@ +import { NoopTransport } from '@sentry/core'; + +import { + FetchTransport, + makeNewFetchTransport, + makeNewXHRTransport, + setupBrowserTransport, + XHRTransport, +} from '../../../src/transports'; +import { SimpleTransport } from '../mocks/simpletransport'; + +const DSN = 'https://username@domain/123'; + +let fetchSupported = true; + +jest.mock('@sentry/utils', () => { + const original = jest.requireActual('@sentry/utils'); + return { + ...original, + supportsFetch(): boolean { + return fetchSupported; + }, + getGlobalObject(): any { + return { + fetch: () => {}, + }; + }, + }; +}); + +jest.mock('../../../src/transports/new-fetch', () => { + const original = jest.requireActual('../../../src/transports/new-fetch'); + return { + ...original, + makeNewFetchTransport: jest.fn(() => ({ + send: () => Promise.resolve({ status: 'success' }), + flush: () => Promise.resolve(true), + })), + }; +}); + +jest.mock('../../../src/transports/new-xhr', () => { + const original = jest.requireActual('../../../src/transports/new-xhr'); + return { + ...original, + makeNewXHRTransport: jest.fn(() => ({ + send: () => Promise.resolve({ status: 'success' }), + flush: () => Promise.resolve(true), + })), + }; +}); + +describe('setupBrowserTransport', () => { + afterEach(() => jest.clearAllMocks()); + + afterAll(() => jest.resetAllMocks()); + + it('returns NoopTransport if no dsn is passed', () => { + const { transport, newTransport } = setupBrowserTransport({}); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(NoopTransport); + expect(newTransport).toBeUndefined(); + }); + + it('returns the instantiated transport passed via the options', () => { + const options = { dsn: DSN, transport: SimpleTransport }; + const { transport, newTransport } = setupBrowserTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(SimpleTransport); + expect(newTransport).toBeUndefined(); + }); + + it('returns fetchTransports if fetch is supported', () => { + const options = { dsn: DSN }; + const { transport, newTransport } = setupBrowserTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(FetchTransport); + expect(newTransport).toBeDefined(); + expect(makeNewFetchTransport).toHaveBeenCalledTimes(1); + expect(makeNewXHRTransport).toHaveBeenCalledTimes(0); + }); + + it('returns xhrTransports if fetch is not supported', () => { + fetchSupported = false; + + const options = { dsn: DSN }; + const { transport, newTransport } = setupBrowserTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(XHRTransport); + expect(newTransport).toBeDefined(); + expect(makeNewFetchTransport).toHaveBeenCalledTimes(0); + expect(makeNewXHRTransport).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 8486d5e03b9c..2888e9853f5e 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -29,12 +29,11 @@ import { uuid4, } from '@sentry/utils'; -import { initAPIDetails } from './api'; +import { APIDetails, initAPIDetails } from './api'; import { IS_DEBUG_BUILD } from './flags'; import { IntegrationIndex, setupIntegrations } from './integration'; import { createEventEnvelope, createSessionEnvelope } from './request'; import { NewTransport } from './transports/base'; -import { NoopTransport } from './transports/noop'; const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; @@ -92,8 +91,10 @@ export abstract class BaseClient implements Client { * Initializes this client instance. * * @param options Options for the client. + * @param transport The (old) Transport instance for the client to use (TODO(v7): remove) + * @param newTransport The NewTransport instance for the client to use */ - protected constructor(options: O) { + protected constructor(options: O, transport: Transport, newTransport?: NewTransport) { this._options = options; if (options.dsn) { @@ -102,7 +103,16 @@ export abstract class BaseClient implements Client { IS_DEBUG_BUILD && logger.warn('No DSN provided, client will not do anything.'); } - this._transport = this._setupTransport(); + // TODO(v7): remove old transport + this._transport = transport; + this._newTransport = newTransport; + + // TODO(v7): refactor this to keep metadata/api outside of transport. This hack is used to + // satisfy tests until we move to NewTransport where we have to revisit this. + (this._transport as unknown as { _api: Partial })._api = { + ...((this._transport as unknown as { _api: Partial })._api || {}), + metadata: options._metadata || {}, + }; } /** @@ -676,13 +686,6 @@ export abstract class BaseClient implements Client { ); } - /** - * Sets up the transport so it can be used later to send requests. - */ - protected _setupTransport(): Transport { - return new NoopTransport(); - } - /** * @inheritDoc */ diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index 381a54839a0a..97c8b349a235 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -1,11 +1,16 @@ import { getCurrentHub } from '@sentry/hub'; -import { Client, Options } from '@sentry/types'; +import { Client, Options, Transport } from '@sentry/types'; import { logger } from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; +import { NewTransport } from './transports/base'; /** A class object that can instantiate Client objects. */ -export type ClientClass = new (options: O) => F; +export type ClientClass = new ( + options: O, + transport: Transport, + newTransport?: NewTransport, +) => F; /** * Internal function to create a new SDK client instance. The client is @@ -14,7 +19,12 @@ export type ClientClass = new (options: O) * @param clientClass The client class to instantiate. * @param options Options to pass to the client. */ -export function initAndBind(clientClass: ClientClass, options: O): void { +export function initAndBind( + clientClass: ClientClass, + options: O, + transport: Transport, + newTransport?: NewTransport, +): void { if (options.debug === true) { if (IS_DEBUG_BUILD) { logger.enable(); @@ -29,6 +39,7 @@ export function initAndBind(clientClass: Cl if (scope) { scope.update(options.initialScope); } - const client = new clientClass(options); + + const client = new clientClass(options, transport, newTransport); hub.bindClient(client); } diff --git a/packages/core/src/transports/base.ts b/packages/core/src/transports/base.ts index 663a4c3c686f..787e175b9985 100644 --- a/packages/core/src/transports/base.ts +++ b/packages/core/src/transports/base.ts @@ -51,7 +51,6 @@ export type TransportResponse = { interface InternalBaseTransportOptions { bufferSize?: number; } - export interface BaseTransportOptions extends InternalBaseTransportOptions { // url to send the event // transport does not care about dsn specific - client should take care of @@ -59,14 +58,6 @@ export interface BaseTransportOptions extends InternalBaseTransportOptions { url: string; } -// TODO: Move into Browser Transport -export interface BrowserTransportOptions extends BaseTransportOptions { - // options to pass into fetch request - fetchParams: Record; - headers?: Record; - sendClientReports?: boolean; -} - export interface NewTransport { send(request: Envelope): PromiseLike; flush(timeout?: number): PromiseLike; diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 6bb72ed99f16..72c0ef63c211 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -4,7 +4,7 @@ import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import * as integrationModule from '../../src/integration'; import { NoopTransport } from '../../src/transports/noop'; -import { TestClient } from '../mocks/client'; +import { setupTestTransport, TestClient } from '../mocks/client'; import { TestIntegration } from '../mocks/integration'; import { FakeTransport } from '../mocks/transport'; @@ -67,14 +67,16 @@ describe('BaseClient', () => { test('returns the Dsn', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); expect(dsnToString(client.getDsn())).toBe(PUBLIC_DSN); }); test('allows missing Dsn', () => { expect.assertions(1); - const client = new TestClient({}); + const options = {}; + const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getDsn()).toBeUndefined(); }); @@ -82,7 +84,8 @@ describe('BaseClient', () => { test('throws with invalid Dsn', () => { expect.assertions(1); - expect(() => new TestClient({ dsn: 'abc' })).toThrow(SentryError); + const options = { dsn: 'abc' }; + expect(() => new TestClient(options, setupTestTransport(options).transport)).toThrow(SentryError); }); }); @@ -91,7 +94,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = { dsn: PUBLIC_DSN, test: true }; - const client = new TestClient(options); + const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getOptions()).toEqual(options); }); @@ -102,7 +105,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = { dsn: PUBLIC_DSN, transport: FakeTransport }; - const client = new TestClient(options); + const client = new TestClient(options, new FakeTransport()); expect(client.getTransport()).toBeInstanceOf(FakeTransport); expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); @@ -112,7 +115,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = { dsn: PUBLIC_DSN }; - const client = new TestClient(options); + const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getTransport()).toBeInstanceOf(NoopTransport); expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); @@ -123,7 +126,8 @@ describe('BaseClient', () => { test('adds a breadcrumb', () => { expect.assertions(1); - const client = new TestClient({}); + const options = {}; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -136,7 +140,8 @@ describe('BaseClient', () => { test('adds a timestamp to new breadcrumbs', () => { expect.assertions(1); - const client = new TestClient({}); + const options = {}; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -149,7 +154,8 @@ describe('BaseClient', () => { test('discards breadcrumbs beyond maxBreadcrumbs', () => { expect.assertions(2); - const client = new TestClient({ maxBreadcrumbs: 1 }); + const options = { maxBreadcrumbs: 1 }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -163,7 +169,8 @@ describe('BaseClient', () => { test('allows concurrent updates', () => { expect.assertions(1); - const client = new TestClient({}); + const options = {}; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -177,7 +184,8 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); - const client = new TestClient({ beforeBreadcrumb }); + const options = { beforeBreadcrumb }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -190,7 +198,8 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(() => ({ message: 'changed' })); - const client = new TestClient({ beforeBreadcrumb }); + const options = { beforeBreadcrumb }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -203,7 +212,8 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(() => null); - const client = new TestClient({ beforeBreadcrumb }); + const options = { beforeBreadcrumb }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -216,7 +226,8 @@ describe('BaseClient', () => { expect.assertions(2); const beforeBreadcrumb = jest.fn((breadcrumb, hint) => ({ ...breadcrumb, data: hint.data })); - const client = new TestClient({ beforeBreadcrumb }); + const options = { beforeBreadcrumb }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -229,7 +240,8 @@ describe('BaseClient', () => { describe('captureException', () => { test('captures and sends exceptions', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureException(new Error('test exception')); @@ -251,7 +263,8 @@ describe('BaseClient', () => { }); test('allows for providing explicit scope', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -278,7 +291,8 @@ describe('BaseClient', () => { }); test('allows for clearing data from existing scope if explicit one does so in a callback function', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -312,7 +326,8 @@ describe('BaseClient', () => { // already-seen check to work . Any primitive which is passed without being wrapped will be captured each time it // is encountered, so this test doesn't apply. ])("doesn't capture the same exception twice - %s", (_name: string, thrown: any) => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); expect(thrown.__sentry_captured__).toBeUndefined(); @@ -330,7 +345,8 @@ describe('BaseClient', () => { describe('captureMessage', () => { test('captures and sends messages', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureMessage('test message'); @@ -346,7 +362,8 @@ describe('BaseClient', () => { }); test('should call eventFromException if input to captureMessage is not a primitive', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const spy = jest.spyOn(TestClient.instance!, 'eventFromException'); client.captureMessage('foo'); @@ -364,7 +381,8 @@ describe('BaseClient', () => { }); test('allows for providing explicit scope', () => { - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -397,7 +415,8 @@ describe('BaseClient', () => { test('skips when disabled', () => { expect.assertions(1); - const client = new TestClient({ enabled: false, dsn: PUBLIC_DSN }); + const options = { enabled: false, dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({}, undefined, scope); @@ -408,7 +427,8 @@ describe('BaseClient', () => { test('skips without a Dsn', () => { expect.assertions(1); - const client = new TestClient({}); + const options = {}; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({}, undefined, scope); @@ -425,10 +445,11 @@ describe('BaseClient', () => { // already-seen check to work . Any primitive which is passed without being wrapped will be captured each time it // is encountered, so this test doesn't apply. ])("doesn't capture an event wrapping the same exception twice - %s", (_name: string, thrown: any) => { + const options = { dsn: PUBLIC_DSN }; // Note: this is the same test as in `describe(captureException)`, except with the exception already wrapped in a // hint and accompanying an event. Duplicated here because some methods skip `captureException` and go straight to // `captureEvent`. - const client = new TestClient({ dsn: PUBLIC_DSN }); + const client = new TestClient(options, setupTestTransport(options).transport); const event = { exception: { values: [{ type: 'Error', message: 'Will I get caught twice?' }] } }; const hint = { originalException: thrown }; @@ -448,7 +469,8 @@ describe('BaseClient', () => { test('sends an event', () => { expect.assertions(2); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -467,7 +489,8 @@ describe('BaseClient', () => { test('does not overwrite existing timestamp', () => { expect.assertions(2); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message', timestamp: 1234 }, undefined, scope); @@ -486,7 +509,8 @@ describe('BaseClient', () => { test('adds event_id from hint if available', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope); @@ -504,9 +528,10 @@ describe('BaseClient', () => { test('sets default environment to `production` if none provided', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -524,10 +549,11 @@ describe('BaseClient', () => { test('adds the configured environment', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, environment: 'env', - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -545,10 +571,11 @@ describe('BaseClient', () => { test('allows for environment to be explicitly set to falsy value', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, environment: undefined, - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -566,10 +593,11 @@ describe('BaseClient', () => { test('adds the configured release', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, release: 'v1.0.0', - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -588,7 +616,8 @@ describe('BaseClient', () => { test('adds breadcrumbs', () => { expect.assertions(4); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.addBreadcrumb({ message: 'breadcrumb' }, 100); @@ -603,7 +632,8 @@ describe('BaseClient', () => { test('limits previously saved breadcrumbs', () => { expect.assertions(2); - const client = new TestClient({ dsn: PUBLIC_DSN, maxBreadcrumbs: 1 }); + const options = { dsn: PUBLIC_DSN, maxBreadcrumbs: 1 }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); hub.addBreadcrumb({ message: '1' }); @@ -618,7 +648,8 @@ describe('BaseClient', () => { test('adds context data', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('b', 'b'); scope.setTag('a', 'a'); @@ -642,7 +673,8 @@ describe('BaseClient', () => { test('adds fingerprint', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setFingerprint(['abcd']); @@ -660,7 +692,8 @@ describe('BaseClient', () => { }); test('adds installed integrations to sdk info', () => { - const client = new TestClient({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); + const options = { dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }; + const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); client.captureEvent({ message: 'message' }); @@ -673,7 +706,8 @@ describe('BaseClient', () => { test('normalizes event with default depth of 3', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { b: { @@ -724,10 +758,11 @@ describe('BaseClient', () => { test('normalization respects `normalizeDepth` option', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, normalizeDepth: 2, - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { b: { @@ -775,10 +810,11 @@ describe('BaseClient', () => { test('skips normalization when `normalizeDepth: 0`', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, normalizeDepth: 0, - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { b: { @@ -831,7 +867,8 @@ describe('BaseClient', () => { test('normalization applies to Transaction and Span consistently', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const transaction: Event = { contexts: { trace: { @@ -905,7 +942,8 @@ describe('BaseClient', () => { expect.assertions(1); const beforeSend = jest.fn(event => event); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -916,7 +954,8 @@ describe('BaseClient', () => { expect.assertions(1); const beforeSend = jest.fn(() => ({ message: 'changed1' })); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -927,7 +966,7 @@ describe('BaseClient', () => { expect.assertions(3); const beforeSend = jest.fn(() => null); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }, setupTestTransport({ dsn: PUBLIC_DSN }).transport); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); @@ -944,8 +983,9 @@ describe('BaseClient', () => { for (const val of invalidValues) { const beforeSend = jest.fn(() => val); + const options = { dsn: PUBLIC_DSN, beforeSend }; // @ts-ignore we need to test regular-js behavior - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const client = new TestClient(options, setupTestTransport({ dsn: PUBLIC_DSN }).transport); const loggerErrorSpy = jest.spyOn(logger, 'error'); client.captureEvent({ message: 'hello' }); @@ -969,7 +1009,8 @@ describe('BaseClient', () => { }, 1); }), ); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); @@ -997,7 +1038,8 @@ describe('BaseClient', () => { }, 1); }), ); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); @@ -1025,7 +1067,8 @@ describe('BaseClient', () => { }); }), ); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); jest.runAllTimers(); @@ -1037,7 +1080,8 @@ describe('BaseClient', () => { expect.assertions(2); const beforeSend = jest.fn((event, hint) => ({ ...event, data: hint.data })); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }); + const options = { dsn: PUBLIC_DSN, beforeSend }; + const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }, { data: 'someRandomThing' }); @@ -1048,12 +1092,15 @@ describe('BaseClient', () => { test('beforeSend records dropped events', () => { expect.assertions(1); - const client = new TestClient({ - dsn: PUBLIC_DSN, - beforeSend() { - return null; + const client = new TestClient( + { + dsn: PUBLIC_DSN, + beforeSend() { + return null; + }, }, - }); + setupTestTransport({ dsn: PUBLIC_DSN }).transport, + ); const recordLostEventSpy = jest.fn(); jest.spyOn(client, 'getTransport').mockImplementationOnce( () => @@ -1070,7 +1117,7 @@ describe('BaseClient', () => { test('eventProcessor can drop the even when it returns null', () => { expect.assertions(3); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const client = new TestClient({ dsn: PUBLIC_DSN }, setupTestTransport({ dsn: PUBLIC_DSN }).transport); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); const scope = new Scope(); @@ -1086,7 +1133,8 @@ describe('BaseClient', () => { test('eventProcessor records dropped events', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const recordLostEventSpy = jest.fn(); jest.spyOn(client, 'getTransport').mockImplementationOnce( @@ -1107,7 +1155,8 @@ describe('BaseClient', () => { test('eventProcessor sends an event and logs when it crashes', () => { expect.assertions(3); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); const scope = new Scope(); @@ -1135,10 +1184,11 @@ describe('BaseClient', () => { test('records events dropped due to sampleRate', () => { expect.assertions(1); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, sampleRate: 0, - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); const recordLostEventSpy = jest.fn(); jest.spyOn(client, 'getTransport').mockImplementationOnce( @@ -1161,10 +1211,11 @@ describe('BaseClient', () => { test('setup each one of them on setupIntegration call', () => { expect.assertions(2); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, integrations: [new TestIntegration()], - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(1); @@ -1174,9 +1225,10 @@ describe('BaseClient', () => { test('skips installation if DSN is not provided', () => { expect.assertions(2); - const client = new TestClient({ + const options = { integrations: [new TestIntegration()], - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(0); @@ -1186,11 +1238,12 @@ describe('BaseClient', () => { test('skips installation if enabled is set to false', () => { expect.assertions(2); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, enabled: false, integrations: [new TestIntegration()], - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(0); @@ -1200,10 +1253,11 @@ describe('BaseClient', () => { test('skips installation if integrations are already installed', () => { expect.assertions(4); - const client = new TestClient({ + const options = { dsn: PUBLIC_DSN, integrations: [new TestIntegration()], - }); + }; + const client = new TestClient(options, setupTestTransport(options).transport); // note: not the `Client` method `setupIntegrations`, but the free-standing function which that method calls const setupIntegrationsHelper = jest.spyOn(integrationModule, 'setupIntegrations'); @@ -1226,11 +1280,14 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(5); - const client = new TestClient({ - dsn: PUBLIC_DSN, - enableSend: true, - transport: FakeTransport, - }); + const client = new TestClient( + { + dsn: PUBLIC_DSN, + enableSend: true, + transport: FakeTransport, + }, + new FakeTransport(), + ); const delay = 1; const transportInstance = client.getTransport() as FakeTransport; @@ -1252,11 +1309,14 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(5); - const client = new TestClient({ - dsn: PUBLIC_DSN, - enableSend: true, - transport: FakeTransport, - }); + const client = new TestClient( + { + dsn: PUBLIC_DSN, + enableSend: true, + transport: FakeTransport, + }, + new FakeTransport(), + ); const delay = 300; const spy = jest.spyOn(TestClient.instance!, 'eventFromMessage'); @@ -1288,11 +1348,14 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(2); - const client = new TestClient({ - dsn: PUBLIC_DSN, - enableSend: true, - transport: FakeTransport, - }); + const client = new TestClient( + { + dsn: PUBLIC_DSN, + enableSend: true, + transport: FakeTransport, + }, + new FakeTransport(), + ); const delay = 1; const transportInstance = client.getTransport() as FakeTransport; @@ -1310,7 +1373,8 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(3); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); return Promise.all([ client.flush(1).then(() => { @@ -1330,7 +1394,8 @@ describe('BaseClient', () => { test('sends sessions to the client', () => { expect.assertions(1); - const client = new TestClient({ dsn: PUBLIC_DSN }); + const options = { dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const session = new Session({ release: 'test' }); client.captureSession(session); @@ -1341,7 +1406,8 @@ describe('BaseClient', () => { test('skips when disabled', () => { expect.assertions(1); - const client = new TestClient({ enabled: false, dsn: PUBLIC_DSN }); + const options = { enabled: false, dsn: PUBLIC_DSN }; + const client = new TestClient(options, setupTestTransport(options).transport); const session = new Session({ release: 'test' }); client.captureSession(session); diff --git a/packages/core/test/lib/sdk.test.ts b/packages/core/test/lib/sdk.test.ts index 04f704d0698e..578361a97511 100644 --- a/packages/core/test/lib/sdk.test.ts +++ b/packages/core/test/lib/sdk.test.ts @@ -3,7 +3,7 @@ import { Client, Integration } from '@sentry/types'; import { installedIntegrations } from '../../src/integration'; import { initAndBind } from '../../src/sdk'; -import { TestClient } from '../mocks/client'; +import { setupTestTransport, TestClient, TestOptions } from '../mocks/client'; // eslint-disable-next-line no-var declare var global: any; @@ -55,7 +55,8 @@ describe('SDK', () => { new MockIntegration('MockIntegration 1'), new MockIntegration('MockIntegration 2'), ]; - initAndBind(TestClient, { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS }); + const options = { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS }; + initAndBind(TestClient, options, setupTestTransport(options).transport); expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); }); @@ -65,7 +66,8 @@ describe('SDK', () => { new MockIntegration('MockIntegration 1'), new MockIntegration('MockIntegration 2'), ]; - initAndBind(TestClient, { dsn: PUBLIC_DSN, defaultIntegrations: false }); + const options: TestOptions = { dsn: PUBLIC_DSN, defaultIntegrations: false }; + initAndBind(TestClient, options, setupTestTransport(options).transport); expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(0); expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(0); }); @@ -75,7 +77,8 @@ describe('SDK', () => { new MockIntegration('MockIntegration 1'), new MockIntegration('MockIntegration 2'), ]; - initAndBind(TestClient, { dsn: PUBLIC_DSN, integrations }); + const options = { dsn: PUBLIC_DSN, integrations }; + initAndBind(TestClient, options, setupTestTransport(options).transport); expect((integrations[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((integrations[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); }); @@ -89,7 +92,8 @@ describe('SDK', () => { new MockIntegration('MockIntegration 1'), new MockIntegration('MockIntegration 3'), ]; - initAndBind(TestClient, { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS, integrations }); + const options = { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS, integrations }; + initAndBind(TestClient, options, setupTestTransport(options).transport); // 'MockIntegration 1' should be overridden by the one with the same name provided through options expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(0); expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); @@ -103,12 +107,12 @@ describe('SDK', () => { new MockIntegration('MockIntegration 2'), ]; const newIntegration = new MockIntegration('MockIntegration 3'); - initAndBind(TestClient, { - // Take only the first one and add a new one to it + const options = { defaultIntegrations: DEFAULT_INTEGRATIONS, dsn: PUBLIC_DSN, integrations: (integrations: Integration[]) => integrations.slice(0, 1).concat(newIntegration), - }); + }; + initAndBind(TestClient, options, setupTestTransport(options).transport); expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((newIntegration.setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(0); diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 36f053429e7f..2a49f9fea757 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,13 +1,16 @@ import { Session } from '@sentry/hub'; -import { Event, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { Event, Integration, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; import { resolvedSyncPromise } from '@sentry/utils'; import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; +import { NewTransport } from '../../src/transports/base'; +import { NoopTransport } from '../../src/transports/noop'; export interface TestOptions extends Options { test?: boolean; mockInstallFailure?: boolean; enableSend?: boolean; + defaultIntegrations?: Integration[] | false; } export class TestClient extends BaseClient { @@ -17,8 +20,8 @@ export class TestClient extends BaseClient { public event?: Event; public session?: Session; - public constructor(options: TestOptions) { - super(options); + public constructor(options: TestOptions, transport: Transport, newTransport?: NewTransport) { + super(options, transport, newTransport); TestClient.instance = this; } @@ -59,25 +62,25 @@ export class TestClient extends BaseClient { public sendSession(session: Session): void { this.session = session; } +} - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } +export function init(options: TestOptions, transport: Transport, newTransport?: NewTransport): void { + initAndBind(TestClient, options, transport, newTransport); +} - const transportOptions = this._options.transportOptions - ? this._options.transportOptions - : { dsn: this._options.dsn }; +export function setupTestTransport(options: TestOptions): { transport: Transport; newTransport?: NewTransport } { + const noop = { transport: new NoopTransport() }; - if (this._options.transport) { - return new this._options.transport(transportOptions); - } + if (!options.dsn) { + // We return the noop transport here in case there is no Dsn. + return noop; + } + + const transportOptions = options.transportOptions ? options.transportOptions : { dsn: options.dsn }; - return super._setupTransport(); + if (options.transport) { + return { transport: new this._options.transport(transportOptions) }; } -} -export function init(options: TestOptions): void { - initAndBind(TestClient, options); + return noop; } diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 6c4812b65980..e660c6c7b421 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,11 +1,10 @@ -import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, Scope, SDK_VERSION } from '@sentry/core'; +import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; -import { Event, EventHint, Severity, SeverityLevel, Transport, TransportOptions } from '@sentry/types'; -import { logger, makeDsn, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils'; +import { Event, EventHint, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { logger, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; -import { HTTPSTransport, HTTPTransport, makeNodeTransport } from './transports'; import { NodeOptions } from './types'; /** @@ -21,7 +20,7 @@ export class NodeClient extends BaseClient { * Creates a new Node SDK instance. * @param options Configuration options for this SDK. */ - public constructor(options: NodeOptions) { + public constructor(options: NodeOptions, transport: Transport, newTransport?: NewTransport) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.node', @@ -34,7 +33,7 @@ export class NodeClient extends BaseClient { version: SDK_VERSION, }; - super(options); + super(options, transport, newTransport); } /** @@ -151,45 +150,4 @@ export class NodeClient extends BaseClient { this._sessionFlusher.incrementSessionStatusCount(); } } - - /** - * @inheritDoc - */ - protected _setupTransport(): Transport { - if (!this._options.dsn) { - // We return the noop transport here in case there is no Dsn. - return super._setupTransport(); - } - - const dsn = makeDsn(this._options.dsn); - - const transportOptions: TransportOptions = { - ...this._options.transportOptions, - ...(this._options.httpProxy && { httpProxy: this._options.httpProxy }), - ...(this._options.httpsProxy && { httpsProxy: this._options.httpsProxy }), - ...(this._options.caCerts && { caCerts: this._options.caCerts }), - dsn: this._options.dsn, - tunnel: this._options.tunnel, - _metadata: this._options._metadata, - }; - - if (this._options.transport) { - return new this._options.transport(transportOptions); - } - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - this._newTransport = makeNodeTransport({ - url, - headers: transportOptions.headers, - proxy: transportOptions.httpProxy, - caCerts: transportOptions.caCerts, - }); - - if (dsn.protocol === 'http') { - return new HTTPTransport(transportOptions); - } - return new HTTPSTransport(transportOptions); - } } diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index 095bd3114144..0b7fb9bd5671 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -8,6 +8,7 @@ import { NodeClient } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations'; import { nodeStackParser } from './stack-parser'; +import { setupNodeTransport } from './transports'; import { NodeOptions } from './types'; export const defaultIntegrations = [ @@ -130,7 +131,8 @@ export function init(options: NodeOptions = {}): void { setHubOnCarrier(carrier, getCurrentHub()); } - initAndBind(NodeClient, options); + const { transport, newTransport } = setupNodeTransport(options); + initAndBind(NodeClient, options, transport, newTransport); if (options.autoSessionTracking) { startSessionTracking(); diff --git a/packages/node/src/transports/index.ts b/packages/node/src/transports/index.ts index 958562933321..01877029269e 100644 --- a/packages/node/src/transports/index.ts +++ b/packages/node/src/transports/index.ts @@ -4,3 +4,4 @@ export { BaseTransport } from './base'; export { HTTPTransport } from './http'; export { HTTPSTransport } from './https'; export { makeNodeTransport } from './new'; +export { setupNodeTransport } from './setup'; diff --git a/packages/node/src/transports/setup.ts b/packages/node/src/transports/setup.ts new file mode 100644 index 000000000000..2cffd2d43ecd --- /dev/null +++ b/packages/node/src/transports/setup.ts @@ -0,0 +1,52 @@ +import { getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, NewTransport, NoopTransport } from '@sentry/core'; +import { Transport, TransportOptions } from '@sentry/types'; +import { makeDsn } from '@sentry/utils'; + +import { NodeOptions } from '../types'; +import { HTTPSTransport, HTTPTransport, makeNodeTransport } from '.'; + +/** + * Sets up Node transport based on the passed `options`. + * + * @returns an object currently still containing both, the old `Transport` and + * `NewTransport` which will eventually replace `Transport`. Once this is replaced, + * this function will return a ready to use `NewTransport`. + */ +// TODO(v7): Adjust return value when NewTransport is the default +export function setupNodeTransport(options: NodeOptions): { transport: Transport; newTransport?: NewTransport } { + if (!options.dsn) { + // We return the noop transport here in case there is no Dsn. + return { transport: new NoopTransport() }; + } + + const dsn = makeDsn(options.dsn); + + const transportOptions: TransportOptions = { + ...options.transportOptions, + ...(options.httpProxy && { httpProxy: options.httpProxy }), + ...(options.httpsProxy && { httpsProxy: options.httpsProxy }), + ...(options.caCerts && { caCerts: options.caCerts }), + dsn: options.dsn, + tunnel: options.tunnel, + _metadata: options._metadata, + }; + + if (options.transport) { + return { transport: new options.transport(transportOptions) }; + } + + const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); + const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); + + const newTransport = makeNodeTransport({ + url, + headers: transportOptions.headers, + proxy: transportOptions.httpProxy, + caCerts: transportOptions.caCerts, + }); + + if (dsn.protocol === 'http') { + return { transport: new HTTPTransport(transportOptions), newTransport }; + } + return { transport: new HTTPSTransport(transportOptions), newTransport }; +} diff --git a/packages/node/test/client.test.ts b/packages/node/test/client.test.ts index f18f66c716af..1cddd0e85e3f 100644 --- a/packages/node/test/client.test.ts +++ b/packages/node/test/client.test.ts @@ -1,6 +1,7 @@ import { Scope, SessionFlusher } from '@sentry/hub'; import { NodeClient } from '../src'; +import { setupNodeTransport } from '../src/transports'; const PUBLIC_DSN = 'https://username@domain/123'; @@ -14,7 +15,8 @@ describe('NodeClient', () => { describe('captureException', () => { test('when autoSessionTracking is enabled, and requestHandler is not used -> requestStatus should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const scope = new Scope(); scope.setRequestSession({ status: 'ok' }); @@ -24,7 +26,8 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('ok'); }); test('when autoSessionTracking is disabled -> requestStatus should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -38,7 +41,8 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('ok'); }); test('when autoSessionTracking is enabled + requestSession status is Crashed -> requestStatus should not be overridden', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -52,7 +56,8 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('crashed'); }); test('when autoSessionTracking is enabled + error occurs within request bounds -> requestStatus should be set to Errored', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -66,7 +71,8 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('errored'); }); test('when autoSessionTracking is enabled + error occurs outside of request bounds -> requestStatus should not be set to Errored', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -82,7 +88,8 @@ describe('NodeClient', () => { describe('captureEvent()', () => { test('If autoSessionTracking is disabled, requestSession status should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -100,7 +107,8 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception, requestSession status should be set to Errored', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -115,7 +123,8 @@ describe('NodeClient', () => { }); test('When captureEvent is called without an exception, requestSession status should not be set to Errored', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -130,7 +139,8 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception but outside of a request, then requestStatus should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -147,7 +157,8 @@ describe('NodeClient', () => { }); test('When captureEvent is called with a transaction, then requestSession status should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -161,7 +172,8 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception but requestHandler is not used, then requestSession status should not be set', () => { - client = new NodeClient({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const scope = new Scope(); scope.setRequestSession({ status: 'ok' }); @@ -180,11 +192,12 @@ describe('NodeClient', () => { describe('flush/close', () => { test('client close function disables _sessionFlusher', async () => { jest.useRealTimers(); - const client = new NodeClient({ + const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.1', - }); + }; + const client = new NodeClient(options, setupNodeTransport(options).transport); client.initSessionFlusher(); // Clearing interval is important here to ensure that the flush function later on is called by the `client.close()` // not due to the interval running every 60s diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index f0959de22132..d7d47fda053d 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -18,6 +18,7 @@ import { tracingHandler, } from '../src/handlers'; import * as SDK from '../src/sdk'; +import { setupNodeTransport } from '../src/transports'; describe('parseRequest', () => { let mockReq: { [key: string]: any }; @@ -223,7 +224,8 @@ describe('requestHandler', () => { }); it('autoSessionTracking is enabled, sets requestSession status to ok, when handling a request', () => { - client = new NodeClient({ autoSessionTracking: true, release: '1.2' }); + const options = { autoSessionTracking: true, release: '1.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -235,7 +237,8 @@ describe('requestHandler', () => { }); it('autoSessionTracking is disabled, does not set requestSession, when handling a request', () => { - client = new NodeClient({ autoSessionTracking: false, release: '1.2' }); + const options = { autoSessionTracking: false, release: '1.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -247,7 +250,8 @@ describe('requestHandler', () => { }); it('autoSessionTracking is enabled, calls _captureRequestSession, on response finish', done => { - client = new NodeClient({ autoSessionTracking: true, release: '1.2' }); + const options = { autoSessionTracking: true, release: '1.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -267,7 +271,8 @@ describe('requestHandler', () => { }); it('autoSessionTracking is disabled, does not call _captureRequestSession, on response finish', done => { - client = new NodeClient({ autoSessionTracking: false, release: '1.2' }); + const options = { autoSessionTracking: false, release: '1.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -367,7 +372,8 @@ describe('tracingHandler', () => { it('extracts request data for sampling context', () => { const tracesSampler = jest.fn(); - const hub = new Hub(new NodeClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -389,7 +395,8 @@ describe('tracingHandler', () => { }); it('puts its transaction on the scope', () => { - const hub = new Hub(new NodeClient({ tracesSampleRate: 1.0 })); + const options = { tracesSampleRate: 1.0 }; + const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -720,7 +727,8 @@ describe('errorHandler()', () => { jest.restoreAllMocks(); }); it('when autoSessionTracking is disabled, does not set requestSession status on Crash', () => { - client = new NodeClient({ autoSessionTracking: false, release: '3.3' }); + const options = { autoSessionTracking: false, release: '3.3' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -739,7 +747,8 @@ describe('errorHandler()', () => { }); it('autoSessionTracking is enabled + requestHandler is not used -> does not set requestSession status on Crash', () => { - client = new NodeClient({ autoSessionTracking: false, release: '3.3' }); + const options = { autoSessionTracking: false, release: '3.3' }; + client = new NodeClient(options, setupNodeTransport(options).transport); const scope = sentryCore.getCurrentHub().getScope(); const hub = new Hub(client); @@ -755,7 +764,8 @@ describe('errorHandler()', () => { }); it('when autoSessionTracking is enabled, should set requestSession status to Crashed when an unhandled error occurs within the bounds of a request', () => { - client = new NodeClient({ autoSessionTracking: true, release: '1.1' }); + const options = { autoSessionTracking: true, release: '1.1' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -773,7 +783,8 @@ describe('errorHandler()', () => { }); it('when autoSessionTracking is enabled, should not set requestSession status on Crash when it occurs outside the bounds of a request', () => { - client = new NodeClient({ autoSessionTracking: true, release: '2.2' }); + const options = { autoSessionTracking: true, release: '2.2' }; + client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index af12a4b35994..02eaad72b2c0 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -18,6 +18,7 @@ import { } from '../src'; import { ContextLines, LinkedErrors } from '../src/integrations'; import { nodeStackParser } from '../src/stack-parser'; +import { setupNodeTransport } from '../src/transports'; const stackParser = createStackParser(nodeStackParser); @@ -89,8 +90,7 @@ describe('SentryNode', () => { }); test('record auto breadcrumbs', done => { - const client = new NodeClient({ - stackParser, + const options = { beforeSend: (event: Event) => { // TODO: It should be 3, but we don't capture a breadcrumb // for our own captureMessage/captureException calls yet @@ -99,7 +99,9 @@ describe('SentryNode', () => { return null; }, dsn, - }); + stackParser, + }; + const client = new NodeClient(options, setupNodeTransport(options).transport); getCurrentHub().bindClient(client); addBreadcrumb({ message: 'test1' }); addBreadcrumb({ message: 'test2' }); @@ -120,22 +122,21 @@ describe('SentryNode', () => { test('capture an exception', done => { expect.assertions(6); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect(event.tags).toEqual({ test: '1' }); - expect(event.exception).not.toBeUndefined(); - expect(event.exception!.values![0]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![2]).not.toBeUndefined(); - expect(event.exception!.values![0].value).toEqual('test'); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect(event.tags).toEqual({ test: '1' }); + expect(event.exception).not.toBeUndefined(); + expect(event.exception!.values![0]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![2]).not.toBeUndefined(); + expect(event.exception!.values![0].value).toEqual('test'); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -148,22 +149,21 @@ describe('SentryNode', () => { test('capture a string exception', done => { expect.assertions(6); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect(event.tags).toEqual({ test: '1' }); - expect(event.exception).not.toBeUndefined(); - expect(event.exception!.values![0]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![2]).not.toBeUndefined(); - expect(event.exception!.values![0].value).toEqual('test string exception'); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect(event.tags).toEqual({ test: '1' }); + expect(event.exception).not.toBeUndefined(); + expect(event.exception!.values![0]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![2]).not.toBeUndefined(); + expect(event.exception!.values![0].value).toEqual('test string exception'); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -176,26 +176,25 @@ describe('SentryNode', () => { test('capture an exception with pre/post context', done => { expect.assertions(10); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect(event.tags).toEqual({ test: '1' }); - expect(event.exception).not.toBeUndefined(); - expect(event.exception!.values![0]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1].pre_context).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1].post_context).not.toBeUndefined(); - expect(event.exception!.values![0].type).toBe('Error'); - expect(event.exception!.values![0].value).toBe('test'); - expect(event.exception!.values![0].stacktrace).toBeTruthy(); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect(event.tags).toEqual({ test: '1' }); + expect(event.exception).not.toBeUndefined(); + expect(event.exception!.values![0]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1].pre_context).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1].post_context).not.toBeUndefined(); + expect(event.exception!.values![0].type).toBe('Error'); + expect(event.exception!.values![0].value).toBe('test'); + expect(event.exception!.values![0].stacktrace).toBeTruthy(); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -208,33 +207,32 @@ describe('SentryNode', () => { test('capture a linked exception with pre/post context', done => { expect.assertions(15); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - integrations: [new ContextLines(), new LinkedErrors()], - beforeSend: (event: Event) => { - expect(event.exception).not.toBeUndefined(); - expect(event.exception!.values![1]).not.toBeUndefined(); - expect(event.exception!.values![1].stacktrace!).not.toBeUndefined(); - expect(event.exception!.values![1].stacktrace!.frames![1]).not.toBeUndefined(); - expect(event.exception!.values![1].stacktrace!.frames![1].pre_context).not.toBeUndefined(); - expect(event.exception!.values![1].stacktrace!.frames![1].post_context).not.toBeUndefined(); - expect(event.exception!.values![1].type).toBe('Error'); - expect(event.exception!.values![1].value).toBe('test'); - - expect(event.exception!.values![0]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1]).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1].pre_context).not.toBeUndefined(); - expect(event.exception!.values![0].stacktrace!.frames![1].post_context).not.toBeUndefined(); - expect(event.exception!.values![0].type).toBe('Error'); - expect(event.exception!.values![0].value).toBe('cause'); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + integrations: [new ContextLines(), new LinkedErrors()], + beforeSend: (event: Event) => { + expect(event.exception).not.toBeUndefined(); + expect(event.exception!.values![1]).not.toBeUndefined(); + expect(event.exception!.values![1].stacktrace!).not.toBeUndefined(); + expect(event.exception!.values![1].stacktrace!.frames![1]).not.toBeUndefined(); + expect(event.exception!.values![1].stacktrace!.frames![1].pre_context).not.toBeUndefined(); + expect(event.exception!.values![1].stacktrace!.frames![1].post_context).not.toBeUndefined(); + expect(event.exception!.values![1].type).toBe('Error'); + expect(event.exception!.values![1].value).toBe('test'); + + expect(event.exception!.values![0]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1]).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1].pre_context).not.toBeUndefined(); + expect(event.exception!.values![0].stacktrace!.frames![1].post_context).not.toBeUndefined(); + expect(event.exception!.values![0].type).toBe('Error'); + expect(event.exception!.values![0].value).toBe('cause'); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); try { throw new Error('test'); } catch (e) { @@ -249,42 +247,40 @@ describe('SentryNode', () => { test('capture a message', done => { expect.assertions(2); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect(event.message).toBe('test'); - expect(event.exception).toBeUndefined(); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect(event.message).toBe('test'); + expect(event.exception).toBeUndefined(); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); captureMessage('test'); }); test('capture an event', done => { expect.assertions(2); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect(event.message).toBe('test event'); - expect(event.exception).toBeUndefined(); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect(event.message).toBe('test event'); + expect(event.exception).toBeUndefined(); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); captureEvent({ message: 'test event' }); }); test('capture an event in a domain', done => { const d = domain.create(); - const client = new NodeClient({ + const options = { stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test domain'); @@ -293,7 +289,8 @@ describe('SentryNode', () => { return null; }, dsn, - }); + }; + const client = new NodeClient(options, setupNodeTransport(options).transport); d.run(() => { getCurrentHub().bindClient(client); @@ -304,21 +301,19 @@ describe('SentryNode', () => { test('stacktrace order', done => { expect.assertions(1); - getCurrentHub().bindClient( - new NodeClient({ - stackParser, - beforeSend: (event: Event) => { - expect( - event.exception!.values![0].stacktrace!.frames![ - event.exception!.values![0].stacktrace!.frames!.length - 1 - ].function, - ).toEqual('testy'); - done(); - return null; - }, - dsn, - }), - ); + const options = { + stackParser, + beforeSend: (event: Event) => { + expect( + event.exception!.values![0].stacktrace!.frames![event.exception!.values![0].stacktrace!.frames!.length - 1] + .function, + ).toEqual('testy'); + done(); + return null; + }, + dsn, + }; + getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); try { // @ts-ignore allow function declarations in strict mode // eslint-disable-next-line no-inner-declarations @@ -381,7 +376,8 @@ describe('SentryNode initialization', () => { }); it('should set SDK data when instantiating a client directly', () => { - const client = new NodeClient({ dsn }); + const options = { dsn }; + const client = new NodeClient(options, setupNodeTransport(options).transport); // eslint-disable-next-line @typescript-eslint/no-explicit-any const sdkData = (client as any).getTransport()._api.metadata?.sdk; diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index bc71b994c7a5..5a05d79e3b1b 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -11,18 +11,18 @@ import * as nock from 'nock'; import { Breadcrumb } from '../../src'; import { NodeClient } from '../../src/client'; import { Http as HttpIntegration } from '../../src/integrations/http'; +import { setupNodeTransport } from '../../src/transports'; const NODE_VERSION = parseSemver(process.versions.node); describe('tracing', () => { function createTransactionOnScope() { - const hub = new Hub( - new NodeClient({ - dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', - tracesSampleRate: 1.0, - integrations: [new HttpIntegration({ tracing: true })], - }), - ); + const options = { + dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', + tracesSampleRate: 1.0, + integrations: [new HttpIntegration({ tracing: true })], + }; + const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); addExtensionMethods(); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on @@ -97,18 +97,17 @@ describe('default protocols', () => { const p = new Promise(r => { resolve = r; }); - hub.bindClient( - new NodeClient({ - dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', - integrations: [new HttpIntegration({ breadcrumbs: true })], - beforeBreadcrumb: (b: Breadcrumb) => { - if ((b.data?.url as string).includes(key)) { - resolve(b); - } - return b; - }, - }), - ); + const options = { + dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', + integrations: [new HttpIntegration({ breadcrumbs: true })], + beforeBreadcrumb: (b: Breadcrumb) => { + if ((b.data?.url as string).includes(key)) { + resolve(b); + } + return b; + }, + }; + hub.bindClient(new NodeClient(options, setupNodeTransport(options).transport)); return p; } diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 296384a5f222..2c2957bf6a69 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -4,6 +4,7 @@ import { createStackParser } from '@sentry/utils'; import { Event, NodeClient } from '../../src'; import { LinkedErrors } from '../../src/integrations/linkederrors'; import { nodeStackParser } from '../../src/stack-parser'; +import { setupNodeTransport } from '../../src/transports'; const stackParser = createStackParser(nodeStackParser); @@ -31,7 +32,8 @@ describe('LinkedErrors', () => { expect.assertions(2); const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); - const client = new NodeClient({ stackParser }); + const options = { stackParser }; + const client = new NodeClient(options, setupNodeTransport(options).transport); let event: Event | undefined; return client .eventFromException(one) @@ -54,7 +56,8 @@ describe('LinkedErrors', () => { }), ); const one = new Error('originalException'); - const client = new NodeClient({ stackParser }); + const options = { stackParser }; + const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -74,7 +77,8 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new NodeClient({ stackParser }); + const options = { stackParser }; + const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -107,7 +111,8 @@ describe('LinkedErrors', () => { one.reason = two; two.reason = three; - const client = new NodeClient({ stackParser }); + const options = { stackParser }; + const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -140,7 +145,8 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const client = new NodeClient({ stackParser }); + const options = { stackParser }; + const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { diff --git a/packages/node/test/transports/setup.test.ts b/packages/node/test/transports/setup.test.ts new file mode 100644 index 000000000000..6864ac89ea1e --- /dev/null +++ b/packages/node/test/transports/setup.test.ts @@ -0,0 +1,61 @@ +import { NoopTransport } from '@sentry/core'; +import { FakeTransport } from '@sentry/core/test/mocks/transport'; +import { HTTPSTransport, HTTPTransport, setupNodeTransport } from '@sentry/node/src/transports'; + +import { makeNodeTransport } from '../../src/transports/new'; + +jest.mock('../../src/transports/new', () => { + const original = jest.requireActual('../../src/transports/new'); + return { + ...original, + makeNodeTransport: jest.fn(() => ({ + send: () => Promise.resolve({ status: 'success' }), + flush: () => Promise.resolve(true), + })), + }; +}); + +const DSN = 'https://username@domain/123'; + +describe('setupNodeTransport', () => { + afterEach(() => jest.clearAllMocks()); + + afterAll(() => jest.resetAllMocks()); + + it('returns NoopTransport if no dsn is passed', () => { + const { transport, newTransport } = setupNodeTransport({}); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(NoopTransport); + expect(newTransport).toBeUndefined(); + }); + + it('returns the instantiated transport passed via the options', () => { + const options = { dsn: DSN, transport: FakeTransport }; + const { transport, newTransport } = setupNodeTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(FakeTransport); + expect(newTransport).toBeUndefined(); + }); + + it('returns HTTPS transport as a default', () => { + const options = { dsn: DSN }; + const { transport, newTransport } = setupNodeTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(HTTPSTransport); + expect(newTransport).toBeDefined(); + expect(makeNodeTransport).toHaveBeenCalledTimes(1); + }); + + it('returns HTTP transport if specified in the dsn', () => { + const options = { dsn: 'http://username@domain/123' }; + const { transport, newTransport } = setupNodeTransport(options); + + expect(transport).toBeDefined(); + expect(transport).toBeInstanceOf(HTTPTransport); + expect(newTransport).toBeDefined(); + expect(makeNodeTransport).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/tracing/test/browser/backgroundtab.test.ts b/packages/tracing/test/browser/backgroundtab.test.ts index e46c79695d20..440eb785a609 100644 --- a/packages/tracing/test/browser/backgroundtab.test.ts +++ b/packages/tracing/test/browser/backgroundtab.test.ts @@ -1,4 +1,5 @@ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; import { JSDOM } from 'jsdom'; @@ -13,7 +14,8 @@ describe('registerBackgroundTabDetection', () => { // @ts-ignore need to override global document global.document = dom.window.document; - hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); // If we do not add extension methods, invoking hub.startTransaction returns undefined diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index 8db3cc10e41e..510befc29064 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,4 +1,5 @@ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; import { getGlobalObject } from '@sentry/utils'; import { JSDOM } from 'jsdom'; @@ -51,7 +52,8 @@ describe('BrowserTracing', () => { let hub: Hub; beforeEach(() => { jest.useFakeTimers(); - hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); document.head.innerHTML = ''; @@ -472,7 +474,8 @@ describe('BrowserTracing', () => { getGlobalObject().location = dogParkLocation as any; const tracesSampler = jest.fn(); - hub.bindClient(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); // setting up the BrowserTracing integration automatically starts a pageload transaction createBrowserTracing(true); @@ -488,7 +491,8 @@ describe('BrowserTracing', () => { getGlobalObject().location = dogParkLocation as any; const tracesSampler = jest.fn(); - hub.bindClient(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); // setting up the BrowserTracing integration normally automatically starts a pageload transaction, but that's not // what we're testing here createBrowserTracing(true, { startTransactionOnPageLoad: false }); diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index 2ba1c906818a..a31aa10d5c8a 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -1,4 +1,5 @@ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; import * as utils from '@sentry/utils'; @@ -72,7 +73,8 @@ describe('callbacks', () => { }; beforeAll(() => { - hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); }); diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index 43583b352ef1..ca042672b595 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,4 +1,5 @@ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; import { registerErrorInstrumentation } from '../src/errors'; @@ -33,7 +34,8 @@ describe('registerErrorHandlers()', () => { let hub: Hub; beforeEach(() => { mockAddInstrumentationHandler.mockClear(); - hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); }); diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 5e4c8a806cac..045d9fa96fb1 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; import * as utilsModule from '@sentry/utils'; // for mocking import { logger } from '@sentry/utils'; @@ -32,7 +33,8 @@ describe('Hub', () => { describe('getTransaction()', () => { it('should find a transaction which has been set on the scope if sampled = true', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); transaction.sampled = true; @@ -45,7 +47,8 @@ describe('Hub', () => { }); it('should find a transaction which has been set on the scope if sampled = false', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -57,7 +60,8 @@ describe('Hub', () => { }); it("should not find an open transaction if it's not on the scope", () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -69,7 +73,8 @@ describe('Hub', () => { describe('default sample context', () => { it('should add transaction context data to default sample context', () => { const tracesSampler = jest.fn(); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transactionContext = { @@ -85,7 +90,8 @@ describe('Hub', () => { it("should add parent's sampling decision to default sample context", () => { const tracesSampler = jest.fn(); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const parentSamplingDecsion = false; @@ -103,8 +109,9 @@ describe('Hub', () => { describe('sample()', () => { it('should set sampled = false when tracing is disabled', () => { + const options = {}; // neither tracesSampleRate nor tracesSampler is defined -> tracing disabled - const hub = new Hub(new BrowserClient({})); + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -112,7 +119,8 @@ describe('Hub', () => { }); it('should set sampled = false if tracesSampleRate is 0', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 0 })); + const options = { tracesSampleRate: 0 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -120,7 +128,8 @@ describe('Hub', () => { }); it('should set sampled = true if tracesSampleRate is 1', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -128,7 +137,8 @@ describe('Hub', () => { }); it('should set sampled = true if tracesSampleRate is 1 (without global hub)', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const options = { tracesSampleRate: 1 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const transaction = hub.startTransaction({ name: 'dogpark' }); expect(transaction.sampled).toBe(true); @@ -136,7 +146,8 @@ describe('Hub', () => { it("should call tracesSampler if it's defined", () => { const tracesSampler = jest.fn(); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -145,7 +156,8 @@ describe('Hub', () => { it('should set sampled = false if tracesSampler returns 0', () => { const tracesSampler = jest.fn().mockReturnValue(0); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -155,7 +167,8 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1', () => { const tracesSampler = jest.fn().mockReturnValue(1); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -165,7 +178,8 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1 (without global hub)', () => { const tracesSampler = jest.fn().mockReturnValue(1); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const transaction = hub.startTransaction({ name: 'dogpark' }); expect(tracesSampler).toHaveBeenCalled(); @@ -175,7 +189,8 @@ describe('Hub', () => { it('should not try to override explicitly set positive sampling decision', () => { // so that the decision otherwise would be false const tracesSampler = jest.fn().mockReturnValue(0); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -185,7 +200,8 @@ describe('Hub', () => { it('should not try to override explicitly set negative sampling decision', () => { // so that the decision otherwise would be true const tracesSampler = jest.fn().mockReturnValue(1); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -195,7 +211,8 @@ describe('Hub', () => { it('should prefer tracesSampler to tracesSampleRate', () => { // make the two options do opposite things to prove precedence const tracesSampler = jest.fn().mockReturnValue(true); - const hub = new Hub(new BrowserClient({ tracesSampleRate: 0, tracesSampler })); + const options = { tracesSampleRate: 0, tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -205,7 +222,8 @@ describe('Hub', () => { it('should tolerate tracesSampler returning a boolean', () => { const tracesSampler = jest.fn().mockReturnValue(true); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -215,7 +233,8 @@ describe('Hub', () => { it('should record sampling method when sampling decision is explicitly set', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -226,7 +245,8 @@ describe('Hub', () => { it('should record sampling method and rate when sampling decision comes from tracesSampler', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -236,7 +256,8 @@ describe('Hub', () => { }); it('should record sampling method when sampling decision is inherited', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 0.1121 })); + const options = { tracesSampleRate: 0.1121 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark', parentSampled: true }); @@ -246,7 +267,8 @@ describe('Hub', () => { }); it('should record sampling method and rate when sampling decision comes from traceSampleRate', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 0.1121 })); + const options = { tracesSampleRate: 0.1121 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -258,7 +280,8 @@ describe('Hub', () => { describe('isValidSampleRate()', () => { it("should reject tracesSampleRates which aren't numbers or booleans", () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 'dogs!' as any })); + const options = { tracesSampleRate: 'dogs!' as any }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -266,7 +289,8 @@ describe('Hub', () => { }); it('should reject tracesSampleRates which are NaN', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 'dogs!' as any })); + const options = { tracesSampleRate: 'dogs!' as any }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -275,7 +299,8 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates less than 0', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: -26 })); + const options = { tracesSampleRate: -26 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -284,7 +309,8 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates greater than 1', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: 26 })); + const options = { tracesSampleRate: 26 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -293,7 +319,8 @@ describe('Hub', () => { it("should reject tracesSampler return values which aren't numbers or booleans", () => { const tracesSampler = jest.fn().mockReturnValue('dogs!'); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -302,7 +329,8 @@ describe('Hub', () => { it('should reject tracesSampler return values which are NaN', () => { const tracesSampler = jest.fn().mockReturnValue(NaN); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -312,7 +340,8 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampler return values less than 0', () => { const tracesSampler = jest.fn().mockReturnValue(-12); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -322,7 +351,8 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampler return values greater than 1', () => { const tracesSampler = jest.fn().mockReturnValue(31); - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -331,7 +361,8 @@ describe('Hub', () => { }); it('should drop transactions with sampled = false', () => { - const client = new BrowserClient({ tracesSampleRate: 0 }); + const options = { tracesSampleRate: 0 }; + const client = new BrowserClient(options, setupBrowserTransport(options).transport); jest.spyOn(client, 'captureEvent'); const hub = new Hub(client); @@ -348,7 +379,8 @@ describe('Hub', () => { describe('sampling inheritance', () => { it('should propagate sampling decision to child spans', () => { - const hub = new Hub(new BrowserClient({ tracesSampleRate: Math.random() })); + const options = { tracesSampleRate: Math.random() }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); const child = transaction.startChild({ op: 'ball.chase' }); @@ -360,13 +392,12 @@ describe('Hub', () => { testOnlyIfNodeVersionAtLeast(10)( 'should propagate positive sampling decision to child transactions in XHR header', async () => { - const hub = new Hub( - new BrowserClient({ - dsn: 'https://1231@dogs.are.great/1121', - tracesSampleRate: 1, - integrations: [new BrowserTracing()], - }), - ); + const options = { + dsn: 'https://1231@dogs.are.great/1121', + tracesSampleRate: 1, + integrations: [new BrowserTracing()], + }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -402,13 +433,12 @@ describe('Hub', () => { testOnlyIfNodeVersionAtLeast(10)( 'should propagate negative sampling decision to child transactions in XHR header', async () => { - const hub = new Hub( - new BrowserClient({ - dsn: 'https://1231@dogs.are.great/1121', - tracesSampleRate: 1, - integrations: [new BrowserTracing()], - }), - ); + const options = { + dsn: 'https://1231@dogs.are.great/1121', + tracesSampleRate: 1, + integrations: [new BrowserTracing()], + }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -453,7 +483,8 @@ describe('Hub', () => { // sample rate), so make parent's decision the opposite to prove that inheritance takes precedence over // tracesSampleRate mathRandom.mockReturnValueOnce(1); - const hub = new Hub(new BrowserClient({ tracesSampleRate: 0.5 })); + const options = { tracesSampleRate: 0.5 }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const parentSamplingDecsion = true; @@ -467,9 +498,10 @@ describe('Hub', () => { }); it("should inherit parent's negative sampling decision if tracesSampler is undefined", () => { + const options = { tracesSampleRate: 1 }; // tracesSampleRate = 1 means every transaction should end up with sampled = true, so make parent's decision the // opposite to prove that inheritance takes precedence over tracesSampleRate - const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const parentSamplingDecsion = false; @@ -488,7 +520,8 @@ describe('Hub', () => { const tracesSampler = () => true; const parentSamplingDecsion = false; - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ @@ -506,7 +539,8 @@ describe('Hub', () => { const tracesSampler = () => false; const parentSamplingDecsion = true; - const hub = new Hub(new BrowserClient({ tracesSampler })); + const options = { tracesSampler }; + const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index b60fec726c54..f2565e1c7e5f 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -14,7 +14,8 @@ export class SimpleTransport extends Transports.BaseTransport {} const dsn = 'https://123@sentry.io/42'; let hub: Hub; beforeEach(() => { - hub = new Hub(new BrowserClient({ dsn, tracesSampleRate: 1, transport: SimpleTransport })); + const options = { dsn, tracesSampleRate: 1, transport: SimpleTransport }; + hub = new Hub(new BrowserClient(options, new SimpleTransport(options))); }); describe('IdleTransaction', () => { diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index 4b0887f2dda7..fe11fbf143ee 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -1,4 +1,5 @@ import { BrowserClient } from '@sentry/browser'; +import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain, Scope } from '@sentry/hub'; import { Span, Transaction } from '../src'; @@ -9,7 +10,8 @@ describe('Span', () => { beforeEach(() => { const myScope = new Scope(); - hub = new Hub(new BrowserClient({ tracesSampleRate: 1 }), myScope); + const options = { tracesSampleRate: 1 }; + hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport), myScope); makeMain(hub); }); @@ -216,12 +218,11 @@ describe('Span', () => { }); test('maxSpans correctly limits number of spans', () => { - const _hub = new Hub( - new BrowserClient({ - _experiments: { maxSpans: 3 }, - tracesSampleRate: 1, - }), - ); + const options = { + _experiments: { maxSpans: 3 }, + tracesSampleRate: 1, + }; + const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test' }); for (let i = 0; i < 10; i++) { @@ -233,11 +234,10 @@ describe('Span', () => { }); test('no span recorder created if transaction.sampled is false', () => { - const _hub = new Hub( - new BrowserClient({ - tracesSampleRate: 1, - }), - ); + const options = { + tracesSampleRate: 1, + }; + const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test', sampled: false }); for (let i = 0; i < 10; i++) { From bf2dc7b2e6b3e55c6317fdc473c2fbd91eb86961 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 14 Apr 2022 13:54:20 +0200 Subject: [PATCH 44/94] doc(migration): Add `Backend` removal and `Transport` injection to migration docs (#4934) Add two small bullet points to the "General API changes" section, briefly explaining the removal of `Backend` and the injection of `Transport`s. The transport injection part needs to be revisited once we switch over to just using `NewTransport` as well as when we're passing the transports as `options` properties to the client constructors. --- MIGRATION.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 4e5de472634d..f6017755e902 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -91,6 +91,19 @@ For our efforts to reduce bundle size of the SDK we had to remove and refactor p - Remove deprecated `Status`, `SessionStatus`, and `RequestSessionStatus` enums. These were only part of an internal API. If you are using these enums, we encourage you to to look at [b177690d](https://github.com/getsentry/sentry-javascript/commit/b177690d89640aef2587039113c614672c07d2be), [5fc3147d](https://github.com/getsentry/sentry-javascript/commit/5fc3147dfaaf1a856d5923e4ba409479e87273be), and [f99bdd16](https://github.com/getsentry/sentry-javascript/commit/f99bdd16539bf6fac14eccf1a974a4988d586b28) to to see the changes we've made to our code as result. We generally recommend using string literals instead of the removed enums. - Remove deprecated `getActiveDomain` method and `DomainAsCarrier` type from `@sentry/hub`. - Rename `registerRequestInstrumentation` to `instrumentOutgoingRequests` in `@sentry/tracing`. +- Remove `Backend` and port its functionality into `Client` (see + [#4911](https://github.com/getsentry/sentry-javascript/pull/4911) and + [#4919](https://github.com/getsentry/sentry-javascript/pull/4919)). `Backend` was an unnecessary abstraction which is + not present in other Sentry SDKs. For the sake of reducing complexity, increasing consistency with other Sentry SDKs and + decreasing bundle-size, `Backend` was removed. + + +- Inject transport into client instead of initializing it in the client in `setupTransport` (see + [#4921](https://github.com/getsentry/sentry-javascript/pull/4921/)). If you are creating your own `Client` or + calling `initAndBind`, you will have to supply your desired transport. Either provide a custom one or call + `setupBrowserTransport` or `setupNodeTransport` for default transports, depending on your requirements. + + # Upgrading from 6.17.x to 6.18.0 From df32f93f04b133c4d4227236d7a95589e4989532 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 14 Apr 2022 14:29:43 +0200 Subject: [PATCH 45/94] doc(migration): Add enum removal and deprecation section to migration docs (#4938) list the removed enums in v7 and the ones we chose to keep deprecated until the next major release. Additionally, provide links to examples how to migrate to string literals for the public enums. Co-authored-by: Luca Forstner --- MIGRATION.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index f6017755e902..286cc2f671c4 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,16 +1,16 @@ -## Upgrading from 6.x to 7.x +# Upgrading from 6.x to 7.x The main goal of version 7 is to reduce bundle size. This version is breaking because we removed deprecated APIs, upgraded our build tooling, and restructured npm package contents. Below we will outline all the breaking changes you should consider when upgrading. -### Dropping Support for Node.js v6 +## Dropping Support for Node.js v6 Node.js version 6 has reached end of life in April 2019. For Sentry JavaScript SDK version 7, we will no longer be supporting version 6 of Node.js. As far as SDK development goes, dropping support means no longer running integration tests for Node.js version 6, and also no longer handling edge cases specific to version 6. Running the new SDK version on Node.js v6 is therefore highly discouraged. -### Removal Of Old Platform Integrations From `@sentry/integrations` Package +## Removal Of Old Platform Integrations From `@sentry/integrations` Package The following classes will be removed from the `@sentry/integrations` package and can no longer be used: @@ -21,19 +21,19 @@ The following classes will be removed from the `@sentry/integrations` package an These classes have been superseded and were moved into their own packages, `@sentry/angular`, `@sentry/ember`, and `@sentry/vue` in a previous version. Refer to those packages if you want to integrate Sentry into your Angular, Ember, or Vue application. -### Moving To ES6 For CommonJS Files +## Moving To ES6 For CommonJS Files From version 7 onwards, the CommonJS files in Sentry JavaScript SDK packages will use ES6. If you need to support Internet Explorer 11 or old Node.js versions, we recommend using a preprocessing tool like [Babel](https://babeljs.io/) to convert Sentry packages to ES5. -### Renaming Of CDN Bundles +## Renaming Of CDN Bundles CDN bundles will be ES6 by default. Files that followed the naming scheme `bundle.es6.min.js` were renamed to `bundle.min.js` and any bundles using ES5 (files without `.es6`) turned into `bundle.es5.min.js`. See our [docs on CDN bundles](https://docs.sentry.io/platforms/javascript/install/cdn/) for more information. -### Restructuring Of Package Content +## Restructuring Of Package Content Up until v6.x, we have published our packages on npm with the following structure: @@ -54,7 +54,7 @@ If you depend on any specific files in a Sentry JavaScript npm package, you will For example, imports on `@sentry/browser/dist/client` will become `@sentry/browser/cjs/client`. However, directly importing from specific files is discouraged. -### Removing the `API` class from `@sentry/core` +## Removing the `API` class from `@sentry/core` The internal `API` class was removed in favor of the `initAPIDetails` function and the `APIDetails` type. More details can be found in the [PR that deprecated this class](https://github.com/getsentry/sentry-javascript/pull/4281). To migrate, see the following example. @@ -80,7 +80,26 @@ const storeEndpoint = api.getStoreEndpointWithUrlEncodedAuth(); const envelopeEndpoint = api.getEnvelopeEndpointWithUrlEncodedAuth(); ``` -### General API Changes +## Enum changes + +Given that enums have a high bundle-size impact, our long term goal is to eventually remove all enums from the SDK in +favor of string literals. + +### Removed Enums +* The previously deprecated enum `Status` was removed (see [#4891](https://github.com/getsentry/sentry-javascript/pull/4891)). + [This example](#status) explains how to migrate. +* The previously deprecated internal-only enum `RequestSessionStatus` was removed (see + [#4889](https://github.com/getsentry/sentry-javascript/pull/4889)) in favor of string literals. +* The previously deprecated internal-only enum `SessionStatus` was removed (see + [#4890](https://github.com/getsentry/sentry-javascript/pull/4890)) in favor of string literals. + +### Deprecated Enums +The two enums `SpanStatus`, and `Severity` remain deprecated, as we decided to limit the number of high-impact breaking +changes in v7. They will be removed in the next major release which is why we strongly recommend moving to the +corresponding string literals. Here's how to adjust [`Severity`](#severity-severitylevel-and-severitylevels) and +[`SpanStatus`](#spanstatus). + +## General API Changes For our efforts to reduce bundle size of the SDK we had to remove and refactor parts of the package which introduced a few changes to the API: From d5c1d58d3fa1b2662e11564c4d2bfa701b0a055a Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 14 Apr 2022 14:47:13 +0200 Subject: [PATCH 46/94] feat(eventprocessors): Add name field to EventProcessor (#4932) --- packages/browser/src/integrations/dedupe.ts | 7 +++++-- .../core/src/integrations/inboundfilters.ts | 7 +++++-- packages/core/test/mocks/integration.ts | 20 +++++++++++-------- packages/hub/src/scope.ts | 18 +++++++++++++++-- packages/integrations/src/dedupe.ts | 7 +++++-- packages/integrations/src/offline.ts | 9 +++++++-- packages/nextjs/src/index.client.ts | 7 ++++++- packages/nextjs/src/index.server.ts | 12 ++++++----- packages/types/src/eventprocessor.ts | 5 ++++- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index c486c84c815e..48aa8411f268 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,10 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 6151e32e5bbd..0e9dc859a3f8 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -33,7 +33,7 @@ export class InboundFilters implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (processor: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((event: Event) => { + const eventProcess: EventProcessor = (event: Event) => { const hub = getCurrentHub(); if (hub) { const self = hub.getIntegration(InboundFilters); @@ -45,7 +45,10 @@ export class InboundFilters implements Integration { } } return event; - }); + }; + + eventProcess.id = this.name; + addGlobalEventProcessor(eventProcess); } } diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 465fac64576a..8b95b5673af8 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -1,6 +1,6 @@ import { getCurrentHub } from '@sentry/hub'; import { configureScope } from '@sentry/minimal'; -import { Event, Integration } from '@sentry/types'; +import { Event, EventProcessor, Integration } from '@sentry/types'; export class TestIntegration implements Integration { public static id: string = 'TestIntegration'; @@ -8,14 +8,18 @@ export class TestIntegration implements Integration { public name: string = 'TestIntegration'; public setupOnce(): void { - configureScope(scope => { - scope.addEventProcessor((event: Event) => { - if (!getCurrentHub().getIntegration(TestIntegration)) { - return event; - } + const eventProcessor: EventProcessor = (event: Event) => { + if (!getCurrentHub().getIntegration(TestIntegration)) { + return event; + } + + return null; + }; - return null; - }); + eventProcessor.id = this.name; + + configureScope(scope => { + scope.addEventProcessor(eventProcessor); }); } } diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 1733cf7f826f..271827519792 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -19,8 +19,16 @@ import { Transaction, User, } from '@sentry/types'; -import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils'; - +import { + dateTimestampInSeconds, + getGlobalSingleton, + isPlainObject, + isThenable, + logger, + SyncPromise, +} from '@sentry/utils'; + +import { IS_DEBUG_BUILD } from './flags'; import { Session } from './session'; /** @@ -462,6 +470,12 @@ export class Scope implements ScopeInterface { resolve(event); } else { const result = processor({ ...event }, hint) as Event | null; + + IS_DEBUG_BUILD && + processor.id && + result === null && + logger.log(`Event processor "${processor.id}" dropped event`); + if (isThenable(result)) { void result .then(final => this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve)) diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 644f3d41cd62..a29223f6832b 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,10 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index 0d2da0841805..78d8ead05dd4 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -80,10 +80,12 @@ export class Offline implements Integration { }); } - addGlobalEventProcessor((event: Event) => { + const eventProcessor: EventProcessor = event => { if (this.hub && this.hub.getIntegration(Offline)) { // cache if we are positively offline if ('navigator' in this.global && 'onLine' in this.global.navigator && !this.global.navigator.onLine) { + IS_DEBUG_BUILD && logger.log('Event dropped due to being a offline - caching instead'); + void this._cacheEvent(event) .then((_event: Event): Promise => this._enforceMaxEvents()) .catch((_error): void => { @@ -96,7 +98,10 @@ export class Offline implements Integration { } return event; - }); + }; + + eventProcessor.id = this.name; + addGlobalEventProcessor(eventProcessor); // if online now, send any events stored in a previous offline session if ('navigator' in this.global && 'onLine' in this.global.navigator && this.global.navigator.onLine) { diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index 817f8ad3ca56..05b4dc64a3f3 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -1,5 +1,6 @@ import { configureScope, init as reactInit, Integrations as BrowserIntegrations } from '@sentry/react'; import { BrowserTracing, defaultRequestInstrumentationOptions } from '@sentry/tracing'; +import { EventProcessor } from '@sentry/types'; import { nextRouterInstrumentation } from './performance/client'; import { buildMetadata } from './utils/metadata'; @@ -42,9 +43,13 @@ export function init(options: NextjsOptions): void { ...options, integrations, }); + configureScope(scope => { scope.setTag('runtime', 'browser'); - scope.addEventProcessor(event => (event.type === 'transaction' && event.transaction === '/404' ? null : event)); + const filterTransactions: EventProcessor = event => + event.type === 'transaction' && event.transaction === '/404' ? null : event; + filterTransactions.id = 'NextClient404Filter'; + scope.addEventProcessor(filterTransactions); }); } diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index 35ef814d97cd..8d34a989264a 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -2,7 +2,7 @@ import { Carrier, getHubFromCarrier, getMainCarrier } from '@sentry/hub'; import { RewriteFrames } from '@sentry/integrations'; import { configureScope, getCurrentHub, init as nodeInit, Integrations } from '@sentry/node'; import { hasTracingEnabled } from '@sentry/tracing'; -import { Event } from '@sentry/types'; +import { EventProcessor } from '@sentry/types'; import { escapeStringForRegex, logger } from '@sentry/utils'; import * as domainModule from 'domain'; import * as path from 'path'; @@ -71,6 +71,12 @@ export function init(options: NextjsOptions): void { nodeInit(options); + const filterTransactions: EventProcessor = event => { + return event.type === 'transaction' && event.transaction === '/404' ? null : event; + }; + + filterTransactions.id = 'NextServer404Filter'; + configureScope(scope => { scope.setTag('runtime', 'node'); if (isVercel) { @@ -131,10 +137,6 @@ function addServerIntegrations(options: NextjsOptions): void { } } -function filterTransactions(event: Event): Event | null { - return event.type === 'transaction' && event.transaction === '/404' ? null : event; -} - export type { SentryWebpackPluginOptions } from './config/types'; export { withSentryConfig } from './config'; export { withSentry } from './utils/withSentry'; diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 13727ae2e797..22bd74f0ab73 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -6,4 +6,7 @@ import { Event, EventHint } from './event'; * Returning a PromiseLike will work just fine, but better be sure that you know what you are doing. * Event processing will be deferred until your Promise is resolved. */ -export type EventProcessor = (event: Event, hint?: EventHint) => PromiseLike | Event | null; +export interface EventProcessor { + id?: string; // This field can't be named "name" because functions already have this field natively + (event: Event, hint?: EventHint): PromiseLike | Event | null; +} From be9465b3b18f7bc0f72a32f63925319e4aeb7b10 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 14 Apr 2022 09:09:52 -0400 Subject: [PATCH 47/94] meta: 7.0.0-alpha.1 changelog (#4939) --- CHANGELOG.md | 52 +++++++++++++++++++++++++++++++++------------------- MIGRATION.md | 3 +-- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4fd090e149..52accc5e665a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,27 +4,41 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 7.0.0-alpha.1 + +- **(breaking)** feat: Remove usage of deprecated event.stacktrace (#4885) +- **(breaking)** ref: Port functionality from Backend to Client (#4911) +- **(breaking)** ref: Delete Backend classes (#4919) +- **(breaking)** feat(browser): Remove stack parser support for Opera pre v15 (#4923) +- **(breaking)** ref(client): Inject Transports into Client (#4921) +- feat: Add name field to EventProcessor (#4932) +- ref: Expose configurable stack parser (#4902) +- ref: Turn on isolatedModules TS option (#4896) +- ref(tracing): Make setMeasurement public API (#4933) +- ref(tracing): Update setMeasurements to only set a single measurement (#4920) +- ref(types): Stop using Severity enum (#4926) + ## 7.0.0-alpha.0 -- **breaking** feat: Drop support for Node 6 (#4851) -- **breaking** feat: Remove references to @sentry/apm (#4845) -- **breaking** feat: Delete deprecated startSpan and child methods (#4849) -- **breaking** feat(bundles): Stop publishing CDN bundles on npm (#4901) -- **breaking** ref(build): Rename dist directories to cjs (#4900) -- **breaking** ref(build): Update to TypeScript 3.8.3 (#4895) -- **breaking** feat(browser): Remove top level eventbuilder exports (#4887) -- **breaking** feat(core): Delete API class (#4848) -- **breaking** feat(core): Remove whitelistUrls/blacklistUrls (#4850) -- **breaking** feat(gatsby): Remove Sentry from window (#4857) -- **breaking** feat(hub): Remove getActiveDomain (#4858) -- **breaking** feat(hub): Remove setTransaction scope method (#4865) -- **breaking** feat(integrations): Remove old angular, ember, and vue integrations (#4893) -- **breaking** feat(node): Remove deprecated frameContextLines (#4884) -- **breaking** feat(tracing): Rename registerRequestInstrumentation -> instrumentOutgoingRequests (#4859) -- **breaking** feat(types): Remove deprecated user dsn field (#4864) -- **breaking** feat(types): Delete RequestSessionStatus enum (#4889) -- **breaking** feat(types): Delete Status enum (#4891) -- **breaking** feat(types): Delete SessionStatus enum (#4890) +- **(breaking)** feat: Drop support for Node 6 (#4851) +- **(breaking)** feat: Remove references to @sentry/apm (#4845) +- **(breaking)** feat: Delete deprecated startSpan and child methods (#4849) +- **(breaking)** feat(bundles): Stop publishing CDN bundles on npm (#4901) +- **(breaking)** ref(build): Rename dist directories to cjs (#4900) +- **(breaking)** ref(build): Update to TypeScript 3.8.3 (#4895) +- **(breaking)** feat(browser): Remove top level eventbuilder exports (#4887) +- **(breaking)** feat(core): Delete API class (#4848) +- **(breaking)** feat(core): Remove whitelistUrls/blacklistUrls (#4850) +- **(breaking)** feat(gatsby): Remove Sentry from window (#4857) +- **(breaking)** feat(hub): Remove getActiveDomain (#4858) +- **(breaking)** feat(hub): Remove setTransaction scope method (#4865) +- **(breaking)** feat(integrations): Remove old angular, ember, and vue integrations (#4893) +- **(breaking)** feat(node): Remove deprecated frameContextLines (#4884) +- **(breaking)** feat(tracing): Rename registerRequestInstrumentation -> instrumentOutgoingRequests (#4859) +- **(breaking)** feat(types): Remove deprecated user dsn field (#4864) +- **(breaking)** feat(types): Delete RequestSessionStatus enum (#4889) +- **(breaking)** feat(types): Delete Status enum (#4891) +- **(breaking)** feat(types): Delete SessionStatus enum (#4890) ## 6.19.6 diff --git a/MIGRATION.md b/MIGRATION.md index 286cc2f671c4..a33feb194af3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -121,8 +121,7 @@ For our efforts to reduce bundle size of the SDK we had to remove and refactor p [#4921](https://github.com/getsentry/sentry-javascript/pull/4921/)). If you are creating your own `Client` or calling `initAndBind`, you will have to supply your desired transport. Either provide a custom one or call `setupBrowserTransport` or `setupNodeTransport` for default transports, depending on your requirements. - - +- Remove support for Opera browser pre v15 # Upgrading from 6.17.x to 6.18.0 From 90c83f1ae274a4bd15c3ce5175c5b18dd4a74040 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Thu, 14 Apr 2022 13:12:39 +0000 Subject: [PATCH 48/94] release: 7.0.0-alpha.1 --- lerna.json | 2 +- packages/angular/package.json | 8 ++++---- packages/browser/package.json | 8 ++++---- packages/core/package.json | 10 +++++----- packages/core/src/version.ts | 2 +- packages/ember/package.json | 10 +++++----- packages/eslint-config-sdk/package.json | 6 +++--- packages/eslint-plugin-sdk/package.json | 2 +- packages/gatsby/package.json | 8 ++++---- packages/hub/package.json | 6 +++--- packages/integration-tests/package.json | 2 +- packages/integrations/package.json | 6 +++--- packages/minimal/package.json | 6 +++--- packages/nextjs/package.json | 18 +++++++++--------- packages/node-integration-tests/package.json | 2 +- packages/node/package.json | 10 +++++----- packages/react/package.json | 10 +++++----- packages/serverless/package.json | 12 ++++++------ packages/tracing/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/typescript/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/vue/package.json | 12 ++++++------ packages/wasm/package.json | 6 +++--- 24 files changed, 83 insertions(+), 83 deletions(-) diff --git a/lerna.json b/lerna.json index ab5fdf259b84..c99f1bd4f741 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "3.4.0", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "packages": "packages/*", "npmClient": "yarn", "useWorkspaces": true diff --git a/packages/angular/package.json b/packages/angular/package.json index e92a3235d969..971bd6a1bfb4 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/angular", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Angular", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular", @@ -21,9 +21,9 @@ "@angular/router": "10.x || 11.x || 12.x || 13.x" }, "dependencies": { - "@sentry/browser": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "rxjs": "^6.6.0", "tslib": "^1.9.3" }, diff --git a/packages/browser/package.json b/packages/browser/package.json index 7f1c79235b59..8ed9132b407e 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/browser", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for browsers", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser", @@ -16,9 +16,9 @@ "access": "public" }, "dependencies": { - "@sentry/core": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/core": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 23ee48723424..8a53ffca97e3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/core", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Base implementation for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "7.0.0-alpha.0", - "@sentry/minimal": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/hub": "7.0.0-alpha.1", + "@sentry/minimal": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/core/src/version.ts b/packages/core/src/version.ts index 485119673c97..2dcfdae39507 100644 --- a/packages/core/src/version.ts +++ b/packages/core/src/version.ts @@ -1 +1 @@ -export const SDK_VERSION = '7.0.0-alpha.0'; +export const SDK_VERSION = '7.0.0-alpha.1'; diff --git a/packages/ember/package.json b/packages/ember/package.json index 3b22b69981b2..23d65a60b571 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/ember", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Ember.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember", @@ -29,10 +29,10 @@ }, "dependencies": { "@embroider/macros": "~0.47.2", - "@sentry/browser": "7.0.0-alpha.0", - "@sentry/tracing": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", + "@sentry/tracing": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "ember-auto-import": "~1.12.1 || ~2.2.0", "ember-cli-babel": "~7.26.6", "ember-cli-htmlbars": "^6.0.1", diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index 45a42c8472d0..844251a06f14 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-config-sdk", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK eslint config", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk", @@ -19,8 +19,8 @@ "access": "public" }, "dependencies": { - "@sentry-internal/eslint-plugin-sdk": "7.0.0-alpha.0", - "@sentry-internal/typescript": "7.0.0-alpha.0", + "@sentry-internal/eslint-plugin-sdk": "7.0.0-alpha.1", + "@sentry-internal/typescript": "7.0.0-alpha.1", "@typescript-eslint/eslint-plugin": "^3.9.0", "@typescript-eslint/parser": "^3.9.0", "eslint-config-prettier": "^6.11.0", diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index 938815cb33a3..65a439ba5555 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-plugin-sdk", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK eslint plugin", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk", diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 976ab9847663..1bf607d15a4c 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/gatsby", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Gatsby.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby", @@ -20,8 +20,8 @@ "access": "public" }, "dependencies": { - "@sentry/react": "7.0.0-alpha.0", - "@sentry/tracing": "7.0.0-alpha.0", + "@sentry/react": "7.0.0-alpha.1", + "@sentry/tracing": "7.0.0-alpha.1", "@sentry/webpack-plugin": "1.18.8" }, "peerDependencies": { @@ -29,7 +29,7 @@ "react": "15.x || 16.x || 17.x || 18.x" }, "devDependencies": { - "@sentry/types": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.1", "@testing-library/react": "^13.0.0", "react": "^18.0.0" }, diff --git a/packages/hub/package.json b/packages/hub/package.json index 8bb57aab02e2..13351981746c 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/hub", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Sentry hub which handles global state managment.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/hub", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 5456ef0e19be..e501c87aca91 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-integration-tests", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "main": "index.js", "license": "MIT", "engines": { diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 52f2c23ea924..de3eb70ed7bd 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/integrations", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Pluggable integrations that can be used to enhance JS SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/integrations", @@ -16,8 +16,8 @@ "module": "build/npm/esm/index.js", "types": "build/npm/types/index.d.ts", "dependencies": { - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "localforage": "^1.8.1", "tslib": "^1.9.3" }, diff --git a/packages/minimal/package.json b/packages/minimal/package.json index 4154add1ca3d..3ca8889512a2 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/minimal", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Sentry minimal library that can be used in other packages", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/minimal", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", + "@sentry/hub": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "scripts": { diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 5674ffc46956..c4ca89888d3a 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nextjs", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Next.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs", @@ -17,18 +17,18 @@ "access": "public" }, "dependencies": { - "@sentry/core": "7.0.0-alpha.0", - "@sentry/hub": "7.0.0-alpha.0", - "@sentry/integrations": "7.0.0-alpha.0", - "@sentry/node": "7.0.0-alpha.0", - "@sentry/react": "7.0.0-alpha.0", - "@sentry/tracing": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/core": "7.0.0-alpha.1", + "@sentry/hub": "7.0.0-alpha.1", + "@sentry/integrations": "7.0.0-alpha.1", + "@sentry/node": "7.0.0-alpha.1", + "@sentry/react": "7.0.0-alpha.1", + "@sentry/tracing": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "@sentry/webpack-plugin": "1.18.8", "tslib": "^1.9.3" }, "devDependencies": { - "@sentry/types": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.1", "@types/webpack": "^4.41.31", "next": "10.1.3" }, diff --git a/packages/node-integration-tests/package.json b/packages/node-integration-tests/package.json index 3f10098ba15b..2e662c2bb2fa 100644 --- a/packages/node-integration-tests/package.json +++ b/packages/node-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/node-integration-tests", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "license": "MIT", "engines": { "node": ">=10" diff --git a/packages/node/package.json b/packages/node/package.json index f7a19037a029..d0710af4fe4c 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/node", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Node.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/core": "7.0.0-alpha.0", - "@sentry/hub": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/core": "7.0.0-alpha.1", + "@sentry/hub": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "cookie": "^0.4.1", "https-proxy-agent": "^5.0.0", "lru_map": "^0.3.3", diff --git a/packages/react/package.json b/packages/react/package.json index 7835071eccdc..2fea1d64d5be 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/react", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for React.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react", @@ -16,10 +16,10 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "7.0.0-alpha.0", - "@sentry/minimal": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", + "@sentry/minimal": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "hoist-non-react-statics": "^3.3.2", "tslib": "^1.9.3" }, diff --git a/packages/serverless/package.json b/packages/serverless/package.json index ac3374862764..d77177b66c1a 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/serverless", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for various serverless solutions", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/serverless", @@ -16,11 +16,11 @@ "access": "public" }, "dependencies": { - "@sentry/minimal": "7.0.0-alpha.0", - "@sentry/node": "7.0.0-alpha.0", - "@sentry/tracing": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/minimal": "7.0.0-alpha.1", + "@sentry/node": "7.0.0-alpha.1", + "@sentry/tracing": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "@types/aws-lambda": "^8.10.62", "@types/express": "^4.17.2", "tslib": "^1.9.3" diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 5100e610ef8a..782bd8bcc658 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/tracing", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Extensions for Sentry AM", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tracing", @@ -16,14 +16,14 @@ "access": "public" }, "dependencies": { - "@sentry/hub": "7.0.0-alpha.0", - "@sentry/minimal": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/hub": "7.0.0-alpha.1", + "@sentry/minimal": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "devDependencies": { - "@sentry/browser": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", "@types/express": "^4.17.1" }, "scripts": { diff --git a/packages/types/package.json b/packages/types/package.json index 2fc59e9a1535..5c1c37c1c159 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/types", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Types for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types", diff --git a/packages/typescript/package.json b/packages/typescript/package.json index 338ab3906aef..fe238ae810aa 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/typescript", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Typescript configuration used at Sentry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript", diff --git a/packages/utils/package.json b/packages/utils/package.json index ddce3d7933aa..142ae23e6010 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/utils", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/utils", @@ -16,7 +16,7 @@ "access": "public" }, "dependencies": { - "@sentry/types": "7.0.0-alpha.0", + "@sentry/types": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/packages/vue/package.json b/packages/vue/package.json index b49beced0934..29452f54ce4c 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vue", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Official Sentry SDK for Vue.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue", @@ -16,11 +16,11 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "7.0.0-alpha.0", - "@sentry/core": "7.0.0-alpha.0", - "@sentry/minimal": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", - "@sentry/utils": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", + "@sentry/core": "7.0.0-alpha.1", + "@sentry/minimal": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", + "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "peerDependencies": { diff --git a/packages/wasm/package.json b/packages/wasm/package.json index b8d70d1bd924..8c850944a72f 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/wasm", - "version": "7.0.0-alpha.0", + "version": "7.0.0-alpha.1", "description": "Support for WASM.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm", @@ -16,8 +16,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "7.0.0-alpha.0", - "@sentry/types": "7.0.0-alpha.0", + "@sentry/browser": "7.0.0-alpha.1", + "@sentry/types": "7.0.0-alpha.1", "tslib": "^1.9.3" }, "devDependencies": { From ffc80e23c8f7efd4020ba885d535597c0b4d02a5 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 14 Apr 2022 07:11:37 -0700 Subject: [PATCH 49/94] chore(gatsby): Create type declarations for gatsby plugin files (#4928) When creating a Gatsby plugin (which is what `@sentry/gatsby` actually is), there are certain files[1] which need to live at the package root level. Because they are written in JS (not TS) and don't live in `src/`, we have thus far more or less ignored them as far as type-ful processing goes. With the recent updates to TS, jest, and ts-jest, typechecking has now gotten stricter (especially in tests) and so now declaration files are needed for those gatsby-required, root-level files if we want to test them (which we do). This adds machinery to create, manage, and publish these declaration files. [1] https://www.gatsbyjs.com/docs/files-gatsby-looks-for-in-a-plugin/ --- .gitignore | 2 ++ packages/gatsby/.eslintrc.js | 5 ++--- packages/gatsby/.npmignore | 2 ++ packages/gatsby/package.json | 5 +++-- packages/gatsby/scripts/prepack.ts | 2 +- packages/gatsby/tsconfig.plugin.json | 17 +++++++++++++++++ 6 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 packages/gatsby/tsconfig.plugin.json diff --git a/.gitignore b/.gitignore index 4418a41432bc..ae301fadfde7 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ tmp.js # eslint .eslintcache eslintcache/* + +*.d.ts diff --git a/packages/gatsby/.eslintrc.js b/packages/gatsby/.eslintrc.js index ab610a82206a..6aff306daa40 100644 --- a/packages/gatsby/.eslintrc.js +++ b/packages/gatsby/.eslintrc.js @@ -6,8 +6,7 @@ module.exports = { parserOptions: { jsx: true, }, - // ignoring the package-specific prepack script here b/c it is not - // covered by a `tsconfig` which makes eslint throw an error - ignorePatterns: ['scripts/prepack.ts'], + // ignore these because they're not covered by a `tsconfig`, which makes eslint throw an error + ignorePatterns: ['scripts/prepack.ts', 'gatsby-browser.d.ts', 'gatsby-node.d.ts'], extends: ['../../.eslintrc.js'], }; diff --git a/packages/gatsby/.npmignore b/packages/gatsby/.npmignore index 66474694b223..35348e6a718d 100644 --- a/packages/gatsby/.npmignore +++ b/packages/gatsby/.npmignore @@ -10,3 +10,5 @@ # Gatsby specific !gatsby-browser.js !gatsby-node.js +!gatsby-browser.d.ts +!gatsby-node.d.ts diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 1bf607d15a4c..23cb258fb512 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -34,11 +34,12 @@ "react": "^18.0.0" }, "scripts": { - "build": "run-p build:cjs build:esm build:types", + "build": "run-p build:cjs build:esm build:types build:plugin", "build:cjs": "tsc -p tsconfig.cjs.json", "build:dev": "run-s build", "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", "build:esm": "tsc -p tsconfig.esm.json", + "build:plugin": "tsc -p tsconfig.plugin.json", "build:types": "tsc -p tsconfig.types.json", "build:watch": "run-p build:cjs:watch build:esm:watch build:types:watch", "build:cjs:watch": "tsc -p tsconfig.cjs.json --watch", @@ -48,7 +49,7 @@ "build:types:watch": "tsc -p tsconfig.types.json --watch", "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf build coverage", + "clean": "rimraf build coverage *.d.ts", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/gatsby/scripts/prepack.ts b/packages/gatsby/scripts/prepack.ts index 5aa95909d70c..3f5a8e24d674 100644 --- a/packages/gatsby/scripts/prepack.ts +++ b/packages/gatsby/scripts/prepack.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import * as path from 'path'; -const PACKAGE_ASSETS = ['gatsby-browser.js', 'gatsby-node.js']; +const PACKAGE_ASSETS = ['gatsby-browser.js', 'gatsby-browser.d.ts', 'gatsby-node.js', 'gatsby-node.d.ts']; export function prepack(buildDir: string): boolean { // copy package-specific assets to build dir diff --git a/packages/gatsby/tsconfig.plugin.json b/packages/gatsby/tsconfig.plugin.json new file mode 100644 index 000000000000..8a755642dd8b --- /dev/null +++ b/packages/gatsby/tsconfig.plugin.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + + "include": ["gatsby-browser.js", "gatsby-node.js"], + + "compilerOptions": { + // should include all types from `./tsconfig.json` plus types for all test frameworks used + // "types": ["node", "jest"] + "declaration": true, + "declarationMap": false, + "emitDeclarationOnly": true, + "allowJs": true, + "skipLibCheck": true + + // other package-specific, plugin-specific options + } +} From 503b79865f384e2f64c794e245c7493229d03c3b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 14 Apr 2022 11:10:19 -0400 Subject: [PATCH 50/94] feat(typescript): Remove tslint (#4940) tslint has been deprecated for eslint: https://github.com/palantir/tslint#tslint. The SDK switched over to eslint in Aug 2020. Let's formally remove tslint support in our typescript package. This cleans up our dependencies and reduces confusion to new SDK devs. --- packages/typescript/.npmignore | 1 - packages/typescript/README.md | 8 --- packages/typescript/package.json | 6 +-- packages/typescript/tsconfig.json | 10 ---- packages/typescript/tslint.json | 88 ------------------------------- yarn.lock | 56 ++------------------ 6 files changed, 4 insertions(+), 165 deletions(-) delete mode 100644 packages/typescript/tslint.json diff --git a/packages/typescript/.npmignore b/packages/typescript/.npmignore index d59f27ed8132..457274275b7c 100644 --- a/packages/typescript/.npmignore +++ b/packages/typescript/.npmignore @@ -1,3 +1,2 @@ * !/tsconfig.json -!/tslint.json diff --git a/packages/typescript/README.md b/packages/typescript/README.md index e06503ddf511..aa32b9fdf48b 100644 --- a/packages/typescript/README.md +++ b/packages/typescript/README.md @@ -36,14 +36,6 @@ npm install --save-dev @sentry-internal/typescript Add the following config files to your project's root directory: -**tslint.json**: - -```json -{ - "extends": "@sentry-internal/typescript/tslint" -} -``` - **tsconfig.json**: ```json diff --git a/packages/typescript/package.json b/packages/typescript/package.json index fe238ae810aa..9a8a3ed28d4c 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -10,12 +10,8 @@ "publishConfig": { "access": "public" }, - "dependencies": { - "tslint-config-prettier": "^1.18.0", - "tslint-consistent-codestyle": "^1.15.1" - }, + "dependencies": {}, "peerDependencies": { - "tslint": "5.16.0", "typescript": "3.8.3" }, "scripts": { diff --git a/packages/typescript/tsconfig.json b/packages/typescript/tsconfig.json index 3a427cc596c9..49c2339c7f21 100644 --- a/packages/typescript/tsconfig.json +++ b/packages/typescript/tsconfig.json @@ -18,16 +18,6 @@ "noImplicitUseStrict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "plugins": [ - { - "name": "typescript-tslint-plugin", - "configFile": "./tslint.json", - "alwaysShowRuleFailuresAsWarnings": false, - "ignoreDefinitionFiles": true, - "mockTypeScriptVersion": false, - "suppressWhileTypeErrorsPresent": false - } - ], "preserveWatchOutput": true, "pretty": true, "sourceMap": true, diff --git a/packages/typescript/tslint.json b/packages/typescript/tslint.json deleted file mode 100644 index a739adabaf6a..000000000000 --- a/packages/typescript/tslint.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "extends": ["tslint:all", "tslint-config-prettier", "tslint-consistent-codestyle"], - "rules": { - // This rule has side effects and must be disabled - "no-unused-variable": false, - - "no-submodule-imports": false, - "no-null-keyword": false, - // We don't want these - "newline-before-return": false, - "no-any": false, - "no-magic-numbers": false, - "no-parameter-properties": false, - "no-require-imports": false, - "prefer-function-over-method": [false], - "strict-boolean-expressions": false, - "no-inferrable-types": false, - "ban-ts-ignore": false, - "increment-decrement": false, - "promise-function-async": false, - "ban-types": [true, ["async", "Use Promises instead, as async/await adds a lot to bundle size."]], - // These are too strict in tslint:all - "comment-format": [true, "check-space"], - "completed-docs": [ - true, - { - "classes": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "enums": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "enum-members": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "functions": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "interfaces": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "methods": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - } - }, - "properties": { - "tags": { - "content": {}, - "existence": ["inheritDoc", "hidden"] - }, - "locations": "instance" - } - } - ], - "interface-name": [true, "never-prefix"], - "member-ordering": [true, "statics-first"], - "no-console": [true, "log"], - "only-arrow-functions": [true, "allow-named-functions"], - "typedef": [true, "call-signature", "parameter", "property-declaration", "member-variable-declaration"], - "variable-name": [true, "check-format", "allow-leading-underscore", "ban-keywords"], - "naming-convention": [ - true, - // This config will apply to properties AND methods. If you only need it for properties, use "property" instead of - // "member". - { "type": "member", "modifiers": "protected", "leadingUnderscore": "require" }, - { "type": "member", "modifiers": "private", "leadingUnderscore": "require" } - ], - // we cannot use Promises as they are not IE10-11 compatibile, so we had to create our own implementation - "await-promise": [true, "PromiseLike"] - } -} diff --git a/yarn.lock b/yarn.lock index 482f2369ee5b..711e8abfe0d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1785,25 +1785,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@fimbul/bifrost@^0.21.0": - version "0.21.0" - resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.21.0.tgz#d0fafa25938fda475657a6a1e407a21bbe02c74e" - integrity sha512-ou8VU+nTmOW1jeg+FT+sn+an/M0Xb9G16RucrfhjXGWv1Q97kCoM5CG9Qj7GYOSdu7km72k7nY83Eyr53Bkakg== - dependencies: - "@fimbul/ymir" "^0.21.0" - get-caller-file "^2.0.0" - tslib "^1.8.1" - tsutils "^3.5.0" - -"@fimbul/ymir@^0.21.0": - version "0.21.0" - resolved "https://registry.yarnpkg.com/@fimbul/ymir/-/ymir-0.21.0.tgz#8525726787aceeafd4e199472c0d795160b5d4a1" - integrity sha512-T/y7WqPsm4n3zhT08EpB5sfdm2Kvw3gurAxr2Lr5dQeLi8ZsMlNT/Jby+ZmuuAAd1PnXYzKp+2SXgIkQIIMCUg== - dependencies: - inversify "^5.0.0" - reflect-metadata "^0.1.12" - tslib "^1.8.1" - "@glimmer/component@~1.0.0": version "1.0.4" resolved "https://registry.yarnpkg.com/@glimmer/component/-/component-1.0.4.tgz#1c85a5181615a6647f6acfaaed68e28ad7e9626e" @@ -11860,7 +11841,7 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.0, get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -13204,11 +13185,6 @@ invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -inversify@^5.0.0: - version "5.0.5" - resolved "https://registry.yarnpkg.com/inversify/-/inversify-5.0.5.tgz#bd1f8e6d8e0f739331acd8ba9bc954635aae0bbf" - integrity sha512-60QsfPz8NAU/GZqXu8hJ+BhNf/C/c+Hp0eDc6XMIJTxBiP36AQyyQKpBkOVTLWBFDQWYVHpbbEuIsHu9dLuJDA== - invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -19185,11 +19161,6 @@ redux@^4.0.5: loose-envify "^1.4.0" symbol-observable "^1.2.0" -reflect-metadata@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" - integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== - regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -21862,7 +21833,7 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.10.0, tslib@^1.7.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -21877,28 +21848,7 @@ tslib@^2.3.0, tslib@^2.3.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslint-config-prettier@^1.18.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" - integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== - -tslint-consistent-codestyle@^1.15.1: - version "1.16.0" - resolved "https://registry.yarnpkg.com/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.16.0.tgz#52348ea899a7e025b37cc6545751c6a566a19077" - integrity sha512-ebR/xHyMEuU36hGNOgCfjGBNYxBPixf0yU1Yoo6s3BrpBRFccjPOmIVaVvQsWAUAMdmfzHOCihVkcaMfimqvHw== - dependencies: - "@fimbul/bifrost" "^0.21.0" - tslib "^1.7.1" - tsutils "^2.29.0" - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - -tsutils@^3.0.0, tsutils@^3.17.1, tsutils@^3.5.0: +tsutils@^3.0.0, tsutils@^3.17.1: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== From 2593be0bef3a71ee47fd55382c66cb2532a2772c Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 14 Apr 2022 18:11:07 +0300 Subject: [PATCH 51/94] ref(test): Switch to `mongodb-memory-server-global`. (#4872) Switching to `mongodb-memory-server-global` which downloads MongoDB binaries on `postinstall` instead of first test run. This will fix test flakiness caused by timeouts. --- .github/workflows/build.yml | 1 + packages/node-integration-tests/package.json | 8 +++++++- .../suites/tracing/auto-instrument/mongodb/test.ts | 7 +++++-- yarn.lock | 6 +++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 21d0fd5685f9..bfefea5392c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,7 @@ env: ${{ github.workspace }}/node_modules ${{ github.workspace }}/packages/**/node_modules ~/.cache/ms-playwright/ + ~/.cache/mongodb-binaries/ # DEPENDENCY_CACHE_KEY: can't be set here because we don't have access to yarn.lock diff --git a/packages/node-integration-tests/package.json b/packages/node-integration-tests/package.json index 2e662c2bb2fa..3f09e8d64192 100644 --- a/packages/node-integration-tests/package.json +++ b/packages/node-integration-tests/package.json @@ -21,10 +21,16 @@ "cors": "^2.8.5", "express": "^4.17.3", "mongodb": "^3.7.3", - "mongodb-memory-server": "^7.6.3", + "mongodb-memory-server-global": "^7.6.3", "mysql": "^2.18.1", "nock": "^13.1.0", "pg": "^8.7.3", "portfinder": "^1.0.28" + }, + "config": { + "mongodbMemoryServer": { + "preferGlobalPath": true, + "runtimeDownload": false + } } } diff --git a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts index dd5f88f860ca..76cadd1518dd 100644 --- a/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts +++ b/packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/test.ts @@ -1,14 +1,17 @@ -import { MongoMemoryServer } from 'mongodb-memory-server'; +import { MongoMemoryServer } from 'mongodb-memory-server-global'; import { assertSentryTransaction, conditionalTest, getEnvelopeRequest, runServer } from '../../../../utils'; +// This test can take longer. +jest.setTimeout(15000); + conditionalTest({ min: 12 })('MongoDB Test', () => { let mongoServer: MongoMemoryServer; beforeAll(async () => { mongoServer = await MongoMemoryServer.create(); process.env.MONGO_URL = mongoServer.getUri(); - }, 40000); + }, 10000); afterAll(async () => { await mongoServer.stop(); diff --git a/yarn.lock b/yarn.lock index 711e8abfe0d4..69010b40b996 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16286,10 +16286,10 @@ mongodb-memory-server-core@7.6.3: uuid "^8.3.1" yauzl "^2.10.0" -mongodb-memory-server@^7.6.3: +mongodb-memory-server-global@^7.6.3: version "7.6.3" - resolved "https://registry.yarnpkg.com/mongodb-memory-server/-/mongodb-memory-server-7.6.3.tgz#8b2827363ca16aaf250cba07f7a2b49e502735d4" - integrity sha512-yHDE9FGxOpSRUzitF9Qx3JjEgayCSJI3JOW2wgeBH/5PAsUdisy2nRxRiNwwLDooQ7tohllWCRTXlWqyarUEMQ== + resolved "https://registry.yarnpkg.com/mongodb-memory-server-global/-/mongodb-memory-server-global-7.6.3.tgz#ad662a640db254eea7927668834c26b665c13547" + integrity sha512-WLlMqkEasuanHjoxyMxlyvQ/HtJgq0eGyrfCXX6lTnY/26Zfs96W2daeWLOQ48VLInSOh2umBvE74Ykqj7gVyA== dependencies: mongodb-memory-server-core "7.6.3" tslib "^2.3.0" From 961d3afd899aa83df63a27c529563eaeed077b11 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 14 Apr 2022 18:20:24 +0300 Subject: [PATCH 52/94] fix(tests): Use non-delayed success endpoints to test `crashed` and `errored` cases. (#4937) --- .../suites/sessions/crashed-session-aggregate/test.ts | 2 +- .../suites/sessions/errored-session-aggregate/test.ts | 2 +- packages/node-integration-tests/suites/sessions/server.ts | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts b/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts index 59bb88d4aae7..28ce0ba822c0 100644 --- a/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts +++ b/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts @@ -8,7 +8,7 @@ test('should aggregate successful and crashed sessions', async () => { const envelope = await Promise.race([ getEnvelopeRequest(`${url}/success`), getEnvelopeRequest(`${url}/error_unhandled`), - getEnvelopeRequest(`${url}/success_slow`), + getEnvelopeRequest(`${url}/success_next`), ]); expect(envelope).toHaveLength(3); diff --git a/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts b/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts index e26cafa8a586..ad1cf46f2704 100644 --- a/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts +++ b/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts @@ -6,7 +6,7 @@ test('should aggregate successful, crashed and erroneous sessions', async () => const url = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`); const envelope = await Promise.race([ - getEnvelopeRequest(`${url}/success_slow`), + getEnvelopeRequest(`${url}/success`), getEnvelopeRequest(`${url}/error_handled`), getEnvelopeRequest(`${url}/error_unhandled`), ]); diff --git a/packages/node-integration-tests/suites/sessions/server.ts b/packages/node-integration-tests/suites/sessions/server.ts index 89b9a0e521ea..a718c07d16c1 100644 --- a/packages/node-integration-tests/suites/sessions/server.ts +++ b/packages/node-integration-tests/suites/sessions/server.ts @@ -24,8 +24,7 @@ clearInterval(flusherIntervalId); // @ts-ignore: need access to `_intervalId` flusherIntervalId = flusher?._intervalId = setInterval(() => flusher?.flush(), 1000); -// @ts-ignore: need access to `_intervalId` again -setTimeout(() => clearInterval(flusherIntervalId), 3000); +setTimeout(() => clearInterval(flusherIntervalId), 2000); app.get('/test/success', (_req, res) => { res.send('Success!'); From 0cf5fb5dde2912c27deec026efee2752b96ff79b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 14 Apr 2022 17:25:57 +0200 Subject: [PATCH 53/94] ref(utils): remove `forget` async utility function (#4941) remove the `forget()` function from Utils as it is a rather unnecessary abstraction around logging a rejected Promise via console.error and it bloats the bundle --- packages/browser/src/transports/utils.ts | 16 ++++++-------- .../src/integrations/utils/errorhandling.ts | 9 ++++---- packages/utils/src/async.ts | 12 ---------- packages/utils/src/index.ts | 1 - packages/utils/test/async.test.ts | 22 ------------------- 5 files changed, 12 insertions(+), 48 deletions(-) delete mode 100644 packages/utils/src/async.ts delete mode 100644 packages/utils/test/async.test.ts diff --git a/packages/browser/src/transports/utils.ts b/packages/browser/src/transports/utils.ts index 5fc614d6b86f..5a8e17b42019 100644 --- a/packages/browser/src/transports/utils.ts +++ b/packages/browser/src/transports/utils.ts @@ -1,4 +1,4 @@ -import { forget, getGlobalObject, isNativeFetch, logger, supportsFetch } from '@sentry/utils'; +import { getGlobalObject, isNativeFetch, logger, supportsFetch } from '@sentry/utils'; import { IS_DEBUG_BUILD } from '../flags'; @@ -98,13 +98,11 @@ export function sendReport(url: string, body: string): void { if (supportsFetch()) { const fetch = getNativeFetchImplementation(); - return forget( - fetch(url, { - body, - method: 'POST', - credentials: 'omit', - keepalive: true, - }), - ); + fetch(url, { + body, + method: 'POST', + credentials: 'omit', + keepalive: true, + }).then(null, error => logger.error(error)); } } diff --git a/packages/node/src/integrations/utils/errorhandling.ts b/packages/node/src/integrations/utils/errorhandling.ts index aa79eebcaee8..587840d040b5 100644 --- a/packages/node/src/integrations/utils/errorhandling.ts +++ b/packages/node/src/integrations/utils/errorhandling.ts @@ -1,5 +1,5 @@ import { getCurrentHub } from '@sentry/core'; -import { forget, logger } from '@sentry/utils'; +import { logger } from '@sentry/utils'; import { NodeClient } from '../../client'; import { IS_DEBUG_BUILD } from '../../flags'; @@ -24,12 +24,13 @@ export function logAndExitProcess(error: Error): void { const timeout = (options && options.shutdownTimeout && options.shutdownTimeout > 0 && options.shutdownTimeout) || DEFAULT_SHUTDOWN_TIMEOUT; - forget( - client.close(timeout).then((result: boolean) => { + client.close(timeout).then( + (result: boolean) => { if (!result) { IS_DEBUG_BUILD && logger.warn('We reached the timeout for emptying the request buffer, still exiting now!'); } global.process.exit(1); - }), + }, + error => logger.error(error), ); } diff --git a/packages/utils/src/async.ts b/packages/utils/src/async.ts deleted file mode 100644 index e811fe25c4a6..000000000000 --- a/packages/utils/src/async.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Consumes the promise and logs the error when it rejects. - * @param promise A promise to forget. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function forget(promise: PromiseLike): void { - void promise.then(null, e => { - // TODO: Use a better logging mechanism - // eslint-disable-next-line no-console - console.error(e); - }); -} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 4d33eeab55e3..0f004218c052 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,4 +1,3 @@ -export * from './async'; export * from './browser'; export * from './dsn'; export * from './error'; diff --git a/packages/utils/test/async.test.ts b/packages/utils/test/async.test.ts deleted file mode 100644 index d4edbeca7129..000000000000 --- a/packages/utils/test/async.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { forget } from '../src/async'; - -describe('forget', () => { - const console = { - error: jest.fn(), - log: jest.fn(), - }; - - beforeEach(() => { - global.console = console as any as Console; - }); - - test('logs rejections to console.error', done => { - const error = new Error(); - forget(Promise.reject(error)); - - setImmediate(() => { - expect(console.error).toHaveBeenCalledWith(error); - done(); - }); - }); -}); From f67b1c2682ecfcd03223429d86bbd93d607178e2 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Thu, 14 Apr 2022 12:41:34 -0400 Subject: [PATCH 54/94] feat(tracing): Add GB unit to device memory tag value (#4935) Since tag values are always strings, it'll be useful to attach units to the `deviceMemory` tag. Since `navigator.deviceMemory` are approximate in gigabytes, we can suffix the tag value with " GB". Reference: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory --- packages/tracing/src/browser/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index dffc39abb088..97d28806096d 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -211,7 +211,7 @@ export class MetricsInstrumentation { } if (isMeasurementValue(navigator.deviceMemory)) { - transaction.setTag('deviceMemory', String(navigator.deviceMemory)); + transaction.setTag('deviceMemory', `${navigator.deviceMemory} GB`); } if (isMeasurementValue(navigator.hardwareConcurrency)) { From 949e90e628cc684eb24fe3f00544d673636036c7 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 14 Apr 2022 11:52:05 -0700 Subject: [PATCH 55/94] fix(build): Cache gatsby plugin types files in CI (#4944) This is a follow up to https://github.com/getsentry/sentry-javascript/pull/4928, which added the creation of types files for the code in the gatsby SDK which lives outside of `src/`. One change which was missed was to have GHA include these new files in the build cache, so that they are available when tests are run. This fixes that oversight. --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfefea5392c5..28895bde0cb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,7 @@ env: ${{ github.workspace }}/packages/**/esm ${{ github.workspace }}/packages/ember/*.d.ts ${{ github.workspace }}/packages/ember/instance-initializers + ${{ github.workspace }}/packages/gatsby/*.d.ts ${{ github.workspace }}/packages/serverless/dist-awslambda-layer/*.zip BUILD_CACHE_KEY: ${{ github.event.inputs.commit || github.sha }} From 91f26345ef6d0011eaa902acc646d51d3e11c8b2 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 14 Apr 2022 13:30:23 -0700 Subject: [PATCH 56/94] fix(tests): Fix type errors in tests (#4908) In the process of updating our jest dependencies, a significant number of type errors in tests suddenly appeared. (It seems newer versions of `jest` et al are stricter than the ones we had been using.) This fixes those errors, and changes our jest config so that it will throw an error on any types problems in a test, so we'll know to fix them locally. (Still to do: Fix our configuration so that the linter will catch the errors, so we don't have to actually run the tests to find them.) --- jest.config.js | 1 - .../unit/integrations/linkederrors.test.ts | 14 ++- .../test/unit/mocks/simpletransport.ts | 1 + .../browser/test/unit/transports/base.test.ts | 6 +- .../test/unit/transports/new-xhr.test.ts | 10 +- packages/core/test/lib/base.test.ts | 2 +- packages/core/test/mocks/client.ts | 2 +- packages/gatsby/test/gatsby-browser.test.ts | 4 +- packages/gatsby/test/gatsby-node.test.ts | 6 +- packages/gatsby/test/setEnvVars.ts | 4 + packages/hub/test/global.test.ts | 4 + packages/hub/test/hub.test.ts | 92 ++++++++++++++----- packages/hub/test/scope.test.ts | 22 ++--- .../integrations/test/captureconsole.test.ts | 54 +++++------ packages/integrations/test/debug.test.ts | 1 + packages/integrations/test/dedupe.test.ts | 14 ++- .../integrations/test/extraerrordata.test.ts | 4 +- packages/integrations/test/offline.test.ts | 2 +- .../test/reportingobserver.test.ts | 45 ++++----- .../integrations/test/rewriteframes.test.ts | 6 -- packages/integrations/tsconfig.test.json | 2 +- packages/node/test/integrations/http.test.ts | 2 +- packages/node/test/transports/http.test.ts | 1 + packages/serverless/src/awslambda.ts | 2 +- packages/serverless/src/gcpfunction/http.ts | 2 +- .../serverless/test/google-cloud-http.test.ts | 1 + .../test/browser/browsertracing.test.ts | 4 +- packages/tracing/test/browser/metrics.test.ts | 12 +-- packages/tracing/test/browser/request.test.ts | 38 ++++---- packages/tracing/test/browser/router.test.ts | 3 +- packages/tracing/test/errors.test.ts | 15 +-- packages/tracing/test/idletransaction.test.ts | 8 +- packages/utils/src/instrument.ts | 4 +- packages/utils/test/clientreport.test.ts | 2 +- packages/utils/test/syncpromise.test.ts | 22 ++--- 35 files changed, 243 insertions(+), 169 deletions(-) diff --git a/jest.config.js b/jest.config.js index 208a643187f4..8b7b7f1f5b7c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,7 +11,6 @@ module.exports = { globals: { 'ts-jest': { tsconfig: '/tsconfig.test.json', - diagnostics: false, }, }, testPathIgnorePatterns: ['/build/', '/node_modules/'], diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 6650877ff39b..6ccd4b5975a3 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -1,4 +1,4 @@ -import { ExtendedError } from '@sentry/types'; +import { Event as SentryEvent, Exception, ExtendedError } from '@sentry/types'; import { createStackParser } from '@sentry/utils'; import { BrowserClient } from '../../../src/client'; @@ -8,6 +8,12 @@ import { setupBrowserTransport } from '../../../src/transports'; const parser = createStackParser(...defaultStackParsers); +type EventWithException = SentryEvent & { + exception: { + values: Exception[]; + }; +}; + describe('LinkedErrors', () => { describe('handler', () => { it('should bail out if event does not contain exception', () => { @@ -44,7 +50,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { originalException, - }); + }) as EventWithException; // It shouldn't include root exception, as it's already processed in the event by the main error handler expect(result.exception.values.length).toBe(3); @@ -75,7 +81,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { originalException, - }); + }) as EventWithException; expect(result.exception.values.length).toBe(3); expect(result.exception.values[0].type).toBe('SyntaxError'); @@ -103,7 +109,7 @@ describe('LinkedErrors', () => { return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, { originalException, - }); + }) as EventWithException; expect(result.exception.values.length).toBe(2); expect(result.exception.values[0].type).toBe('TypeError'); diff --git a/packages/browser/test/unit/mocks/simpletransport.ts b/packages/browser/test/unit/mocks/simpletransport.ts index 7d0b0e9498df..398feb1a3e6a 100644 --- a/packages/browser/test/unit/mocks/simpletransport.ts +++ b/packages/browser/test/unit/mocks/simpletransport.ts @@ -3,6 +3,7 @@ import { eventStatusFromHttpCode, resolvedSyncPromise } from '@sentry/utils'; import { Event, Response } from '../../../src'; import { BaseTransport } from '../../../src/transports'; +// @ts-ignore It's okay that we're not implementing the `_sendRequest()` method because we don't use it in our tests export class SimpleTransport extends BaseTransport { public sendEvent(_: Event): PromiseLike { return this._buffer.add(() => diff --git a/packages/browser/test/unit/transports/base.test.ts b/packages/browser/test/unit/transports/base.test.ts index 2f9fc26d07be..9df498352c1e 100644 --- a/packages/browser/test/unit/transports/base.test.ts +++ b/packages/browser/test/unit/transports/base.test.ts @@ -3,6 +3,8 @@ import { BaseTransport } from '../../../src/transports/base'; const testDsn = 'https://123@sentry.io/42'; const envelopeEndpoint = 'https://sentry.io/api/42/envelope/?sentry_key=123&sentry_version=7'; +// @ts-ignore We're purposely not implementing the methods of the abstract `BaseTransport` class in order to be able to +// assert on what the class provides and what it leaves to the concrete class to implement class SimpleTransport extends BaseTransport {} describe('BaseTransport', () => { @@ -111,12 +113,12 @@ describe('BaseTransport', () => { }); }); - it('doesnt provide sendEvent() implementation', () => { + it('doesnt provide sendEvent() implementation', async () => { expect.assertions(1); const transport = new SimpleTransport({ dsn: testDsn }); try { - void transport.sendEvent({}); + await transport.sendEvent({}); } catch (e) { expect(e).toBeDefined(); } diff --git a/packages/browser/test/unit/transports/new-xhr.test.ts b/packages/browser/test/unit/transports/new-xhr.test.ts index 5b3bbda313c7..603b0f6037dc 100644 --- a/packages/browser/test/unit/transports/new-xhr.test.ts +++ b/packages/browser/test/unit/transports/new-xhr.test.ts @@ -27,7 +27,7 @@ function createXHRMock() { case 'Retry-After': return '10'; case `${retryAfterSeconds}`: - return; + return null; default: return `${retryAfterSeconds}:error:scope`; } @@ -57,7 +57,7 @@ describe('NewXHRTransport', () => { expect(xhrMock.setRequestHeader).toHaveBeenCalledTimes(0); expect(xhrMock.send).toHaveBeenCalledTimes(0); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.open).toHaveBeenCalledTimes(1); expect(xhrMock.open).toHaveBeenCalledWith('POST', DEFAULT_XHR_TRANSPORT_OPTIONS.url); @@ -70,7 +70,7 @@ describe('NewXHRTransport', () => { const [res] = await Promise.all([ transport.send(ERROR_ENVELOPE), - (xhrMock as XMLHttpRequest).onreadystatechange(null), + (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event), ]); expect(res).toBeDefined(); @@ -80,7 +80,7 @@ describe('NewXHRTransport', () => { it('sets rate limit response headers', async () => { const transport = makeNewXHRTransport(DEFAULT_XHR_TRANSPORT_OPTIONS); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.getResponseHeader).toHaveBeenCalledTimes(2); expect(xhrMock.getResponseHeader).toHaveBeenCalledWith('X-Sentry-Rate-Limits'); @@ -99,7 +99,7 @@ describe('NewXHRTransport', () => { }; const transport = makeNewXHRTransport(options); - await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange(null)]); + await Promise.all([transport.send(ERROR_ENVELOPE), (xhrMock as XMLHttpRequest).onreadystatechange!({} as Event)]); expect(xhrMock.setRequestHeader).toHaveBeenCalledTimes(3); expect(xhrMock.setRequestHeader).toHaveBeenCalledWith('referrerPolicy', headers.referrerPolicy); diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 72c0ef63c211..1bd2750e5378 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -69,7 +69,7 @@ describe('BaseClient', () => { const options = { dsn: PUBLIC_DSN }; const client = new TestClient(options, setupTestTransport(options).transport); - expect(dsnToString(client.getDsn())).toBe(PUBLIC_DSN); + expect(dsnToString(client.getDsn()!)).toBe(PUBLIC_DSN); }); test('allows missing Dsn', () => { diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 2a49f9fea757..707513ff91b1 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -79,7 +79,7 @@ export function setupTestTransport(options: TestOptions): { transport: Transport const transportOptions = options.transportOptions ? options.transportOptions : { dsn: options.dsn }; if (options.transport) { - return { transport: new this._options.transport(transportOptions) }; + return { transport: new options.transport(transportOptions) }; } return noop; diff --git a/packages/gatsby/test/gatsby-browser.test.ts b/packages/gatsby/test/gatsby-browser.test.ts index a2044dd2c8a9..cfeb9d227a88 100644 --- a/packages/gatsby/test/gatsby-browser.test.ts +++ b/packages/gatsby/test/gatsby-browser.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-explicit-any */ -const { onClientEntry } = require('../gatsby-browser'); +import { onClientEntry } from '../gatsby-browser'; (global as any).__SENTRY_RELEASE__ = '683f3a6ab819d47d23abfca9a914c81f0524d35b'; (global as any).__SENTRY_DSN__ = 'https://examplePublicKey@o0.ingest.sentry.io/0'; @@ -153,7 +153,7 @@ describe('onClientEntry', () => { // Run this last to check for any test side effects it('does not run if plugin params are undefined', () => { - onClientEntry(); + onClientEntry(undefined, undefined); expect(sentryInit).toHaveBeenCalledTimes(0); expect(tracingAddExtensionMethods).toHaveBeenCalledTimes(0); }); diff --git a/packages/gatsby/test/gatsby-node.test.ts b/packages/gatsby/test/gatsby-node.test.ts index f09f8e5be781..8880c133b90d 100644 --- a/packages/gatsby/test/gatsby-node.test.ts +++ b/packages/gatsby/test/gatsby-node.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-explicit-any */ -const { onCreateWebpackConfig } = require('../gatsby-node'); +import { onCreateWebpackConfig } from '../gatsby-node'; describe('onCreateWebpackConfig', () => { it('sets a webpack config', () => { @@ -12,7 +12,9 @@ describe('onCreateWebpackConfig', () => { setWebpackConfig: jest.fn(), }; - onCreateWebpackConfig({ plugins, actions }); + const getConfig = jest.fn(); + + onCreateWebpackConfig({ plugins, actions, getConfig }); expect(plugins.define).toHaveBeenCalledTimes(1); expect(plugins.define).toHaveBeenLastCalledWith({ diff --git a/packages/gatsby/test/setEnvVars.ts b/packages/gatsby/test/setEnvVars.ts index c97579e924e7..bc9d45b9c84a 100644 --- a/packages/gatsby/test/setEnvVars.ts +++ b/packages/gatsby/test/setEnvVars.ts @@ -1,2 +1,6 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access process.env.SENTRY_RELEASE = '14abbb1678a2eb59d1a171ea33d630dd6c6eee70'; + +// This file needs to have an import or an export to count as a module, which is necessary when using +// the `isolatedModules` tsconfig option. +export const _ = ''; diff --git a/packages/hub/test/global.test.ts b/packages/hub/test/global.test.ts index ec63679d5592..8dc32acb7fc7 100644 --- a/packages/hub/test/global.test.ts +++ b/packages/hub/test/global.test.ts @@ -1,5 +1,9 @@ +import { getGlobalObject } from '@sentry/utils'; + import { getCurrentHub, getHubFromCarrier, Hub } from '../src'; +const global = getGlobalObject(); + describe('global', () => { test('getGlobalHub', () => { expect(getCurrentHub()).toBeTruthy(); diff --git a/packages/hub/test/hub.test.ts b/packages/hub/test/hub.test.ts index 98c8dcea0636..6754ac258669 100644 --- a/packages/hub/test/hub.test.ts +++ b/packages/hub/test/hub.test.ts @@ -1,4 +1,5 @@ -import { Event } from '@sentry/types'; +/* eslint-disable @typescript-eslint/unbound-method */ +import { Client, Event } from '@sentry/types'; import { getCurrentHub, Hub, Scope } from '../src'; @@ -15,7 +16,18 @@ function makeClient() { getIntegration: jest.fn(), setupIntegrations: jest.fn(), captureMessage: jest.fn(), - }; + } as unknown as Client; +} + +/** + * Return an array containing the arguments passed to the given mocked or spied-upon function. + * + * By default, the args passed to the first call of the function are returned, but it is also possible to retrieve the + * nth call by passing `callIndex`. If the function wasn't called, an error message is returned instead. + */ +function getPassedArgs(mock: (...args: any[]) => any, callIndex: number = 0): any[] { + const asMock = mock as jest.MockedFunction<(...args: any[]) => any>; + return asMock.mock.calls[callIndex] || ["Error: Function wasn't called."]; } describe('Hub', () => { @@ -102,7 +114,7 @@ describe('Hub', () => { }); }); - test('inherit processors', () => { + test('inherit processors', async () => { expect.assertions(1); const event: Event = { extra: { b: 3 }, @@ -210,34 +222,45 @@ describe('Hub', () => { test('simple', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureException('a'); - expect(testClient.captureException).toHaveBeenCalled(); - expect(testClient.captureException.mock.calls[0][0]).toBe('a'); + const args = getPassedArgs(testClient.captureException); + + expect(args[0]).toBe('a'); }); test('should set event_id in hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureException('a'); - expect(testClient.captureException.mock.calls[0][1].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureException('a', { event_id: id }); - expect(testClient.captureException.mock.calls[0][1].event_id).toBe(id); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].event_id).toBe(id); }); test('should generate hint if not provided in the call', () => { const testClient = makeClient(); const hub = new Hub(testClient); const ex = new Error('foo'); + hub.captureException(ex); - expect(testClient.captureException.mock.calls[0][1].originalException).toBe(ex); - expect(testClient.captureException.mock.calls[0][1].syntheticException).toBeInstanceOf(Error); - expect(testClient.captureException.mock.calls[0][1].syntheticException.message).toBe('Sentry syntheticException'); + const args = getPassedArgs(testClient.captureException); + + expect(args[1].originalException).toBe(ex); + expect(args[1].syntheticException).toBeInstanceOf(Error); + expect(args[1].syntheticException.message).toBe('Sentry syntheticException'); }); }); @@ -245,32 +268,44 @@ describe('Hub', () => { test('simple', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('a'); - expect(testClient.captureMessage.mock.calls[0][0]).toBe('a'); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[0]).toBe('a'); }); test('should set event_id in hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('a'); - expect(testClient.captureMessage.mock.calls[0][2].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureMessage('a', undefined, { event_id: id }); - expect(testClient.captureMessage.mock.calls[0][2].event_id).toBe(id); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].event_id).toBe(id); }); test('should generate hint if not provided in the call', () => { const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureMessage('foo'); - expect(testClient.captureMessage.mock.calls[0][2].originalException).toBe('foo'); - expect(testClient.captureMessage.mock.calls[0][2].syntheticException).toBeInstanceOf(Error); - expect(testClient.captureMessage.mock.calls[0][2].syntheticException.message).toBe('foo'); + const args = getPassedArgs(testClient.captureMessage); + + expect(args[2].originalException).toBe('foo'); + expect(args[2].syntheticException).toBeInstanceOf(Error); + expect(args[2].syntheticException.message).toBe('foo'); }); }); @@ -281,8 +316,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][0]).toBe(event); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[0]).toBe(event); }); test('should set event_id in hint', () => { @@ -291,8 +329,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toBeTruthy(); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toBeTruthy(); }); test('should keep event_id from hint', () => { @@ -302,8 +343,11 @@ describe('Hub', () => { const testClient = makeClient(); const hub = new Hub(testClient); const id = Math.random().toString(); + hub.captureEvent(event, { event_id: id }); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toBe(id); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toBe(id); }); test('sets lastEventId', () => { @@ -312,8 +356,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).toEqual(hub.lastEventId()); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).toEqual(hub.lastEventId()); }); test('transactions do not set lastEventId', () => { @@ -323,8 +370,11 @@ describe('Hub', () => { }; const testClient = makeClient(); const hub = new Hub(testClient); + hub.captureEvent(event); - expect(testClient.captureEvent.mock.calls[0][1].event_id).not.toEqual(hub.lastEventId()); + const args = getPassedArgs(testClient.captureEvent); + + expect(args[1].event_id).not.toEqual(hub.lastEventId()); }); }); diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index 7cca748fb6f8..b734ac59fcf6 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -1,4 +1,4 @@ -import { Event, EventHint } from '@sentry/types'; +import { Event, EventHint, RequestSessionStatus } from '@sentry/types'; import { getGlobalObject } from '@sentry/utils'; import { addGlobalEventProcessor, Scope } from '../src'; @@ -194,7 +194,7 @@ describe('Scope', () => { }); describe('applyToEvent', () => { - test('basic usage', () => { + test('basic usage', async () => { expect.assertions(9); const scope = new Scope(); @@ -222,7 +222,7 @@ describe('Scope', () => { }); }); - test('merge with existing event data', () => { + test('merge with existing event data', async () => { expect.assertions(8); const scope = new Scope(); scope.setExtra('a', 2); @@ -291,7 +291,7 @@ describe('Scope', () => { }); }); - test('scope level should have priority over event level', () => { + test('scope level should have priority over event level', async () => { expect.assertions(1); const scope = new Scope(); scope.setLevel('warning'); @@ -302,7 +302,7 @@ describe('Scope', () => { }); }); - test('scope transaction should have priority over event transaction', () => { + test('scope transaction should have priority over event transaction', async () => { expect.assertions(1); const scope = new Scope(); scope.setTransactionName('/abc'); @@ -511,10 +511,10 @@ describe('Scope', () => { contexts: { bar: { id: '3' }, baz: { id: '4' } }, extra: { bar: '3', baz: '4' }, fingerprint: ['bar'], - level: 'warning', + level: 'warning' as const, tags: { bar: '3', baz: '4' }, user: { id: '42' }, - requestSession: { status: 'errored' }, + requestSession: { status: 'errored' as RequestSessionStatus }, }; const updatedScope = scope.update(localAttributes) as any; @@ -541,7 +541,7 @@ describe('Scope', () => { }); describe('addEventProcessor', () => { - test('should allow for basic event manipulation', () => { + test('should allow for basic event manipulation', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, @@ -566,7 +566,7 @@ describe('Scope', () => { }); }); - test('should work alongside global event processors', () => { + test('should work alongside global event processors', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, @@ -667,7 +667,7 @@ describe('Scope', () => { }); }); - test('should drop an event when any of processors return null', () => { + test('should drop an event when any of processors return null', async () => { expect.assertions(1); const event: Event = { extra: { b: 3 }, @@ -680,7 +680,7 @@ describe('Scope', () => { }); }); - test('should have an access to the EventHint', () => { + test('should have an access to the EventHint', async () => { expect.assertions(3); const event: Event = { extra: { b: 3 }, diff --git a/packages/integrations/test/captureconsole.test.ts b/packages/integrations/test/captureconsole.test.ts index bb6cce8110d3..966c76879522 100644 --- a/packages/integrations/test/captureconsole.test.ts +++ b/packages/integrations/test/captureconsole.test.ts @@ -1,4 +1,5 @@ -import { Event, Integration } from '@sentry/types'; +/* eslint-disable @typescript-eslint/unbound-method */ +import { Event, Hub, Integration } from '@sentry/types'; import { CaptureConsole } from '../src/captureconsole'; @@ -16,10 +17,11 @@ const mockHub = { captureException: jest.fn(), }; -const getMockHubWithIntegration = (integration: Integration) => ({ - ...mockHub, - getIntegration: jest.fn(() => integration), -}); +const getMockHubWithIntegration = (integration: Integration) => + ({ + ...mockHub, + getIntegration: jest.fn(() => integration), + } as unknown as Hub); // We're using this to un-monkey patch the console after each test. const originalConsole = Object.assign({}, global.console); @@ -36,7 +38,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'warn'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); expect(global.console.error).toBe(originalConsole.error); // not monkey patched @@ -48,7 +50,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // expect a set of defined console levels to have been monkey patched @@ -68,7 +70,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: [] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // expect the default set of console levels not to have been monkey patched @@ -93,7 +95,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); }).not.toThrow(); @@ -105,7 +107,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -119,7 +121,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -135,7 +137,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // call a wrapped function @@ -154,7 +156,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 3); @@ -168,7 +170,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 3, 'expression is false'); @@ -182,7 +184,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['assert'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.assert(1 + 1 === 2); @@ -192,7 +194,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); const someError = new Error('some error'); @@ -206,7 +208,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); const someError = new Error('some error'); @@ -220,7 +222,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole(); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.error('some message'); @@ -233,7 +235,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.error('some non-error message'); @@ -247,7 +249,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['info'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.info('some message'); @@ -265,7 +267,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); global.console.log('some message 1', 'some message 2'); @@ -281,11 +283,11 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'someNonExistingLevel', 'error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); // The provided level should not be created - expect(global.console['someNonExistingLevel']).toBeUndefined(); + expect((global.console as any)['someNonExistingLevel']).toBeUndefined(); // Ohter levels should be wrapped as expected expect(global.console.log).not.toBe(originalConsole.log); @@ -296,7 +298,7 @@ describe('CaptureConsole setup', () => { const captureConsoleIntegration = new CaptureConsole({ levels: ['log', 'error'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, // simulate not having the integration registered + () => getMockHubWithIntegration(null as any), // simulate not having the integration registered ); // Console should be wrapped @@ -310,12 +312,12 @@ describe('CaptureConsole setup', () => { it("should not crash when the original console methods don't exist at time of invocation", () => { const originalConsoleLog = global.console.log; - global.console.log = undefined; // don't `delete` here, otherwise `fill` won't wrap the function + global.console.log = undefined as any; // don't `delete` here, otherwise `fill` won't wrap the function const captureConsoleIntegration = new CaptureConsole({ levels: ['log'] }); captureConsoleIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(captureConsoleIntegration) as any, + () => getMockHubWithIntegration(captureConsoleIntegration), ); expect(() => { diff --git a/packages/integrations/test/debug.test.ts b/packages/integrations/test/debug.test.ts index 5c2f84f5d1e6..768c9606a1fb 100644 --- a/packages/integrations/test/debug.test.ts +++ b/packages/integrations/test/debug.test.ts @@ -8,6 +8,7 @@ const mockGetCurrentHub = (getIntegrationResult: Integration) => ({ // Replace console log with a mock so we can check for invocations const mockConsoleLog = jest.fn(); +// eslint-disable-next-line @typescript-eslint/unbound-method const originalConsoleLog = global.console.log; global.console.log = mockConsoleLog; diff --git a/packages/integrations/test/dedupe.test.ts b/packages/integrations/test/dedupe.test.ts index c56ab59d5b82..8bc354ffa620 100644 --- a/packages/integrations/test/dedupe.test.ts +++ b/packages/integrations/test/dedupe.test.ts @@ -1,13 +1,21 @@ -import { Event } from '@sentry/types'; +import { Event as SentryEvent, Exception, StackFrame, Stacktrace } from '@sentry/types'; import { _shouldDropEvent } from '../src/dedupe'; +type EventWithException = SentryEvent & { + exception: { + values: ExceptionWithStacktrace[]; + }; +}; +type ExceptionWithStacktrace = Exception & { stacktrace: StacktraceWithFrames }; +type StacktraceWithFrames = Stacktrace & { frames: StackFrame[] }; + /** JSDoc */ function clone(data: T): T { return JSON.parse(JSON.stringify(data)); } -const messageEvent: Event = { +const messageEvent: EventWithException = { fingerprint: ['MrSnuffles'], message: 'PickleRick', exception: { @@ -34,7 +42,7 @@ const messageEvent: Event = { ], }, }; -const exceptionEvent: Event = { +const exceptionEvent: EventWithException = { exception: { values: [ { diff --git a/packages/integrations/test/extraerrordata.test.ts b/packages/integrations/test/extraerrordata.test.ts index ed76a2dc75ca..68e38720f761 100644 --- a/packages/integrations/test/extraerrordata.test.ts +++ b/packages/integrations/test/extraerrordata.test.ts @@ -71,7 +71,7 @@ describe('ExtraErrorData()', () => { event = { // @ts-ignore Allow contexts on event contexts: { - foo: 42, + foo: { bar: 42 }, }, }; const error = new TypeError('foo') as ExtendedError; @@ -85,7 +85,7 @@ describe('ExtraErrorData()', () => { TypeError: { baz: 42, }, - foo: 42, + foo: { bar: 42 }, }); }); diff --git a/packages/integrations/test/offline.test.ts b/packages/integrations/test/offline.test.ts index 1f728d835abd..9c4eb8ad2e36 100644 --- a/packages/integrations/test/offline.test.ts +++ b/packages/integrations/test/offline.test.ts @@ -169,7 +169,7 @@ function initIntegration(options: { maxStoredEvents?: number } = {}): void { jest.spyOn(utils, 'getGlobalObject').mockImplementation( () => ({ - addEventListener: (_windowEvent, callback) => { + addEventListener: (_windowEvent: any, callback: any) => { eventListeners.push(callback); }, navigator: { diff --git a/packages/integrations/test/reportingobserver.test.ts b/packages/integrations/test/reportingobserver.test.ts index 1d6417e8ccc7..91547d5572f8 100644 --- a/packages/integrations/test/reportingobserver.test.ts +++ b/packages/integrations/test/reportingobserver.test.ts @@ -1,4 +1,4 @@ -import { Integration } from '@sentry/types'; +import { Hub, Integration } from '@sentry/types'; import { ReportingObserver } from '../src/reportingobserver'; @@ -13,10 +13,11 @@ const mockHub = { captureMessage: jest.fn(), }; -const getMockHubWithIntegration = (integration: Integration) => ({ - ...mockHub, - getIntegration: jest.fn(() => integration), -}); +const getMockHubWithIntegration = (integration: Integration) => + ({ + ...mockHub, + getIntegration: jest.fn(() => integration), + } as unknown as Hub); const mockReportingObserverConstructor = jest.fn(); const mockObserve = jest.fn(); @@ -49,7 +50,7 @@ describe('ReportingObserver', () => { expect(() => { reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, + () => getMockHubWithIntegration(null as any), ); }).not.toThrow(); @@ -61,7 +62,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -75,7 +76,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver({ types: ['crash'] }); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -89,7 +90,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockReportingObserverConstructor).toHaveBeenCalledTimes(1); @@ -103,7 +104,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); expect(mockObserve).toHaveBeenCalledTimes(1); @@ -115,7 +116,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(null) as any, + () => getMockHubWithIntegration(null as any), ); expect(() => { @@ -129,7 +130,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([ @@ -144,7 +145,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([ @@ -160,7 +161,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report1 = { type: 'crash', url: 'some url 1', body: { crashId: 'id1' } } as const; @@ -176,7 +177,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); reportingObserverIntegration.handler([{ type: 'crash', url: 'some url' }]); @@ -188,7 +189,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -207,7 +208,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -225,7 +226,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -243,7 +244,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -260,7 +261,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { type: 'crash', url: 'some url', body: { crashId: '', reason: '' } } as const; @@ -274,7 +275,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { @@ -292,7 +293,7 @@ describe('ReportingObserver', () => { const reportingObserverIntegration = new ReportingObserver(); reportingObserverIntegration.setupOnce( () => undefined, - () => getMockHubWithIntegration(reportingObserverIntegration) as any, + () => getMockHubWithIntegration(reportingObserverIntegration), ); const report = { diff --git a/packages/integrations/test/rewriteframes.test.ts b/packages/integrations/test/rewriteframes.test.ts index ff18e16f753d..bbe0a157e44a 100644 --- a/packages/integrations/test/rewriteframes.test.ts +++ b/packages/integrations/test/rewriteframes.test.ts @@ -3,18 +3,12 @@ import { Event, StackFrame } from '@sentry/types'; import { RewriteFrames } from '../src/rewriteframes'; let rewriteFrames: RewriteFrames; -let messageEvent: Event; let exceptionEvent: Event; let windowsExceptionEvent: Event; let multipleStacktracesEvent: Event; describe('RewriteFrames', () => { beforeEach(() => { - messageEvent = { - stacktrace: { - frames: [{ filename: '/www/src/app/file1.js' }, { filename: '/www/src/app/mo\\dule/file2.js' }], - }, - }; exceptionEvent = { exception: { values: [ diff --git a/packages/integrations/tsconfig.test.json b/packages/integrations/tsconfig.test.json index af7e36ec0eda..87f6afa06b86 100644 --- a/packages/integrations/tsconfig.test.json +++ b/packages/integrations/tsconfig.test.json @@ -5,7 +5,7 @@ "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["jest"] + "types": ["node", "jest"] // other package-specific, test-specific options } diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 5a05d79e3b1b..f66f847cd298 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -168,7 +168,7 @@ describe('default protocols', () => { let nockProtocol = 'https'; const proxy = 'http://:3128'; - const agent = new HttpsProxyAgent(proxy); + const agent = HttpsProxyAgent(proxy); if (NODE_VERSION.major && NODE_VERSION.major < 9) { nockProtocol = 'http'; diff --git a/packages/node/test/transports/http.test.ts b/packages/node/test/transports/http.test.ts index e2e837fee2d3..8c7abfa2ade2 100644 --- a/packages/node/test/transports/http.test.ts +++ b/packages/node/test/transports/http.test.ts @@ -31,6 +31,7 @@ const sessionPayload: Session = { update: jest.fn(), close: jest.fn(), toJSON: jest.fn(), + ignoreDuration: false, }; const sessionsPayload: SessionAggregates = { attrs: { environment: 'test', release: '1.0' }, diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index 0b86f560a820..bac3e1412c8b 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -279,7 +279,7 @@ export function wrapHandler( scope.setTag('timeout', humanReadableTimeout); captureMessage(`Possible function timeout: ${context.functionName}`, 'warning'); }); - }, timeoutWarningDelay); + }, timeoutWarningDelay) as unknown as NodeJS.Timeout; } // Applying `sentry-trace` to context diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts index 607656fb3dbd..2e274bad3491 100644 --- a/packages/serverless/src/gcpfunction/http.ts +++ b/packages/serverless/src/gcpfunction/http.ts @@ -86,7 +86,7 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial void), encoding?: string | (() => void), cb?: () => void): void { + res.end = function (chunk?: any | (() => void), encoding?: string | (() => void), cb?: () => void): any { transaction.setHttpStatus(res.statusCode); transaction.finish(); diff --git a/packages/serverless/test/google-cloud-http.test.ts b/packages/serverless/test/google-cloud-http.test.ts index fced84730b00..7d785462a4d9 100644 --- a/packages/serverless/test/google-cloud-http.test.ts +++ b/packages/serverless/test/google-cloud-http.test.ts @@ -62,6 +62,7 @@ describe('GoogleCloudHttp tracing', () => { op: 'gcloud.http.bigquery', description: 'POST /jobs', }); + // @ts-ignore see "Why @ts-ignore" note expect(Sentry.fakeTransaction.startChild).toBeCalledWith({ op: 'gcloud.http.bigquery', description: expect.stringMatching(new RegExp('^GET /queries/.+')), diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index 510befc29064..dfa4e0436b8c 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,7 +1,7 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; -import { getGlobalObject } from '@sentry/utils'; +import { getGlobalObject, InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; import { @@ -24,7 +24,7 @@ jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback): void => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback): void => { if (type === 'history') { // rather than actually add the navigation-change handler, grab a reference to it, so we can trigger it manually mockChangeHistory = callback; diff --git a/packages/tracing/test/browser/metrics.test.ts b/packages/tracing/test/browser/metrics.test.ts index 7133f7975221..eb79ff30df93 100644 --- a/packages/tracing/test/browser/metrics.test.ts +++ b/packages/tracing/test/browser/metrics.test.ts @@ -1,11 +1,5 @@ import { Span, Transaction } from '../../src'; -import { - _startChild, - addResourceSpans, - DEFAULT_METRICS_INSTR_OPTIONS, - MetricsInstrumentation, - ResourceEntry, -} from '../../src/browser/metrics'; +import { _startChild, addResourceSpans, MetricsInstrumentation, ResourceEntry } from '../../src/browser/metrics'; import { addDOMPropertiesToGlobal } from '../testutils'; // eslint-disable-next-line @typescript-eslint/no-explicit-any, no-var @@ -186,7 +180,7 @@ describe('MetricsInstrumentation', () => { jest.spyOn(MetricsInstrumentation.prototype as any, tracker), ); - new MetricsInstrumentation(DEFAULT_METRICS_INSTR_OPTIONS); + new MetricsInstrumentation(); trackers.forEach(tracker => expect(tracker).not.toBeCalled()); }); @@ -200,7 +194,7 @@ describe('MetricsInstrumentation', () => { const trackers = ['_trackCLS', '_trackLCP', '_trackFID'].map(tracker => jest.spyOn(MetricsInstrumentation.prototype as any, tracker), ); - new MetricsInstrumentation(DEFAULT_METRICS_INSTR_OPTIONS); + new MetricsInstrumentation(); global.process = backup; trackers.forEach(tracker => expect(tracker).toBeCalled()); diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index a31aa10d5c8a..65823e293351 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -4,7 +4,7 @@ import { Hub, makeMain } from '@sentry/hub'; import * as utils from '@sentry/utils'; import { Span, spanStatusfromHttpCode, Transaction } from '../../src'; -import { fetchCallback, FetchData, instrumentOutgoingRequests, xhrCallback, XHRData } from '../../src/browser/request'; +import { fetchCallback, FetchData, instrumentOutgoingRequests, xhrCallback } from '../../src/browser/request'; import { addExtensionMethods } from '../../src/hubextensions'; import * as tracingUtils from '../../src/utils'; @@ -56,7 +56,7 @@ describe('callbacks', () => { fetchData: { url: 'http://dogs.are.great/', method: 'GET' }, startTimestamp, }; - const xhrHandlerData: XHRData = { + const xhrHandlerData = { xhr: { __sentry_xhr__: { method: 'GET', @@ -130,17 +130,17 @@ describe('callbacks', () => { // triggered by request being sent fetchCallback(fetchHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); expect(newSpan).toBeInstanceOf(Span); - expect(newSpan!.data).toEqual({ + expect(newSpan.data).toEqual({ method: 'GET', type: 'fetch', url: 'http://dogs.are.great/', }); - expect(newSpan!.description).toBe('GET http://dogs.are.great/'); - expect(newSpan!.op).toBe('http.client'); + expect(newSpan.description).toBe('GET http://dogs.are.great/'); + expect(newSpan.op).toBe('http.client'); expect(fetchHandlerData.fetchData?.__span).toBeDefined(); const postRequestFetchHandlerData = { @@ -151,7 +151,7 @@ describe('callbacks', () => { // triggered by response coming back fetchCallback(postRequestFetchHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.endTimestamp).toBeDefined(); + expect(newSpan.endTimestamp).toBeDefined(); }); it('sets response status on finish', () => { @@ -160,7 +160,7 @@ describe('callbacks', () => { // triggered by request being sent fetchCallback(fetchHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); @@ -173,7 +173,7 @@ describe('callbacks', () => { // triggered by response coming back fetchCallback(postRequestFetchHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.status).toBe(spanStatusfromHttpCode(404)); + expect(newSpan.status).toBe(spanStatusfromHttpCode(404)); }); it('ignores response with no associated span', () => { @@ -238,18 +238,18 @@ describe('callbacks', () => { // triggered by request being sent xhrCallback(xhrHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeInstanceOf(Span); - expect(newSpan!.data).toEqual({ + expect(newSpan.data).toEqual({ method: 'GET', type: 'xhr', url: 'http://dogs.are.great/', }); - expect(newSpan!.description).toBe('GET http://dogs.are.great/'); - expect(newSpan!.op).toBe('http.client'); - expect(xhrHandlerData.xhr!.__sentry_xhr_span_id__).toBeDefined(); - expect(xhrHandlerData.xhr!.__sentry_xhr_span_id__).toEqual(newSpan?.spanId); + expect(newSpan.description).toBe('GET http://dogs.are.great/'); + expect(newSpan.op).toBe('http.client'); + expect(xhrHandlerData.xhr.__sentry_xhr_span_id__).toBeDefined(); + expect(xhrHandlerData.xhr.__sentry_xhr_span_id__).toEqual(newSpan?.spanId); const postRequestXHRHandlerData = { ...xhrHandlerData, @@ -259,7 +259,7 @@ describe('callbacks', () => { // triggered by response coming back xhrCallback(postRequestXHRHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.endTimestamp).toBeDefined(); + expect(newSpan.endTimestamp).toBeDefined(); }); it('sets response status on finish', () => { @@ -268,7 +268,7 @@ describe('callbacks', () => { // triggered by request being sent xhrCallback(xhrHandlerData, alwaysCreateSpan, spans); - const newSpan = transaction.spanRecorder?.spans[1]; + const newSpan = transaction.spanRecorder?.spans[1] as Span; expect(newSpan).toBeDefined(); @@ -276,12 +276,12 @@ describe('callbacks', () => { ...xhrHandlerData, endTimestamp, }; - postRequestXHRHandlerData.xhr!.__sentry_xhr__!.status_code = 404; + postRequestXHRHandlerData.xhr.__sentry_xhr__.status_code = 404; // triggered by response coming back xhrCallback(postRequestXHRHandlerData, alwaysCreateSpan, spans); - expect(newSpan!.status).toBe(spanStatusfromHttpCode(404)); + expect(newSpan.status).toBe(spanStatusfromHttpCode(404)); }); it('ignores response with no associated span', () => { diff --git a/packages/tracing/test/browser/router.test.ts b/packages/tracing/test/browser/router.test.ts index e340a81222fe..9d1ae86f4e01 100644 --- a/packages/tracing/test/browser/router.test.ts +++ b/packages/tracing/test/browser/router.test.ts @@ -1,3 +1,4 @@ +import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; import { instrumentRoutingWithDefaults } from '../../src/browser/router'; @@ -8,7 +9,7 @@ jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback): void => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback): void => { addInstrumentationHandlerType = type; mockChangeHistory = callback; }, diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index ca042672b595..c15825fd5480 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,18 +1,19 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; import { Hub, makeMain } from '@sentry/hub'; +import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { registerErrorInstrumentation } from '../src/errors'; import { _addTracingExtensions } from '../src/hubextensions'; const mockAddInstrumentationHandler = jest.fn(); -let mockErrorCallback: () => void = () => undefined; -let mockUnhandledRejectionCallback: () => void = () => undefined; +let mockErrorCallback: InstrumentHandlerCallback = () => undefined; +let mockUnhandledRejectionCallback: InstrumentHandlerCallback = () => undefined; jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, - addInstrumentationHandler: (type, callback) => { + addInstrumentationHandler: (type: InstrumentHandlerType, callback: InstrumentHandlerCallback) => { if (type === 'error') { mockErrorCallback = callback; } @@ -55,10 +56,10 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); expect(transaction.status).toBe(undefined); - mockErrorCallback(); + mockErrorCallback({}); expect(transaction.status).toBe(undefined); - mockUnhandledRejectionCallback(); + mockUnhandledRejectionCallback({}); expect(transaction.status).toBe(undefined); transaction.finish(); }); @@ -68,7 +69,7 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); hub.configureScope(scope => scope.setSpan(transaction)); - mockErrorCallback(); + mockErrorCallback({}); expect(transaction.status).toBe('internal_error'); transaction.finish(); @@ -79,7 +80,7 @@ describe('registerErrorHandlers()', () => { const transaction = hub.startTransaction({ name: 'test' }); hub.configureScope(scope => scope.setSpan(transaction)); - mockUnhandledRejectionCallback(); + mockUnhandledRejectionCallback({}); expect(transaction.status).toBe('internal_error'); transaction.finish(); }); diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index f2565e1c7e5f..b8029c6b92d7 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -9,7 +9,9 @@ import { } from '../src/idletransaction'; import { Span } from '../src/span'; -export class SimpleTransport extends Transports.BaseTransport {} +// @ts-ignore It's okay that we're not implementing the methods of the abstract `BaseTransport` class, because it's not +// what we're testing here +class SimpleTransport extends Transports.BaseTransport {} const dsn = 'https://123@sentry.io/42'; let hub: Hub; @@ -167,9 +169,9 @@ describe('IdleTransaction', () => { it('should record dropped transactions', async () => { const transaction = new IdleTransaction({ name: 'foo', startTimestamp: 1234, sampled: false }, hub, 1000); - const transport = hub.getClient()?.getTransport(); + const transport = hub.getClient()!.getTransport!(); - const spy = jest.spyOn(transport!, 'recordLostEvent'); + const spy = jest.spyOn(transport, 'recordLostEvent'); transaction.initSpanRecorder(10); transaction.finish(transaction.startTimestamp + 10); diff --git a/packages/utils/src/instrument.ts b/packages/utils/src/instrument.ts index 30fcef290c19..a77e0c8222f3 100644 --- a/packages/utils/src/instrument.ts +++ b/packages/utils/src/instrument.ts @@ -13,7 +13,7 @@ import { supportsHistory, supportsNativeFetch } from './supports'; const global = getGlobalObject(); -type InstrumentHandlerType = +export type InstrumentHandlerType = | 'console' | 'dom' | 'fetch' @@ -22,7 +22,7 @@ type InstrumentHandlerType = | 'xhr' | 'error' | 'unhandledrejection'; -type InstrumentHandlerCallback = (data: any) => void; +export type InstrumentHandlerCallback = (data: any) => void; /** * Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc. diff --git a/packages/utils/test/clientreport.test.ts b/packages/utils/test/clientreport.test.ts index 8d98291c3a14..156ddb95008f 100644 --- a/packages/utils/test/clientreport.test.ts +++ b/packages/utils/test/clientreport.test.ts @@ -3,7 +3,7 @@ import { ClientReport } from '@sentry/types'; import { createClientReportEnvelope } from '../src/clientreport'; import { serializeEnvelope } from '../src/envelope'; -const DEFAULT_DISCARDED_EVENTS: Array = [ +const DEFAULT_DISCARDED_EVENTS: ClientReport['discarded_events'] = [ { reason: 'before_send', category: 'event', diff --git a/packages/utils/test/syncpromise.test.ts b/packages/utils/test/syncpromise.test.ts index 6164c666d967..cdb0a7c6e0e7 100644 --- a/packages/utils/test/syncpromise.test.ts +++ b/packages/utils/test/syncpromise.test.ts @@ -1,7 +1,7 @@ import { rejectedSyncPromise, resolvedSyncPromise, SyncPromise } from '../src/syncpromise'; describe('SyncPromise', () => { - test('simple', () => { + test('simple', async () => { expect.assertions(1); return new SyncPromise(resolve => { @@ -11,7 +11,7 @@ describe('SyncPromise', () => { }); }); - test('simple chaining', () => { + test('simple chaining', async () => { expect.assertions(1); return new SyncPromise(resolve => { @@ -94,7 +94,7 @@ describe('SyncPromise', () => { ); }); - test('simple static', () => { + test('simple static', async () => { expect.assertions(1); const p = resolvedSyncPromise(10); @@ -103,7 +103,7 @@ describe('SyncPromise', () => { }); }); - test('using new Promise internally', () => { + test('using new Promise internally', async () => { expect.assertions(2); return new SyncPromise(done => { @@ -120,7 +120,7 @@ describe('SyncPromise', () => { }); }); - test('with setTimeout', () => { + test('with setTimeout', async () => { jest.useFakeTimers(); expect.assertions(1); @@ -175,7 +175,7 @@ describe('SyncPromise', () => { expect(qp).toHaveProperty('_value'); }); - test('multiple then returning undefined', () => { + test('multiple then returning undefined', async () => { expect.assertions(3); return new SyncPromise(resolve => { @@ -192,7 +192,7 @@ describe('SyncPromise', () => { }); }); - test('multiple then returning different values', () => { + test('multiple then returning different values', async () => { expect.assertions(3); return new SyncPromise(resolve => { @@ -211,7 +211,7 @@ describe('SyncPromise', () => { }); }); - test('multiple then returning different SyncPromise', () => { + test('multiple then returning different SyncPromise', async () => { expect.assertions(2); return new SyncPromise(resolve => { @@ -228,7 +228,7 @@ describe('SyncPromise', () => { }); }); - test('reject immediatly and do not call then', () => { + test('reject immediatly and do not call then', async () => { expect.assertions(1); return new SyncPromise((_, reject) => { @@ -242,7 +242,7 @@ describe('SyncPromise', () => { }); }); - test('reject', () => { + test('reject', async () => { expect.assertions(1); return new SyncPromise((_, reject) => { @@ -252,7 +252,7 @@ describe('SyncPromise', () => { }); }); - test('rejecting after first then', () => { + test('rejecting after first then', async () => { expect.assertions(2); return new SyncPromise(resolve => { From 0b2163b87c9a46caf728d97c3658a9f62f40f1eb Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 18 Apr 2022 13:41:31 -0400 Subject: [PATCH 57/94] ref(node): Remove raven-node backward-compat code (#4942) Removes functionality around syncing context from domain. --- .../src/integrations/onunhandledrejection.ts | 37 ++++--------------- .../node/test/onunhandledrejection.test.ts | 10 ----- 2 files changed, 8 insertions(+), 39 deletions(-) diff --git a/packages/node/src/integrations/onunhandledrejection.ts b/packages/node/src/integrations/onunhandledrejection.ts index 19f733b1f908..2ba9a3d8f205 100644 --- a/packages/node/src/integrations/onunhandledrejection.ts +++ b/packages/node/src/integrations/onunhandledrejection.ts @@ -46,36 +46,15 @@ export class OnUnhandledRejection implements Integration { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any public sendUnhandledPromise(reason: any, promise: any): void { const hub = getCurrentHub(); - - if (!hub.getIntegration(OnUnhandledRejection)) { - this._handleRejection(reason); - return; - } - - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - const context = (promise.domain && promise.domain.sentryContext) || {}; - - hub.withScope((scope: Scope) => { - scope.setExtra('unhandledPromiseRejection', true); - - // Preserve backwards compatibility with raven-node for now - if (context.user) { - scope.setUser(context.user); - } - if (context.tags) { - scope.setTags(context.tags); - } - if (context.extra) { - scope.setExtras(context.extra); - } - - hub.captureException(reason, { - originalException: promise, - data: { mechanism: { handled: false, type: 'onunhandledrejection' } }, + if (hub.getIntegration(OnUnhandledRejection)) { + hub.withScope((scope: Scope) => { + scope.setExtra('unhandledPromiseRejection', true); + hub.captureException(reason, { + originalException: promise, + data: { mechanism: { handled: false, type: 'onunhandledrejection' } }, + }); }); - }); - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - + } this._handleRejection(reason); } diff --git a/packages/node/test/onunhandledrejection.test.ts b/packages/node/test/onunhandledrejection.test.ts index 5d8d498079e5..8588c9edddd6 100644 --- a/packages/node/test/onunhandledrejection.test.ts +++ b/packages/node/test/onunhandledrejection.test.ts @@ -1,4 +1,3 @@ -import { Scope } from '@sentry/core'; import { Hub } from '@sentry/hub'; import { OnUnhandledRejection } from '../src/integrations/onunhandledrejection'; @@ -35,10 +34,6 @@ describe('unhandled promises', () => { }; const captureException = jest.spyOn(Hub.prototype, 'captureException'); - const setUser = jest.spyOn(Scope.prototype, 'setUser'); - const setExtra = jest.spyOn(Scope.prototype, 'setExtra'); - const setExtras = jest.spyOn(Scope.prototype, 'setExtras'); - const setTags = jest.spyOn(Scope.prototype, 'setTags'); integration.sendUnhandledPromise('bla', promise); @@ -46,10 +41,5 @@ describe('unhandled promises', () => { mechanism: { handled: false, type: 'onunhandledrejection' }, }); expect(captureException.mock.calls[0][0]).toBe('bla'); - expect(setUser.mock.calls[0][0]).toEqual({ id: 1 }); - expect(setExtra.mock.calls[0]).toEqual(['unhandledPromiseRejection', true]); - - expect(setExtras.mock.calls[0]).toEqual([{ extra: '1' }]); - expect(setTags.mock.calls[0]).toEqual([{ tag: '2' }]); }); }); From 7e6f7f2f5a831f1fc3410a9d721cf91128ea17a5 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Tue, 19 Apr 2022 06:09:05 -0700 Subject: [PATCH 58/94] ref(build): Split up rollup config code (#4950) As part of the new build process, a fair amount of new rollup-related code is going to be added. To keep things from getting too unwieldy, this splits the existing code up into modules. It also makes two other small changes, one for consistency and one to differentiate the current rollup code (which is for building bundles) from the future rollup code (which will be for building npm packages): - All plugins are now generated through factory functions (`makeXXXPlugin`). - Both the `makeConfigVariants` function and the individual `rollup.config.js` files have been renamed to make it clear they're for creating bundles. For now all of the resulting modules live in a `rollup` folder at the top level of the repo. In the long run, these would be good candidates to go into an `@sentry-internal/dev-utils` package. --- .eslintrc.js | 2 +- packages/browser/package.json | 2 +- ...llup.config.js => rollup.bundle.config.js} | 4 +- ...llup.config.js => rollup.bundle.config.js} | 4 +- packages/integrations/scripts/buildBundles.sh | 2 +- packages/tracing/package.json | 2 +- ...llup.config.js => rollup.bundle.config.js} | 4 +- packages/vue/package.json | 2 +- ...llup.config.js => rollup.bundle.config.js} | 4 +- packages/wasm/package.json | 2 +- ...llup.config.js => rollup.bundle.config.js} | 4 +- rollup.config.js | 270 ------------------ rollup/bundleHelpers.js | 143 ++++++++++ rollup/index.js | 8 + rollup/plugins/bundlePlugins.js | 142 +++++++++ rollup/plugins/index.js | 1 + rollup/utils.js | 16 ++ 17 files changed, 326 insertions(+), 286 deletions(-) rename packages/browser/{rollup.config.js => rollup.bundle.config.js} (67%) rename packages/integrations/{rollup.config.js => rollup.bundle.config.js} (81%) rename packages/tracing/{rollup.config.js => rollup.bundle.config.js} (70%) rename packages/vue/{rollup.config.js => rollup.bundle.config.js} (55%) rename packages/wasm/{rollup.config.js => rollup.bundle.config.js} (55%) delete mode 100644 rollup.config.js create mode 100644 rollup/bundleHelpers.js create mode 100644 rollup/index.js create mode 100644 rollup/plugins/bundlePlugins.js create mode 100644 rollup/plugins/index.js create mode 100644 rollup/utils.js diff --git a/.eslintrc.js b/.eslintrc.js index da303c683c01..956f3681ba72 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -42,7 +42,7 @@ module.exports = { }, }, { - files: ['scenarios/**'], + files: ['scenarios/**', 'rollup/**'], parserOptions: { sourceType: 'module', }, diff --git a/packages/browser/package.json b/packages/browser/package.json index 8ed9132b407e..8f9eb0013e26 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -44,7 +44,7 @@ }, "scripts": { "build": "run-p build:cjs build:esm build:bundle build:types", - "build:bundle": "rollup --config", + "build:bundle": "rollup --config rollup.bundle.config.js", "build:cjs": "tsc -p tsconfig.cjs.json", "build:dev": "run-p build:cjs build:esm build:types", "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", diff --git a/packages/browser/rollup.config.js b/packages/browser/rollup.bundle.config.js similarity index 67% rename from packages/browser/rollup.config.js rename to packages/browser/rollup.bundle.config.js index d49892da07be..aec9560621b1 100644 --- a/packages/browser/rollup.config.js +++ b/packages/browser/rollup.bundle.config.js @@ -1,4 +1,4 @@ -import { makeBaseBundleConfig, makeConfigVariants } from '../../rollup.config'; +import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; const builds = []; @@ -11,7 +11,7 @@ const builds = []; outputFileBase: `bundles/bundle${jsVersion === 'es6' ? '.es6' : ''}`, }); - builds.push(...makeConfigVariants(baseBundleConfig)); + builds.push(...makeBundleConfigVariants(baseBundleConfig)); }); export default builds; diff --git a/packages/integrations/rollup.config.js b/packages/integrations/rollup.bundle.config.js similarity index 81% rename from packages/integrations/rollup.config.js rename to packages/integrations/rollup.bundle.config.js index 7b23d698dfa2..de984497b9a8 100644 --- a/packages/integrations/rollup.config.js +++ b/packages/integrations/rollup.bundle.config.js @@ -1,6 +1,6 @@ import commonjs from '@rollup/plugin-commonjs'; -import { insertAt, makeBaseBundleConfig, makeConfigVariants } from '../../rollup.config'; +import { insertAt, makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; const builds = []; @@ -19,6 +19,6 @@ const baseBundleConfig = makeBaseBundleConfig({ baseBundleConfig.plugins = insertAt(baseBundleConfig.plugins, -2, commonjs()); // this makes non-minified, minified, and minified-with-debug-logging versions of each bundle -builds.push(...makeConfigVariants(baseBundleConfig)); +builds.push(...makeBundleConfigVariants(baseBundleConfig)); export default builds; diff --git a/packages/integrations/scripts/buildBundles.sh b/packages/integrations/scripts/buildBundles.sh index 3e81a8e6e045..2b75b83ee670 100644 --- a/packages/integrations/scripts/buildBundles.sh +++ b/packages/integrations/scripts/buildBundles.sh @@ -11,7 +11,7 @@ for filepath in ./src/*; do fi # run the build for each integration - INTEGRATION_FILE=$file JS_VERSION=$js_version yarn --silent rollup -c rollup.config.js + INTEGRATION_FILE=$file JS_VERSION=$js_version yarn --silent rollup --config rollup.bundle.config.js done done diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 782bd8bcc658..e77bfbadc5fa 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -28,7 +28,7 @@ }, "scripts": { "build": "run-p build:cjs build:esm build:types build:bundle && ts-node ../../scripts/prepack.ts #necessary for integration tests", - "build:bundle": "rollup --config", + "build:bundle": "rollup --config rollup.bundle.config.js", "build:cjs": "tsc -p tsconfig.cjs.json", "build:dev": "run-p build:cjs build:esm build:types", "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", diff --git a/packages/tracing/rollup.config.js b/packages/tracing/rollup.bundle.config.js similarity index 70% rename from packages/tracing/rollup.config.js rename to packages/tracing/rollup.bundle.config.js index 529ddea29a1b..66d79286f38c 100644 --- a/packages/tracing/rollup.config.js +++ b/packages/tracing/rollup.bundle.config.js @@ -1,4 +1,4 @@ -import { makeBaseBundleConfig, makeConfigVariants } from '../../rollup.config'; +import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; const builds = []; @@ -11,7 +11,7 @@ const builds = []; outputFileBase: `bundles/bundle.tracing${jsVersion === 'es6' ? '.es6' : ''}`, }); - builds.push(...makeConfigVariants(baseBundleConfig)); + builds.push(...makeBundleConfigVariants(baseBundleConfig)); }); export default builds; diff --git a/packages/vue/package.json b/packages/vue/package.json index 29452f54ce4c..b6eefc1ab6f3 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -28,7 +28,7 @@ }, "scripts": { "build": "run-p build:cjs build:esm build:types", - "build:bundle": "rollup --config", + "build:bundle": "rollup --config rollup.bundle.config.js", "build:cjs": "tsc -p tsconfig.cjs.json", "build:dev": "run-p build:cjs build:esm build:types", "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", diff --git a/packages/vue/rollup.config.js b/packages/vue/rollup.bundle.config.js similarity index 55% rename from packages/vue/rollup.config.js rename to packages/vue/rollup.bundle.config.js index 2185b2b716c5..745205cda85f 100644 --- a/packages/vue/rollup.config.js +++ b/packages/vue/rollup.bundle.config.js @@ -1,4 +1,4 @@ -import { makeBaseBundleConfig, makeConfigVariants } from '../../rollup.config'; +import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; const baseBundleConfig = makeBaseBundleConfig({ input: 'src/index.bundle.ts', @@ -8,4 +8,4 @@ const baseBundleConfig = makeBaseBundleConfig({ outputFileBase: 'bundle.vue', }); -export default makeConfigVariants(baseBundleConfig); +export default makeBundleConfigVariants(baseBundleConfig); diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 8c850944a72f..671ddad9c5f2 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -30,7 +30,7 @@ }, "scripts": { "build": "run-p build:cjs build:esm build:bundle build:types", - "build:bundle": "rollup --config", + "build:bundle": "rollup --config rollup.bundle.config.js", "build:cjs": "tsc -p tsconfig.cjs.json", "build:dev": "run-p build:cjs build:esm build:types", "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", diff --git a/packages/wasm/rollup.config.js b/packages/wasm/rollup.bundle.config.js similarity index 55% rename from packages/wasm/rollup.config.js rename to packages/wasm/rollup.bundle.config.js index edccdbd9287a..265b557c76a7 100644 --- a/packages/wasm/rollup.config.js +++ b/packages/wasm/rollup.bundle.config.js @@ -1,4 +1,4 @@ -import { makeBaseBundleConfig, makeConfigVariants } from '../../rollup.config'; +import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/index.js'; const baseBundleConfig = makeBaseBundleConfig({ input: 'src/index.ts', @@ -8,4 +8,4 @@ const baseBundleConfig = makeBaseBundleConfig({ outputFileBase: 'bundles/wasm', }); -export default makeConfigVariants(baseBundleConfig); +export default makeBundleConfigVariants(baseBundleConfig); diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 041f269f1095..000000000000 --- a/rollup.config.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Code for generating config used by individual packages' Rollup configs - */ - -import assert from 'assert'; - -import deepMerge from 'deepmerge'; -import license from 'rollup-plugin-license'; -import resolve from '@rollup/plugin-node-resolve'; -import replace from '@rollup/plugin-replace'; -import { terser } from 'rollup-plugin-terser'; -import typescript from 'rollup-plugin-typescript2'; - -Error.stackTraceLimit = Infinity; - -/** - * Helper functions to compensate for the fact that JS can't handle negative array indices very well - * - * TODO `insertAt` is only exported so the integrations config can inject the `commonjs` plugin, for localforage (used - * in the offline plugin). Once that's fixed to no longer be necessary, this can stop being exported. - */ -const getLastElement = array => { - return array[array.length - 1]; -}; -export const insertAt = (arr, index, ...insertees) => { - const newArr = [...arr]; - // Add 1 to the array length so that the inserted element ends up in the right spot with respect to the length of the - // new array (which will be one element longer), rather than that of the current array - const destinationIndex = index >= 0 ? index : arr.length + 1 + index; - newArr.splice(destinationIndex, 0, ...insertees); - return newArr; -}; - -/** - * Create a plugin to add an identification banner to the top of stand-alone bundles. - * - * @param title The title to use for the SDK, if not the package name - * @returns An instance of the `rollup-plugin-license` plugin - */ -function makeLicensePlugin(title) { - const commitHash = require('child_process').execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).trim(); - - return license({ - banner: { - content: `/*! <%= data.title %> <%= pkg.version %> (${commitHash}) | https://github.com/getsentry/sentry-javascript */`, - data: { title }, - }, - }); -} - -function makeIsDebugBuildPlugin(includeDebugging) { - return replace({ - // __SENTRY_DEBUG__ should be save to replace in any case, so no checks for assignments necessary - preventAssignment: false, - values: { - __SENTRY_DEBUG__: includeDebugging, - }, - }); -} - -// `terser` options reference: https://github.com/terser/terser#api-reference -// `rollup-plugin-terser` options reference: https://github.com/TrySound/rollup-plugin-terser#options -export const terserPlugin = terser({ - mangle: { - // captureExceptions and captureMessage are public API methods and they don't need to be listed here - // as mangler doesn't touch user-facing thing, however sentryWrapped is not, and it would be mangled into a minified version. - // We need those full names to correctly detect our internal frames for stripping. - // I listed all of them here just for the clarity sake, as they are all used in the frames manipulation process. - reserved: ['captureException', 'captureMessage', 'sentryWrapped'], - properties: { - regex: /^_[^_]/, - reserved: ['_experiments'], - }, - }, - output: { - comments: false, - }, -}); - -export function makeBaseBundleConfig(options) { - const { input, isAddOn, jsVersion, licenseTitle, outputFileBase } = options; - - const baseTSPluginOptions = { - tsconfig: 'tsconfig.esm.json', - tsconfigOverride: { - compilerOptions: { - declaration: false, - declarationMap: false, - paths: { - '@sentry/browser': ['../browser/src'], - '@sentry/core': ['../core/src'], - '@sentry/hub': ['../hub/src'], - '@sentry/minimal': ['../minimal/src'], - '@sentry/types': ['../types/src'], - '@sentry/utils': ['../utils/src'], - }, - baseUrl: '.', - }, - }, - include: ['*.ts+(|x)', '**/*.ts+(|x)', '../**/*.ts+(|x)'], - // the typescript plugin doesn't handle concurrency very well, so clean the cache between builds - // (see https://github.com/ezolenko/rollup-plugin-typescript2/issues/15) - clean: true, - // TODO: For the moment, the above issue seems to have stopped spamming the build with (non-blocking) errors, as it - // was originally. If it starts again, this will suppress that output. If we get to the end of the bundle revamp and - // it still seems okay, we can take this out entirely. - // verbosity: 0, - }; - - const typescriptPluginES5 = typescript( - deepMerge(baseTSPluginOptions, { - tsconfigOverride: { - compilerOptions: { - target: 'es5', - }, - }, - }), - ); - - const typescriptPluginES6 = typescript( - deepMerge(baseTSPluginOptions, { - tsconfigOverride: { - compilerOptions: { - target: 'es6', - }, - }, - }), - ); - - const nodeResolvePlugin = resolve(); - - const markAsBrowserBuildPlugin = replace({ - // don't replace `__placeholder__` where it's followed immediately by a single `=` (to prevent ending up - // with something of the form `let "replacementValue" = "some assigned value"`, which would cause a - // syntax error) - preventAssignment: true, - // the replacement to make - values: { - __SENTRY_BROWSER_BUNDLE__: true, - }, - }); - - const licensePlugin = makeLicensePlugin(licenseTitle); - - // used by `@sentry/browser`, `@sentry/tracing`, and `@sentry/vue` (bundles which are a full SDK in and of themselves) - const standAloneBundleConfig = { - output: { - format: 'iife', - name: 'Sentry', - }, - context: 'window', - }; - - // used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle) - const addOnBundleConfig = { - // These output settings are designed to mimic an IIFE. We don't use Rollup's `iife` format because we don't want to - // attach this code to a new global variable, but rather inject it into the existing SDK's `Integrations` object. - output: { - format: 'cjs', - - // code to add before the CJS wrapper - banner: '(function (__window) {', - - // code to add just inside the CJS wrapper, before any of the wrapped code - intro: 'var exports = {};', - - // code to add after all of the wrapped code, but still inside the CJS wrapper - outro: () => - [ - '', - " // Add this module's exports to the global `Sentry.Integrations`", - ' __window.Sentry = __window.Sentry || {};', - ' __window.Sentry.Integrations = __window.Sentry.Integrations || {};', - ' for (var key in exports) {', - ' if (Object.prototype.hasOwnProperty.call(exports, key)) {', - ' __window.Sentry.Integrations[key] = exports[key];', - ' }', - ' }', - ].join('\n'), - - // code to add after the CJS wrapper - footer: '}(window));', - }, - }; - - // used by all bundles - const sharedBundleConfig = { - input, - output: { - // a file extension will be added to this base value when we specify either a minified or non-minified build - file: `build/${outputFileBase}`, - sourcemap: true, - strict: false, - esModule: false, - }, - plugins: [ - jsVersion.toLowerCase() === 'es5' ? typescriptPluginES5 : typescriptPluginES6, - markAsBrowserBuildPlugin, - nodeResolvePlugin, - licensePlugin, - ], - treeshake: 'smallest', - }; - - return deepMerge(sharedBundleConfig, isAddOn ? addOnBundleConfig : standAloneBundleConfig); -} - -/** - * Takes the CDN rollup config for a given package and produces three versions of it: - * - non-minified, including debug logging, - * - minified, including debug logging, - * - minified, with debug logging stripped - * - * @param baseConfig The rollup config shared by the entire package - * @returns An array of versions of that config - */ -export function makeConfigVariants(baseConfig) { - const configVariants = []; - - const { plugins } = baseConfig; - const includeDebuggingPlugin = makeIsDebugBuildPlugin(true); - const stripDebuggingPlugin = makeIsDebugBuildPlugin(false); - - // The license plugin has to be last, so it ends up after terser. Otherwise, terser will remove the license banner. - assert( - getLastElement(plugins).name === 'rollup-plugin-license', - `Last plugin in given options should be \`rollup-plugin-license\`. Found ${getLastElement(plugins).name}`, - ); - - // The additional options to use for each variant we're going to create - const variantSpecificConfigs = [ - { - output: { - file: `${baseConfig.output.file}.js`, - }, - plugins: insertAt(plugins, -2, includeDebuggingPlugin), - }, - // This variant isn't particularly helpful for an SDK user, as it strips logging while making no other minification - // changes, so by default we don't create it. It is however very useful when debugging rollup's treeshaking, so it's - // left here for that purpose. - // { - // output: { file: `${baseConfig.output.file}.no-debug.js`, - // }, - // plugins: insertAt(plugins, -2, stripDebuggingPlugin), - // }, - { - output: { - file: `${baseConfig.output.file}.min.js`, - }, - plugins: insertAt(plugins, -2, stripDebuggingPlugin, terserPlugin), - }, - { - output: { - file: `${baseConfig.output.file}.debug.min.js`, - }, - plugins: insertAt(plugins, -2, includeDebuggingPlugin, terserPlugin), - }, - ]; - - variantSpecificConfigs.forEach(variant => { - const mergedConfig = deepMerge(baseConfig, variant, { - // this makes it so that instead of concatenating the `plugin` properties of the two objects, the first value is - // just overwritten by the second value - arrayMerge: (first, second) => second, - }); - configVariants.push(mergedConfig); - }); - - return configVariants; -} diff --git a/rollup/bundleHelpers.js b/rollup/bundleHelpers.js new file mode 100644 index 000000000000..d4ddc0e706e2 --- /dev/null +++ b/rollup/bundleHelpers.js @@ -0,0 +1,143 @@ +/** + * Rollup config docs: https://rollupjs.org/guide/en/#big-list-of-options + */ + +import assert from 'assert'; + +import deepMerge from 'deepmerge'; + +import { + makeBrowserBuildPlugin, + makeIsDebugBuildPlugin, + makeLicensePlugin, + makeNodeResolvePlugin, + makeTerserPlugin, + makeTSPlugin, +} from './plugins/index.js'; +import { getLastElement, insertAt } from './utils.js'; + +export function makeBaseBundleConfig(options) { + const { input, isAddOn, jsVersion, licenseTitle, outputFileBase } = options; + + const nodeResolvePlugin = makeNodeResolvePlugin(); + const markAsBrowserBuildPlugin = makeBrowserBuildPlugin(true); + const licensePlugin = makeLicensePlugin(licenseTitle); + const tsPlugin = makeTSPlugin(jsVersion.toLowerCase()); + + // used by `@sentry/browser`, `@sentry/tracing`, and `@sentry/vue` (bundles which are a full SDK in and of themselves) + const standAloneBundleConfig = { + output: { + format: 'iife', + name: 'Sentry', + }, + context: 'window', + }; + + // used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle) + const addOnBundleConfig = { + // These output settings are designed to mimic an IIFE. We don't use Rollup's `iife` format because we don't want to + // attach this code to a new global variable, but rather inject it into the existing SDK's `Integrations` object. + output: { + format: 'cjs', + + // code to add before the CJS wrapper + banner: '(function (__window) {', + + // code to add just inside the CJS wrapper, before any of the wrapped code + intro: 'var exports = {};', + + // code to add after all of the wrapped code, but still inside the CJS wrapper + outro: () => + [ + '', + " // Add this module's exports to the global `Sentry.Integrations`", + ' __window.Sentry = __window.Sentry || {};', + ' __window.Sentry.Integrations = __window.Sentry.Integrations || {};', + ' for (var key in exports) {', + ' if (Object.prototype.hasOwnProperty.call(exports, key)) {', + ' __window.Sentry.Integrations[key] = exports[key];', + ' }', + ' }', + ].join('\n'), + + // code to add after the CJS wrapper + footer: '}(window));', + }, + }; + + // used by all bundles + const sharedBundleConfig = { + input, + output: { + // a file extension will be added to this base value when we specify either a minified or non-minified build + file: `build/${outputFileBase}`, + sourcemap: true, + strict: false, + esModule: false, + }, + plugins: [tsPlugin, markAsBrowserBuildPlugin, nodeResolvePlugin, licensePlugin], + treeshake: 'smallest', + }; + + return deepMerge(sharedBundleConfig, isAddOn ? addOnBundleConfig : standAloneBundleConfig); +} + +/** + * Takes the CDN rollup config for a given package and produces three versions of it: + * - non-minified, including debug logging, + * - minified, including debug logging, + * - minified, with debug logging stripped + * + * @param baseConfig The rollup config shared by the entire package + * @returns An array of versions of that config + */ +export function makeBundleConfigVariants(baseConfig) { + const { plugins: baseConfigPlugins } = baseConfig; + const includeDebuggingPlugin = makeIsDebugBuildPlugin(true); + const stripDebuggingPlugin = makeIsDebugBuildPlugin(false); + const terserPlugin = makeTerserPlugin(); + + // The license plugin has to be last, so it ends up after terser. Otherwise, terser will remove the license banner. + assert( + getLastElement(baseConfigPlugins).name === 'rollup-plugin-license', + `Last plugin in given options should be \`rollup-plugin-license\`. Found ${getLastElement(baseConfigPlugins).name}`, + ); + + // The additional options to use for each variant we're going to create + const variantSpecificConfigs = [ + { + output: { + file: `${baseConfig.output.file}.js`, + }, + plugins: insertAt(baseConfigPlugins, -2, includeDebuggingPlugin), + }, + // This variant isn't particularly helpful for an SDK user, as it strips logging while making no other minification + // changes, so by default we don't create it. It is however very useful when debugging rollup's treeshaking, so it's + // left here for that purpose. + // { + // output: { file: `${baseConfig.output.file}.no-debug.js`, + // }, + // plugins: insertAt(plugins, -2, stripDebuggingPlugin), + // }, + { + output: { + file: `${baseConfig.output.file}.min.js`, + }, + plugins: insertAt(baseConfigPlugins, -2, stripDebuggingPlugin, terserPlugin), + }, + { + output: { + file: `${baseConfig.output.file}.debug.min.js`, + }, + plugins: insertAt(baseConfigPlugins, -2, includeDebuggingPlugin, terserPlugin), + }, + ]; + + return variantSpecificConfigs.map(variant => + deepMerge(baseConfig, variant, { + // this makes it so that instead of concatenating the `plugin` properties of the two objects, the first value is + // just overwritten by the second value + arrayMerge: (first, second) => second, + }), + ); +} diff --git a/rollup/index.js b/rollup/index.js new file mode 100644 index 000000000000..51baa9ba247c --- /dev/null +++ b/rollup/index.js @@ -0,0 +1,8 @@ +Error.stackTraceLimit = Infinity; + +// TODO Is this necessary? +import * as plugins from './plugins/index.js'; +export { plugins }; + +export * from './bundleHelpers.js'; +export { insertAt } from './utils.js'; diff --git a/rollup/plugins/bundlePlugins.js b/rollup/plugins/bundlePlugins.js new file mode 100644 index 000000000000..17c8d5977044 --- /dev/null +++ b/rollup/plugins/bundlePlugins.js @@ -0,0 +1,142 @@ +/** + * License plugin docs: https://github.com/mjeanroy/rollup-plugin-license + * Replace plugin docs: https://github.com/rollup/plugins/tree/master/packages/replace + * Resolve plugin docs: https://github.com/rollup/plugins/tree/master/packages/node-resolve + * Terser plugin docs: https://github.com/TrySound/rollup-plugin-terser#options + * Terser docs: https://github.com/terser/terser#api-reference + * Typescript plugin docs: https://github.com/ezolenko/rollup-plugin-typescript2 + */ + +import deepMerge from 'deepmerge'; +import license from 'rollup-plugin-license'; +import resolve from '@rollup/plugin-node-resolve'; +import replace from '@rollup/plugin-replace'; +import { terser } from 'rollup-plugin-terser'; +import typescript from 'rollup-plugin-typescript2'; + +/** + * Create a plugin to add an identification banner to the top of stand-alone bundles. + * + * @param title The title to use for the SDK, if not the package name + * @returns An instance of the `rollup-plugin-license` plugin + */ +export function makeLicensePlugin(title) { + const commitHash = require('child_process').execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).trim(); + + return license({ + banner: { + content: `/*! <%= data.title %> <%= pkg.version %> (${commitHash}) | https://github.com/getsentry/sentry-javascript */`, + data: { title }, + }, + }); +} + +/** + * Create a plugin to set the value of the `__SENTRY_DEBUG__` magic string. + * + * @param includeDebugging Whether or not the resulting build should include log statements + * @returns An instance of the `replace` plugin to do the replacement of the magic string with `true` or 'false` + */ +export function makeIsDebugBuildPlugin(includeDebugging) { + return replace({ + // __SENTRY_DEBUG__ should be save to replace in any case, so no checks for assignments necessary + preventAssignment: false, + values: { + __SENTRY_DEBUG__: includeDebugging, + }, + }); +} + +/** + * Create a plugin to set the value of the `__SENTRY_BROWSER_BUNDLE__` magic string. + * + * @param isBrowserBuild Whether or not the resulting build will be run in the browser + * @returns An instance of the `replace` plugin to do the replacement of the magic string with `true` or 'false` + */ +export function makeBrowserBuildPlugin(isBrowserBuild) { + return replace({ + // TODO This will be the default in the next version of the `replace` plugin + preventAssignment: true, + values: { + __SENTRY_BROWSER_BUNDLE__: isBrowserBuild, + }, + }); +} + +// `terser` options reference: https://github.com/terser/terser#api-reference +// `rollup-plugin-terser` options reference: https://github.com/TrySound/rollup-plugin-terser#options + +/** + * Create a plugin to perform minification using `terser`. + * + * @returns An instance of the `terser` plugin + */ +export function makeTerserPlugin() { + return terser({ + mangle: { + // `captureException` and `captureMessage` are public API methods and they don't need to be listed here, as the + // mangler won't touch user-facing things, but `sentryWrapped` is not user-facing, and would be mangled during + // minification. (We need it in its original form to correctly detect our internal frames for stripping.) All three + // are all listed here just for the clarity's sake, as they are all used in the frames manipulation process. + reserved: ['captureException', 'captureMessage', 'sentryWrapped'], + properties: { + // allow mangling of private field names... + regex: /^_[^_]/, + // ...except for `_experiments`, which we want to remain usable from the outside + reserved: ['_experiments'], + }, + }, + output: { + comments: false, + }, + }); +} + +/** + * Create a TypeScript plugin, which will down-compile if necessary, based on the given JS version. + * + * @param jsVersion Either `es5` or `es6` + * @returns An instance of the `typescript` plugin + */ +export function makeTSPlugin(jsVersion) { + const baseTSPluginOptions = { + tsconfig: 'tsconfig.esm.json', + tsconfigOverride: { + compilerOptions: { + declaration: false, + declarationMap: false, + paths: { + '@sentry/browser': ['../browser/src'], + '@sentry/core': ['../core/src'], + '@sentry/hub': ['../hub/src'], + '@sentry/minimal': ['../minimal/src'], + '@sentry/types': ['../types/src'], + '@sentry/utils': ['../utils/src'], + }, + baseUrl: '.', + }, + }, + include: ['*.ts+(|x)', '**/*.ts+(|x)', '../**/*.ts+(|x)'], + // the typescript plugin doesn't handle concurrency very well, so clean the cache between builds + // (see https://github.com/ezolenko/rollup-plugin-typescript2/issues/15) + clean: true, + // TODO: For the moment, the above issue seems to have stopped spamming the build with (non-blocking) errors, as it + // was originally. If it starts again, this will suppress that output. If we get to the end of the bundle revamp and + // it still seems okay, we can take this out entirely. + // verbosity: 0, + }; + + return typescript( + deepMerge(baseTSPluginOptions, { + tsconfigOverride: { + compilerOptions: { + target: jsVersion, + }, + }, + }), + ); +} + +// We don't pass this plugin any options, so no need to wrap it in another factory function, as `resolve` is itself +// already a factory function. +export { resolve as makeNodeResolvePlugin }; diff --git a/rollup/plugins/index.js b/rollup/plugins/index.js new file mode 100644 index 000000000000..bb05969c2caf --- /dev/null +++ b/rollup/plugins/index.js @@ -0,0 +1 @@ +export * from './bundlePlugins'; diff --git a/rollup/utils.js b/rollup/utils.js new file mode 100644 index 000000000000..00a97e991edf --- /dev/null +++ b/rollup/utils.js @@ -0,0 +1,16 @@ +/** + * Helper functions to compensate for the fact that JS can't handle negative array indices very well + */ + +export const getLastElement = array => { + return array[array.length - 1]; +}; + +export const insertAt = (arr, index, ...insertees) => { + const newArr = [...arr]; + // Add 1 to the array length so that the inserted element ends up in the right spot with respect to the length of the + // new array (which will be one element longer), rather than that of the current array + const destinationIndex = index >= 0 ? index : arr.length + 1 + index; + newArr.splice(destinationIndex, 0, ...insertees); + return newArr; +}; From a5ef02c6845a487faf3c80e83c2a37ba593f4452 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Tue, 19 Apr 2022 15:24:29 +0000 Subject: [PATCH 59/94] ref(tests): Suppress unconstructive listener and open handle warnings. (#4951) Removes warnings that we can't address at the moment from Jest logs. 1 - `MaxEventListener` warning is about a potential memory leak when more than 10 event listeners are assigned inside a single thread. As we're running all our integration tests on a single Jest thread, after 10th Sentry initialization, this warning starts polluting logs. Still, it's not great to have unregistered handles around. But we know it's limited to the number of test scenarios here. So IMO this workaround is safe to use for these tests. 2 - `detectOpenHandles` warns about uncleared intervals from `session` tests (where we're hackily replacing flush interval), which we are eventually clearing but can't set a reliable timeout, and we're also using `--forceExit` that does that on exit. --- packages/node-integration-tests/jest.config.js | 1 + packages/node-integration-tests/package.json | 2 +- packages/node-integration-tests/setup-tests.ts | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 packages/node-integration-tests/setup-tests.ts diff --git a/packages/node-integration-tests/jest.config.js b/packages/node-integration-tests/jest.config.js index 617a25ea0817..81e7d8f63d18 100644 --- a/packages/node-integration-tests/jest.config.js +++ b/packages/node-integration-tests/jest.config.js @@ -1,6 +1,7 @@ const baseConfig = require('../../jest.config.js'); module.exports = { + globalSetup: '/setup-tests.ts', ...baseConfig, testMatch: ['**/test.ts'], }; diff --git a/packages/node-integration-tests/package.json b/packages/node-integration-tests/package.json index 3f09e8d64192..002031983f52 100644 --- a/packages/node-integration-tests/package.json +++ b/packages/node-integration-tests/package.json @@ -11,7 +11,7 @@ "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "lint:prettier": "prettier --check \"{suites,utils}/**/*.ts\"", "type-check": "tsc", - "test": "jest --detectOpenHandles --runInBand --forceExit", + "test": "jest --runInBand --forceExit", "test:watch": "yarn test --watch" }, "dependencies": { diff --git a/packages/node-integration-tests/setup-tests.ts b/packages/node-integration-tests/setup-tests.ts new file mode 100644 index 000000000000..6f7bb2bec369 --- /dev/null +++ b/packages/node-integration-tests/setup-tests.ts @@ -0,0 +1,12 @@ +import EventEmitter from 'events'; + +const setup = async (): Promise => { + // Node warns about a potential memory leak + // when more than 10 event listeners are assigned inside a single thread. + // Initializing Sentry for each test triggers these warnings after 10th test inside Jest thread. + // As we know that it's not a memory leak and number of listeners are limited to the number of tests, + // removing the limit on listener count here. + EventEmitter.defaultMaxListeners = 0; +}; + +export default setup; From 6227c7fed0a76f7f323ec5ac01ef70a744bbf33e Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 19 Apr 2022 12:46:27 -0400 Subject: [PATCH 60/94] feat(core): Introduce seperate client options (#4927) This PR works toward differentiating the options that are passed into `Sentry.init` and the options passed into clients. We want to make this differentiation to minimize internal state in the client, and instead rely on the max number of items being passed in to the client constructor. We do this by explicitly differentiating between the options that are configured in sdk init (`Options`) and the options that are passed into the client constructor (`ClientOptions`). --- packages/browser/src/client.ts | 25 ++- packages/browser/src/sdk.ts | 26 ++- packages/browser/src/transports/setup.ts | 5 +- .../unit/helper/browser-client-options.ts | 12 ++ packages/browser/test/unit/index.test.ts | 111 +++++------ .../unit/integrations/linkederrors.test.ts | 7 +- packages/browser/test/unit/sdk.test.ts | 124 +++++++++++++ .../test/unit/transports/setup.test.ts | 9 +- packages/core/src/baseclient.ts | 4 +- packages/core/src/index.ts | 1 + packages/core/src/integration.ts | 6 +- packages/core/src/sdk.ts | 6 +- packages/core/test/lib/base.test.ts | 174 ++++++++---------- packages/core/test/lib/sdk.test.ts | 63 +------ packages/core/test/mocks/client.ts | 22 ++- packages/node/src/client.ts | 8 +- packages/node/src/sdk.ts | 22 ++- packages/node/src/types.ts | 23 ++- packages/node/test/client.test.ts | 27 +-- packages/node/test/handlers.test.ts | 23 +-- .../node/test/helper/node-client-options.ts | 12 ++ packages/node/test/index.test.ts | 39 ++-- packages/node/test/integrations/http.test.ts | 11 +- .../test/integrations/linkederrors.test.ts | 11 +- packages/node/test/sdk.test.ts | 92 +++++++++ packages/node/test/transports/setup.test.ts | 3 +- packages/tracing/src/hubextensions.ts | 11 +- packages/tracing/src/utils.ts | 4 +- .../test/browser/backgroundtab.test.ts | 3 +- .../test/browser/browsertracing.test.ts | 7 +- packages/tracing/test/browser/request.test.ts | 3 +- packages/tracing/test/errors.test.ts | 3 +- packages/tracing/test/hub.test.ts | 79 ++++---- packages/tracing/test/idletransaction.test.ts | 5 +- packages/tracing/test/span.test.ts | 11 +- packages/types/src/client.ts | 4 +- packages/types/src/index.ts | 2 +- packages/types/src/options.ts | 136 ++++++++------ packages/utils/src/dsn.ts | 2 - 39 files changed, 685 insertions(+), 451 deletions(-) create mode 100644 packages/browser/test/unit/helper/browser-client-options.ts create mode 100644 packages/browser/test/unit/sdk.test.ts create mode 100644 packages/node/test/helper/node-client-options.ts create mode 100644 packages/node/test/sdk.test.ts diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 8666eaebe8d5..a889d7f69d06 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,5 +1,5 @@ import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; -import { Event, EventHint, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; import { getGlobalObject, logger, stackParserFromOptions } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; @@ -7,11 +7,7 @@ import { IS_DEBUG_BUILD } from './flags'; import { injectReportDialog, ReportDialogOptions } from './helpers'; import { Breadcrumbs } from './integrations'; -/** - * Configuration options for the Sentry Browser SDK. - * @see BrowserClient for more information. - */ -export interface BrowserOptions extends Options { +export interface BaseBrowserOptions { /** * A pattern for error URLs which should exclusively be sent to Sentry. * This is the opposite of {@link Options.denyUrls}. @@ -27,19 +23,31 @@ export interface BrowserOptions extends Options { denyUrls?: Array; } +/** + * Configuration options for the Sentry Browser SDK. + * @see @sentry/types Options for more information. + */ +export interface BrowserOptions extends Options, BaseBrowserOptions {} + +/** + * Configuration options for the Sentry Browser SDK Client class + * @see BrowserClient for more information. + */ +export interface BrowserClientOptions extends ClientOptions, BaseBrowserOptions {} + /** * The Sentry Browser SDK Client. * * @see BrowserOptions for documentation on configuration options. * @see SentryClient for usage documentation. */ -export class BrowserClient extends BaseClient { +export class BrowserClient extends BaseClient { /** * Creates a new Browser SDK instance. * * @param options Configuration options for this SDK. */ - public constructor(options: BrowserOptions = {}, transport: Transport, newTransport?: NewTransport) { + public constructor(options: BrowserClientOptions, transport: Transport, newTransport?: NewTransport) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.browser', @@ -51,7 +59,6 @@ export class BrowserClient extends BaseClient { ], version: SDK_VERSION, }; - super(options, transport, newTransport); } diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 94ec87cb4279..05d9d9c34462 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -1,12 +1,20 @@ -import { getCurrentHub, initAndBind, Integrations as CoreIntegrations } from '@sentry/core'; +import { getCurrentHub, getIntegrationsToSetup, initAndBind, Integrations as CoreIntegrations } from '@sentry/core'; import { Hub } from '@sentry/types'; -import { addInstrumentationHandler, getGlobalObject, logger, resolvedSyncPromise } from '@sentry/utils'; +import { + addInstrumentationHandler, + getGlobalObject, + logger, + resolvedSyncPromise, + stackParserFromOptions, + supportsFetch, +} from '@sentry/utils'; -import { BrowserClient, BrowserOptions } from './client'; +import { BrowserClient, BrowserClientOptions, BrowserOptions } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { ReportDialogOptions, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, LinkedErrors, TryCatch, UserAgent } from './integrations'; import { defaultStackParsers } from './stack-parsers'; +import { FetchTransport, XHRTransport } from './transports'; import { setupBrowserTransport } from './transports/setup'; export const defaultIntegrations = [ @@ -97,9 +105,17 @@ export function init(options: BrowserOptions = {}): void { if (options.stackParser === undefined) { options.stackParser = defaultStackParsers; } - const { transport, newTransport } = setupBrowserTransport(options); - initAndBind(BrowserClient, options, transport, newTransport); + + const clientOptions: BrowserClientOptions = { + ...options, + stackParser: stackParserFromOptions(options), + integrations: getIntegrationsToSetup(options), + // TODO(v7): get rid of transport being passed down below + transport: options.transport || (supportsFetch() ? FetchTransport : XHRTransport), + }; + + initAndBind(BrowserClient, clientOptions, transport, newTransport); if (options.autoSessionTracking) { startSessionTracking(); diff --git a/packages/browser/src/transports/setup.ts b/packages/browser/src/transports/setup.ts index 0af6aad90676..f72365e7dc94 100644 --- a/packages/browser/src/transports/setup.ts +++ b/packages/browser/src/transports/setup.ts @@ -31,7 +31,10 @@ export interface BrowserTransportOptions extends BaseTransportOptions { * this function will return a ready to use `NewTransport`. */ // TODO(v7): Adjust return value when NewTransport is the default -export function setupBrowserTransport(options: BrowserOptions): { transport: Transport; newTransport?: NewTransport } { +export function setupBrowserTransport(options: BrowserOptions): { + transport: Transport; + newTransport?: NewTransport; +} { if (!options.dsn) { // We return the noop transport here in case there is no Dsn. return { transport: new NoopTransport() }; diff --git a/packages/browser/test/unit/helper/browser-client-options.ts b/packages/browser/test/unit/helper/browser-client-options.ts new file mode 100644 index 000000000000..aa763a5de06b --- /dev/null +++ b/packages/browser/test/unit/helper/browser-client-options.ts @@ -0,0 +1,12 @@ +import { NoopTransport } from '@sentry/core'; + +import { BrowserClientOptions } from '../../../src/client'; + +export function getDefaultBrowserClientOptions(options: Partial = {}): BrowserClientOptions { + return { + integrations: [], + transport: NoopTransport, + stackParser: () => [], + ...options, + }; +} diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 9371e60073c1..434dea98977a 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -16,6 +16,7 @@ import { showReportDialog, wrap, } from '../../src'; +import { getDefaultBrowserClientOptions } from './helper/browser-client-options'; import { SimpleTransport } from './mocks/simpletransport'; const dsn = 'https://53039209a22b4ec1bcc296a3c9fdecd6@sentry.io/4291'; @@ -75,7 +76,8 @@ describe('SentryBrowser', () => { describe('showReportDialog', () => { describe('user', () => { const EX_USER = { email: 'test@example.com' }; - const client = new BrowserClient({ dsn }, new SimpleTransport({ dsn })); + const options = getDefaultBrowserClientOptions({ dsn }); + const client = new BrowserClient(options, new SimpleTransport({ dsn })); const reportDialogSpy = jest.spyOn(client, 'showReportDialog'); beforeEach(() => { @@ -139,53 +141,41 @@ describe('SentryBrowser', () => { }); it('should capture a message', done => { - getCurrentHub().bindClient( - new BrowserClient( - { - beforeSend: (event: Event): Event | null => { - expect(event.message).toBe('test'); - expect(event.exception).toBeUndefined(); - done(); - return event; - }, - dsn, - }, - new SimpleTransport({ dsn }), - ), - ); + const options = getDefaultBrowserClientOptions({ + beforeSend: (event: Event): Event | null => { + expect(event.message).toBe('test'); + expect(event.exception).toBeUndefined(); + done(); + return event; + }, + dsn, + }); + getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); captureMessage('test'); }); it('should capture an event', done => { - getCurrentHub().bindClient( - new BrowserClient( - { - beforeSend: (event: Event): Event | null => { - expect(event.message).toBe('event'); - expect(event.exception).toBeUndefined(); - done(); - return event; - }, - dsn, - }, - new SimpleTransport({ dsn }), - ), - ); + const options = getDefaultBrowserClientOptions({ + beforeSend: (event: Event): Event | null => { + expect(event.message).toBe('event'); + expect(event.exception).toBeUndefined(); + done(); + return event; + }, + dsn, + }); + getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); captureEvent({ message: 'event' }); }); it('should not dedupe an event on bound client', async () => { const localBeforeSend = jest.fn(); - getCurrentHub().bindClient( - new BrowserClient( - { - beforeSend: localBeforeSend, - dsn, - integrations: [], - }, - new SimpleTransport({ dsn }), - ), - ); + const options = getDefaultBrowserClientOptions({ + beforeSend: localBeforeSend, + dsn, + integrations: [], + }); + getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); captureMessage('event222'); captureMessage('event222'); @@ -197,16 +187,12 @@ describe('SentryBrowser', () => { it('should use inboundfilter rules of bound client', async () => { const localBeforeSend = jest.fn(); - getCurrentHub().bindClient( - new BrowserClient( - { - beforeSend: localBeforeSend, - dsn, - integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], - }, - new SimpleTransport({ dsn }), - ), - ); + const options = getDefaultBrowserClientOptions({ + beforeSend: localBeforeSend, + dsn, + integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], + }); + getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); captureMessage('capture'); @@ -267,7 +253,8 @@ describe('SentryBrowser initialization', () => { }); it('should set SDK data when instantiating a client directly', () => { - const client = new BrowserClient({ dsn }, new SimpleTransport({ dsn })); + const options = getDefaultBrowserClientOptions({ dsn }); + const client = new BrowserClient(options, new SimpleTransport({ dsn })); const sdkData = (client.getTransport() as any)._api.metadata?.sdk; @@ -309,20 +296,16 @@ describe('SentryBrowser initialization', () => { describe('wrap()', () => { it('should wrap and call function while capturing error', done => { - getCurrentHub().bindClient( - new BrowserClient( - { - beforeSend: (event: Event): Event | null => { - expect(event.exception!.values![0].type).toBe('TypeError'); - expect(event.exception!.values![0].value).toBe('mkey'); - done(); - return null; - }, - dsn, - }, - new SimpleTransport({ dsn }), - ), - ); + const options = getDefaultBrowserClientOptions({ + beforeSend: (event: Event): Event | null => { + expect(event.exception!.values![0].type).toBe('TypeError'); + expect(event.exception!.values![0].value).toBe('mkey'); + done(); + return null; + }, + dsn, + }); + getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); try { wrap(() => { diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 6ccd4b5975a3..4b862705bccc 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -5,6 +5,7 @@ import { BrowserClient } from '../../../src/client'; import * as LinkedErrorsModule from '../../../src/integrations/linkederrors'; import { defaultStackParsers } from '../../../src/stack-parsers'; import { setupBrowserTransport } from '../../../src/transports'; +import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; const parser = createStackParser(...defaultStackParsers); @@ -45,7 +46,7 @@ describe('LinkedErrors', () => { one.cause = two; const originalException = one; - const options = { stackParser: parser }; + const options = getDefaultBrowserClientOptions({ stackParser: parser }); const client = new BrowserClient(options, setupBrowserTransport(options).transport); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { @@ -76,7 +77,7 @@ describe('LinkedErrors', () => { one.reason = two; const originalException = one; - const options = { stackParser: parser }; + const options = getDefaultBrowserClientOptions({ stackParser: parser }); const client = new BrowserClient(options, setupBrowserTransport(options).transport); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { @@ -103,7 +104,7 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const options = { stackParser: parser }; + const options = getDefaultBrowserClientOptions({ stackParser: parser }); const client = new BrowserClient(options, setupBrowserTransport(options).transport); const originalException = one; return client.eventFromException(originalException).then(event => { diff --git a/packages/browser/test/unit/sdk.test.ts b/packages/browser/test/unit/sdk.test.ts new file mode 100644 index 000000000000..8814329f16e9 --- /dev/null +++ b/packages/browser/test/unit/sdk.test.ts @@ -0,0 +1,124 @@ +/* eslint-disable @typescript-eslint/unbound-method */ +import { NoopTransport, Scope } from '@sentry/core'; +import { MockIntegration } from '@sentry/core/test/lib/sdk.test'; +import { Client, Integration } from '@sentry/types'; + +import { BrowserOptions } from '../../src'; +import { init } from '../../src/sdk'; +// eslint-disable-next-line no-var +declare var global: any; + +const PUBLIC_DSN = 'https://username@domain/123'; + +function getDefaultBrowserOptions(options: Partial = {}): BrowserOptions { + return { + integrations: [], + transport: NoopTransport, + stackParser: () => [], + ...options, + }; +} + +jest.mock('@sentry/hub', () => { + const original = jest.requireActual('@sentry/hub'); + return { + ...original, + getCurrentHub(): { + bindClient(client: Client): boolean; + getClient(): boolean; + getScope(): Scope; + } { + return { + getClient(): boolean { + return false; + }, + getScope(): Scope { + return new Scope(); + }, + bindClient(client: Client): boolean { + client.setupIntegrations(); + return true; + }, + }; + }, + }; +}); + +describe('init', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterAll(() => { + jest.resetAllMocks(); + }); + + test('installs default integrations', () => { + const DEFAULT_INTEGRATIONS: Integration[] = [ + new MockIntegration('MockIntegration 0.1'), + new MockIntegration('MockIntegration 0.2'), + ]; + const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS }); + + init(options); + + expect(DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + }); + + test("doesn't install default integrations if told not to", () => { + const DEFAULT_INTEGRATIONS: Integration[] = [ + new MockIntegration('MockIntegration 0.3'), + new MockIntegration('MockIntegration 0.4'), + ]; + const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, defaultIntegrations: false }); + init(options); + + expect(DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + expect(DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + }); + + it('installs merged default integrations, with overrides provided through options', () => { + const DEFAULT_INTEGRATIONS = [ + new MockIntegration('MockIntegration 1.1'), + new MockIntegration('MockIntegration 1.2'), + ]; + + const integrations = [new MockIntegration('MockIntegration 1.1'), new MockIntegration('MockIntegration 1.3')]; + const options = getDefaultBrowserOptions({ + dsn: PUBLIC_DSN, + defaultIntegrations: DEFAULT_INTEGRATIONS, + integrations, + }); + + init(options); + // 'MockIntegration 1' should be overridden by the one with the same name provided through options + expect(DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + expect(DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(integrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(integrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + }); + + it('installs integrations returned from a callback function', () => { + const DEFAULT_INTEGRATIONS = [ + new MockIntegration('MockIntegration 2.1'), + new MockIntegration('MockIntegration 2.2'), + ]; + + const newIntegration = new MockIntegration('MockIntegration 2.3'); + const options = getDefaultBrowserOptions({ + defaultIntegrations: DEFAULT_INTEGRATIONS, + dsn: PUBLIC_DSN, + integrations: (integrations: Integration[]) => { + const t = integrations.slice(0, 1).concat(newIntegration); + return t; + }, + }); + + init(options); + + expect(DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(newIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + }); +}); diff --git a/packages/browser/test/unit/transports/setup.test.ts b/packages/browser/test/unit/transports/setup.test.ts index 2683a0619aea..41b361d684d5 100644 --- a/packages/browser/test/unit/transports/setup.test.ts +++ b/packages/browser/test/unit/transports/setup.test.ts @@ -7,6 +7,7 @@ import { setupBrowserTransport, XHRTransport, } from '../../../src/transports'; +import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; import { SimpleTransport } from '../mocks/simpletransport'; const DSN = 'https://username@domain/123'; @@ -64,7 +65,7 @@ describe('setupBrowserTransport', () => { }); it('returns the instantiated transport passed via the options', () => { - const options = { dsn: DSN, transport: SimpleTransport }; + const options = getDefaultBrowserClientOptions({ dsn: DSN, transport: SimpleTransport }); const { transport, newTransport } = setupBrowserTransport(options); expect(transport).toBeDefined(); @@ -73,7 +74,8 @@ describe('setupBrowserTransport', () => { }); it('returns fetchTransports if fetch is supported', () => { - const options = { dsn: DSN }; + const options = getDefaultBrowserClientOptions({ dsn: DSN }); + delete options.transport; const { transport, newTransport } = setupBrowserTransport(options); expect(transport).toBeDefined(); @@ -86,7 +88,8 @@ describe('setupBrowserTransport', () => { it('returns xhrTransports if fetch is not supported', () => { fetchSupported = false; - const options = { dsn: DSN }; + const options = getDefaultBrowserClientOptions({ dsn: DSN }); + delete options.transport; const { transport, newTransport } = setupBrowserTransport(options); expect(transport).toBeDefined(); diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 2888e9853f5e..3d82d829cead 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -2,12 +2,12 @@ import { Scope, Session } from '@sentry/hub'; import { Client, + ClientOptions, DsnComponents, Event, EventHint, Integration, IntegrationClass, - Options, Severity, SeverityLevel, Transport, @@ -68,7 +68,7 @@ const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been ca * // ... * } */ -export abstract class BaseClient implements Client { +export abstract class BaseClient implements Client { /** Options passed to the SDK. */ protected readonly _options: O; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ccf2aa519775..da68917c936e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -37,6 +37,7 @@ export { initAndBind } from './sdk'; export { NoopTransport } from './transports/noop'; export { createTransport } from './transports/base'; export { SDK_VERSION } from './version'; +export { getIntegrationsToSetup } from './integration'; import * as Integrations from './integrations'; diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index cc694c815289..b4f35e7d5b1e 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,5 +1,5 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/hub'; -import { Integration, Options } from '@sentry/types'; +import { ClientOptions, Integration, Options } from '@sentry/types'; import { addNonEnumerableProperty, logger } from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; @@ -70,9 +70,9 @@ export function setupIntegration(integration: Integration): void { * @param integrations array of integration instances * @param withDefault should enable default integrations */ -export function setupIntegrations(options: O): IntegrationIndex { +export function setupIntegrations(options: O): IntegrationIndex { const integrations: IntegrationIndex = {}; - getIntegrationsToSetup(options).forEach(integration => { + options.integrations.forEach(integration => { integrations[integration.name] = integration; setupIntegration(integration); }); diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index 97c8b349a235..c7f7bb4916a3 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -1,12 +1,12 @@ import { getCurrentHub } from '@sentry/hub'; -import { Client, Options, Transport } from '@sentry/types'; +import { Client, ClientOptions, Transport } from '@sentry/types'; import { logger } from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; import { NewTransport } from './transports/base'; /** A class object that can instantiate Client objects. */ -export type ClientClass = new ( +export type ClientClass = new ( options: O, transport: Transport, newTransport?: NewTransport, @@ -19,7 +19,7 @@ export type ClientClass = new ( * @param clientClass The client class to instantiate. * @param options Options to pass to the client. */ -export function initAndBind( +export function initAndBind( clientClass: ClientClass, options: O, transport: Transport, diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 1bd2750e5378..47ec8ae70266 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -4,7 +4,7 @@ import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import * as integrationModule from '../../src/integration'; import { NoopTransport } from '../../src/transports/noop'; -import { setupTestTransport, TestClient } from '../mocks/client'; +import { getDefaultTestClientOptions, setupTestTransport, TestClient } from '../mocks/client'; import { TestIntegration } from '../mocks/integration'; import { FakeTransport } from '../mocks/transport'; @@ -67,7 +67,7 @@ describe('BaseClient', () => { test('returns the Dsn', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); expect(dsnToString(client.getDsn()!)).toBe(PUBLIC_DSN); }); @@ -75,7 +75,7 @@ describe('BaseClient', () => { test('allows missing Dsn', () => { expect.assertions(1); - const options = {}; + const options = getDefaultTestClientOptions(); const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getDsn()).toBeUndefined(); @@ -84,7 +84,7 @@ describe('BaseClient', () => { test('throws with invalid Dsn', () => { expect.assertions(1); - const options = { dsn: 'abc' }; + const options = getDefaultTestClientOptions({ dsn: 'abc' }); expect(() => new TestClient(options, setupTestTransport(options).transport)).toThrow(SentryError); }); }); @@ -93,7 +93,7 @@ describe('BaseClient', () => { test('returns the options', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN, test: true }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, test: true }); const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getOptions()).toEqual(options); @@ -104,7 +104,7 @@ describe('BaseClient', () => { test('returns the transport from client', () => { expect.assertions(2); - const options = { dsn: PUBLIC_DSN, transport: FakeTransport }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, transport: FakeTransport }); const client = new TestClient(options, new FakeTransport()); expect(client.getTransport()).toBeInstanceOf(FakeTransport); @@ -114,7 +114,7 @@ describe('BaseClient', () => { test('retruns NoopTransport when no transport is passed', () => { expect.assertions(2); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); expect(client.getTransport()).toBeInstanceOf(NoopTransport); @@ -126,7 +126,7 @@ describe('BaseClient', () => { test('adds a breadcrumb', () => { expect.assertions(1); - const options = {}; + const options = getDefaultTestClientOptions({}); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -140,7 +140,7 @@ describe('BaseClient', () => { test('adds a timestamp to new breadcrumbs', () => { expect.assertions(1); - const options = {}; + const options = getDefaultTestClientOptions({}); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -154,7 +154,7 @@ describe('BaseClient', () => { test('discards breadcrumbs beyond maxBreadcrumbs', () => { expect.assertions(2); - const options = { maxBreadcrumbs: 1 }; + const options = getDefaultTestClientOptions({ maxBreadcrumbs: 1 }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -169,7 +169,7 @@ describe('BaseClient', () => { test('allows concurrent updates', () => { expect.assertions(1); - const options = {}; + const options = getDefaultTestClientOptions({}); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -184,7 +184,7 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); - const options = { beforeBreadcrumb }; + const options = getDefaultTestClientOptions({ beforeBreadcrumb }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -198,7 +198,7 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(() => ({ message: 'changed' })); - const options = { beforeBreadcrumb }; + const options = getDefaultTestClientOptions({ beforeBreadcrumb }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -212,7 +212,7 @@ describe('BaseClient', () => { expect.assertions(1); const beforeBreadcrumb = jest.fn(() => null); - const options = { beforeBreadcrumb }; + const options = getDefaultTestClientOptions({ beforeBreadcrumb }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -226,7 +226,7 @@ describe('BaseClient', () => { expect.assertions(2); const beforeBreadcrumb = jest.fn((breadcrumb, hint) => ({ ...breadcrumb, data: hint.data })); - const options = { beforeBreadcrumb }; + const options = getDefaultTestClientOptions({ beforeBreadcrumb }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -240,7 +240,7 @@ describe('BaseClient', () => { describe('captureException', () => { test('captures and sends exceptions', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureException(new Error('test exception')); @@ -263,7 +263,7 @@ describe('BaseClient', () => { }); test('allows for providing explicit scope', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -291,7 +291,7 @@ describe('BaseClient', () => { }); test('allows for clearing data from existing scope if explicit one does so in a callback function', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -326,7 +326,7 @@ describe('BaseClient', () => { // already-seen check to work . Any primitive which is passed without being wrapped will be captured each time it // is encountered, so this test doesn't apply. ])("doesn't capture the same exception twice - %s", (_name: string, thrown: any) => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); expect(thrown.__sentry_captured__).toBeUndefined(); @@ -345,7 +345,7 @@ describe('BaseClient', () => { describe('captureMessage', () => { test('captures and sends messages', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureMessage('test message'); @@ -362,7 +362,7 @@ describe('BaseClient', () => { }); test('should call eventFromException if input to captureMessage is not a primitive', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const spy = jest.spyOn(TestClient.instance!, 'eventFromException'); @@ -381,7 +381,7 @@ describe('BaseClient', () => { }); test('allows for providing explicit scope', () => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -415,7 +415,7 @@ describe('BaseClient', () => { test('skips when disabled', () => { expect.assertions(1); - const options = { enabled: false, dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ enabled: false, dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -427,7 +427,7 @@ describe('BaseClient', () => { test('skips without a Dsn', () => { expect.assertions(1); - const options = {}; + const options = getDefaultTestClientOptions({}); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -445,7 +445,7 @@ describe('BaseClient', () => { // already-seen check to work . Any primitive which is passed without being wrapped will be captured each time it // is encountered, so this test doesn't apply. ])("doesn't capture an event wrapping the same exception twice - %s", (_name: string, thrown: any) => { - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); // Note: this is the same test as in `describe(captureException)`, except with the exception already wrapped in a // hint and accompanying an event. Duplicated here because some methods skip `captureException` and go straight to // `captureEvent`. @@ -469,7 +469,7 @@ describe('BaseClient', () => { test('sends an event', () => { expect.assertions(2); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -489,7 +489,7 @@ describe('BaseClient', () => { test('does not overwrite existing timestamp', () => { expect.assertions(2); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -509,7 +509,7 @@ describe('BaseClient', () => { test('adds event_id from hint if available', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -528,9 +528,7 @@ describe('BaseClient', () => { test('sets default environment to `production` if none provided', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -549,10 +547,7 @@ describe('BaseClient', () => { test('adds the configured environment', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - environment: 'env', - }; + const options = getDefaultTestClientOptions({ environment: 'env', dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -571,10 +566,7 @@ describe('BaseClient', () => { test('allows for environment to be explicitly set to falsy value', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - environment: undefined, - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, environment: undefined }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -593,10 +585,7 @@ describe('BaseClient', () => { test('adds the configured release', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - release: 'v1.0.0', - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, release: 'v1.0.0' }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); @@ -616,7 +605,7 @@ describe('BaseClient', () => { test('adds breadcrumbs', () => { expect.assertions(4); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.addBreadcrumb({ message: 'breadcrumb' }, 100); @@ -632,7 +621,7 @@ describe('BaseClient', () => { test('limits previously saved breadcrumbs', () => { expect.assertions(2); - const options = { dsn: PUBLIC_DSN, maxBreadcrumbs: 1 }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, maxBreadcrumbs: 1 }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); const hub = new Hub(client, scope); @@ -648,7 +637,7 @@ describe('BaseClient', () => { test('adds context data', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setExtra('b', 'b'); @@ -673,7 +662,7 @@ describe('BaseClient', () => { test('adds fingerprint', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const scope = new Scope(); scope.setFingerprint(['abcd']); @@ -692,7 +681,7 @@ describe('BaseClient', () => { }); test('adds installed integrations to sdk info', () => { - const options = { dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); @@ -706,7 +695,7 @@ describe('BaseClient', () => { test('normalizes event with default depth of 3', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { @@ -758,10 +747,7 @@ describe('BaseClient', () => { test('normalization respects `normalizeDepth` option', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - normalizeDepth: 2, - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, normalizeDepth: 2 }); const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { @@ -810,10 +796,7 @@ describe('BaseClient', () => { test('skips normalization when `normalizeDepth: 0`', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - normalizeDepth: 0, - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, normalizeDepth: 0 }); const client = new TestClient(options, setupTestTransport(options).transport); const fourLevelsObject = { a: { @@ -867,7 +850,7 @@ describe('BaseClient', () => { test('normalization applies to Transaction and Span consistently', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const transaction: Event = { contexts: { @@ -942,7 +925,7 @@ describe('BaseClient', () => { expect.assertions(1); const beforeSend = jest.fn(event => event); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -954,7 +937,7 @@ describe('BaseClient', () => { expect.assertions(1); const beforeSend = jest.fn(() => ({ message: 'changed1' })); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -966,7 +949,8 @@ describe('BaseClient', () => { expect.assertions(3); const beforeSend = jest.fn(() => null); - const client = new TestClient({ dsn: PUBLIC_DSN, beforeSend }, setupTestTransport({ dsn: PUBLIC_DSN }).transport); + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); + const client = new TestClient(options, setupTestTransport(options).transport); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); @@ -983,9 +967,9 @@ describe('BaseClient', () => { for (const val of invalidValues) { const beforeSend = jest.fn(() => val); - const options = { dsn: PUBLIC_DSN, beforeSend }; // @ts-ignore we need to test regular-js behavior - const client = new TestClient(options, setupTestTransport({ dsn: PUBLIC_DSN }).transport); + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); + const client = new TestClient(options, setupTestTransport(options).transport); const loggerErrorSpy = jest.spyOn(logger, 'error'); client.captureEvent({ message: 'hello' }); @@ -1009,7 +993,7 @@ describe('BaseClient', () => { }, 1); }), ); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -1038,7 +1022,7 @@ describe('BaseClient', () => { }, 1); }), ); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -1067,7 +1051,7 @@ describe('BaseClient', () => { }); }), ); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }); @@ -1080,7 +1064,7 @@ describe('BaseClient', () => { expect.assertions(2); const beforeSend = jest.fn((event, hint) => ({ ...event, data: hint.data })); - const options = { dsn: PUBLIC_DSN, beforeSend }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); const client = new TestClient(options, setupTestTransport(options).transport); client.captureEvent({ message: 'hello' }, { data: 'someRandomThing' }); @@ -1093,13 +1077,13 @@ describe('BaseClient', () => { expect.assertions(1); const client = new TestClient( - { + getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend() { return null; }, - }, - setupTestTransport({ dsn: PUBLIC_DSN }).transport, + }), + setupTestTransport(getDefaultTestClientOptions({ dsn: PUBLIC_DSN })).transport, ); const recordLostEventSpy = jest.fn(); jest.spyOn(client, 'getTransport').mockImplementationOnce( @@ -1117,7 +1101,10 @@ describe('BaseClient', () => { test('eventProcessor can drop the even when it returns null', () => { expect.assertions(3); - const client = new TestClient({ dsn: PUBLIC_DSN }, setupTestTransport({ dsn: PUBLIC_DSN }).transport); + const client = new TestClient( + getDefaultTestClientOptions({ dsn: PUBLIC_DSN }), + setupTestTransport(getDefaultTestClientOptions({ dsn: PUBLIC_DSN })).transport, + ); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); const scope = new Scope(); @@ -1133,7 +1120,7 @@ describe('BaseClient', () => { test('eventProcessor records dropped events', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const recordLostEventSpy = jest.fn(); @@ -1155,7 +1142,7 @@ describe('BaseClient', () => { test('eventProcessor sends an event and logs when it crashes', () => { expect.assertions(3); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); @@ -1184,10 +1171,7 @@ describe('BaseClient', () => { test('records events dropped due to sampleRate', () => { expect.assertions(1); - const options = { - dsn: PUBLIC_DSN, - sampleRate: 0, - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, sampleRate: 0 }); const client = new TestClient(options, setupTestTransport(options).transport); const recordLostEventSpy = jest.fn(); @@ -1211,10 +1195,7 @@ describe('BaseClient', () => { test('setup each one of them on setupIntegration call', () => { expect.assertions(2); - const options = { - dsn: PUBLIC_DSN, - integrations: [new TestIntegration()], - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); @@ -1225,9 +1206,7 @@ describe('BaseClient', () => { test('skips installation if DSN is not provided', () => { expect.assertions(2); - const options = { - integrations: [new TestIntegration()], - }; + const options = getDefaultTestClientOptions({ integrations: [new TestIntegration()] }); const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); @@ -1238,11 +1217,11 @@ describe('BaseClient', () => { test('skips installation if enabled is set to false', () => { expect.assertions(2); - const options = { + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enabled: false, integrations: [new TestIntegration()], - }; + }); const client = new TestClient(options, setupTestTransport(options).transport); client.setupIntegrations(); @@ -1253,10 +1232,7 @@ describe('BaseClient', () => { test('skips installation if integrations are already installed', () => { expect.assertions(4); - const options = { - dsn: PUBLIC_DSN, - integrations: [new TestIntegration()], - }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); const client = new TestClient(options, setupTestTransport(options).transport); // note: not the `Client` method `setupIntegrations`, but the free-standing function which that method calls const setupIntegrationsHelper = jest.spyOn(integrationModule, 'setupIntegrations'); @@ -1281,11 +1257,11 @@ describe('BaseClient', () => { expect.assertions(5); const client = new TestClient( - { + getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, transport: FakeTransport, - }, + }), new FakeTransport(), ); @@ -1310,11 +1286,11 @@ describe('BaseClient', () => { expect.assertions(5); const client = new TestClient( - { + getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, transport: FakeTransport, - }, + }), new FakeTransport(), ); @@ -1349,11 +1325,11 @@ describe('BaseClient', () => { expect.assertions(2); const client = new TestClient( - { + getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, transport: FakeTransport, - }, + }), new FakeTransport(), ); @@ -1373,7 +1349,7 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(3); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); return Promise.all([ @@ -1394,7 +1370,7 @@ describe('BaseClient', () => { test('sends sessions to the client', () => { expect.assertions(1); - const options = { dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const session = new Session({ release: 'test' }); @@ -1406,7 +1382,7 @@ describe('BaseClient', () => { test('skips when disabled', () => { expect.assertions(1); - const options = { enabled: false, dsn: PUBLIC_DSN }; + const options = getDefaultTestClientOptions({ enabled: false, dsn: PUBLIC_DSN }); const client = new TestClient(options, setupTestTransport(options).transport); const session = new Session({ release: 'test' }); diff --git a/packages/core/test/lib/sdk.test.ts b/packages/core/test/lib/sdk.test.ts index 578361a97511..7dd3229c5c7e 100644 --- a/packages/core/test/lib/sdk.test.ts +++ b/packages/core/test/lib/sdk.test.ts @@ -3,7 +3,7 @@ import { Client, Integration } from '@sentry/types'; import { installedIntegrations } from '../../src/integration'; import { initAndBind } from '../../src/sdk'; -import { setupTestTransport, TestClient, TestOptions } from '../mocks/client'; +import { getDefaultTestClientOptions, setupTestTransport, TestClient } from '../mocks/client'; // eslint-disable-next-line no-var declare var global: any; @@ -35,7 +35,7 @@ jest.mock('@sentry/hub', () => { }; }); -class MockIntegration implements Integration { +export class MockIntegration implements Integration { public name: string; public setupOnce: () => void = jest.fn(); public constructor(name: string) { @@ -50,72 +50,15 @@ describe('SDK', () => { }); describe('initAndBind', () => { - test('installs default integrations', () => { - const DEFAULT_INTEGRATIONS: Integration[] = [ - new MockIntegration('MockIntegration 1'), - new MockIntegration('MockIntegration 2'), - ]; - const options = { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS }; - initAndBind(TestClient, options, setupTestTransport(options).transport); - expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); - expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); - }); - - test("doesn't install default integrations if told not to", () => { - const DEFAULT_INTEGRATIONS: Integration[] = [ - new MockIntegration('MockIntegration 1'), - new MockIntegration('MockIntegration 2'), - ]; - const options: TestOptions = { dsn: PUBLIC_DSN, defaultIntegrations: false }; - initAndBind(TestClient, options, setupTestTransport(options).transport); - expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(0); - expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(0); - }); - test('installs integrations provided through options', () => { const integrations: Integration[] = [ new MockIntegration('MockIntegration 1'), new MockIntegration('MockIntegration 2'), ]; - const options = { dsn: PUBLIC_DSN, integrations }; - initAndBind(TestClient, options, setupTestTransport(options).transport); - expect((integrations[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); - expect((integrations[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); - }); - - test('installs merged default integrations, with overrides provided through options', () => { - const DEFAULT_INTEGRATIONS: Integration[] = [ - new MockIntegration('MockIntegration 1'), - new MockIntegration('MockIntegration 2'), - ]; - const integrations: Integration[] = [ - new MockIntegration('MockIntegration 1'), - new MockIntegration('MockIntegration 3'), - ]; - const options = { dsn: PUBLIC_DSN, defaultIntegrations: DEFAULT_INTEGRATIONS, integrations }; + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations }); initAndBind(TestClient, options, setupTestTransport(options).transport); - // 'MockIntegration 1' should be overridden by the one with the same name provided through options - expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(0); - expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((integrations[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((integrations[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); }); - - test('installs integrations returned from a callback function', () => { - const DEFAULT_INTEGRATIONS: Integration[] = [ - new MockIntegration('MockIntegration 1'), - new MockIntegration('MockIntegration 2'), - ]; - const newIntegration = new MockIntegration('MockIntegration 3'); - const options = { - defaultIntegrations: DEFAULT_INTEGRATIONS, - dsn: PUBLIC_DSN, - integrations: (integrations: Integration[]) => integrations.slice(0, 1).concat(newIntegration), - }; - initAndBind(TestClient, options, setupTestTransport(options).transport); - expect((DEFAULT_INTEGRATIONS[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); - expect((newIntegration.setupOnce as jest.Mock).mock.calls.length).toBe(1); - expect((DEFAULT_INTEGRATIONS[1].setupOnce as jest.Mock).mock.calls.length).toBe(0); - }); }); }); diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 707513ff91b1..5778dcf5e193 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,26 +1,36 @@ import { Session } from '@sentry/hub'; -import { Event, Integration, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { ClientOptions, Event, Integration, Severity, SeverityLevel, Transport } from '@sentry/types'; import { resolvedSyncPromise } from '@sentry/utils'; import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; import { NewTransport } from '../../src/transports/base'; import { NoopTransport } from '../../src/transports/noop'; -export interface TestOptions extends Options { + +export function getDefaultTestClientOptions(options: Partial = {}): TestClientOptions { + return { + integrations: [], + transport: NoopTransport, + stackParser: () => [], + ...options, + }; +} + +export interface TestClientOptions extends ClientOptions { test?: boolean; mockInstallFailure?: boolean; enableSend?: boolean; defaultIntegrations?: Integration[] | false; } -export class TestClient extends BaseClient { +export class TestClient extends BaseClient { public static instance?: TestClient; public static sendEventCalled?: (event: Event) => void; public event?: Event; public session?: Session; - public constructor(options: TestOptions, transport: Transport, newTransport?: NewTransport) { + public constructor(options: TestClientOptions, transport: Transport, newTransport?: NewTransport) { super(options, transport, newTransport); TestClient.instance = this; } @@ -64,11 +74,11 @@ export class TestClient extends BaseClient { } } -export function init(options: TestOptions, transport: Transport, newTransport?: NewTransport): void { +export function init(options: TestClientOptions, transport: Transport, newTransport?: NewTransport): void { initAndBind(TestClient, options, transport, newTransport); } -export function setupTestTransport(options: TestOptions): { transport: Transport; newTransport?: NewTransport } { +export function setupTestTransport(options: TestClientOptions): { transport: Transport; newTransport?: NewTransport } { const noop = { transport: new NoopTransport() }; if (!options.dsn) { diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index e660c6c7b421..7864fd1b7ccc 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -5,22 +5,22 @@ import { logger, resolvedSyncPromise, stackParserFromOptions } from '@sentry/uti import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; -import { NodeOptions } from './types'; +import { NodeClientOptions } from './types'; /** * The Sentry Node SDK Client. * - * @see NodeOptions for documentation on configuration options. + * @see NodeClientOptions for documentation on configuration options. * @see SentryClient for usage documentation. */ -export class NodeClient extends BaseClient { +export class NodeClient extends BaseClient { protected _sessionFlusher: SessionFlusher | undefined; /** * Creates a new Node SDK instance. * @param options Configuration options for this SDK. */ - public constructor(options: NodeOptions, transport: Transport, newTransport?: NewTransport) { + public constructor(options: NodeClientOptions, transport: Transport, newTransport?: NewTransport) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.node', diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index 0b7fb9bd5671..fa4b22a12066 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -1,15 +1,15 @@ -import { getCurrentHub, initAndBind, Integrations as CoreIntegrations } from '@sentry/core'; +import { getCurrentHub, getIntegrationsToSetup, initAndBind, Integrations as CoreIntegrations } from '@sentry/core'; import { getMainCarrier, setHubOnCarrier } from '@sentry/hub'; import { SessionStatus } from '@sentry/types'; -import { getGlobalObject, logger } from '@sentry/utils'; +import { getGlobalObject, logger, stackParserFromOptions } from '@sentry/utils'; import * as domain from 'domain'; import { NodeClient } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations'; import { nodeStackParser } from './stack-parser'; -import { setupNodeTransport } from './transports'; -import { NodeOptions } from './types'; +import { HTTPSTransport, HTTPTransport, setupNodeTransport } from './transports'; +import { NodeClientOptions, NodeOptions } from './types'; export const defaultIntegrations = [ // Common @@ -132,7 +132,17 @@ export function init(options: NodeOptions = {}): void { } const { transport, newTransport } = setupNodeTransport(options); - initAndBind(NodeClient, options, transport, newTransport); + + // TODO(v7): Refactor this to reduce the logic above + const clientOptions: NodeClientOptions = { + ...options, + stackParser: stackParserFromOptions(options), + integrations: getIntegrationsToSetup(options), + // TODO(v7): Fix me when we switch to new transports entirely. + transport: options.transport || (transport instanceof HTTPTransport ? HTTPTransport : HTTPSTransport), + }; + + initAndBind(NodeClient, clientOptions, transport, newTransport); if (options.autoSessionTracking) { startSessionTracking(); @@ -189,7 +199,7 @@ export function isAutoSessionTrackingEnabled(client?: NodeClient): boolean { if (client === undefined) { return false; } - const clientOptions: NodeOptions = client && client.getOptions(); + const clientOptions = client && client.getOptions(); if (clientOptions && clientOptions.autoSessionTracking !== undefined) { return clientOptions.autoSessionTracking; } diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 055006a47e9e..a2311a4698f9 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -1,16 +1,9 @@ -import { Options } from '@sentry/types'; +import { ClientOptions, Options } from '@sentry/types'; -/** - * Configuration options for the Sentry Node SDK. - * @see NodeClient for more information. - */ -export interface NodeOptions extends Options { +export interface BaseNodeOptions { /** Sets an optional server name (device name) */ serverName?: string; - /** Maximum time in milliseconds to wait to drain the request queue, before the process is allowed to exit. */ - shutdownTimeout?: number; - /** Set a HTTP proxy that should be used for outbound requests. */ httpProxy?: string; @@ -23,3 +16,15 @@ export interface NodeOptions extends Options { /** Callback that is executed when a fatal global error occurs. */ onFatalError?(error: Error): void; } + +/** + * Configuration options for the Sentry Node SDK + * @see @sentry/types Options for more information. + */ +export interface NodeOptions extends Options, BaseNodeOptions {} + +/** + * Configuration options for the Sentry Node SDK Client class + * @see NodeClient for more information. + */ +export interface NodeClientOptions extends ClientOptions, BaseNodeOptions {} diff --git a/packages/node/test/client.test.ts b/packages/node/test/client.test.ts index 1cddd0e85e3f..bb3d13ca4122 100644 --- a/packages/node/test/client.test.ts +++ b/packages/node/test/client.test.ts @@ -2,6 +2,7 @@ import { Scope, SessionFlusher } from '@sentry/hub'; import { NodeClient } from '../src'; import { setupNodeTransport } from '../src/transports'; +import { getDefaultNodeClientOptions } from './helper/node-client-options'; const PUBLIC_DSN = 'https://username@domain/123'; @@ -15,7 +16,7 @@ describe('NodeClient', () => { describe('captureException', () => { test('when autoSessionTracking is enabled, and requestHandler is not used -> requestStatus should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); const scope = new Scope(); scope.setRequestSession({ status: 'ok' }); @@ -26,7 +27,7 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('ok'); }); test('when autoSessionTracking is disabled -> requestStatus should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -41,7 +42,7 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('ok'); }); test('when autoSessionTracking is enabled + requestSession status is Crashed -> requestStatus should not be overridden', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -56,7 +57,7 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('crashed'); }); test('when autoSessionTracking is enabled + error occurs within request bounds -> requestStatus should be set to Errored', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -71,7 +72,7 @@ describe('NodeClient', () => { expect(requestSession!.status).toEqual('errored'); }); test('when autoSessionTracking is enabled + error occurs outside of request bounds -> requestStatus should not be set to Errored', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -88,7 +89,7 @@ describe('NodeClient', () => { describe('captureEvent()', () => { test('If autoSessionTracking is disabled, requestSession status should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -107,7 +108,7 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception, requestSession status should be set to Errored', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -123,7 +124,7 @@ describe('NodeClient', () => { }); test('When captureEvent is called without an exception, requestSession status should not be set to Errored', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -139,7 +140,7 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception but outside of a request, then requestStatus should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -157,7 +158,7 @@ describe('NodeClient', () => { }); test('When captureEvent is called with a transaction, then requestSession status should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -172,7 +173,7 @@ describe('NodeClient', () => { }); test('When captureEvent is called with an exception but requestHandler is not used, then requestSession status should not be set', () => { - const options = { dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }; + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); client = new NodeClient(options, setupNodeTransport(options).transport); const scope = new Scope(); @@ -192,11 +193,11 @@ describe('NodeClient', () => { describe('flush/close', () => { test('client close function disables _sessionFlusher', async () => { jest.useRealTimers(); - const options = { + const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.1', - }; + }); const client = new NodeClient(options, setupNodeTransport(options).transport); client.initSessionFlusher(); // Clearing interval is important here to ensure that the flush function later on is called by the `client.close()` diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index d7d47fda053d..b857e1b74bf5 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -1,6 +1,6 @@ import * as sentryCore from '@sentry/core'; -import { Hub } from '@sentry/hub'; import * as sentryHub from '@sentry/hub'; +import { Hub } from '@sentry/hub'; import { Transaction } from '@sentry/tracing'; import { Runtime } from '@sentry/types'; import { SentryError } from '@sentry/utils'; @@ -19,6 +19,7 @@ import { } from '../src/handlers'; import * as SDK from '../src/sdk'; import { setupNodeTransport } from '../src/transports'; +import { getDefaultNodeClientOptions } from './helper/node-client-options'; describe('parseRequest', () => { let mockReq: { [key: string]: any }; @@ -224,7 +225,7 @@ describe('requestHandler', () => { }); it('autoSessionTracking is enabled, sets requestSession status to ok, when handling a request', () => { - const options = { autoSessionTracking: true, release: '1.2' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); @@ -237,7 +238,7 @@ describe('requestHandler', () => { }); it('autoSessionTracking is disabled, does not set requestSession, when handling a request', () => { - const options = { autoSessionTracking: false, release: '1.2' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); @@ -250,7 +251,7 @@ describe('requestHandler', () => { }); it('autoSessionTracking is enabled, calls _captureRequestSession, on response finish', done => { - const options = { autoSessionTracking: true, release: '1.2' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); @@ -271,7 +272,7 @@ describe('requestHandler', () => { }); it('autoSessionTracking is disabled, does not call _captureRequestSession, on response finish', done => { - const options = { autoSessionTracking: false, release: '1.2' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -372,7 +373,7 @@ describe('tracingHandler', () => { it('extracts request data for sampling context', () => { const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultNodeClientOptions({ tracesSampler }); const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two @@ -395,7 +396,7 @@ describe('tracingHandler', () => { }); it('puts its transaction on the scope', () => { - const options = { tracesSampleRate: 1.0 }; + const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two @@ -727,7 +728,7 @@ describe('errorHandler()', () => { jest.restoreAllMocks(); }); it('when autoSessionTracking is disabled, does not set requestSession status on Crash', () => { - const options = { autoSessionTracking: false, release: '3.3' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '3.3' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -747,7 +748,7 @@ describe('errorHandler()', () => { }); it('autoSessionTracking is enabled + requestHandler is not used -> does not set requestSession status on Crash', () => { - const options = { autoSessionTracking: false, release: '3.3' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '3.3' }); client = new NodeClient(options, setupNodeTransport(options).transport); const scope = sentryCore.getCurrentHub().getScope(); @@ -764,7 +765,7 @@ describe('errorHandler()', () => { }); it('when autoSessionTracking is enabled, should set requestSession status to Crashed when an unhandled error occurs within the bounds of a request', () => { - const options = { autoSessionTracking: true, release: '1.1' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.1' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) @@ -783,7 +784,7 @@ describe('errorHandler()', () => { }); it('when autoSessionTracking is enabled, should not set requestSession status on Crash when it occurs outside the bounds of a request', () => { - const options = { autoSessionTracking: true, release: '2.2' }; + const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '2.2' }); client = new NodeClient(options, setupNodeTransport(options).transport); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) diff --git a/packages/node/test/helper/node-client-options.ts b/packages/node/test/helper/node-client-options.ts new file mode 100644 index 000000000000..c2bb1d42a871 --- /dev/null +++ b/packages/node/test/helper/node-client-options.ts @@ -0,0 +1,12 @@ +import { NoopTransport } from '@sentry/core'; + +import { NodeClientOptions } from '../../src/types'; + +export function getDefaultNodeClientOptions(options: Partial = {}): NodeClientOptions { + return { + integrations: [], + transport: NoopTransport, + stackParser: () => [], + ...options, + }; +} diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index 02eaad72b2c0..2bdf8497097c 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -19,6 +19,7 @@ import { import { ContextLines, LinkedErrors } from '../src/integrations'; import { nodeStackParser } from '../src/stack-parser'; import { setupNodeTransport } from '../src/transports'; +import { getDefaultNodeClientOptions } from './helper/node-client-options'; const stackParser = createStackParser(nodeStackParser); @@ -90,7 +91,7 @@ describe('SentryNode', () => { }); test('record auto breadcrumbs', done => { - const options = { + const options = getDefaultNodeClientOptions({ beforeSend: (event: Event) => { // TODO: It should be 3, but we don't capture a breadcrumb // for our own captureMessage/captureException calls yet @@ -100,7 +101,7 @@ describe('SentryNode', () => { }, dsn, stackParser, - }; + }); const client = new NodeClient(options, setupNodeTransport(options).transport); getCurrentHub().bindClient(client); addBreadcrumb({ message: 'test1' }); @@ -122,7 +123,7 @@ describe('SentryNode', () => { test('capture an exception', done => { expect.assertions(6); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); @@ -135,7 +136,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); @@ -149,7 +150,7 @@ describe('SentryNode', () => { test('capture a string exception', done => { expect.assertions(6); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); @@ -162,7 +163,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); @@ -176,7 +177,7 @@ describe('SentryNode', () => { test('capture an exception with pre/post context', done => { expect.assertions(10); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.tags).toEqual({ test: '1' }); @@ -193,7 +194,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); configureScope((scope: Scope) => { scope.setTag('test', '1'); @@ -207,7 +208,7 @@ describe('SentryNode', () => { test('capture a linked exception with pre/post context', done => { expect.assertions(15); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, integrations: [new ContextLines(), new LinkedErrors()], beforeSend: (event: Event) => { @@ -231,7 +232,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); try { throw new Error('test'); @@ -247,7 +248,7 @@ describe('SentryNode', () => { test('capture a message', done => { expect.assertions(2); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test'); @@ -256,14 +257,14 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); captureMessage('test'); }); test('capture an event', done => { expect.assertions(2); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test event'); @@ -272,7 +273,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); captureEvent({ message: 'test event' }); }); @@ -280,7 +281,7 @@ describe('SentryNode', () => { test('capture an event in a domain', done => { const d = domain.create(); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect(event.message).toBe('test domain'); @@ -289,7 +290,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); const client = new NodeClient(options, setupNodeTransport(options).transport); d.run(() => { @@ -301,7 +302,7 @@ describe('SentryNode', () => { test('stacktrace order', done => { expect.assertions(1); - const options = { + const options = getDefaultNodeClientOptions({ stackParser, beforeSend: (event: Event) => { expect( @@ -312,7 +313,7 @@ describe('SentryNode', () => { return null; }, dsn, - }; + }); getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); try { // @ts-ignore allow function declarations in strict mode @@ -376,7 +377,7 @@ describe('SentryNode initialization', () => { }); it('should set SDK data when instantiating a client directly', () => { - const options = { dsn }; + const options = getDefaultNodeClientOptions({ dsn }); const client = new NodeClient(options, setupNodeTransport(options).transport); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index f66f847cd298..30a923524a3e 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -1,6 +1,6 @@ import * as sentryCore from '@sentry/core'; -import { Hub } from '@sentry/hub'; import * as hubModule from '@sentry/hub'; +import { Hub } from '@sentry/hub'; import { addExtensionMethods, Span, TRACEPARENT_REGEXP, Transaction } from '@sentry/tracing'; import { parseSemver } from '@sentry/utils'; import * as http from 'http'; @@ -12,16 +12,17 @@ import { Breadcrumb } from '../../src'; import { NodeClient } from '../../src/client'; import { Http as HttpIntegration } from '../../src/integrations/http'; import { setupNodeTransport } from '../../src/transports'; +import { getDefaultNodeClientOptions } from '../helper/node-client-options'; const NODE_VERSION = parseSemver(process.versions.node); describe('tracing', () => { function createTransactionOnScope() { - const options = { + const options = getDefaultNodeClientOptions({ dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', tracesSampleRate: 1.0, integrations: [new HttpIntegration({ tracing: true })], - }; + }); const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); addExtensionMethods(); @@ -97,7 +98,7 @@ describe('default protocols', () => { const p = new Promise(r => { resolve = r; }); - const options = { + const options = getDefaultNodeClientOptions({ dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012', integrations: [new HttpIntegration({ breadcrumbs: true })], beforeBreadcrumb: (b: Breadcrumb) => { @@ -106,7 +107,7 @@ describe('default protocols', () => { } return b; }, - }; + }); hub.bindClient(new NodeClient(options, setupNodeTransport(options).transport)); return p; diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 2c2957bf6a69..4d18707be904 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -5,6 +5,7 @@ import { Event, NodeClient } from '../../src'; import { LinkedErrors } from '../../src/integrations/linkederrors'; import { nodeStackParser } from '../../src/stack-parser'; import { setupNodeTransport } from '../../src/transports'; +import { getDefaultNodeClientOptions } from '../helper/node-client-options'; const stackParser = createStackParser(nodeStackParser); @@ -32,7 +33,7 @@ describe('LinkedErrors', () => { expect.assertions(2); const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); - const options = { stackParser }; + const options = getDefaultNodeClientOptions({ stackParser }); const client = new NodeClient(options, setupNodeTransport(options).transport); let event: Event | undefined; return client @@ -56,7 +57,7 @@ describe('LinkedErrors', () => { }), ); const one = new Error('originalException'); - const options = { stackParser }; + const options = getDefaultNodeClientOptions({ stackParser }); const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors @@ -77,7 +78,7 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const options = { stackParser }; + const options = getDefaultNodeClientOptions({ stackParser }); const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors @@ -111,7 +112,7 @@ describe('LinkedErrors', () => { one.reason = two; two.reason = three; - const options = { stackParser }; + const options = getDefaultNodeClientOptions({ stackParser }); const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors @@ -145,7 +146,7 @@ describe('LinkedErrors', () => { one.cause = two; two.cause = three; - const options = { stackParser }; + const options = getDefaultNodeClientOptions({ stackParser }); const client = new NodeClient(options, setupNodeTransport(options).transport); return client.eventFromException(one).then(event => linkedErrors diff --git a/packages/node/test/sdk.test.ts b/packages/node/test/sdk.test.ts new file mode 100644 index 000000000000..48e5accee439 --- /dev/null +++ b/packages/node/test/sdk.test.ts @@ -0,0 +1,92 @@ +import { Integration } from '@sentry/types'; + +import { init } from '../src/sdk'; +import * as sdk from '../src/sdk'; + +// eslint-disable-next-line no-var +declare var global: any; + +const PUBLIC_DSN = 'https://username@domain/123'; + +class MockIntegration implements Integration { + public name: string; + public setupOnce: jest.Mock = jest.fn(); + public constructor(name: string) { + this.name = name; + } +} + +const defaultIntegrationsBackup = sdk.defaultIntegrations; + +describe('init()', () => { + beforeEach(() => { + global.__SENTRY__ = {}; + }); + + afterEach(() => { + // @ts-ignore - Reset the default integrations of node sdk to original + sdk.defaultIntegrations = defaultIntegrationsBackup; + }); + + it("doesn't install default integrations if told not to", () => { + const mockDefaultIntegrations = [ + new MockIntegration('Mock integration 1.1'), + new MockIntegration('Mock integration 1.2'), + ]; + + // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly + sdk.defaultIntegrations = mockDefaultIntegrations; + + init({ dsn: PUBLIC_DSN, defaultIntegrations: false }); + + expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + }); + + it('installs merged default integrations, with overrides provided through options', () => { + const mockDefaultIntegrations = [ + new MockIntegration('Some mock integration 2.1'), + new MockIntegration('Some mock integration 2.2'), + ]; + + // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly + sdk.defaultIntegrations = mockDefaultIntegrations; + + const mockIntegrations = [ + new MockIntegration('Some mock integration 2.1'), + new MockIntegration('Some mock integration 2.3'), + ]; + + init({ dsn: PUBLIC_DSN, integrations: mockIntegrations }); + + expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + }); + + it('installs integrations returned from a callback function', () => { + const mockDefaultIntegrations = [ + new MockIntegration('Some mock integration 3.1'), + new MockIntegration('Some mock integration 3.2'), + ]; + + // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly + sdk.defaultIntegrations = mockDefaultIntegrations; + + const newIntegration = new MockIntegration('Some mock integration 3.3'); + + init({ + dsn: PUBLIC_DSN, + integrations: integrations => { + const newIntegrations = [...integrations]; + newIntegrations[1] = newIntegration; + return newIntegrations; + }, + }); + + expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0); + expect(newIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/node/test/transports/setup.test.ts b/packages/node/test/transports/setup.test.ts index 6864ac89ea1e..38f99a4c95f3 100644 --- a/packages/node/test/transports/setup.test.ts +++ b/packages/node/test/transports/setup.test.ts @@ -3,6 +3,7 @@ import { FakeTransport } from '@sentry/core/test/mocks/transport'; import { HTTPSTransport, HTTPTransport, setupNodeTransport } from '@sentry/node/src/transports'; import { makeNodeTransport } from '../../src/transports/new'; +import { getDefaultNodeClientOptions } from '../helper/node-client-options'; jest.mock('../../src/transports/new', () => { const original = jest.requireActual('../../src/transports/new'); @@ -31,7 +32,7 @@ describe('setupNodeTransport', () => { }); it('returns the instantiated transport passed via the options', () => { - const options = { dsn: DSN, transport: FakeTransport }; + const options = getDefaultNodeClientOptions({ dsn: DSN, transport: FakeTransport }); const { transport, newTransport } = setupNodeTransport(options); expect(transport).toBeDefined(); diff --git a/packages/tracing/src/hubextensions.ts b/packages/tracing/src/hubextensions.ts index bd38b270cc22..80bd7a5783c8 100644 --- a/packages/tracing/src/hubextensions.ts +++ b/packages/tracing/src/hubextensions.ts @@ -1,5 +1,6 @@ import { getMainCarrier, Hub } from '@sentry/hub'; import { + ClientOptions, CustomSamplingContext, Integration, IntegrationClass, @@ -41,7 +42,11 @@ function traceHeaders(this: Hub): { [key: string]: string } { * * @returns The given transaction with its `sampled` value set */ -function sample(transaction: T, options: Options, samplingContext: SamplingContext): T { +function sample( + transaction: T, + options: Pick, + samplingContext: SamplingContext, +): T { // nothing to do if tracing is not enabled if (!hasTracingEnabled(options)) { transaction.sampled = false; @@ -171,7 +176,7 @@ function _startTransaction( customSamplingContext?: CustomSamplingContext, ): Transaction { const client = this.getClient(); - const options = (client && client.getOptions()) || {}; + const options: Partial = (client && client.getOptions()) || {}; let transaction = new Transaction(transactionContext, this); transaction = sample(transaction, options, { @@ -196,7 +201,7 @@ export function startIdleTransaction( customSamplingContext?: CustomSamplingContext, ): IdleTransaction { const client = hub.getClient(); - const options = (client && client.getOptions()) || {}; + const options: Partial = (client && client.getOptions()) || {}; let transaction = new IdleTransaction(transactionContext, hub, idleTimeout, onScope); transaction = sample(transaction, options, { diff --git a/packages/tracing/src/utils.ts b/packages/tracing/src/utils.ts index 63598c00ac58..9d999df486fb 100644 --- a/packages/tracing/src/utils.ts +++ b/packages/tracing/src/utils.ts @@ -20,7 +20,9 @@ export { TRACEPARENT_REGEXP, extractTraceparentData } from '@sentry/utils'; * * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config. */ -export function hasTracingEnabled(maybeOptions?: Options | undefined): boolean { +export function hasTracingEnabled( + maybeOptions?: Pick | undefined, +): boolean { const client = getCurrentHub().getClient(); const options = maybeOptions || (client && client.getOptions()); return !!options && ('tracesSampleRate' in options || 'tracesSampler' in options); diff --git a/packages/tracing/test/browser/backgroundtab.test.ts b/packages/tracing/test/browser/backgroundtab.test.ts index 440eb785a609..29612b410322 100644 --- a/packages/tracing/test/browser/backgroundtab.test.ts +++ b/packages/tracing/test/browser/backgroundtab.test.ts @@ -1,5 +1,6 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import { JSDOM } from 'jsdom'; @@ -14,7 +15,7 @@ describe('registerBackgroundTabDetection', () => { // @ts-ignore need to override global document global.document = dom.window.document; - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index dfa4e0436b8c..76ccaf947271 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,5 +1,6 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import { getGlobalObject, InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; @@ -52,7 +53,7 @@ describe('BrowserTracing', () => { let hub: Hub; beforeEach(() => { jest.useFakeTimers(); - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); document.head.innerHTML = ''; @@ -474,7 +475,7 @@ describe('BrowserTracing', () => { getGlobalObject().location = dogParkLocation as any; const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); // setting up the BrowserTracing integration automatically starts a pageload transaction createBrowserTracing(true); @@ -491,7 +492,7 @@ describe('BrowserTracing', () => { getGlobalObject().location = dogParkLocation as any; const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); // setting up the BrowserTracing integration normally automatically starts a pageload transaction, but that's not // what we're testing here diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index 65823e293351..4ead6fe5bb9b 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -1,5 +1,6 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import * as utils from '@sentry/utils'; @@ -73,7 +74,7 @@ describe('callbacks', () => { }; beforeAll(() => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); }); diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index c15825fd5480..8dbcb2454539 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,5 +1,6 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { NoopTransport } from '@sentry/core/src/transports/noop'; import { Hub, makeMain } from '@sentry/hub'; import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; @@ -35,7 +36,7 @@ describe('registerErrorHandlers()', () => { let hub: Hub; beforeEach(() => { mockAddInstrumentationHandler.mockClear(); - const options = { tracesSampleRate: 1 }; + const options = { tracesSampleRate: 1, transport: NoopTransport, integrations: [], stackParser: () => [] }; hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); }); diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 045d9fa96fb1..6df8bad175c1 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import * as utilsModule from '@sentry/utils'; // for mocking import { logger } from '@sentry/utils'; @@ -33,7 +34,7 @@ describe('Hub', () => { describe('getTransaction()', () => { it('should find a transaction which has been set on the scope if sampled = true', () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -47,7 +48,7 @@ describe('Hub', () => { }); it('should find a transaction which has been set on the scope if sampled = false', () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -60,7 +61,7 @@ describe('Hub', () => { }); it("should not find an open transaction if it's not on the scope", () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -73,7 +74,7 @@ describe('Hub', () => { describe('default sample context', () => { it('should add transaction context data to default sample context', () => { const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); @@ -90,7 +91,7 @@ describe('Hub', () => { it("should add parent's sampling decision to default sample context", () => { const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const parentSamplingDecsion = false; @@ -109,7 +110,7 @@ describe('Hub', () => { describe('sample()', () => { it('should set sampled = false when tracing is disabled', () => { - const options = {}; + const options = getDefaultBrowserClientOptions({}); // neither tracesSampleRate nor tracesSampler is defined -> tracing disabled const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); @@ -119,7 +120,7 @@ describe('Hub', () => { }); it('should set sampled = false if tracesSampleRate is 0', () => { - const options = { tracesSampleRate: 0 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -128,7 +129,7 @@ describe('Hub', () => { }); it('should set sampled = true if tracesSampleRate is 1', () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -137,7 +138,7 @@ describe('Hub', () => { }); it('should set sampled = true if tracesSampleRate is 1 (without global hub)', () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -146,7 +147,7 @@ describe('Hub', () => { it("should call tracesSampler if it's defined", () => { const tracesSampler = jest.fn(); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -156,7 +157,7 @@ describe('Hub', () => { it('should set sampled = false if tracesSampler returns 0', () => { const tracesSampler = jest.fn().mockReturnValue(0); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -167,7 +168,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1', () => { const tracesSampler = jest.fn().mockReturnValue(1); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -178,7 +179,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1 (without global hub)', () => { const tracesSampler = jest.fn().mockReturnValue(1); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -189,7 +190,7 @@ describe('Hub', () => { it('should not try to override explicitly set positive sampling decision', () => { // so that the decision otherwise would be false const tracesSampler = jest.fn().mockReturnValue(0); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -200,7 +201,7 @@ describe('Hub', () => { it('should not try to override explicitly set negative sampling decision', () => { // so that the decision otherwise would be true const tracesSampler = jest.fn().mockReturnValue(1); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -211,7 +212,7 @@ describe('Hub', () => { it('should prefer tracesSampler to tracesSampleRate', () => { // make the two options do opposite things to prove precedence const tracesSampler = jest.fn().mockReturnValue(true); - const options = { tracesSampleRate: 0, tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0, tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -222,7 +223,7 @@ describe('Hub', () => { it('should tolerate tracesSampler returning a boolean', () => { const tracesSampler = jest.fn().mockReturnValue(true); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -233,7 +234,7 @@ describe('Hub', () => { it('should record sampling method when sampling decision is explicitly set', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -245,7 +246,7 @@ describe('Hub', () => { it('should record sampling method and rate when sampling decision comes from tracesSampler', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -256,7 +257,7 @@ describe('Hub', () => { }); it('should record sampling method when sampling decision is inherited', () => { - const options = { tracesSampleRate: 0.1121 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark', parentSampled: true }); @@ -267,7 +268,7 @@ describe('Hub', () => { }); it('should record sampling method and rate when sampling decision comes from traceSampleRate', () => { - const options = { tracesSampleRate: 0.1121 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -280,7 +281,7 @@ describe('Hub', () => { describe('isValidSampleRate()', () => { it("should reject tracesSampleRates which aren't numbers or booleans", () => { - const options = { tracesSampleRate: 'dogs!' as any }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -289,7 +290,7 @@ describe('Hub', () => { }); it('should reject tracesSampleRates which are NaN', () => { - const options = { tracesSampleRate: 'dogs!' as any }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -299,7 +300,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates less than 0', () => { - const options = { tracesSampleRate: -26 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: -26 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -309,7 +310,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates greater than 1', () => { - const options = { tracesSampleRate: 26 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 26 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -319,7 +320,7 @@ describe('Hub', () => { it("should reject tracesSampler return values which aren't numbers or booleans", () => { const tracesSampler = jest.fn().mockReturnValue('dogs!'); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -329,7 +330,7 @@ describe('Hub', () => { it('should reject tracesSampler return values which are NaN', () => { const tracesSampler = jest.fn().mockReturnValue(NaN); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -340,7 +341,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampler return values less than 0', () => { const tracesSampler = jest.fn().mockReturnValue(-12); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -351,7 +352,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampler return values greater than 1', () => { const tracesSampler = jest.fn().mockReturnValue(31); - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -361,7 +362,7 @@ describe('Hub', () => { }); it('should drop transactions with sampled = false', () => { - const options = { tracesSampleRate: 0 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); const client = new BrowserClient(options, setupBrowserTransport(options).transport); jest.spyOn(client, 'captureEvent'); @@ -379,7 +380,7 @@ describe('Hub', () => { describe('sampling inheritance', () => { it('should propagate sampling decision to child spans', () => { - const options = { tracesSampleRate: Math.random() }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: Math.random() }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -392,11 +393,11 @@ describe('Hub', () => { testOnlyIfNodeVersionAtLeast(10)( 'should propagate positive sampling decision to child transactions in XHR header', async () => { - const options = { + const options = getDefaultBrowserClientOptions({ dsn: 'https://1231@dogs.are.great/1121', tracesSampleRate: 1, integrations: [new BrowserTracing()], - }; + }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); @@ -433,11 +434,11 @@ describe('Hub', () => { testOnlyIfNodeVersionAtLeast(10)( 'should propagate negative sampling decision to child transactions in XHR header', async () => { - const options = { + const options = getDefaultBrowserClientOptions({ dsn: 'https://1231@dogs.are.great/1121', tracesSampleRate: 1, integrations: [new BrowserTracing()], - }; + }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); @@ -483,7 +484,7 @@ describe('Hub', () => { // sample rate), so make parent's decision the opposite to prove that inheritance takes precedence over // tracesSampleRate mathRandom.mockReturnValueOnce(1); - const options = { tracesSampleRate: 0.5 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.5 }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); const parentSamplingDecsion = true; @@ -498,7 +499,7 @@ describe('Hub', () => { }); it("should inherit parent's negative sampling decision if tracesSampler is undefined", () => { - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); // tracesSampleRate = 1 means every transaction should end up with sampled = true, so make parent's decision the // opposite to prove that inheritance takes precedence over tracesSampleRate const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); @@ -520,7 +521,7 @@ describe('Hub', () => { const tracesSampler = () => true; const parentSamplingDecsion = false; - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); @@ -539,7 +540,7 @@ describe('Hub', () => { const tracesSampler = () => false; const parentSamplingDecsion = true; - const options = { tracesSampler }; + const options = getDefaultBrowserClientOptions({ tracesSampler }); const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); makeMain(hub); diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index b8029c6b92d7..b040f4adbd9b 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -1,4 +1,5 @@ import { BrowserClient, Transports } from '@sentry/browser'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub } from '@sentry/hub'; import { @@ -16,8 +17,8 @@ class SimpleTransport extends Transports.BaseTransport {} const dsn = 'https://123@sentry.io/42'; let hub: Hub; beforeEach(() => { - const options = { dsn, tracesSampleRate: 1, transport: SimpleTransport }; - hub = new Hub(new BrowserClient(options, new SimpleTransport(options))); + const options = getDefaultBrowserClientOptions({ dsn, tracesSampleRate: 1, transport: SimpleTransport }); + hub = new Hub(new BrowserClient(options, new SimpleTransport({ dsn }))); }); describe('IdleTransaction', () => { diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index fe11fbf143ee..13f47c51ae7b 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -1,5 +1,6 @@ import { BrowserClient } from '@sentry/browser'; import { setupBrowserTransport } from '@sentry/browser/src/transports'; +import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain, Scope } from '@sentry/hub'; import { Span, Transaction } from '../src'; @@ -10,7 +11,7 @@ describe('Span', () => { beforeEach(() => { const myScope = new Scope(); - const options = { tracesSampleRate: 1 }; + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport), myScope); makeMain(hub); }); @@ -218,10 +219,10 @@ describe('Span', () => { }); test('maxSpans correctly limits number of spans', () => { - const options = { + const options = getDefaultBrowserClientOptions({ _experiments: { maxSpans: 3 }, tracesSampleRate: 1, - }; + }); const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test' }); @@ -234,9 +235,9 @@ describe('Span', () => { }); test('no span recorder created if transaction.sampled is false', () => { - const options = { + const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1, - }; + }); const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test', sampled: false }); diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index c3f2a9920258..f0cdc8b3a988 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -1,7 +1,7 @@ import { DsnComponents } from './dsn'; import { Event, EventHint } from './event'; import { Integration, IntegrationClass } from './integration'; -import { Options } from './options'; +import { ClientOptions } from './options'; import { Scope } from './scope'; import { Session } from './session'; import { Severity, SeverityLevel } from './severity'; @@ -16,7 +16,7 @@ import { Transport } from './transport'; * there will only be one instance during runtime. * */ -export interface Client { +export interface Client { /** * Captures an exception event and sends it to Sentry. * diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 84430c1d3976..5fe4ced6375b 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -27,7 +27,7 @@ export type { Hub } from './hub'; export type { Integration, IntegrationClass } from './integration'; export type { Mechanism } from './mechanism'; export type { ExtractedNodeRequestData, Primitive, WorkerLocation } from './misc'; -export type { Options } from './options'; +export type { ClientOptions, Options } from './options'; export type { Package } from './package'; export type { QueryParams, Request, SentryRequest, SentryRequestType } from './request'; export type { Response } from './response'; diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index a7306acdd76f..8bd273752700 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -7,8 +7,7 @@ import { StackLineParser, StackParser } from './stacktrace'; import { SamplingContext } from './transaction'; import { Transport, TransportClass, TransportOptions } from './transport'; -/** Base configuration options for every SDK. */ -export interface Options { +export interface ClientOptions { /** * Enable debug functionality in the SDK itself */ @@ -20,6 +19,21 @@ export interface Options { */ enabled?: boolean; + /** Attaches stacktraces to pure capture message / log integrations */ + attachStacktrace?: boolean; + + /** + * A flag enabling Sessions Tracking feature. + * By default, Sessions Tracking is enabled. + */ + autoSessionTracking?: boolean; + + /** + * Send SDK Client Reports. + * By default, Client Reports are enabled. + */ + sendClientReports?: boolean; + /** * The Dsn used to connect to Sentry and identify the project. If omitted, the * SDK will not send any data to Sentry. @@ -27,29 +41,33 @@ export interface Options { dsn?: string; /** - * If this is set to false, default integrations will not be added, otherwise this will internally be set to the - * recommended default integrations. - * TODO: We should consider changing this to `boolean | Integration[]` + * The release identifier used when uploading respective source maps. Specify + * this value to allow Sentry to resolve the correct source maps when + * processing events. */ - defaultIntegrations?: false | Integration[]; + release?: string; + + /** The current environment of your application (e.g. "production"). */ + environment?: string; + + /** Sets the distribution for all events */ + dist?: string; /** * List of integrations that should be installed after SDK was initialized. - * Accepts either a list of integrations or a function that receives - * default integrations and returns a new, updated list. */ - integrations?: Integration[] | ((integrations: Integration[]) => Integration[]); + integrations: Integration[]; /** - * A pattern for error messages which should not be sent to Sentry. - * By default, all errors will be sent. + * Transport object that should be used to send events to Sentry */ - ignoreErrors?: Array; + transport: TransportClass; /** - * Transport object that should be used to send events to Sentry + * A stack parser implementation + * By default, a stack parser is supplied for all supported platforms */ - transport?: TransportClass; + stackParser: StackParser; /** * Options for the default transport that the SDK uses. @@ -57,24 +75,20 @@ export interface Options { transportOptions?: TransportOptions; /** - * A URL to an envelope tunnel endpoint. An envelope tunnel is an HTTP endpoint - * that accepts Sentry envelopes for forwarding. This can be used to force data - * through a custom server independent of the type of data. + * 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. */ - tunnel?: string; + tracesSampleRate?: number; /** - * The release identifier used when uploading respective source maps. Specify - * this value to allow Sentry to resolve the correct source maps when - * processing events. + * Initial data to populate scope. */ - release?: string; - - /** The current environment of your application (e.g. "production"). */ - environment?: string; - - /** Sets the distribution for all events */ - dist?: string; + initialScope?: CaptureContext; /** * The maximum number of breadcrumbs sent with events. Defaults to 100. @@ -85,9 +99,6 @@ export interface Options { /** A global sample rate to apply to all events (0 - 1). */ sampleRate?: number; - /** Attaches stacktraces to pure capture message / log integrations */ - attachStacktrace?: boolean; - /** Maximum number of chars a single value can have before it will be truncated. */ maxValueLength?: number; @@ -123,38 +134,17 @@ export interface Options { shutdownTimeout?: number; /** - * 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; - - /** - * A flag enabling Sessions Tracking feature. - * By default, Sessions Tracking is enabled. - */ - autoSessionTracking?: boolean; - - /** - * Send SDK Client Reports. - * By default, Client Reports are enabled. - */ - sendClientReports?: boolean; - - /** - * Initial data to populate scope. + * A pattern for error messages which should not be sent to Sentry. + * By default, all errors will be sent. */ - initialScope?: CaptureContext; + ignoreErrors?: Array; /** - * A stack parser implementation or an array of stack line parsers - * By default, a stack parser is supplied for all supported browsers + * A URL to an envelope tunnel endpoint. An envelope tunnel is an HTTP endpoint + * that accepts Sentry envelopes for forwarding. This can be used to force data + * through a custom server independent of the type of data. */ - stackParser?: StackParser | StackLineParser[]; + tunnel?: string; /** * Set of metadata about the SDK that can be internally used to enhance envelopes and events, @@ -210,3 +200,31 @@ export interface Options { */ beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | null; } + +/** Base configuration options for every SDK. */ +export interface Options extends Omit, 'integrations' | 'transport' | 'stackParser'> { + /** + * If this is set to false, default integrations will not be added, otherwise this will internally be set to the + * recommended default integrations. + * TODO: We should consider changing this to `boolean | Integration[]` + */ + defaultIntegrations?: false | Integration[]; + + /** + * List of integrations that should be installed after SDK was initialized. + * Accepts either a list of integrations or a function that receives + * default integrations and returns a new, updated list. + */ + integrations?: Integration[] | ((integrations: Integration[]) => Integration[]); + + /** + * Transport object that should be used to send events to Sentry + */ + transport?: TransportClass; + + /** + * A stack parser implementation or an array of stack line parsers + * By default, a stack parser is supplied for all supported browsers + */ + stackParser?: StackParser | StackLineParser[]; +} diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 5c500c5ec654..56b864e2863b 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -98,8 +98,6 @@ function validateDsn(dsn: DsnComponents): boolean | void { /** The Sentry Dsn, identifying a Sentry instance and project. */ export function makeDsn(from: DsnLike): DsnComponents { const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from); - validateDsn(components); - return components; } From ff810cb496bde5c076ab99b5b96e8204509a43a7 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Tue, 19 Apr 2022 18:27:26 -0700 Subject: [PATCH 61/94] fix(dev): Check out correct commit in manual GHA `Build & Test` workflow (#4954) Our `Build & Test` GHA workflow can be triggered manually, and when you trigger it, you can either pick the branch to run it on or give it a specific commit to test. The former works fine, but the latter does not - though it picks up the given commit and correctly puts it in the env, it doesn't actually use that value when checking out the commit, instead always relying on the default value. This fixes that by always specifying what value to use. --- .github/workflows/build.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28895bde0cb1..0ff66932e93b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,6 +41,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 # we use a hash of yarn.lock as our cache key, because if it hasn't changed, our dependencies haven't changed, @@ -68,6 +70,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 - name: Check dependency cache @@ -109,6 +113,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: @@ -139,6 +145,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 - name: Check dependency cache @@ -162,6 +170,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 - name: Check dependency cache @@ -186,6 +196,8 @@ jobs: steps: - name: Check out current commit (${{ github.sha }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 - name: Check dependency cache @@ -223,6 +235,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: @@ -256,6 +270,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: @@ -288,11 +304,12 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} # TODO: removing `fetch-depth` below seems to have no effect, and the commit which added it had no description, # so it's not clear why it's necessary. That said, right now ember tests are xfail, so it's a little hard to # tell if it's safe to remove. Once ember tests are fixed, let's try again with it turned off, and if all goes # well, we can pull it out. - with: fetch-depth: 0 - name: Set up Node uses: actions/setup-node@v1 @@ -343,6 +360,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: @@ -381,6 +400,8 @@ jobs: steps: - name: Check out current commit (${{ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 - name: Check dependency cache @@ -410,6 +431,8 @@ jobs: steps: - name: Check out current commit (${ env.HEAD_COMMIT }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: @@ -445,6 +468,8 @@ jobs: steps: - name: Check out current commit (${{ github.sha }}) uses: actions/checkout@v2 + with: + ref: ${{ env.HEAD_COMMIT }} - name: Set up Node uses: actions/setup-node@v1 with: From 5d74974f4136e9a18e0414261198bff70ebb33d6 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 20 Apr 2022 11:33:57 +0200 Subject: [PATCH 62/94] ref(baseclient): Simplify the setup logic of integrations (#4952) --- packages/core/src/baseclient.ts | 10 +++++--- packages/core/src/integration.ts | 39 +++++++++++++------------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 3d82d829cead..314d3d6216a0 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -75,9 +75,12 @@ export abstract class BaseClient implements Client { /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */ protected readonly _dsn?: DsnComponents; - /** Array of used integrations. */ + /** Array of set up integrations. */ protected _integrations: IntegrationIndex = {}; + /** Indicates whether this client's integrations have been set up. */ + protected _integrationsInitialized: boolean = false; + /** Number of calls being processed */ protected _numProcessing: number = 0; @@ -251,8 +254,9 @@ export abstract class BaseClient implements Client { * Sets up the integrations */ public setupIntegrations(): void { - if (this._isEnabled() && !this._integrations.initialized) { - this._integrations = setupIntegrations(this._options); + if (this._isEnabled() && !this._integrationsInitialized) { + this._integrations = setupIntegrations(this._options.integrations); + this._integrationsInitialized = true; } } diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index b4f35e7d5b1e..e45f4a7c09d7 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,6 +1,6 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/hub'; -import { ClientOptions, Integration, Options } from '@sentry/types'; -import { addNonEnumerableProperty, logger } from '@sentry/utils'; +import { Integration, Options } from '@sentry/types'; +import { logger } from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; @@ -9,7 +9,7 @@ export const installedIntegrations: string[] = []; /** Map of integrations assigned to a client */ export type IntegrationIndex = { [key: string]: Integration; -} & { initialized?: boolean }; +}; /** * @private @@ -54,31 +54,24 @@ export function getIntegrationsToSetup(options: Options): Integration[] { return integrations; } -/** Setup given integration */ -export function setupIntegration(integration: Integration): void { - if (installedIntegrations.indexOf(integration.name) !== -1) { - return; - } - integration.setupOnce(addGlobalEventProcessor, getCurrentHub); - installedIntegrations.push(integration.name); - IS_DEBUG_BUILD && logger.log(`Integration installed: ${integration.name}`); -} - /** * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default * integrations are added unless they were already provided before. * @param integrations array of integration instances * @param withDefault should enable default integrations */ -export function setupIntegrations(options: O): IntegrationIndex { - const integrations: IntegrationIndex = {}; - options.integrations.forEach(integration => { - integrations[integration.name] = integration; - setupIntegration(integration); +export function setupIntegrations(integrations: Integration[]): IntegrationIndex { + const integrationIndex: IntegrationIndex = {}; + + integrations.forEach(integration => { + integrationIndex[integration.name] = integration; + + if (installedIntegrations.indexOf(integration.name) === -1) { + integration.setupOnce(addGlobalEventProcessor, getCurrentHub); + installedIntegrations.push(integration.name); + IS_DEBUG_BUILD && logger.log(`Integration installed: ${integration.name}`); + } }); - // set the `initialized` flag so we don't run through the process again unecessarily; use `Object.defineProperty` - // because by default it creates a property which is nonenumerable, which we want since `initialized` shouldn't be - // considered a member of the index the way the actual integrations are - addNonEnumerableProperty(integrations, 'initialized', true); - return integrations; + + return integrationIndex; } From 6d7326ce5affb9faeae9d183e02bbaaa98c36f60 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 21 Apr 2022 11:28:42 +0200 Subject: [PATCH 63/94] build(bundles): Rename CDN bundles to be es6 per default (#4958) --- .size-limit.js | 12 ++++++------ packages/browser/rollup.bundle.config.js | 2 +- .../integration-tests/utils/generatePlugin.ts | 16 ++++++++-------- packages/integrations/rollup.bundle.config.js | 2 +- packages/tracing/rollup.bundle.config.js | 2 +- packages/vue/rollup.bundle.config.js | 2 +- packages/wasm/rollup.bundle.config.js | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index 8c51fdb70b84..a8df3eb88e83 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -1,25 +1,25 @@ module.exports = [ { name: '@sentry/browser - ES5 CDN Bundle (gzipped + minified)', - path: 'packages/browser/build/bundles/bundle.min.js', + path: 'packages/browser/build/bundles/bundle.es5.min.js', gzip: true, limit: '100 KB', }, { name: '@sentry/browser - ES5 CDN Bundle (minified)', - path: 'packages/browser/build/bundles/bundle.min.js', + path: 'packages/browser/build/bundles/bundle.es5.min.js', gzip: false, limit: '120 KB', }, { name: '@sentry/browser - ES6 CDN Bundle (gzipped + minified)', - path: 'packages/browser/build/bundles/bundle.es6.min.js', + path: 'packages/browser/build/bundles/bundle.min.js', gzip: true, limit: '100 KB', }, { name: '@sentry/browser - ES6 CDN Bundle (minified)', - path: 'packages/browser/build/bundles/bundle.es6.min.js', + path: 'packages/browser/build/bundles/bundle.min.js', gzip: false, limit: '120 KB', }, @@ -53,13 +53,13 @@ module.exports = [ }, { name: '@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified)', - path: 'packages/tracing/build/bundles/bundle.tracing.min.js', + path: 'packages/tracing/build/bundles/bundle.tracing.es5.min.js', gzip: true, limit: '100 KB', }, { name: '@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified)', - path: 'packages/tracing/build/bundles/bundle.tracing.es6.min.js', + path: 'packages/tracing/build/bundles/bundle.tracing.min.js', gzip: true, limit: '100 KB', }, diff --git a/packages/browser/rollup.bundle.config.js b/packages/browser/rollup.bundle.config.js index aec9560621b1..04ce4b438bc3 100644 --- a/packages/browser/rollup.bundle.config.js +++ b/packages/browser/rollup.bundle.config.js @@ -8,7 +8,7 @@ const builds = []; isAddOn: false, jsVersion, licenseTitle: '@sentry/browser', - outputFileBase: `bundles/bundle${jsVersion === 'es6' ? '.es6' : ''}`, + outputFileBase: `bundles/bundle${jsVersion === 'es5' ? '.es5' : ''}`, }); builds.push(...makeBundleConfigVariants(baseBundleConfig)); diff --git a/packages/integration-tests/utils/generatePlugin.ts b/packages/integration-tests/utils/generatePlugin.ts index 1a7ebefad0b7..62a91b31dc9c 100644 --- a/packages/integration-tests/utils/generatePlugin.ts +++ b/packages/integration-tests/utils/generatePlugin.ts @@ -19,18 +19,18 @@ const BUNDLE_PATHS: Record> = { browser: { cjs: 'build/npm/cjs/index.js', esm: 'build/npm/esm/index.js', - bundle_es5: 'build/bundles/bundle.js', - bundle_es5_min: 'build/bundles/bundle.min.js', - bundle_es6: 'build/bundles/bundle.es6.js', - bundle_es6_min: 'build/bundles/bundle.es6.min.js', + bundle_es5: 'build/bundles/bundle.es5.js', + bundle_es5_min: 'build/bundles/bundle.es5.min.js', + bundle_es6: 'build/bundles/bundle.js', + bundle_es6_min: 'build/bundles/bundle.min.js', }, tracing: { cjs: 'build/npm/cjs/index.js', esm: 'build/npm/esm/index.js', - bundle_es5: 'build/bundles/bundle.tracing.js', - bundle_es5_min: 'build/bundles/bundle.tracing.min.js', - bundle_es6: 'build/bundles/bundle.tracing.es6.js', - bundle_es6_min: 'build/bundles/bundle.tracing.es6.min.js', + bundle_es5: 'build/bundles/bundle.tracing.es5.js', + bundle_es5_min: 'build/bundles/bundle.tracing.es5.min.js', + bundle_es6: 'build/bundles/bundle.tracing.js', + bundle_es6_min: 'build/bundles/bundle.tracing.min.js', }, }; diff --git a/packages/integrations/rollup.bundle.config.js b/packages/integrations/rollup.bundle.config.js index de984497b9a8..9549a07b8f94 100644 --- a/packages/integrations/rollup.bundle.config.js +++ b/packages/integrations/rollup.bundle.config.js @@ -12,7 +12,7 @@ const baseBundleConfig = makeBaseBundleConfig({ isAddOn: true, jsVersion, licenseTitle: '@sentry/integrations', - outputFileBase: `bundles/${file.replace('.ts', '')}${jsVersion === 'ES6' ? '.es6' : ''}`, + outputFileBase: `bundles/${file.replace('.ts', '')}${jsVersion === 'ES5' ? '.es5' : ''}`, }); // TODO We only need `commonjs` for localforage (used in the offline plugin). Once that's fixed, this can come out. diff --git a/packages/tracing/rollup.bundle.config.js b/packages/tracing/rollup.bundle.config.js index 66d79286f38c..091cb1f56958 100644 --- a/packages/tracing/rollup.bundle.config.js +++ b/packages/tracing/rollup.bundle.config.js @@ -8,7 +8,7 @@ const builds = []; isAddOn: false, jsVersion, licenseTitle: '@sentry/tracing & @sentry/browser', - outputFileBase: `bundles/bundle.tracing${jsVersion === 'es6' ? '.es6' : ''}`, + outputFileBase: `bundles/bundle.tracing${jsVersion === 'es5' ? '.es5' : ''}`, }); builds.push(...makeBundleConfigVariants(baseBundleConfig)); diff --git a/packages/vue/rollup.bundle.config.js b/packages/vue/rollup.bundle.config.js index 745205cda85f..41bf0e7f659d 100644 --- a/packages/vue/rollup.bundle.config.js +++ b/packages/vue/rollup.bundle.config.js @@ -3,7 +3,7 @@ import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/ind const baseBundleConfig = makeBaseBundleConfig({ input: 'src/index.bundle.ts', isAddOn: false, - jsVersion: 'es5', + jsVersion: 'es6', licenseTitle: '@sentry/vue', outputFileBase: 'bundle.vue', }); diff --git a/packages/wasm/rollup.bundle.config.js b/packages/wasm/rollup.bundle.config.js index 265b557c76a7..e928d466049d 100644 --- a/packages/wasm/rollup.bundle.config.js +++ b/packages/wasm/rollup.bundle.config.js @@ -3,7 +3,7 @@ import { makeBaseBundleConfig, makeBundleConfigVariants } from '../../rollup/ind const baseBundleConfig = makeBaseBundleConfig({ input: 'src/index.ts', isAddOn: true, - jsVersion: 'es5', + jsVersion: 'es6', licenseTitle: '@sentry/wasm', outputFileBase: 'bundles/wasm', }); From 45f432011125606a77f547c1d1c4ad74779c872b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 21 Apr 2022 16:43:20 +0200 Subject: [PATCH 64/94] fix(angular): Use Angular compiler to compile @sentry/angular (#4641) * switch from tsc to the Angular compiler to compile our Angular SDK. This is done via the Angular CLI which internally uses ngc and ng-packagr to build and package our SDK correctly so that the Angular runtime can process all SDK components (including TraceDirective) correctly. * important: This is a breaking change as it requires SDK users to use Angular >= 10. Currently, our SDK might support earlier Angular versions despite the fact that we only list Angular 10-13 as peer dependencies of the SDK. With this new compiler, applications using the Sentry Angular SDK on earlier versions than Angular 10 will not be able to compile correctly. * change some yarn scripts by making the Angular compiler the default builder --- packages/angular/angular.json | 27 + packages/angular/ng-package.json | 13 + packages/angular/package.json | 42 +- packages/angular/src/errorhandler.ts | 4 +- packages/angular/tsconfig.cjs.json | 8 - packages/angular/tsconfig.esm.json | 8 - packages/angular/tsconfig.ngc.json | 28 + packages/angular/tsconfig.types.json | 10 - yarn.lock | 3027 ++++++++++++++++++++++++-- 9 files changed, 2891 insertions(+), 276 deletions(-) create mode 100644 packages/angular/angular.json create mode 100644 packages/angular/ng-package.json delete mode 100644 packages/angular/tsconfig.cjs.json delete mode 100644 packages/angular/tsconfig.esm.json create mode 100644 packages/angular/tsconfig.ngc.json delete mode 100644 packages/angular/tsconfig.types.json diff --git a/packages/angular/angular.json b/packages/angular/angular.json new file mode 100644 index 000000000000..f771c0e78df0 --- /dev/null +++ b/packages/angular/angular.json @@ -0,0 +1,27 @@ +/* To learn more about this file see: https://angular.io/guide/workspace-config */ +{ + "$schema": "../../node_modules/@angular/cli/lib/config/schema.json", + "version": 1, // version of angular.json + "projects": { + "sentry-angular": { + "projectType": "library", + "root": ".", + "sourceRoot": "src", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:ng-packagr", + "options": { + "tsConfig": "tsconfig.ngc.json", + "project": "ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "tsconfig.ngc.json" + } + } + } + } + } + }, + "defaultProject": "sentry-angular" +} diff --git a/packages/angular/ng-package.json b/packages/angular/ng-package.json new file mode 100644 index 000000000000..88df70c1c7bd --- /dev/null +++ b/packages/angular/ng-package.json @@ -0,0 +1,13 @@ +{ + "$schema": "node_modules/ng-packagr/ng-package.schema.json", + "dest": "build", + "lib": { + "entryFile": "src/index.ts", + "umdModuleIds": { + "@sentry/browser": "Sentry", + "@sentry/utils": "Sentry.util" + } + }, + "whitelistedNonPeerDependencies": ["@sentry/browser", "@sentry/utils", "@sentry/types", "tslib"], + "assets": ["README.md", "LICENSE"] +} diff --git a/packages/angular/package.json b/packages/angular/package.json index 971bd6a1bfb4..2b1c8f69fd55 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -9,45 +9,43 @@ "engines": { "node": ">=8" }, - "main": "cjs/index.js", - "module": "esm/index.js", - "types": "build/types/index.d.ts", + "main": "build/bundles/sentry-angular.umd.js", + "module": "build/fesm2015/sentry-angular.js", "publishConfig": { "access": "public" }, "peerDependencies": { "@angular/common": "10.x || 11.x || 12.x || 13.x", "@angular/core": "10.x || 11.x || 12.x || 13.x", - "@angular/router": "10.x || 11.x || 12.x || 13.x" + "@angular/router": "10.x || 11.x || 12.x || 13.x", + "rxjs": "^6.5.5 || ^7.x" }, "dependencies": { "@sentry/browser": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", "@sentry/utils": "7.0.0-alpha.1", - "rxjs": "^6.6.0", - "tslib": "^1.9.3" + "tslib": "^2.0.0" }, "devDependencies": { - "@angular/common": "^10.0.3", - "@angular/core": "^10.0.3", - "@angular/router": "^10.0.3" + "@angular-devkit/build-angular": "~0.1002.4", + "@angular/cli": "^10.2.4", + "@angular/common": "~10.2.5", + "@angular/compiler": "^10.2.5", + "@angular/compiler-cli": "~10.2.5", + "@angular/core": "~10.2.5", + "@angular/router": "~10.2.5", + "ng-packagr": "^10.1.0", + "typescript": "~4.0.2" }, "scripts": { - "build": "run-p build:cjs build:esm build:types", - "build:cjs": "tsc -p tsconfig.cjs.json", + "build": "yarn build:ngc", + "build:ngc": "ng build --prod", "build:dev": "run-s build", - "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", - "build:esm": "tsc -p tsconfig.esm.json", - "build:types": "tsc -p tsconfig.types.json", - "build:watch": "run-p build:cjs:watch build:esm:watch build:types:watch", - "build:cjs:watch": "tsc -p tsconfig.cjs.json --watch", - "build:dev:watch": "run-s build:watch", - "build:es5:watch": "yarn build:cjs:watch # *** backwards compatibility - remove in v7 ***", - "build:esm:watch": "tsc -p tsconfig.esm.json --watch", - "build:types:watch": "tsc -p tsconfig.types.json --watch", - "build:npm": "npm pack", + "build:watch": "run-p build:ngc:watch", + "build:ngc:watch": "ng build --prod --watch", + "build:npm": "npm pack ./build", "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf cjs esm build coverage", + "clean": "rimraf build coverage", "fix": "run-s fix:eslint fix:prettier", "fix:eslint": "eslint . --format stylish --fix", "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 4e9c0f7ed037..54449071ee89 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -1,5 +1,5 @@ import { HttpErrorResponse } from '@angular/common/http'; -import { ErrorHandler as AngularErrorHandler, Injectable } from '@angular/core'; +import { ErrorHandler as AngularErrorHandler, Inject, Injectable } from '@angular/core'; import * as Sentry from '@sentry/browser'; import { runOutsideAngular } from './zone'; @@ -26,7 +26,7 @@ export interface ErrorHandlerOptions { class SentryErrorHandler implements AngularErrorHandler { protected readonly _options: ErrorHandlerOptions; - public constructor(options?: ErrorHandlerOptions) { + public constructor(@Inject('errorHandlerOptions') options?: ErrorHandlerOptions) { this._options = { logErrors: true, ...options, diff --git a/packages/angular/tsconfig.cjs.json b/packages/angular/tsconfig.cjs.json deleted file mode 100644 index 4ec31d2ff68b..000000000000 --- a/packages/angular/tsconfig.cjs.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "module": "commonjs", - "outDir": "cjs" - } -} diff --git a/packages/angular/tsconfig.esm.json b/packages/angular/tsconfig.esm.json deleted file mode 100644 index b6ee3fa615c0..000000000000 --- a/packages/angular/tsconfig.esm.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "module": "es6", - "outDir": "esm" - } -} diff --git a/packages/angular/tsconfig.ngc.json b/packages/angular/tsconfig.ngc.json new file mode 100644 index 000000000000..9dd04ce14239 --- /dev/null +++ b/packages/angular/tsconfig.ngc.json @@ -0,0 +1,28 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +// This tsconfig is used when building @sentry/angular with the Angular +// compiler and `ng-packagr`. It configures a production build conforming +// to the Angular Package Format (APF). +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "es2015", + "lib": ["dom", "es2015"], + "baseUrl": "./" + }, + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "enableResourceInlining": true, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true, + // As per Angular 10, the recommendation from the library creation guide + // is to disable compilation for the Ivy rendering engine in production builds + // to ensure compatibility with Angular 10. + // For Angular 11-13 applications, ngcc and the Angular linker convert the compiled JS + // at application compile time into an Ivy-compatible version which is then further used in + // the build process. This ensures compatibility with newer Angular versions than the one + // that was used to initially compile the library (Angular 10 in our case). + "enableIvy": false + } +} diff --git a/packages/angular/tsconfig.types.json b/packages/angular/tsconfig.types.json deleted file mode 100644 index 65455f66bd75..000000000000 --- a/packages/angular/tsconfig.types.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "outDir": "build/types" - } -} diff --git a/yarn.lock b/yarn.lock index 69010b40b996..ca4e027ca772 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,24 +9,195 @@ dependencies: "@jridgewell/trace-mapping" "^0.3.0" -"@angular/common@^10.0.3": +"@angular-devkit/architect@0.1002.4": + version "0.1002.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1002.4.tgz#2e1fa9c7a4718a4d0d101516ab0cc9cb653c5c57" + integrity sha512-Vrb2XSnvqj4RByqSWPeG/o9BSNX2DL3pxwQgLMrxofG8/+1VHQ2MsN/KTxBnEZtqeW4/l2QWTsQyzY5frJI69A== + dependencies: + "@angular-devkit/core" "10.2.4" + rxjs "6.6.2" + +"@angular-devkit/build-angular@~0.1002.4": + version "0.1002.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.1002.4.tgz#6525c8ac8ec88d79aa34fdb4f224a914f9ea520f" + integrity sha512-0jo8fCbOyo1HGRDKBVzIzmGd3/Z+x5YP/9t1QHQrPTq9gRoVI+1vFgrKh7XApmGPa/S4bN6hows1wnGzTq5xJg== + dependencies: + "@angular-devkit/architect" "0.1002.4" + "@angular-devkit/build-optimizer" "0.1002.4" + "@angular-devkit/build-webpack" "0.1002.4" + "@angular-devkit/core" "10.2.4" + "@babel/core" "7.11.1" + "@babel/generator" "7.11.0" + "@babel/plugin-transform-runtime" "7.11.0" + "@babel/preset-env" "7.11.0" + "@babel/runtime" "7.11.2" + "@babel/template" "7.10.4" + "@jsdevtools/coverage-istanbul-loader" "3.0.5" + "@ngtools/webpack" "10.2.4" + autoprefixer "9.8.6" + babel-loader "8.1.0" + browserslist "^4.9.1" + cacache "15.0.5" + caniuse-lite "^1.0.30001032" + circular-dependency-plugin "5.2.0" + copy-webpack-plugin "6.0.3" + core-js "3.6.4" + css-loader "4.2.2" + cssnano "4.1.10" + file-loader "6.0.0" + find-cache-dir "3.3.1" + glob "7.1.6" + jest-worker "26.3.0" + karma-source-map-support "1.4.0" + less-loader "6.2.0" + license-webpack-plugin "2.3.0" + loader-utils "2.0.0" + mini-css-extract-plugin "0.10.0" + minimatch "3.0.4" + open "7.2.0" + parse5 "6.0.1" + parse5-htmlparser2-tree-adapter "6.0.1" + pnp-webpack-plugin "1.6.4" + postcss "7.0.32" + postcss-import "12.0.1" + postcss-loader "3.0.0" + raw-loader "4.0.1" + regenerator-runtime "0.13.7" + resolve-url-loader "3.1.2" + rimraf "3.0.2" + rollup "2.26.5" + rxjs "6.6.2" + sass "1.26.10" + sass-loader "10.0.1" + semver "7.3.2" + source-map "0.7.3" + source-map-loader "1.0.2" + source-map-support "0.5.19" + speed-measure-webpack-plugin "1.3.3" + style-loader "1.2.1" + stylus "0.54.8" + stylus-loader "3.0.2" + terser "5.3.0" + terser-webpack-plugin "4.1.0" + tree-kill "1.2.2" + webpack "4.44.1" + webpack-dev-middleware "3.7.2" + webpack-dev-server "3.11.0" + webpack-merge "4.2.2" + webpack-sources "1.4.3" + webpack-subresource-integrity "1.4.1" + worker-plugin "5.0.0" + +"@angular-devkit/build-optimizer@0.1002.4": + version "0.1002.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1002.4.tgz#ddaa74e7e79cdc915631ec212780d6b7e2650c4a" + integrity sha512-O705v4N+VCaeTnePYVHf+XZaPxU8eTWCx2mYvCmG0urHh1GCehb+vX1v332tTaC2uzMoH+RSg2Nh2apFX+pE0Q== + dependencies: + loader-utils "2.0.0" + source-map "0.7.3" + tslib "2.0.1" + typescript "4.0.2" + webpack-sources "1.4.3" + +"@angular-devkit/build-webpack@0.1002.4": + version "0.1002.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1002.4.tgz#ed3a88a5c0af8a96ac0a14fa59ce66d4b7b850ac" + integrity sha512-5K+hPWmWV1q0HKcvJrTjJ5ABKEQintJlMMaewfmDUDOfslpabtXtY3LF+18a2RBdktAtLpIxoVTX1j/dvotu+w== + dependencies: + "@angular-devkit/architect" "0.1002.4" + "@angular-devkit/core" "10.2.4" + rxjs "6.6.2" + +"@angular-devkit/core@10.2.4": version "10.2.4" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.4.tgz#fb1772ea5780c96e00411900c54457f0cbcf401b" - integrity sha512-bBfsLJNDQaC2OI1mReDJuSZ/uBb7Pf3HVpRmlQKNIPllIxqX1hLH8I3Plodrns9m32JMJ6FMsQthcP0KMdRCJA== + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-10.2.4.tgz#b1f6b580406e4a497eeba54cf34013b88e36cb47" + integrity sha512-gnm/+Iyaa6Jt3E803bpTjkwDAIb0AhP9badaGwbx44+bhbNSE2WzOBmdsQrsxJXHAMEG9CGeBzeRd8XZtLACWg== dependencies: - tslib "^2.0.0" + ajv "6.12.4" + fast-json-stable-stringify "2.1.0" + magic-string "0.25.7" + rxjs "6.6.2" + source-map "0.7.3" -"@angular/core@^10.0.3": +"@angular-devkit/schematics@10.2.4": version "10.2.4" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.2.4.tgz#1124061f8232d79fcff7508c9243ec5ec3fc00f3" - integrity sha512-5xpAvmZwD9nZ8eWx10urjibqEeePGEiFXVMEn3IaJWgfdOcMmeSoioW9JUllT3w85+DlNVWbRbhz0YfE9a4jyw== + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-10.2.4.tgz#6f8bc7c0a5c4ac101460a0f709df33782782e6ad" + integrity sha512-poBGWRwMgnnnmoZfwyOBcQMJm7U5y5XxnxvMsBJEyAQRxfQa+KLvcCfGWXqskNTyBdQFpy4kxmtCzRClkoEiKQ== dependencies: - tslib "^2.0.0" + "@angular-devkit/core" "10.2.4" + ora "5.0.0" + rxjs "6.6.2" -"@angular/router@^10.0.3": +"@angular/cli@^10.2.4": version "10.2.4" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.2.4.tgz#0c6a680d8cbf8f5ce8b904636c8ee0e75765124d" - integrity sha512-y3xMwZHWS84fbm3FoU8vTAeXaTuPd4ZfmZ3dhkG9c1tkVq/jCmc6pkqNxjv3L1iPenKrvt2bFhh+wCs+bcUPhw== + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-10.2.4.tgz#f8899eee8f774cd805b1831a8f2f865024e9f4e1" + integrity sha512-S8xAJemX3zE/I/xi81DT6NuzfDwEAEtEeITHxrAH0AHE4kaUBy2O9bAopvYqMNzxs/XGqyxMv8vwYYpGax7EEQ== + dependencies: + "@angular-devkit/architect" "0.1002.4" + "@angular-devkit/core" "10.2.4" + "@angular-devkit/schematics" "10.2.4" + "@schematics/angular" "10.2.4" + "@schematics/update" "0.1002.4" + "@yarnpkg/lockfile" "1.1.0" + ansi-colors "4.1.1" + debug "4.1.1" + ini "1.3.6" + inquirer "7.3.3" + npm-package-arg "8.0.1" + npm-pick-manifest "6.1.0" + open "7.2.0" + pacote "9.5.12" + read-package-tree "5.3.1" + rimraf "3.0.2" + semver "7.3.2" + symbol-observable "1.2.0" + universal-analytics "0.4.23" + uuid "8.3.0" + +"@angular/common@~10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.2.5.tgz#5313f530446998e2f7af2dc43611addcfa6fd1c1" + integrity sha512-553yf6ZUHNqT4XpOqbW7EKKMfX56u/8DkwYXuSv8MAKdl4/AW6gliFOEJGYo04JcKF7Knq3VPvGSCO9kupf0hg== + dependencies: + tslib "^2.0.0" + +"@angular/compiler-cli@~10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.2.5.tgz#adb65bb9ecea14762a501226fde7760b73c3ab1e" + integrity sha512-xddSpKudoPidEebIW3x1CvQdx69WEmnFg4DneeQi/tit7mtAKYTJemzYZmP6abdSYhtxovL0bPX5LxYlrtuxIw== + dependencies: + canonical-path "1.0.0" + chokidar "^3.0.0" + convert-source-map "^1.5.1" + dependency-graph "^0.7.2" + fs-extra "4.0.2" + magic-string "^0.25.0" + minimist "^1.2.0" + reflect-metadata "^0.1.2" + semver "^6.3.0" + source-map "^0.6.1" + sourcemap-codec "^1.4.8" + tslib "^2.0.0" + yargs "^16.1.1" + +"@angular/compiler@^10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.2.5.tgz#1ff8514fdd2c07ff3c265b960dc49af6376071c9" + integrity sha512-ddJiTPCoVBIGjFDYoYWDpmq3Zs8UKoWpzaeW4u+p17gWW54HwyT5XTxrgtbeUmaxIuRdL4/KT1lGHs9/9bwbCA== + dependencies: + tslib "^2.0.0" + +"@angular/core@~10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.2.5.tgz#2050b0dbb180aa98c2ec46bba6d4827565ba2a2d" + integrity sha512-krhOKNTj5XE92Rk9ASX5KmgTF72j7qT2PLVxrGEVjuUKjBY2XaK3TV0Kotq9zI3qa9WgeCrP/Njn6jlKQCCAEQ== + dependencies: + tslib "^2.0.0" + +"@angular/router@~10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.2.5.tgz#acc75a29ab0b54c8ebad7d2a896986a59d7d99ec" + integrity sha512-AtSMB/d4V+pw/FL4G/mWWoiJJtZ/075TqsGW7uEFKgxS6Gh2kalv6BTMlXVG5GO+2oU0lsuDvguq5E7Atbak3Q== dependencies: tslib "^2.0.0" @@ -58,6 +229,11 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/compat-data@^7.11.0", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" + integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== + "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.15.0": version "7.15.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" @@ -68,10 +244,27 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa" integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew== -"@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== +"@babel/core@7.11.1": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" + integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.1" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.0" + "@babel/types" "^7.11.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.12.0", "@babel/core@^7.3.4": version "7.13.14" @@ -94,7 +287,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": +"@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== @@ -157,6 +350,24 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/generator@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" + integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== + dependencies: + "@babel/types" "^7.11.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/generator@^7.11.0", "@babel/generator@^7.17.9", "@babel/generator@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" + integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/generator@^7.13.9", "@babel/generator@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" @@ -184,15 +395,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.17.9", "@babel/generator@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" - integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" @@ -222,6 +424,24 @@ "@babel/helper-explode-assignable-expression" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" + integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + "@babel/helper-compilation-targets@^7.12.0", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.13.8", "@babel/helper-compilation-targets@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" @@ -242,16 +462,6 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.5.5": version "7.13.11" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" @@ -275,6 +485,19 @@ "@babel/helper-replace-supers" "^7.16.0" "@babel/helper-split-export-declaration" "^7.16.0" +"@babel/helper-create-class-features-plugin@^7.16.10": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d" + integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-member-expression-to-functions" "^7.17.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-create-class-features-plugin@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz#9c5b34b53a01f2097daf10678d65135c1b9f84ba" @@ -296,6 +519,14 @@ "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + "@babel/helper-define-polyfill-provider@^0.1.5": version "0.1.5" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" @@ -324,6 +555,13 @@ dependencies: "@babel/types" "^7.13.0" +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" @@ -422,6 +660,20 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-member-expression-to-functions@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" + integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.15.4", "@babel/helper-module-imports@^7.8.3": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" @@ -436,12 +688,19 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== +"@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" + integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== dependencies: - "@babel/types" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.15.4": version "7.15.4" @@ -471,20 +730,6 @@ "@babel/traverse" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - "@babel/helper-optimise-call-expression@^7.12.13", "@babel/helper-optimise-call-expression@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" @@ -525,6 +770,15 @@ "@babel/helper-wrap-function" "^7.13.0" "@babel/types" "^7.13.0" +"@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + "@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" @@ -647,6 +901,25 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== + dependencies: + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helpers@^7.10.4", "@babel/helpers@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" + integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.9" + "@babel/types" "^7.17.0" + "@babel/helpers@^7.13.10", "@babel/helpers@^7.16.0": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.3.tgz#27fc64f40b996e7074dc73128c3e5c3e7f55c43c" @@ -665,15 +938,6 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - "@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" @@ -706,7 +970,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746" integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ== -"@babel/parser@^7.14.7", "@babel/parser@^7.17.9": +"@babel/parser@^7.10.4", "@babel/parser@^7.11.1", "@babel/parser@^7.14.7", "@babel/parser@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== @@ -735,6 +999,15 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-proposal-optional-chaining" "^7.13.12" +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-proposal-async-generator-functions@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1" @@ -752,6 +1025,14 @@ "@babel/helper-create-class-features-plugin" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-proposal-class-properties@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-proposal-class-properties@^7.14.5": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" @@ -769,6 +1050,14 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-decorators" "^7.12.13" +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-dynamic-import@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" @@ -785,6 +1074,14 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" +"@babel/plugin-proposal-export-namespace-from@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-proposal-export-namespace-from@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" @@ -801,6 +1098,14 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-proposal-json-strings@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" @@ -809,6 +1114,14 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-json-strings" "^7.8.3" +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" @@ -825,6 +1138,14 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" @@ -841,6 +1162,14 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" @@ -857,6 +1186,17 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-proposal-object-rest-spread@^7.11.0": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" + integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== + dependencies: + "@babel/compat-data" "^7.17.0" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" @@ -868,6 +1208,14 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.13.0" +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-catch-binding@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" @@ -876,6 +1224,15 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-proposal-optional-chaining@^7.11.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-proposal-optional-chaining@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" @@ -894,6 +1251,14 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" +"@babel/plugin-proposal-private-methods@^7.10.4": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-proposal-private-methods@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" @@ -920,6 +1285,14 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" +"@babel/plugin-proposal-unicode-property-regex@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" @@ -928,7 +1301,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-async-generators@^7.8.4": +"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -942,7 +1315,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.10.4", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -956,7 +1329,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.8.3": +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -977,7 +1350,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.8.3": +"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -991,7 +1364,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -1005,21 +1378,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": +"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.3": +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== @@ -1033,6 +1406,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-top-level-await@^7.10.4", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-top-level-await@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" @@ -1040,13 +1420,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript@^7.12.13", "@babel/plugin-syntax-typescript@^7.2.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" @@ -1068,6 +1441,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-arrow-functions@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" @@ -1075,6 +1455,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-transform-async-to-generator@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" @@ -1084,6 +1473,13 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-remap-async-to-generator" "^7.13.0" +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-block-scoped-functions@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" @@ -1091,6 +1487,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-block-scoping@^7.12.13", "@babel/plugin-transform-block-scoping@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" @@ -1098,6 +1501,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-classes@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" + "@babel/plugin-transform-classes@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" @@ -1111,6 +1528,13 @@ "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-computed-properties@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" @@ -1118,6 +1542,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" + integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-destructuring@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963" @@ -1125,6 +1556,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-dotall-regex@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" @@ -1133,6 +1572,13 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-duplicate-keys@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" @@ -1140,6 +1586,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" @@ -1148,6 +1602,13 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-for-of@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-for-of@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" @@ -1155,6 +1616,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-function-name@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== + dependencies: + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-function-name@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" @@ -1163,6 +1633,13 @@ "@babel/helper-function-name" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-literals@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-literals@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" @@ -1170,6 +1647,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-member-expression-literals@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" @@ -1177,6 +1661,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-modules-amd@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + "@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3" @@ -1186,6 +1679,16 @@ "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.10.4": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" + integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== + dependencies: + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + babel-plugin-dynamic-import-node "^2.3.3" + "@babel/plugin-transform-modules-commonjs@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" @@ -1206,6 +1709,17 @@ "@babel/helper-simple-access" "^7.16.0" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz#81fd834024fae14ea78fbe34168b042f38703859" + integrity sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw== + dependencies: + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + "@babel/plugin-transform-modules-systemjs@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" @@ -1217,6 +1731,14 @@ "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-modules-umd@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b" @@ -1225,6 +1747,13 @@ "@babel/helper-module-transforms" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" + integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" @@ -1232,6 +1761,13 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.12.13" +"@babel/plugin-transform-new-target@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-new-target@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" @@ -1246,6 +1782,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-transform-object-super@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/plugin-transform-object-super@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" @@ -1254,6 +1798,13 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" +"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-parameters@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" @@ -1261,6 +1812,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-property-literals@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" @@ -1268,6 +1826,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" + integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ== + dependencies: + regenerator-transform "^0.15.0" + "@babel/plugin-transform-regenerator@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5" @@ -1275,6 +1840,13 @@ dependencies: regenerator-transform "^0.14.2" +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-reserved-words@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" @@ -1282,6 +1854,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-runtime@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" + integrity sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-runtime@^7.13.9": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz#a1e40d22e2bf570c591c9c7e5ab42d6bf1e419e1" @@ -1294,6 +1876,13 @@ babel-plugin-polyfill-regenerator "^0.1.2" semver "^6.3.0" +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-shorthand-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" @@ -1301,6 +1890,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-spread@^7.11.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-transform-spread@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" @@ -1309,6 +1906,13 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-sticky-regex@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" @@ -1316,6 +1920,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-template-literals@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" @@ -1323,6 +1934,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-typeof-symbol@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" @@ -1374,6 +1992,13 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.2.0" +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-unicode-escapes@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" @@ -1381,6 +2006,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-unicode-regex@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" @@ -1397,6 +2030,80 @@ core-js "^2.6.5" regenerator-runtime "^0.13.4" +"@babel/preset-env@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" + integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.11.0" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + "@babel/preset-env@^7.10.2", "@babel/preset-env@^7.12.0": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.12.tgz#6dff470478290582ac282fb77780eadf32480237" @@ -1472,6 +2179,17 @@ core-js-compat "^3.9.0" semver "^6.3.0" +"@babel/preset-modules@^0.1.3": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + "@babel/preset-modules@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" @@ -1501,6 +2219,13 @@ "@babel/helper-validator-option" "^7.16.7" "@babel/plugin-transform-typescript" "^7.16.7" +"@babel/runtime@7.11.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@7.12.18": version "7.12.18" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.18.tgz#af137bd7e7d9705a412b3caaf991fe6aaa97831b" @@ -1522,6 +2247,24 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/template@7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/template@^7.10.4", "@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/template@^7.12.13", "@babel/template@^7.15.4", "@babel/template@^7.4.0": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" @@ -1540,15 +2283,6 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/template@^7.16.7", "@babel/template@^7.3.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": version "7.13.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" @@ -1563,6 +2297,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.11.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" + integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.9" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.9" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" @@ -1609,22 +2359,6 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" - integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.9" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.9" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - "@babel/types@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -1643,6 +2377,14 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.17.0", "@babel/types@^7.3.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + "@babel/types@^7.15.4": version "7.15.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" @@ -1667,14 +2409,6 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@babel/types@^7.17.0", "@babel/types@^7.3.3": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1785,6 +2519,11 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@gar/promisify@^1.0.1": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@glimmer/component@~1.0.0": version "1.0.4" resolved "https://registry.yarnpkg.com/@glimmer/component/-/component-1.0.4.tgz#1c85a5181615a6647f6acfaaed68e28ad7e9626e" @@ -2388,6 +3127,17 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jsdevtools/coverage-istanbul-loader@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#2a4bc65d0271df8d4435982db4af35d81754ee26" + integrity sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA== + dependencies: + convert-source-map "^1.7.0" + istanbul-lib-instrument "^4.0.3" + loader-utils "^2.0.0" + merge-source-map "^1.1.0" + schema-utils "^2.7.0" + "@lerna/add@3.13.3": version "3.13.3" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.3.tgz#f4c1674839780e458f0426d4f7b6d0a77b9a2ae9" @@ -3049,6 +3799,15 @@ resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.1.3.tgz#65b3e1b9846c02452787fde1d54ad9c54b506dbd" integrity sha512-P4GJZuLKfD/o42JvGZ/xP4Hxg68vd3NeZxOLqIuQKFjjaYgC2IrO+lE5PTwGmRkytjfprJC+9j7Jss/xQAS6QA== +"@ngtools/webpack@10.2.4": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-10.2.4.tgz#6060970d1de053b5c33f5dd649ffb9f34e6b74a7" + integrity sha512-7rnGrd0TlnAHwOSwvKjKuD+/vwPEP2aVwD9ZnvWYafQFpLYQj+9TYOBj+nbg2l4PCRx5ByYy7xPKnu88GX5/lw== + dependencies: + "@angular-devkit/core" "10.2.4" + enhanced-resolve "4.3.0" + webpack-sources "1.4.3" + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -3075,6 +3834,22 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@octokit/auth-token@^2.4.0": version "2.4.5" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3" @@ -3345,6 +4120,19 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@rollup/plugin-commonjs@^15.0.0": + version "15.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-15.1.0.tgz#1e7d076c4f1b2abf7e65248570e555defc37c238" + integrity sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + "@rollup/plugin-commonjs@^21.0.1": version "21.0.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz#1e57c81ae1518e4df0954d681c642e7d94588fee" @@ -3358,6 +4146,13 @@ magic-string "^0.25.7" resolve "^1.17.0" +"@rollup/plugin-json@^4.0.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" + integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== + dependencies: + "@rollup/pluginutils" "^3.0.8" + "@rollup/plugin-node-resolve@^13.1.3": version "13.1.3" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz#2ed277fb3ad98745424c1d2ba152484508a92d79" @@ -3370,6 +4165,18 @@ is-module "^1.0.0" resolve "^1.19.0" +"@rollup/plugin-node-resolve@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" + integrity sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.17.0" + "@rollup/plugin-replace@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-3.0.1.tgz#f774550f482091719e52e9f14f67ffc0046a883d" @@ -3378,7 +4185,7 @@ "@rollup/pluginutils" "^3.1.0" magic-string "^0.25.7" -"@rollup/pluginutils@^3.1.0": +"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.0.9", "@rollup/pluginutils@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== @@ -3395,6 +4202,29 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@schematics/angular@10.2.4": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-10.2.4.tgz#3b99b9da572b57381d221e2008804e6bb9c98b82" + integrity sha512-irU3cnamfd5Hgy1B6oY7oweApJHhVaD2oYPq0NfI+F14JalERO+DGO0Tq3MWmEGn32tLQPv9fwM5O8EElEp9pA== + dependencies: + "@angular-devkit/core" "10.2.4" + "@angular-devkit/schematics" "10.2.4" + jsonc-parser "2.3.0" + +"@schematics/update@0.1002.4": + version "0.1002.4" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.1002.4.tgz#e8f5ff82d308f72fd521abd88316f7b0ccd296c1" + integrity sha512-qnDn3SSMmolfzWpj8CTAoC/TSPe43azKPYLR5r76GkRvuUbwr/dQEj92wu59twjGcsmjF54qcG4fGaxMndUn3Q== + dependencies: + "@angular-devkit/core" "10.2.4" + "@angular-devkit/schematics" "10.2.4" + "@yarnpkg/lockfile" "1.1.0" + ini "1.3.6" + npm-package-arg "^8.0.0" + pacote "9.5.12" + semver "7.3.2" + semver-intersect "1.4.0" + "@sentry/cli@^1.73.0": version "1.73.0" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.73.0.tgz#0d0bce913e0060ae192741c6693c57e50078c886" @@ -4341,6 +5171,15 @@ "@types/source-list-map" "*" source-map "^0.7.3" +"@types/webpack-sources@^0.1.5": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.9.tgz#da69b06eb34f6432e6658acb5a6893c55d983920" + integrity sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + "@types/webpack@^4.41.31": version "4.41.31" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.31.tgz#c35f252a3559ddf9c85c0d8b0b42019025e581aa" @@ -4758,6 +5597,11 @@ tslib "^2.3.1" upath2 "^3.1.12" +"@yarnpkg/lockfile@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + JSONStream@^1.0.4, JSONStream@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -4862,6 +5706,14 @@ acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz#5ae12fb5b7b1c585e80bbb5a63ec163a1a45e61e" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" @@ -4879,6 +5731,14 @@ agentkeepalive@^3.4.1: dependencies: humanize-ms "^1.2.1" +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -4889,6 +5749,16 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== +ajv@6.12.4: + version "6.12.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" + integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -4944,6 +5814,11 @@ ansi-colors@3.2.3: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== +ansi-colors@4.1.1, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" @@ -4951,10 +5826,10 @@ ansi-colors@^1.0.1: dependencies: ansi-wrap "^0.1.0" -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== ansi-escapes@^3.2.0: version "3.2.0" @@ -4968,7 +5843,7 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-html@^0.0.7: +ansi-html@0.0.7, ansi-html@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= @@ -5054,7 +5929,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1: +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -5112,6 +5987,11 @@ aria-query@^5.0.0: resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -5152,6 +6032,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + array-from@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" @@ -5352,6 +6237,11 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async-mutex@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.2.tgz#1485eda5bda1b0ec7c8df1ac2e815757ad1831df" @@ -5416,6 +6306,32 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +autoprefixer@9.8.6: + version "9.8.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" + integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + colorette "^1.2.1" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +autoprefixer@^9.6.5: + version "9.8.8" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" + integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + picocolors "^0.2.1" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" @@ -5640,6 +6556,17 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" +babel-loader@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + babel-loader@^8.0.6: version "8.2.2" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" @@ -6276,6 +7203,11 @@ basic-auth@~2.0.1: dependencies: safe-buffer "5.1.2" +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -6414,6 +7346,18 @@ body@^5.1.0: raw-body "~1.1.0" safe-json-parse "~1.0.1" +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -7124,6 +8068,17 @@ browserslist@^4.0.0, browserslist@^4.16.3, browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.75" +browserslist@^4.12.0, browserslist@^4.20.2, browserslist@^4.7.0, browserslist@^4.9.1: + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== + dependencies: + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" + escalade "^3.1.1" + node-releases "^2.0.2" + picocolors "^1.0.0" + browserslist@^4.14.5: version "4.18.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" @@ -7214,6 +8169,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + buffer-writer@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" @@ -7294,6 +8254,29 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacache@15.0.5: + version "15.0.5" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" + integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.0" + tar "^6.0.2" + unique-filename "^1.1.1" + cacache@^11.3.3: version "11.3.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" @@ -7335,6 +8318,30 @@ cacache@^12.0.0, cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" +cacache@^15.0.4, cacache@^15.0.5: + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -7441,6 +8448,11 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" +camelcase@5.3.1, camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -7451,12 +8463,7 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.1.0: +camelcase@^6.0.0, camelcase@^6.1.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -7488,6 +8495,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001173, can resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001257.tgz#150aaf649a48bee531104cfeda57f92ce587f6e5" integrity sha512-JN49KplOgHSXpIsVSF+LUyhD8PUp6xPpAXeRrrcBh4KBeP7W864jHn6RvzJgDlrReyeVjMFJL3PLpPvKIxlIHA== +caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001317: + version "1.0.30001332" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" + integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== + caniuse-lite@^1.0.30001274: version "1.0.30001279" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001279.tgz#eb06818da481ef5096a3b3760f43e5382ed6b0ce" @@ -7498,6 +8510,11 @@ caniuse-lite@^1.0.30001280: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001286.tgz#3e9debad420419618cfdf52dc9b6572b28a8fff6" integrity sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ== +canonical-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/canonical-path/-/canonical-path-1.0.0.tgz#fcb470c23958def85081856be7a86e904f180d1d" + integrity sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -7616,6 +8633,21 @@ chokidar@3.5.1, chokidar@^3.0.2, chokidar@^3.3.1, chokidar@^3.4.1, chokidar@^3.5 optionalDependencies: fsevents "~2.3.1" +"chokidar@>=2.0.0 <4.0.0", "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.2.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -7640,6 +8672,11 @@ chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -7675,6 +8712,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +circular-dependency-plugin@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz#e09dbc2dd3e2928442403e2d45b41cea06bc0a93" + integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw== + cjs-module-lexer@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" @@ -7724,7 +8766,7 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" -clean-stack@^2.2.0: +clean-stack@^2.0.0, clean-stack@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== @@ -7753,6 +8795,11 @@ cli-spinners@^2.0.0, cli-spinners@^2.5.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== +cli-spinners@^2.4.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + cli-table3@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -8007,7 +9054,7 @@ commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^6.2.0, commander@^6.2.1: +commander@^6.0.0, commander@^6.2.0, commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== @@ -8065,6 +9112,13 @@ component-inherit@0.0.3: resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + compressible@^2.0.12, compressible@~2.0.16: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -8130,6 +9184,11 @@ configstore@^5.0.0, configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + connect@^3.6.6, connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -8292,6 +9351,11 @@ convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1, dependencies: safe-buffer "~5.1.1" +convert-source-map@^0.3.3: + version "0.3.5" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" + integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= + convert-source-map@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" @@ -8317,6 +9381,13 @@ cookie@^0.4.1, cookie@~0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -8339,6 +9410,31 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-webpack-plugin@6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz#2b3d2bfc6861b96432a65f0149720adbd902040b" + integrity sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q+9yPRu7MtYFPt+GBOXRav9lvIINifTQ1vSCs+eA== + dependencies: + cacache "^15.0.4" + fast-glob "^3.2.4" + find-cache-dir "^3.3.1" + glob-parent "^5.1.1" + globby "^11.0.1" + loader-utils "^2.0.0" + normalize-path "^3.0.0" + p-limit "^3.0.1" + schema-utils "^2.7.0" + serialize-javascript "^4.0.0" + webpack-sources "^1.4.3" + +core-js-compat@^3.6.2: + version "3.22.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.1.tgz#47b9c5e79efbf13935f637449fa1cdec8cd9515f" + integrity sha512-CWbNqTluLMvZg1cjsQUbGiCM91dobSHKfDIyCoxuqxthdjGuUlaMbCsSehP3CBiVvG0C7P6UIrC1v0hgFE75jw== + dependencies: + browserslist "^4.20.2" + semver "7.0.0" + core-js-compat@^3.8.1, core-js-compat@^3.9.0: version "3.9.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.1.tgz#4e572acfe90aff69d76d8c37759d21a5c59bb455" @@ -8347,6 +9443,11 @@ core-js-compat@^3.8.1, core-js-compat@^3.9.0: browserslist "^4.16.3" semver "7.0.0" +core-js@3.6.4: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" + integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== + core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" @@ -8503,6 +9604,24 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-loader@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.2.2.tgz#b668b3488d566dc22ebcf9425c5f254a05808c89" + integrity sha512-omVGsTkZPVwVRpckeUnLshPp12KsmMSLqYxs12+RzM9jRR5Y+Idn/tBffjXRvOE+qW7if24cuceFJqYR5FmGBg== + dependencies: + camelcase "^6.0.0" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^2.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.3" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^7.3.2" + css-loader@^5.1.1: version "5.2.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.0.tgz#a9ecda190500863673ce4434033710404efbff00" @@ -8537,6 +9656,13 @@ css-loader@^5.2.0: schema-utils "^3.0.0" semver "^7.3.5" +css-parse@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" + integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q= + dependencies: + css "^2.0.0" + css-select-base-adapter@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" @@ -8594,6 +9720,16 @@ css.escape@1.5.1: resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= +css@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -8673,7 +9809,7 @@ cssnano-util-same-parent@^4.0.0: resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== -cssnano@^4.1.10: +cssnano@4.1.10, cssnano@^4.1.10: version "4.1.10" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== @@ -8717,6 +9853,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== +cuint@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" + integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -8742,6 +9883,14 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dag-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dag-map/-/dag-map-2.0.2.tgz#9714b472de82a1843de2fba9b6876938cab44c68" @@ -8845,7 +9994,14 @@ debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" -debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: +debug@4.1.1, debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -8866,13 +10022,6 @@ debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: dependencies: ms "2.1.2" -debug@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -8932,6 +10081,18 @@ deep-eql@^3.0.1: dependencies: type-detect "^4.0.0" +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -8947,6 +10108,14 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -8988,6 +10157,19 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -9013,6 +10195,11 @@ depd@~2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +dependency-graph@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.7.2.tgz#91db9de6eb72699209d88aea4c1fd5221cac1c49" + integrity sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ== + dependency-tree@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-8.1.0.tgz#1b896a0418bd7ba3e6d55c39bb664452a001579f" @@ -9069,6 +10256,11 @@ detect-newline@3.1.0, detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + detective-amd@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-3.1.0.tgz#92daee3214a0ca4522646cf333cac90a3fca6373" @@ -9218,6 +10410,26 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -9447,6 +10659,11 @@ electron-to-chromium@^1.3.896: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.14.tgz#b0aa41fbfbf2eff8c2c6f7a871c03075250f8956" integrity sha512-RsGkAN9JEAYMObS72kzUsPPcPGMqX1rBqGuXi9aa4TBKLzICoLf+DAAtd0fVFzrniJqYzpby47gthCUoObfs0Q== +electron-to-chromium@^1.4.84: + version "1.4.114" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.114.tgz#d85ec0808dd50b0cf6e6b262480ffd385f71c873" + integrity sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA== + elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -10265,7 +11482,16 @@ engine.io@~6.1.0: engine.io-parser "~5.0.3" ws "~8.2.3" -enhanced-resolve@^4.5.0: +enhanced-resolve@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126" + integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enhanced-resolve@^4.3.0, enhanced-resolve@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== @@ -10332,7 +11558,7 @@ errlop@^2.0.0: resolved "https://registry.yarnpkg.com/errlop/-/errlop-2.2.0.tgz#1ff383f8f917ae328bebb802d6ca69666a42d21b" integrity sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw== -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== @@ -10415,11 +11641,37 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.60" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.60.tgz#e8060a86472842b93019c31c34865012449883f4" + integrity sha512-jpKNXIt60htYG59/9FGf2PYT3pwMpnEbNKysU+k/4FGwyGtMotOvcZOuW+EmXXYASRqYSXQfGL5cVIthOTgbkg== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@2.0.3, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-object-assign@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -10786,6 +12038,13 @@ events@^3.0.0, events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" + integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== + dependencies: + original "^1.0.0" + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -10998,6 +12257,13 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -11096,7 +12362,18 @@ fast-glob@^3.0.3, fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-glob@^3.2.4: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -11139,6 +12416,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + faye-websocket@^0.11.3: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" @@ -11146,6 +12430,13 @@ faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" +faye-websocket@~0.11.1: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -11199,6 +12490,14 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-loader@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" + integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + file-loader@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" @@ -11319,6 +12618,11 @@ find-index@^1.1.0: resolved "https://registry.yarnpkg.com/find-index/-/find-index-1.1.1.tgz#4b221f8d46b7f8bea33d8faed953f3ca7a081cbc" integrity sha512-XYKutXMrIK99YMUPf91KX5QVJoG31/OsgftD6YoTPAObfQIxM4ziA9f0J1AsqKhJmo+IeaIPP0CFopTD4bdUBw== +find-parent-dir@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.1.tgz#c5c385b96858c3351f95d446cab866cbf9f11125" + integrity sha512-o4UcykWV/XN9wm+jMEtWLPlV8RXCZnMhQI6F6OdHeSez7iiJWePw8ijOlskJZMsaQoGR/b7dH6lO02HhaTN7+A== + find-pkg@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/find-pkg/-/find-pkg-0.1.2.tgz#1bdc22c06e36365532e2a248046854b9788da557" @@ -11610,6 +12914,15 @@ fs-exists-sync@^0.1.0: resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0= +fs-extra@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" + integrity sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^0.24.0: version "0.24.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" @@ -11674,7 +12987,7 @@ fs-extra@^8.0.0, fs-extra@^8.0.1, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.1, fs-extra@^9.1.0: +fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -11702,6 +13015,13 @@ fs-minipass@^1.2.7: dependencies: minipass "^2.6.0" +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6: version "0.5.9" resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz#a4ec6182c2f5bd80b9b83c8e23e4522e6f5fd946" @@ -11762,6 +13082,11 @@ fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -11772,6 +13097,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -11823,7 +13153,7 @@ genfun@^5.0.0: resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== -gensync@^1.0.0-beta.2: +gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -12069,7 +13399,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -12098,6 +13428,18 @@ glob@7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@7.2.0, glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -12207,6 +13549,17 @@ globby@^11.0.1, globby@^11.0.2: merge2 "^1.3.0" slash "^3.0.0" +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^8.0.1: version "8.0.2" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" @@ -12379,6 +13732,11 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + handlebars@^4.0.1, handlebars@^4.0.4, handlebars@^4.3.1, handlebars@^4.7.3, handlebars@^4.7.6: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -12693,6 +14051,13 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== +hosted-git-info@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" + integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== + dependencies: + lru-cache "^6.0.0" + hosted-git-info@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" @@ -12700,6 +14065,16 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + hsl-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" @@ -12729,6 +14104,11 @@ html-encoding-sniffer@^3.0.0: dependencies: whatwg-encoding "^2.0.0" +html-entities@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -12773,6 +14153,11 @@ http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -12847,7 +14232,17 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-proxy@^1.13.1, http-proxy@^1.18.1: +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.13.1, http-proxy@^1.17.0, http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== @@ -12937,6 +14332,13 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" @@ -12979,11 +14381,28 @@ ignore@^5.1.1, ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= +immutable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -13000,6 +14419,13 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -13008,6 +14434,14 @@ import-local@^1.0.0: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -13081,6 +14515,11 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +ini@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.6.tgz#f1c46a2a93a253e7b3905115e74d527cd23061a1" + integrity sha512-IZUoxEjNjubzrmvzZU4lKP7OnYmX72XRl3sqkfJhBKweKi5rnGi5+IUdlj/H1M+Ip5JQ1WzaDMOBRY90Ajc5jg== + ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -13100,6 +14539,13 @@ init-package-json@^1.10.3: validate-npm-package-license "^3.0.1" validate-npm-package-name "^3.0.0" +injection-js@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/injection-js/-/injection-js-2.4.0.tgz#ebe8871b1a349f23294eaa751bbd8209a636e754" + integrity sha512-6jiJt0tCAo9zjHbcwLiPL+IuNe9SQ6a9g0PEzafThW3fOQi0mrmiJGBJvDD6tmhPh8cQHIQtCOrJuBfQME4kPA== + dependencies: + tslib "^2.0.0" + inline-source-map-comment@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" @@ -13118,6 +14564,25 @@ inline-source-map@~0.6.0: dependencies: source-map "~0.5.3" +inquirer@7.3.3, inquirer@^7.0.1: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + inquirer@^6, inquirer@^6.2.0: version "6.5.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" @@ -13137,24 +14602,13 @@ inquirer@^6, inquirer@^6.2.0: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^7.0.1: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" internal-slot@^1.0.3: version "1.0.3" @@ -13190,12 +14644,17 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ip@1.1.5, ip@^1.1.5: +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ip@1.1.5, ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1: +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -13205,6 +14664,11 @@ is-absolute-url@^2.0.0: resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -13322,6 +14786,13 @@ is-core-module@^2.8.0: dependencies: has "^1.0.3" +is-core-module@^2.8.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -13502,6 +14973,25 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + is-plain-obj@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -13541,6 +15031,14 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" +is-regex@^1.0.4, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" @@ -13549,14 +15047,6 @@ is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.1" -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -13692,6 +15182,11 @@ is-weakref@^1.0.1: dependencies: call-bind "^1.0.0" +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + is-windows@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" @@ -13707,7 +15202,7 @@ is-wsl@^1.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= -is-wsl@^2.1.0, is-wsl@^2.2.0: +is-wsl@^2.1.0, is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -13792,6 +15287,16 @@ istanbul-lib-instrument@^3.3.0: istanbul-lib-coverage "^2.0.5" semver "^6.0.0" +istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" @@ -14427,6 +15932,15 @@ jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-worker@26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.3.0.tgz#7c8a97e4f4364b4f05ed8bca8ca0c24de091871f" + integrity sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + jest-worker@27.0.0-next.5: version "27.0.0-next.5" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" @@ -14444,7 +15958,7 @@ jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" -jest-worker@^26.2.1: +jest-worker@^26.2.1, jest-worker@^26.3.0: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -14689,6 +16203,11 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + json5@2.x, json5@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -14713,6 +16232,11 @@ json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +jsonc-parser@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.0.tgz#7c7fc988ee1486d35734faaaa866fadb00fa91ee" + integrity sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -14863,6 +16387,13 @@ karma-sinon@^1.0.5: resolved "https://registry.yarnpkg.com/karma-sinon/-/karma-sinon-1.0.5.tgz#4e3443f2830fdecff624d3747163f1217daa2a9a" integrity sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo= +karma-source-map-support@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" + integrity sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A== + dependencies: + source-map-support "^0.5.5" + karma-typescript-es6-transform@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/karma-typescript-es6-transform/-/karma-typescript-es6-transform-4.1.1.tgz#b24e8ea8cb8431c5342f7bbb9f1fd6060335ca39" @@ -14966,6 +16497,11 @@ keyv@3.0.0: dependencies: json-buffer "3.0.0" +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + kind-of@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" @@ -15002,6 +16538,11 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +klona@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + last-call-webpack-plugin@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" @@ -15059,11 +16600,44 @@ lerna@3.13.4: import-local "^1.0.0" npmlog "^4.1.2" +less-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-6.2.0.tgz#8b26f621c155b342eefc24f5bd6e9dc40c42a719" + integrity sha512-Cl5h95/Pz/PWub/tCBgT1oNMFeH1WTD33piG80jn5jr12T4XbxZcjThwNXDQ7AG649WEynuIzO4b0+2Tn9Qolg== + dependencies: + clone "^2.1.2" + less "^3.11.3" + loader-utils "^2.0.0" + schema-utils "^2.7.0" + +less@^3.10.3, less@^3.11.3: + version "3.13.1" + resolved "https://registry.yarnpkg.com/less/-/less-3.13.1.tgz#0ebc91d2a0e9c0c6735b83d496b0ab0583077909" + integrity sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw== + dependencies: + copy-anything "^2.0.1" + tslib "^1.10.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + native-request "^1.0.5" + source-map "~0.6.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -15105,6 +16679,14 @@ libnpmpublish@^1.1.1: semver "^5.5.1" ssri "^6.0.1" +license-webpack-plugin@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.3.0.tgz#c00f70d5725ba0408de208acb9e66612cc2eceda" + integrity sha512-JK/DXrtN6UeYQSgkg5q1+pgJ8aiKPL9tnz9Wzw+Ikkf+8mJxG56x6t8O+OH/tAeF/5NREnelTEMyFtbJNkjH4w== + dependencies: + "@types/webpack-sources" "^0.1.5" + webpack-sources "^1.2.0" + lie@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" @@ -15206,16 +16788,7 @@ loader-utils@1.2.3: emojis-list "^2.0.0" json5 "^1.0.1" -loader-utils@^1.2.3, loader-utils@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" - integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0: +loader-utils@2.0.0, loader-utils@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== @@ -15224,6 +16797,15 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + loader.js@~4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/loader.js/-/loader.js-4.7.0.tgz#a1a52902001c83631efde9688b8ab3799325ef1f" @@ -15496,7 +17078,7 @@ log-symbols@2.2.0, log-symbols@^2.1.0, log-symbols@^2.2.0: dependencies: chalk "^2.0.1" -log-symbols@^4.1.0: +log-symbols@^4.0.0, log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -15526,6 +17108,11 @@ log4js@^6.4.1: rfdc "^1.3.0" streamroller "^3.0.2" +loglevel@^1.6.8: + version "1.8.0" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114" + integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA== + lolex@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7" @@ -15649,6 +17236,13 @@ magic-string@0.25.7, magic-string@^0.25.1, magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" +magic-string@^0.25.0: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -15656,7 +17250,7 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" -make-dir@^2.0.0: +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -15947,6 +17541,13 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -16035,6 +17636,11 @@ mime-db@1.51.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.0.8, mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.26, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.30" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" @@ -16049,12 +17655,19 @@ mime-types@^2.1.27, mime-types@~2.1.34: dependencies: mime-db "1.51.0" -mime@1.6.0: +mime-types@~2.1.17: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.2.0, mime@^2.3.1, mime@^2.4.6, mime@^2.5.2: +mime@^2.2.0, mime@^2.3.1, mime@^2.4.4, mime@^2.4.6, mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== @@ -16079,6 +17692,16 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +mini-css-extract-plugin@0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.10.0.tgz#a0e6bfcad22a9c73f6c882a3c7557a98e2d3d27d" + integrity sha512-QgKgJBjaJhxVPwrLNqqwNS0AGkuQQ31Hp4xGXEK/P7wehEg6qmNtReHKai3zRXqY60wGVWLYcOMJK2b98aGc3A== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -16128,6 +17751,27 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + minipass@^2.2.0, minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" @@ -16136,6 +17780,13 @@ minipass@^2.2.0, minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0: safe-buffer "^5.1.2" yallist "^3.0.0" +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" + integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + dependencies: + yallist "^4.0.0" + minizlib@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" @@ -16143,6 +17794,14 @@ minizlib@^1.3.3: dependencies: minipass "^2.9.0" +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -16194,7 +17853,7 @@ mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp dependencies: minimist "^1.2.5" -mkdirp@1.0.4, mkdirp@^1.0.4: +mkdirp@1.0.4, mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -16355,6 +18014,19 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + multimatch@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" @@ -16417,6 +18089,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +native-request@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/native-request/-/native-request-1.1.0.tgz#acdb30fe2eefa3e1bc8c54b3a6852e9c5c0d3cb0" + integrity sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw== + native-url@0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" @@ -16452,6 +18129,11 @@ new-find-package-json@^1.1.0: debug "^4.3.2" tslib "^2.3.0" +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + next@10.1.3: version "10.1.3" resolved "https://registry.yarnpkg.com/next/-/next-10.1.3.tgz#e26e8371343a42bc2ba9be5cb253a7d324d03673" @@ -16508,6 +18190,37 @@ next@10.1.3: vm-browserify "1.1.2" watchpack "2.1.1" +ng-packagr@^10.1.0: + version "10.1.2" + resolved "https://registry.yarnpkg.com/ng-packagr/-/ng-packagr-10.1.2.tgz#7c869ec5bea92ff3ab65392913ad4e8af749799a" + integrity sha512-pm61gu6jPkohL8tFWk+2DwUtb3rs5GpND1ZjKUYv5WUJPUQmBfG5WvEO/CDVQpSDWhNWWLTt17NIQ+RS3hNUHg== + dependencies: + "@rollup/plugin-commonjs" "^15.0.0" + "@rollup/plugin-json" "^4.0.0" + "@rollup/plugin-node-resolve" "^9.0.0" + ajv "^6.12.3" + ansi-colors "^4.1.1" + autoprefixer "^9.6.5" + browserslist "^4.7.0" + chokidar "^3.2.1" + commander "^6.0.0" + cssnano-preset-default "^4.0.7" + fs-extra "^9.0.0" + glob "^7.1.2" + injection-js "^2.2.1" + less "^3.10.3" + node-sass-tilde-importer "^1.0.0" + postcss "^7.0.29" + postcss-url "^8.0.0" + read-pkg-up "^5.0.0" + rimraf "^3.0.0" + rollup "^2.8.0" + rollup-plugin-sourcemaps "^0.6.0" + rxjs "^6.5.0" + sass "^1.23.0" + stylus "^0.54.7" + terser "^5.0.0" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -16695,6 +18408,18 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" + integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== + +node-sass-tilde-importer@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/node-sass-tilde-importer/-/node-sass-tilde-importer-1.0.2.tgz#1a15105c153f648323b4347693fdb0f331bad1ce" + integrity sha512-Swcmr38Y7uB78itQeBm3mThjxBy9/Ah/ykPIaURY/L6Nec9AyRoL/jJ7ECfMR+oZeCTVQNxVMu/aHU+TLRVbdg== + dependencies: + find-parent-dir "^0.3.0" + node-source-walk@^4.0.0, node-source-walk@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c" @@ -16746,6 +18471,21 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + normalize-url@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" @@ -16767,6 +18507,13 @@ npm-bundled@^1.0.1, npm-bundled@^1.1.1: dependencies: npm-normalize-package-bin "^1.0.1" +npm-install-checks@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" + integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== + dependencies: + semver "^7.1.1" + npm-lifecycle@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.1.tgz#0027c09646f0fd346c5c93377bdaba59c6748fdf" @@ -16786,6 +18533,15 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== +npm-package-arg@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.0.1.tgz#9d76f8d7667b2373ffda60bb801a27ef71e3e270" + integrity sha512-/h5Fm6a/exByzFSTm7jAyHbgOqErl9qSNJDQF32Si/ZzgwT2TERVxRxn3Jurw1wflgyVVAxnFR4fRHPM7y1ClQ== + dependencies: + hosted-git-info "^3.0.2" + semver "^7.0.0" + validate-npm-package-name "^3.0.0" + "npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: version "6.1.1" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" @@ -16796,6 +18552,15 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: semver "^5.6.0" validate-npm-package-name "^3.0.0" +npm-package-arg@^8.0.0: + version "8.1.5" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" + integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== + dependencies: + hosted-git-info "^4.0.1" + semver "^7.3.4" + validate-npm-package-name "^3.0.0" + npm-package-arg@^8.1.0: version "8.1.2" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.2.tgz#b868016ae7de5619e729993fbd8d11dc3c52ab62" @@ -16824,6 +18589,15 @@ npm-packlist@^2.1.4: npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" +npm-pick-manifest@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz#2befed87b0fce956790f62d32afb56d7539c022a" + integrity sha512-ygs4k6f54ZxJXrzT0x34NybRlLeZ4+6nECAIbr2i0foTnijtS1TJiyzpqtuUAJOps/hO0tNDr8fRV5g+BtRlTw== + dependencies: + npm-install-checks "^4.0.0" + npm-package-arg "^8.0.0" + semver "^7.0.0" + npm-pick-manifest@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7" @@ -16923,6 +18697,11 @@ null-check@^1.0.0: resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -17053,6 +18832,11 @@ object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3: es-abstract "^1.18.0-next.2" has "^1.0.3" +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + octokit-pagination-methods@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" @@ -17091,6 +18875,14 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +open@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.2.0.tgz#212959bd7b0ce2e8e3676adc76e3cf2f0a2498b4" + integrity sha512-4HeyhxCvBTI5uBePsAdi55C5fmqnWZ2e2MlmvWi5KW5tdH5rxoiv/aMtbeVxKZc3eWkT1GymMnLG8XC4Rq4TDQ== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + open@^8.3.0: version "8.4.0" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" @@ -17105,6 +18897,13 @@ opener@^1.5.2: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + optimize-css-assets-webpack-plugin@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" @@ -17144,6 +18943,20 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +ora@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.0.0.tgz#4f0b34f2994877b49b452a707245ab1e9f6afccb" + integrity sha512-s26qdWqke2kjN/wC4dy+IQPBIMWBJlSU/0JZhk30ZDBLelW25rv66yutUWARMigpGPzcXHb+Nac5pNhN/WsARw== + dependencies: + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.4.0" + is-interactive "^1.0.0" + log-symbols "^4.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + ora@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" @@ -17171,6 +18984,13 @@ ora@^5.1.0, ora@^5.3.0: strip-ansi "^6.0.0" wcwidth "^1.0.1" +original@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + os-browserify@0.3.0, os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -17314,6 +19134,18 @@ p-map@^1.2.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-pipe@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" @@ -17324,6 +19156,13 @@ p-reduce@^1.0.0: resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + p-timeout@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" @@ -17375,7 +19214,7 @@ packet-reader@1.0.0: resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== -pacote@^9.5.0: +pacote@9.5.12, pacote@^9.5.0: version "9.5.12" resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66" integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ== @@ -17523,6 +19362,13 @@ parse-url@^5.0.0: parse-path "^4.0.0" protocols "^1.4.0" +parse5-htmlparser2-tree-adapter@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + parse5@6.0.1, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -17538,7 +19384,7 @@ parseuri@0.0.6: resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== -parseurl@~1.3.3: +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -17593,6 +19439,11 @@ path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + path-is-network-drive@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/path-is-network-drive/-/path-is-network-drive-1.0.13.tgz#c9aa0183eb72c328aa83f43def93ddcb9d7ec4d4" @@ -17763,6 +19614,11 @@ pgpass@1.x: dependencies: split2 "^4.1.0" +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -17942,7 +19798,7 @@ pnp-webpack-plugin@1.6.4, pnp-webpack-plugin@^1.6.4: dependencies: ts-pnp "^1.1.6" -portfinder@^1.0.28: +portfinder@^1.0.26, portfinder@^1.0.28: version "1.0.28" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== @@ -18012,6 +19868,34 @@ postcss-discard-overridden@^4.0.1: dependencies: postcss "^7.0.0" +postcss-import@12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" + integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== + dependencies: + postcss "^7.0.1" + postcss-value-parser "^3.2.3" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-load-config@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" + integrity sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + integrity sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA== + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + postcss-merge-longhand@^4.0.11: version "4.0.11" resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" @@ -18074,11 +19958,28 @@ postcss-minify-selectors@^4.0.2: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + postcss-modules-extract-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-local-by-default@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + postcss-modules-local-by-default@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" @@ -18088,6 +19989,14 @@ postcss-modules-local-by-default@^4.0.0: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-modules-scope@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" @@ -18095,6 +20004,14 @@ postcss-modules-scope@^3.0.0: dependencies: postcss-selector-parser "^6.0.4" +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + postcss-modules-values@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" @@ -18221,6 +20138,14 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" +postcss-selector-parser@^6.0.0: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" @@ -18250,7 +20175,18 @@ postcss-unique-selectors@^4.0.1: postcss "^7.0.0" uniqs "^2.0.0" -postcss-value-parser@^3.0.0: +postcss-url@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/postcss-url/-/postcss-url-8.0.0.tgz#7b10059bd12929cdbb1971c60f61a0e5af86b4ca" + integrity sha512-E2cbOQ5aii2zNHh8F6fk1cxls7QVFZjLPSrqvmiza8OuXLzIpErij8BDS5Y3STPfJgpIMNCPEr8JlKQWEoozUw== + dependencies: + mime "^2.3.1" + minimatch "^3.0.4" + mkdirp "^0.5.0" + postcss "^7.0.2" + xxhashjs "^0.2.1" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== @@ -18269,6 +20205,24 @@ postcss-values-parser@^2.0.1: indexes-of "^1.0.1" uniq "^1.0.1" +postcss@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@7.0.32: + version "7.0.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" + integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + postcss@8.1.7: version "8.1.7" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.1.7.tgz#ff6a82691bd861f3354fd9b17b2332f88171233f" @@ -18288,6 +20242,14 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.32: source-map "^0.6.1" supports-color "^6.1.0" +postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.29, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + postcss@^8.1.7, postcss@^8.2.8: version "8.2.15" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" @@ -18357,7 +20319,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.1: +prepend-http@^1.0.0, prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= @@ -18698,7 +20660,7 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.2.2: +query-string@^4.1.0, query-string@^4.2.2: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= @@ -18740,6 +20702,11 @@ querystring@^0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -18840,6 +20807,14 @@ raw-body@~1.1.0: bytes "1" string_decoder "0.10" +raw-loader@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.1.tgz#14e1f726a359b68437e183d5a5b7d33a3eba6933" + integrity sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -18929,6 +20904,13 @@ react@^18.0.0: dependencies: loose-envify "^1.1.0" +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + read-cmd-shim@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" @@ -18946,7 +20928,7 @@ read-cmd-shim@^1.0.1: normalize-package-data "^2.0.0" npm-normalize-package-bin "^1.0.0" -read-package-tree@^5.1.6: +read-package-tree@5.3.1, read-package-tree@^5.1.6: version "5.3.1" resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== @@ -18987,6 +20969,14 @@ read-pkg-up@^4.0.0: find-up "^3.0.0" read-pkg "^3.0.0" +read-pkg-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-5.0.0.tgz#b6a6741cb144ed3610554f40162aa07a6db621b8" + integrity sha512-XBQjqOBtTzyol2CpsQOw8LHV0XbDZVG7xMMjmXAJomlVY03WOBRmYgDJETlvcg0H63AJvPRwT7GFi5rvOzUOKg== + dependencies: + find-up "^3.0.0" + read-pkg "^5.0.0" + read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -19023,7 +21013,7 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -read-pkg@^5.2.0: +read-pkg@^5.0.0, read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== @@ -19053,7 +21043,7 @@ read@1, read@~1.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -19098,6 +21088,13 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -19161,6 +21158,18 @@ redux@^4.0.5: loose-envify "^1.4.0" symbol-observable "^1.2.0" +reflect-metadata@^0.1.2: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -19168,11 +21177,16 @@ regenerate-unicode-properties@^8.2.0: dependencies: regenerate "^1.4.0" -regenerate@^1.2.1, regenerate@^1.4.0: +regenerate@^1.2.1, regenerate@^1.4.0, regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== +regenerator-runtime@0.13.7, regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -19183,11 +21197,6 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - regenerator-runtime@^0.9.5: version "0.9.6" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" @@ -19209,13 +21218,34 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== + dependencies: + "@babel/runtime" "^7.8.4" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexp.prototype.flags@^1.2.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" regexp.prototype.flags@^1.3.1: version "1.3.1" @@ -19251,6 +21281,18 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + regextras@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.7.1.tgz#be95719d5f43f9ef0b9fa07ad89b7c606995a3b2" @@ -19281,6 +21323,11 @@ regjsgen@^0.5.1: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + regjsparser@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" @@ -19295,6 +21342,13 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -19361,7 +21415,7 @@ replace-in-file@^4.0.0: glob "^7.1.6" yargs "^15.0.2" -request@^2.87.0, request@^2.88.0: +request@^2.87.0, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -19544,6 +21598,22 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== +resolve-url-loader@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" + integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== + dependencies: + adjust-sourcemap-loader "3.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -19568,6 +21638,15 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.1.7, resolve@^1.3.2, resolve@^1.8.1: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -19634,6 +21713,19 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rework-visit@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" + integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= + +rework@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" + integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= + dependencies: + convert-source-map "^0.3.3" + css "^2.0.0" + rfdc@^1.1.4, rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" @@ -19656,7 +21748,7 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2. dependencies: glob "^7.1.3" -rimraf@^3.0.0, rimraf@^3.0.1, rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.1, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -19700,6 +21792,14 @@ rollup-plugin-license@^2.6.1: spdx-expression-validate "2.0.0" spdx-satisfies "5.0.1" +rollup-plugin-sourcemaps@^0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz#bf93913ffe056e414419607f1d02780d7ece84ed" + integrity sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw== + dependencies: + "@rollup/pluginutils" "^3.0.9" + source-map-resolve "^0.6.0" + rollup-plugin-terser@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" @@ -19722,6 +21822,13 @@ rollup-plugin-typescript2@^0.31.2: resolve "^1.20.0" tslib "^2.3.1" +rollup@2.26.5: + version "2.26.5" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.26.5.tgz#5562ec36fcba3eed65cfd630bd78e037ad0e0307" + integrity sha512-rCyFG3ZtQdnn9YwfuAVH0l/Om34BdO5lwCA0W6Hq+bNB21dVEBbCRxhaHOmu1G7OBFDWytbzAC104u7rxHwGjA== + optionalDependencies: + fsevents "~2.1.2" + rollup@^2.67.1: version "2.67.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.67.1.tgz#4402665706fa00f321d446ce45f880e02cf54f01" @@ -19729,6 +21836,13 @@ rollup@^2.67.1: optionalDependencies: fsevents "~2.3.2" +rollup@^2.8.0: + version "2.70.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.2.tgz#808d206a8851628a065097b7ba2053bd83ba0c0d" + integrity sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg== + optionalDependencies: + fsevents "~2.3.2" + rsvp@^3.0.14, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -19768,7 +21882,14 @@ rx@^4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= -rxjs@^6.4.0, rxjs@^6.6.0: +rxjs@6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2" + integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg== + dependencies: + tslib "^1.9.0" + +rxjs@^6.4.0, rxjs@^6.5.0, rxjs@^6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== @@ -19797,7 +21918,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -19824,6 +21945,17 @@ saslprep@^1.0.0: dependencies: sparse-bitfield "^3.0.3" +sass-loader@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.0.1.tgz#10c0364d8034f22fee25ddcc9eded20f99bbe3b4" + integrity sha512-b2PSldKVTS3JcFPHSrEXh3BeAfR7XknGiGCAO5aHruR3Pf3kqLP3Gb2ypXLglRrAzgZkloNxLZ7GXEGDX0hBUQ== + dependencies: + klona "^2.0.3" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^2.7.0" + semver "^7.3.2" + sass-lookup@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-3.0.0.tgz#3b395fa40569738ce857bc258e04df2617c48cac" @@ -19831,6 +21963,22 @@ sass-lookup@^3.0.0: dependencies: commander "^2.16.0" +sass@1.26.10: + version "1.26.10" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.10.tgz#851d126021cdc93decbf201d1eca2a20ee434760" + integrity sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw== + dependencies: + chokidar ">=2.0.0 <4.0.0" + +sass@^1.23.0: + version "1.50.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.50.1.tgz#e9b078a1748863013c4712d2466ce8ca4e4ed292" + integrity sha512-noTnY41KnlW2A9P8sdwESpDmo+KBNkukI1i8+hOK3footBUcohNHtdOJbckp46XO95nuvcHDDZ+4tmOnpK3hjw== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + sax@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -19864,7 +22012,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.5: +schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -19891,7 +22039,26 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.7: + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== + dependencies: + node-forge "^0.10.0" + +semver-intersect@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/semver-intersect/-/semver-intersect-1.4.0.tgz#bdd9c06bedcdd2fedb8cd352c3c43ee8c61321f3" + integrity sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ== + dependencies: + semver "^5.0.0" + +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.0, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -19901,6 +22068,11 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@7.3.4: version "7.3.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" @@ -19920,6 +22092,13 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semve resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.0.0, semver@^7.1.1: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -19984,6 +22163,19 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -20346,6 +22538,27 @@ socket.io@^4.2.0: socket.io-adapter "~2.3.3" socket.io-parser "~4.0.4" +sockjs-client@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" + integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g== + dependencies: + debug "^3.2.5" + eventsource "^1.0.7" + faye-websocket "~0.11.1" + inherits "^2.0.3" + json3 "^3.3.2" + url-parse "^1.4.3" + +sockjs@0.3.20: + version "0.3.20" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" + integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== + dependencies: + faye-websocket "^0.10.0" + uuid "^3.4.0" + websocket-driver "0.6.5" + socks-proxy-agent@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" @@ -20379,6 +22592,13 @@ socks@~2.3.2: ip "1.1.5" smart-buffer "^4.1.0" +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -20408,12 +22628,28 @@ source-list-map@^2.0.0: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +"source-map-js@>=0.6.2 <2.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + source-map-js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== -source-map-resolve@^0.5.0: +source-map-loader@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-1.0.2.tgz#b0a6582b2eaa387ede1ecf8061ae0b93c23f9eb0" + integrity sha512-oX8d6ndRjN+tVyjj6PlXSyFPhDdVAPsZA30nD3/II8g4uOv8fCz0DMn5sy8KtVbDfKQxOpGwGJnK3xIW3tauDw== + dependencies: + data-urls "^2.0.0" + iconv-lite "^0.6.2" + loader-utils "^2.0.0" + schema-utils "^2.7.0" + source-map "^0.6.1" + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== @@ -20424,6 +22660,22 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + +source-map-support@0.5.19, source-map-support@^0.5.6, source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@^0.4.15, source-map-support@^0.4.18: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" @@ -20431,7 +22683,7 @@ source-map-support@^0.4.15, source-map-support@^0.4.18: dependencies: source-map "^0.5.6" -source-map-support@^0.5.17, source-map-support@~0.5.20: +source-map-support@^0.5.17, source-map-support@^0.5.5, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -20439,14 +22691,6 @@ source-map-support@^0.5.17, source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.6, source-map-support@~0.5.12: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-url@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" @@ -20500,7 +22744,7 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" -sourcemap-codec@^1.4.4: +sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== @@ -20593,6 +22837,36 @@ spdx-satisfies@5.0.1: spdx-expression-parse "^3.0.0" spdx-ranges "^2.0.0" +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +speed-measure-webpack-plugin@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.3.tgz#6ff894fc83e8a6310dde3af863a0329cd79da4f5" + integrity sha512-2ljD4Ch/rz2zG3HsLsnPfp23osuPBS0qPuz9sGpkNXTN1Ic4M+W9xB8l8rS8ob2cO4b1L+WTJw/0AJwWYVgcxQ== + dependencies: + chalk "^2.0.1" + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -20680,6 +22954,13 @@ ssri@^6.0.0, ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -21065,6 +23346,14 @@ stubs@^3.0.0: resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" integrity sha1-6NK6H6nJBXAwPAMLaQD31fiavls= +style-loader@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" + integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.6" + style-loader@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" @@ -21111,6 +23400,15 @@ stylis@3.5.4: resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== +stylus-loader@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6" + integrity sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA== + dependencies: + loader-utils "^1.0.2" + lodash.clonedeep "^4.5.0" + when "~3.6.x" + stylus-lookup@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" @@ -21119,6 +23417,20 @@ stylus-lookup@^3.0.1: commander "^2.8.1" debug "^4.1.0" +stylus@0.54.8, stylus@^0.54.7: + version "0.54.8" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.8.tgz#3da3e65966bc567a7b044bfe0eece653e099d147" + integrity sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg== + dependencies: + css-parse "~2.0.0" + debug "~3.1.0" + glob "^7.1.6" + mkdirp "~1.0.4" + safer-buffer "^2.1.2" + sax "~1.2.4" + semver "^6.3.0" + source-map "^0.7.3" + sum-up@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" @@ -21205,7 +23517,7 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-observable@^1.2.0: +symbol-observable@1.2.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== @@ -21312,6 +23624,18 @@ tar@^4.4.10, tar@^4.4.8: safe-buffer "^5.2.1" yallist "^3.1.1" +tar@^6.0.2: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + teeny-request@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-6.0.1.tgz#9b1f512cef152945827ba7e34f62523a4ce2c5b0" @@ -21379,6 +23703,21 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" +terser-webpack-plugin@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.1.0.tgz#6e9d6ae4e1a900d88ddce8da6a47507ea61f44bc" + integrity sha512-0ZWDPIP8BtEDZdChbufcXUigOYk6dOX/P/X0hWxqDDcVAQLb8Yy/0FAaemSfax3PAA67+DJR778oz8qVbmy4hA== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.3.0" + p-limit "^3.0.2" + schema-utils "^2.6.6" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^5.0.0" + webpack-sources "^1.4.3" + terser-webpack-plugin@^1.4.3: version "1.4.5" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" @@ -21405,6 +23744,15 @@ terser-webpack-plugin@^5.1.3: source-map "^0.6.1" terser "^5.7.2" +terser@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.3.0.tgz#c481f4afecdcc182d5e2bdd2ff2dc61555161e81" + integrity sha512-XTT3D3AwxC54KywJijmY2mxZ8nJiEjBHVYzq8l9OaYuRFWeQNBwvipuzzYEP4e+/AVcd1hqG/CqgsdIRyT45Fg== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + terser@^4.1.2, terser@^4.3.9: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" @@ -21538,6 +23886,11 @@ through@~2.2.0, through@~2.2.7: resolved "https://registry.yarnpkg.com/through/-/through-2.2.7.tgz#6e8e21200191d4eb6a99f6f010df46aa1c6eb2bd" integrity sha1-bo4hIAGR1OtqmfbwEN9Gqhxusr0= +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -21733,7 +24086,7 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= -tree-kill@^1.2.2: +tree-kill@1.2.2, tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== @@ -21833,6 +24186,11 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" +tslib@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" + integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== + tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -21939,6 +24297,16 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + typedarray-dts@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/typedarray-dts/-/typedarray-dts-1.0.0.tgz#9dec9811386dbfba964c295c2606cf9a6b982d06" @@ -21994,6 +24362,11 @@ typescript@3.8.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== +typescript@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2" + integrity sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ== + typescript@^3.9.5, typescript@^3.9.7: version "3.9.9" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674" @@ -22004,6 +24377,11 @@ typescript@^4.5.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +typescript@~4.0.2: + version "4.0.8" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.8.tgz#5739105541db80a971fdbd0d56511d1a6f17d37f" + integrity sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg== + ua-parser-js@^0.7.18, ua-parser-js@^0.7.30: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" @@ -22065,6 +24443,11 @@ unicode-canonical-property-names-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + unicode-match-property-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" @@ -22073,16 +24456,34 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + unicode-property-aliases-ecmascript@^1.0.4: version "1.1.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -22124,6 +24525,15 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +universal-analytics@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.4.23.tgz#d915e676850c25c4156762471bdd7cf2eaaca8ac" + integrity sha512-lgMIH7XBI6OgYn1woDEmxhGdj8yDefMKg7GkWdeATAlQZFrMrNyxSkpDzY57iY0/6fdlzTbBV03OawvvzG+q7A== + dependencies: + debug "^4.1.1" + request "^2.88.2" + uuid "^3.0.0" + universal-user-agent@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-4.0.1.tgz#fd8d6cb773a679a709e967ef8288a31fcc03e557" @@ -22216,6 +24626,14 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +url-parse@^1.4.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" @@ -22333,7 +24751,12 @@ uuid@3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -uuid@^3.0.1, uuid@^3.3.2: +uuid@8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" + integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== + +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -22560,6 +24983,13 @@ watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -22607,7 +25037,83 @@ webpack-bundle-analyzer@^4.4.0: sirv "^1.0.7" ws "^7.3.1" -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: +webpack-dev-middleware@3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-middleware@^3.7.2: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" + integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== + dependencies: + ansi-html "0.0.7" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.7" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "0.3.20" + sockjs-client "1.4.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-sources@1.4.3, webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -22620,6 +25126,42 @@ webpack-sources@^3.2.2: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== +webpack-subresource-integrity@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.4.1.tgz#e8bf918b444277df46a66cd84542cbcdc5a6272d" + integrity sha512-XMLFInbGbB1HV7K4vHWANzc1CN0t/c4bBvnlvGxGwV45yE/S/feAXIm8dJsCkzqWtSKnmaEgTp/meyeThxG4Iw== + dependencies: + webpack-sources "^1.3.0" + +webpack@4.44.1: + version "4.44.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21" + integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.3.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + webpack@^4.30.0, webpack@^4.44.1: version "4.46.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" @@ -22679,6 +25221,13 @@ webpack@^5.52.0, webpack@^5.65.0: watchpack "^2.3.1" webpack-sources "^3.2.2" +websocket-driver@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= + dependencies: + websocket-extensions ">=0.1.1" + websocket-driver@>=0.5.1: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" @@ -22756,6 +25305,11 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" +when@~3.6.x: + version "3.6.4" + resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e" + integrity sha1-RztRfsFZ4rhQBUl6E5g/CVQS404= + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -22835,6 +25389,13 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" +worker-plugin@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/worker-plugin/-/worker-plugin-5.0.0.tgz#113b5fe1f4a5d6a957cecd29915bedafd70bb537" + integrity sha512-AXMUstURCxDD6yGam2r4E34aJg6kW85IiaeX72hi+I1cxyaMUtrvVY6sbfpGKAj5e7f68Acl62BjQF5aOOx2IQ== + dependencies: + loader-utils "^1.1.0" + workerpool@^2.3.0: version "2.3.3" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-2.3.3.tgz#49a70089bd55e890d68cc836a19419451d7c81d7" @@ -22949,6 +25510,13 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" +ws@^6.2.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== + dependencies: + async-limiter "~1.0.0" + ws@^7.2.3, ws@^7.3.1, ws@~7.4.2: version "7.4.4" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" @@ -23017,6 +25585,13 @@ xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xxhashjs@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" + integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw== + dependencies: + cuint "^0.2.2" + "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" @@ -23088,7 +25663,7 @@ yargs-unparser@1.6.0: lodash "^4.17.15" yargs "^13.3.0" -yargs@13.3.2, yargs@^13.3.0: +yargs@13.3.2, yargs@^13.3.0, yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== From 9b0c75998b7e19e37a27923743f78cc3d9d7d30b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 21 Apr 2022 16:43:48 +0200 Subject: [PATCH 65/94] doc(angular): Add Angular migration instructions to migration doc (#4960) Co-authored-by: Luca Forstner --- MIGRATION.md | 13 +++++++++++++ packages/angular/README.md | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index a33feb194af3..77f1c21e7aca 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -123,6 +123,19 @@ For our efforts to reduce bundle size of the SDK we had to remove and refactor p `setupBrowserTransport` or `setupNodeTransport` for default transports, depending on your requirements. - Remove support for Opera browser pre v15 +## Sentry Angular SDK Changes + +The Sentry Angular SDK (`@sentry/angular`) is now compiled with the Angular compiler (see [#4641](https://github.com/getsentry/sentry-javascript/pull/4641)). This change was necessary to fix a long-lasting bug in the SDK (see [#3282](https://github.com/getsentry/sentry-javascript/issues/3282)): `TraceDirective` and `TraceModule` can now be used again without risking an application compiler error or having to disable AOT compilation. + +### Angular Version Compatibility + +Given the forward compatibility of the Angular compiler, v7 of our SDK will only work with Angular 10 and above. Previously, it was possible to use the SDK with versions <10, although we officially only supported Angular 10-13 as peer dependencies. If you are using Angular <10 in your project, we recommend staying on the latest 6.x version until you can upgrade your Angular version. + +### Import Changes + +Due to the compiler change, our NPM package structure changed as well as it now conforms to the [Angular Package Format v10](https://docs.google.com/document/d/1uh2D6XqaGh2yjjXwfF4SrJqWl1MBhMPntlNBBsk6rbw/edit). +In case you're importing from specific paths other than `@sentry/angular` you will have to adjust these paths. As an example, `import ... from '@sentry/angular/esm/injex.js'` should be changed to `import ... from '@sentry/angular/esm2015/index.js'`. Generally, we strongly recommend only importing from `@sentry/angular`. + # Upgrading from 6.17.x to 6.18.0 Version 6.18.0 deprecates the `frameContextLines` top-level option for the Node SDK. This option will be removed in an upcoming major version. To migrate off of the top-level option, pass it instead to the new `ContextLines` integration. diff --git a/packages/angular/README.md b/packages/angular/README.md index d42a32344082..2a110538a349 100644 --- a/packages/angular/README.md +++ b/packages/angular/README.md @@ -12,6 +12,11 @@ - [Official SDK Docs](https://docs.sentry.io/platforms/javascript/angular/) - [TypeDoc](http://getsentry.github.io/sentry-javascript/) +## Angular Version Compatibility + +For Angular 10-13 use the latest version of the Sentry Angular SDK. In case +you are using an Angular 9 or earlier, use version 6.x of the SDK as newer versions do not support Angular <10. + ## General This package is a wrapper around `@sentry/browser`, with added functionality related to Angular. All methods available From 7fb13d7a98328dcc2774ad528977e9e2c60ac051 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 21 Apr 2022 13:31:46 -0400 Subject: [PATCH 66/94] ref: Enforce stackParser through options. (#4953) As stackParser will always be defined in client options, we can remove the usage of `stackParserFromOptions` outside of SDK init. --- packages/browser/src/client.ts | 12 +++------- .../src/integrations/globalhandlers.ts | 10 ++++----- .../browser/src/integrations/linkederrors.ts | 11 +++++----- packages/browser/src/sdk.ts | 5 +---- packages/node/src/client.ts | 6 ++--- .../node/src/integrations/linkederrors.ts | 10 ++++----- packages/node/src/sdk.ts | 6 +---- packages/utils/src/stacktrace.ts | 22 +++++-------------- 8 files changed, 29 insertions(+), 53 deletions(-) diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index a889d7f69d06..0679413da1c4 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,6 +1,6 @@ import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; -import { getGlobalObject, logger, stackParserFromOptions } from '@sentry/utils'; +import { getGlobalObject, logger } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; @@ -89,7 +89,7 @@ export class BrowserClient extends BaseClient { * @inheritDoc */ public eventFromException(exception: unknown, hint?: EventHint): PromiseLike { - return eventFromException(stackParserFromOptions(this._options), exception, hint, this._options.attachStacktrace); + return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace); } /** @@ -101,13 +101,7 @@ export class BrowserClient extends BaseClient { level: Severity | SeverityLevel = 'info', hint?: EventHint, ): PromiseLike { - return eventFromMessage( - stackParserFromOptions(this._options), - message, - level, - hint, - this._options.attachStacktrace, - ); + return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace); } /** diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 61e56a533629..9452bf8f7103 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -9,7 +9,6 @@ import { isPrimitive, isString, logger, - stackParserFromOptions, } from '@sentry/utils'; import { BrowserClient } from '../client'; @@ -255,8 +254,9 @@ function addMechanismAndCapture(hub: Hub, error: EventHint['originalException'], function getHubAndOptions(): [Hub, StackParser, boolean | undefined] { const hub = getCurrentHub(); const client = hub.getClient(); - const options = client?.getOptions(); - const parser = stackParserFromOptions(options); - const attachStacktrace = options?.attachStacktrace; - return [hub, parser, attachStacktrace]; + const options = (client && client.getOptions()) || { + stackParser: () => [], + attachStacktrace: false, + }; + return [hub, options.stackParser, options.attachStacktrace]; } diff --git a/packages/browser/src/integrations/linkederrors.ts b/packages/browser/src/integrations/linkederrors.ts index 1cc30c182950..8fa4413f5a83 100644 --- a/packages/browser/src/integrations/linkederrors.ts +++ b/packages/browser/src/integrations/linkederrors.ts @@ -1,6 +1,6 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core'; import { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types'; -import { isInstanceOf, stackParserFromOptions } from '@sentry/utils'; +import { isInstanceOf } from '@sentry/utils'; import { BrowserClient } from '../client'; import { exceptionFromError } from '../eventbuilder'; @@ -47,12 +47,13 @@ export class LinkedErrors implements Integration { * @inheritDoc */ public setupOnce(): void { - const options = getCurrentHub().getClient()?.getOptions(); - const parser = stackParserFromOptions(options); - + const client = getCurrentHub().getClient(); + if (!client) { + return; + } addGlobalEventProcessor((event: Event, hint?: EventHint) => { const self = getCurrentHub().getIntegration(LinkedErrors); - return self ? _handler(parser, self._key, self._limit, event, hint) : event; + return self ? _handler(client.getOptions().stackParser, self._key, self._limit, event, hint) : event; }); } } diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 05d9d9c34462..f8f233a1c230 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -102,14 +102,11 @@ export function init(options: BrowserOptions = {}): void { if (options.sendClientReports === undefined) { options.sendClientReports = true; } - if (options.stackParser === undefined) { - options.stackParser = defaultStackParsers; - } const { transport, newTransport } = setupBrowserTransport(options); const clientOptions: BrowserClientOptions = { ...options, - stackParser: stackParserFromOptions(options), + stackParser: stackParserFromOptions(options.stackParser || defaultStackParsers), integrations: getIntegrationsToSetup(options), // TODO(v7): get rid of transport being passed down below transport: options.transport || (supportsFetch() ? FetchTransport : XHRTransport), diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 7864fd1b7ccc..4ba91d0db9a2 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,7 +1,7 @@ import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; import { Event, EventHint, Severity, SeverityLevel, Transport } from '@sentry/types'; -import { logger, resolvedSyncPromise, stackParserFromOptions } from '@sentry/utils'; +import { logger, resolvedSyncPromise } from '@sentry/utils'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; import { IS_DEBUG_BUILD } from './flags'; @@ -111,7 +111,7 @@ export class NodeClient extends BaseClient { */ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types public eventFromException(exception: any, hint?: EventHint): PromiseLike { - return resolvedSyncPromise(eventFromUnknownInput(stackParserFromOptions(this._options), exception, hint)); + return resolvedSyncPromise(eventFromUnknownInput(this._options.stackParser, exception, hint)); } /** @@ -124,7 +124,7 @@ export class NodeClient extends BaseClient { hint?: EventHint, ): PromiseLike { return resolvedSyncPromise( - eventFromMessage(stackParserFromOptions(this._options), message, level, hint, this._options.attachStacktrace), + eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace), ); } diff --git a/packages/node/src/integrations/linkederrors.ts b/packages/node/src/integrations/linkederrors.ts index c1dfd285db84..19555c9bb542 100644 --- a/packages/node/src/integrations/linkederrors.ts +++ b/packages/node/src/integrations/linkederrors.ts @@ -1,6 +1,6 @@ import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core'; import { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types'; -import { isInstanceOf, resolvedSyncPromise, stackParserFromOptions, SyncPromise } from '@sentry/utils'; +import { isInstanceOf, resolvedSyncPromise, SyncPromise } from '@sentry/utils'; import { NodeClient } from '../client'; import { exceptionFromError } from '../eventbuilder'; @@ -46,12 +46,10 @@ export class LinkedErrors implements Integration { addGlobalEventProcessor(async (event: Event, hint?: EventHint) => { const hub = getCurrentHub(); const self = hub.getIntegration(LinkedErrors); - const stackParser = stackParserFromOptions(hub.getClient()?.getOptions()); - - if (self) { - await self._handler(stackParser, event, hint); + const client = hub.getClient(); + if (client && self) { + await self._handler(client.getOptions().stackParser, event, hint); } - return event; }); } diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index fa4b22a12066..4b1e503e851a 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -122,10 +122,6 @@ export function init(options: NodeOptions = {}): void { options.autoSessionTracking = true; } - if (options.stackParser === undefined) { - options.stackParser = [nodeStackParser]; - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any if ((domain as any).active) { setHubOnCarrier(carrier, getCurrentHub()); @@ -136,7 +132,7 @@ export function init(options: NodeOptions = {}): void { // TODO(v7): Refactor this to reduce the logic above const clientOptions: NodeClientOptions = { ...options, - stackParser: stackParserFromOptions(options), + stackParser: stackParserFromOptions(options.stackParser || [nodeStackParser]), integrations: getIntegrationsToSetup(options), // TODO(v7): Fix me when we switch to new transports entirely. transport: options.transport || (transport instanceof HTTPTransport ? HTTPTransport : HTTPSTransport), diff --git a/packages/utils/src/stacktrace.ts b/packages/utils/src/stacktrace.ts index 15c5401c09bd..b63f7b4c8354 100644 --- a/packages/utils/src/stacktrace.ts +++ b/packages/utils/src/stacktrace.ts @@ -30,27 +30,17 @@ export function createStackParser(...parsers: StackLineParser[]): StackParser { }; } -interface StackParserOptions { - stackParser?: StackParser | StackLineParser[]; -} - /** - * Gets a stack parser implementation from options + * Gets a stack parser implementation from Options.stackParser + * @see Options * * If options contains an array of line parsers, it is converted into a parser */ -export function stackParserFromOptions(options: StackParserOptions | undefined): StackParser { - if (options) { - if (Array.isArray(options.stackParser)) { - options.stackParser = createStackParser(...options.stackParser); - } - - if (typeof options.stackParser === 'function') { - return options.stackParser; - } +export function stackParserFromOptions(stackParser: StackParser | StackLineParser[]): StackParser { + if (Array.isArray(stackParser)) { + return createStackParser(...stackParser); } - - return _ => []; + return stackParser; } /** From 1e0e9d640c5f4e4a39408a5c48e9ea35f7965580 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 21 Apr 2022 17:40:18 +0000 Subject: [PATCH 67/94] feat(tracing): Add Prisma ORM integration. (#4931) Co-authored-by: Abhijeet Prasad --- packages/tracing/src/integrations/index.ts | 1 + .../tracing/src/integrations/node/prisma.ts | 99 +++++++++++++++++++ .../test/integrations/node/prisma.test.ts | 61 ++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 packages/tracing/src/integrations/node/prisma.ts create mode 100644 packages/tracing/test/integrations/node/prisma.test.ts diff --git a/packages/tracing/src/integrations/index.ts b/packages/tracing/src/integrations/index.ts index b35eff6c495f..6fb86c1afc78 100644 --- a/packages/tracing/src/integrations/index.ts +++ b/packages/tracing/src/integrations/index.ts @@ -2,6 +2,7 @@ export { Express } from './node/express'; export { Postgres } from './node/postgres'; export { Mysql } from './node/mysql'; export { Mongo } from './node/mongo'; +export { Prisma } from './node/prisma'; // TODO(v7): Remove this export // Please see `src/index.ts` for more details. diff --git a/packages/tracing/src/integrations/node/prisma.ts b/packages/tracing/src/integrations/node/prisma.ts new file mode 100644 index 000000000000..e70fce9f0f60 --- /dev/null +++ b/packages/tracing/src/integrations/node/prisma.ts @@ -0,0 +1,99 @@ +import { Hub } from '@sentry/hub'; +import { EventProcessor, Integration } from '@sentry/types'; +import { isThenable, logger } from '@sentry/utils'; + +import { IS_DEBUG_BUILD } from '../../flags'; + +type PrismaAction = + | 'findUnique' + | 'findMany' + | 'findFirst' + | 'create' + | 'createMany' + | 'update' + | 'updateMany' + | 'upsert' + | 'delete' + | 'deleteMany' + | 'executeRaw' + | 'queryRaw' + | 'aggregate' + | 'count' + | 'runCommandRaw'; + +interface PrismaMiddlewareParams { + model?: unknown; + action: PrismaAction; + args: unknown; + dataPath: string[]; + runInTransaction: boolean; +} + +type PrismaMiddleware = ( + params: PrismaMiddlewareParams, + next: (params: PrismaMiddlewareParams) => Promise, +) => Promise; + +interface PrismaClient { + $use: (cb: PrismaMiddleware) => void; +} + +/** Tracing integration for @prisma/client package */ +export class Prisma implements Integration { + /** + * @inheritDoc + */ + public static id: string = 'Prisma'; + + /** + * @inheritDoc + */ + public name: string = Prisma.id; + + /** + * Prisma ORM Client Instance + */ + private readonly _client?: PrismaClient; + + /** + * @inheritDoc + */ + public constructor(options: { client?: PrismaClient } = {}) { + this._client = options.client; + } + + /** + * @inheritDoc + */ + public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { + if (!this._client) { + IS_DEBUG_BUILD && logger.error('PrismaIntegration is missing a Prisma Client Instance'); + return; + } + + this._client.$use((params: PrismaMiddlewareParams, next: (params: PrismaMiddlewareParams) => Promise) => { + const scope = getCurrentHub().getScope(); + const parentSpan = scope?.getSpan(); + + const action = params.action; + const model = params.model; + + const span = parentSpan?.startChild({ + description: model ? `${model} ${action}` : action, + op: 'db.prisma', + }); + + const rv = next(params); + + if (isThenable(rv)) { + return rv.then((res: unknown) => { + span?.finish(); + return res; + }); + } + + span?.finish(); + return rv; + }); + } +} diff --git a/packages/tracing/test/integrations/node/prisma.test.ts b/packages/tracing/test/integrations/node/prisma.test.ts new file mode 100644 index 000000000000..501101dbce6f --- /dev/null +++ b/packages/tracing/test/integrations/node/prisma.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/unbound-method */ +import { Hub, Scope } from '@sentry/hub'; + +import { Prisma } from '../../../src/integrations/node/prisma'; +import { Span } from '../../../src/span'; + +type PrismaMiddleware = (params: unknown, next: (params?: unknown) => Promise) => Promise; + +class PrismaClient { + public user: { create: () => Promise | undefined } = { + create: () => this._middleware?.({ action: 'create', model: 'user' }, () => Promise.resolve('result')), + }; + + private _middleware?: PrismaMiddleware; + + constructor() { + this._middleware = undefined; + } + + public $use(cb: PrismaMiddleware) { + this._middleware = cb; + } +} + +describe('setupOnce', function () { + const Client: PrismaClient = new PrismaClient(); + + let scope = new Scope(); + let parentSpan: Span; + let childSpan: Span; + + beforeAll(() => { + // @ts-ignore, not to export PrismaClient types from integration source + new Prisma({ client: Client }).setupOnce( + () => undefined, + () => new Hub(undefined, scope), + ); + }); + + beforeEach(() => { + scope = new Scope(); + parentSpan = new Span(); + childSpan = parentSpan.startChild(); + jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); + jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); + jest.spyOn(childSpan, 'finish'); + }); + + it('should add middleware with $use method correctly', done => { + void Client.user.create()?.then(res => { + expect(res).toBe('result'); + expect(scope.getSpan).toBeCalled(); + expect(parentSpan.startChild).toBeCalledWith({ + description: 'user create', + op: 'db.prisma', + }); + expect(childSpan.finish).toBeCalled(); + done(); + }); + }); +}); From 8b6c50d2f69936d82b33c1e7d5032900ddf7c832 Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Thu, 21 Apr 2022 14:37:01 -0400 Subject: [PATCH 68/94] meta(gha): Deploy action enforce-license-compliance.yml (#4961) --- .github/workflows/enforce-license-compliance.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/enforce-license-compliance.yml diff --git a/.github/workflows/enforce-license-compliance.yml b/.github/workflows/enforce-license-compliance.yml new file mode 100644 index 000000000000..b331974711f3 --- /dev/null +++ b/.github/workflows/enforce-license-compliance.yml @@ -0,0 +1,16 @@ +name: Enforce License Compliance + +on: + push: + branches: [master, main, release/*] + pull_request: + branches: [master, main] + +jobs: + enforce-license-compliance: + runs-on: ubuntu-latest + steps: + - name: 'Enforce License Compliance' + uses: getsentry/action-enforce-license-compliance@main + with: + fossa_api_key: ${{ secrets.FOSSA_API_KEY }} From ac7f18677398602775aa6b3bd84d33c1b0d95c84 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Thu, 21 Apr 2022 16:15:16 -0700 Subject: [PATCH 69/94] fix(dev): Correctly lint `scripts` typescript files (#4963) Previously, we've had to tell eslint to ignore TS files in package-level `scripts` directories, because they weren't included by any existing TS eslint config. This fixes that, by adding them to both our main `.eslintrc.js` and (since that new entry needs a tsconfig to which to point) our main `tsconfig.json`. --- .eslintrc.js | 8 ++++++++ packages/gatsby/.eslintrc.js | 2 +- tsconfig.json | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 956f3681ba72..01d0da16cf14 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -33,6 +33,14 @@ module.exports = { project: ['tsconfig.test.json'], }, }, + { + files: ['**/scripts/**/*.ts'], + parserOptions: { + // since filepaths are relative to the working directory, we need to go back up to reach the repo root level + // tsconfig + project: ['../../tsconfig.json'], + }, + }, { files: ['*.tsx'], rules: { diff --git a/packages/gatsby/.eslintrc.js b/packages/gatsby/.eslintrc.js index 6aff306daa40..56cb2e62ad47 100644 --- a/packages/gatsby/.eslintrc.js +++ b/packages/gatsby/.eslintrc.js @@ -7,6 +7,6 @@ module.exports = { jsx: true, }, // ignore these because they're not covered by a `tsconfig`, which makes eslint throw an error - ignorePatterns: ['scripts/prepack.ts', 'gatsby-browser.d.ts', 'gatsby-node.d.ts'], + ignorePatterns: ['gatsby-browser.d.ts', 'gatsby-node.d.ts'], extends: ['../../.eslintrc.js'], }; diff --git a/tsconfig.json b/tsconfig.json index f2ffa0c4e07c..98848bfdcbe8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { "extends": "./packages/typescript/tsconfig.json", + // include scripts here because their TS config isn't package-specific, and they need to be included in a tsconfig + // file to be linted + "include": ["**/scripts/**/*.ts"], + "compilerOptions": { // TODO: turn these on once we switch to only generating types once, using `tsconfig.types.json` // "declaration": false, From 96b37e77e606e64b179b5f028c7a1e783d40dd0d Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 22 Apr 2022 10:44:31 +0200 Subject: [PATCH 70/94] feat(angular): Log warning if SDK is used with an older Angular version than officially supported (#4964) introduces a check in the Angular SDK's init function to check if the Angular version it is used with is older than our minimum supported version (Angular 10). In case it is, a warning will be logged. adjusts the migration and readme docs to reflect better our officially supported Angular versions and what to do if users are using an older Angular version if they experience problems (i.e. stay on v6). Co-authored-by: Luca Forstner --- MIGRATION.md | 6 +++++- packages/angular/README.md | 3 +-- packages/angular/src/constants.ts | 5 +++++ packages/angular/src/sdk.ts | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 77f1c21e7aca..b3a3a9eb7944 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -129,7 +129,11 @@ The Sentry Angular SDK (`@sentry/angular`) is now compiled with the Angular comp ### Angular Version Compatibility -Given the forward compatibility of the Angular compiler, v7 of our SDK will only work with Angular 10 and above. Previously, it was possible to use the SDK with versions <10, although we officially only supported Angular 10-13 as peer dependencies. If you are using Angular <10 in your project, we recommend staying on the latest 6.x version until you can upgrade your Angular version. +As in v6, we continue to list Angular 10-13 in our peer dependencies, meaning that these are the Angular versions we officially support. +If you are using v7 with Angular <10 in your project and you experience problems, we recommend staying on the latest 6.x +version until you can upgrade your Angular version. As v7 of our SDK is compiled with the Angular 10 compiler and we upgraded +our Typescript version, the SDK will work with Angular 10 and above. Tests have shown that Angular 9 seems to work as well +(use at your own risk) but we recommend upgrading to a more recent Angular version. ### Import Changes diff --git a/packages/angular/README.md b/packages/angular/README.md index 2a110538a349..82132d7543b2 100644 --- a/packages/angular/README.md +++ b/packages/angular/README.md @@ -14,8 +14,7 @@ ## Angular Version Compatibility -For Angular 10-13 use the latest version of the Sentry Angular SDK. In case -you are using an Angular 9 or earlier, use version 6.x of the SDK as newer versions do not support Angular <10. +The latest version of this SDK officially supports Angular 10-13. If you are using an older version of Angular and experience problems with the Angular SDK, we recommend downgrading the SDK to version 6.x. ## General diff --git a/packages/angular/src/constants.ts b/packages/angular/src/constants.ts index a0786e7b516c..9e98b366d841 100644 --- a/packages/angular/src/constants.ts +++ b/packages/angular/src/constants.ts @@ -3,3 +3,8 @@ export const ANGULAR_ROUTING_OP = 'ui.angular.routing'; export const ANGULAR_INIT_OP = 'ui.angular.init'; export const ANGULAR_OP = 'ui.angular'; + +/** + * Minimum Angular version this SDK supports + */ +export const ANGULAR_MINIMUM_VERSION = 10; diff --git a/packages/angular/src/sdk.ts b/packages/angular/src/sdk.ts index 09267d1f2082..bcce7c85ccdb 100644 --- a/packages/angular/src/sdk.ts +++ b/packages/angular/src/sdk.ts @@ -1,4 +1,9 @@ +import { VERSION } from '@angular/core'; import { BrowserOptions, init as browserInit, SDK_VERSION } from '@sentry/browser'; +import { logger } from '@sentry/utils'; + +import { ANGULAR_MINIMUM_VERSION } from './constants'; +import { IS_DEBUG_BUILD } from './flags'; /** * Inits the Angular SDK @@ -15,5 +20,20 @@ export function init(options: BrowserOptions): void { ], version: SDK_VERSION, }; + checkAngularVersion(); browserInit(options); } + +function checkAngularVersion(): void { + if (VERSION && VERSION.major) { + const major = parseInt(VERSION.major, 10); + if (major < ANGULAR_MINIMUM_VERSION) { + IS_DEBUG_BUILD && + logger.warn( + `The Sentry SDK does not officially support Angular ${major}.`, + `This version of the Sentry SDK supports Angular ${ANGULAR_MINIMUM_VERSION} and above.`, + 'Please consider upgrading your Angular version or downgrading the Sentry SDK.', + ); + } + } +} From 6267b54552fd1020e98da87c20fbd319d29e4364 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Sun, 24 Apr 2022 23:08:46 -0400 Subject: [PATCH 71/94] feat: Switch to new transports (#4943) This PR switches over from the old transports to the new ones. It deletes the functionality from the client of passing in transports explicitly and instead expects the transport to be passed in through options. Instead of passing in an instance of a transport to the client, we pass in a constructor function. This allows the client to control exactly what options are passed into the transport. ```ts this._transport = options.transport({ ...options.transportOptions, url }); ``` --- MIGRATION.md | 6 - packages/browser/src/client.ts | 8 +- packages/browser/src/exports.ts | 1 + packages/browser/src/sdk.ts | 9 +- packages/browser/src/transports/index.ts | 2 - packages/browser/src/transports/new-fetch.ts | 9 +- packages/browser/src/transports/new-xhr.ts | 9 +- packages/browser/src/transports/setup.ts | 71 ----- .../unit/helper/browser-client-options.ts | 5 +- packages/browser/test/unit/index.test.ts | 24 +- .../unit/integrations/linkederrors.test.ts | 7 +- .../test/unit/mocks/simpletransport.ts | 17 +- packages/browser/test/unit/sdk.test.ts | 6 +- .../browser/test/unit/transports/base.test.ts | 3 +- .../test/unit/transports/setup.test.ts | 101 ------ packages/core/src/baseclient.ts | 114 +++---- packages/core/src/index.ts | 7 - packages/core/src/request.ts | 33 +- packages/core/src/sdk.ts | 13 +- packages/core/src/transports/base.ts | 62 +--- packages/core/test/lib/base.test.ts | 297 ++++++++---------- packages/core/test/lib/sdk.test.ts | 4 +- .../core/test/lib/transports/base.test.ts | 15 +- packages/core/test/mocks/client.ts | 32 +- packages/core/test/mocks/transport.ts | 41 +-- packages/ember/tests/dummy/app/app.js | 20 +- packages/ember/tests/test-helper.js | 27 +- packages/hub/src/sessionflusher.ts | 32 +- packages/hub/test/sessionflusher.test.ts | 28 +- .../fetch-captureException/subject.js | 1 - .../fetch-captureException/test.ts | 21 -- .../fetch-startTransaction/subject.js | 2 - .../fetch-startTransaction/test.ts | 13 - .../suites/new-transports/init.js | 13 - .../xhr-captureException/subject.js | 4 - .../xhr-captureException/test.ts | 21 -- .../xhr-startTransaction/subject.js | 5 - .../xhr-startTransaction/test.ts | 13 - .../addBreadcrumb/empty_obj/test.ts | 5 +- .../multiple_breadcrumbs/test.ts | 5 +- .../addBreadcrumb/simple_breadcrumb/test.ts | 5 +- .../addBreadcrumb/undefined_arg/test.ts | 5 +- .../captureException/empty_obj/test.ts | 5 +- .../captureException/simple_error/test.ts | 5 +- .../captureException/undefined_arg/test.ts | 5 +- .../captureMessage/simple_message/test.ts | 5 +- .../captureMessage/with_level/test.ts | 5 +- .../configureScope/clear_scope/test.ts | 5 +- .../configureScope/set_properties/test.ts | 5 +- .../setContext/multiple_contexts/test.ts | 5 +- .../non_serializable_context/test.ts | 5 +- .../setContext/simple_context/test.ts | 5 +- .../setExtra/multiple_extras/test.ts | 5 +- .../setExtra/non_serializable_extra/test.ts | 5 +- .../public-api/setExtra/simple_extra/test.ts | 5 +- .../setExtras/consecutive_calls/test.ts | 5 +- .../setExtras/multiple_extras/test.ts | 5 +- .../setTag/with_non_primitives/test.ts | 5 +- .../public-api/setTag/with_primitives/test.ts | 5 +- .../setTags/with_non_primitives/test.ts | 5 +- .../setTags/with_primitives/test.ts | 5 +- .../public-api/setUser/unset_user/test.ts | 5 +- .../public-api/setUser/update_user/test.ts | 5 +- .../withScope/nested_scopes/test.ts | 5 +- .../suites/tracing/request/fetch/test.ts | 22 +- packages/integration-tests/utils/helpers.ts | 83 ++--- packages/nextjs/test/index.client.test.ts | 4 +- packages/nextjs/test/index.server.test.ts | 4 +- .../test/integration/test/utils/client.js | 29 +- .../test/integration/test/utils/server.js | 10 +- .../suites/express/handle-error/test.ts | 8 +- .../addBreadcrumb/empty-obj/test.ts | 9 +- .../multiple_breadcrumbs/test.ts | 6 +- .../addBreadcrumb/simple_breadcrumb/test.ts | 6 +- .../captureException/catched-error/test.ts | 7 +- .../captureException/empty-obj/test.ts | 7 +- .../new-transport/scenario.ts | 11 - .../captureException/new-transport/test.ts | 23 -- .../captureException/simple-error/test.ts | 7 +- .../captureMessage/simple_message/test.ts | 7 +- .../captureMessage/with_level/test.ts | 18 +- .../configureScope/clear_scope/test.ts | 8 +- .../configureScope/set_properties/test.ts | 7 +- .../setContext/multiple-contexts/test.ts | 9 +- .../non-serializable-context/test.ts | 9 +- .../setContext/simple-context/test.ts | 9 +- .../setExtra/multiple-extras/test.ts | 7 +- .../setExtra/non-serializable-extra/test.ts | 7 +- .../public-api/setExtra/simple-extra/test.ts | 7 +- .../setExtras/consecutive-calls/test.ts | 7 +- .../setExtras/multiple-extras/test.ts | 7 +- .../public-api/setTag/with-primitives/test.ts | 7 +- .../setTags/with-primitives/test.ts | 7 +- .../public-api/setUser/unset_user/test.ts | 14 +- .../public-api/setUser/update_user/test.ts | 8 +- .../withScope/nested-scopes/test.ts | 16 +- .../crashed-session-aggregate/test.ts | 12 +- .../errored-session-aggregate/test.ts | 19 +- .../node-integration-tests/utils/index.ts | 36 --- packages/node/src/client.ts | 10 +- packages/node/src/index.ts | 1 + packages/node/src/sdk.ts | 9 +- packages/node/src/transports/index.ts | 1 - packages/node/src/transports/new.ts | 5 +- packages/node/src/transports/setup.ts | 52 --- packages/node/test/client.test.ts | 25 +- packages/node/test/handlers.test.ts | 21 +- .../node/test/helper/node-client-options.ts | 5 +- packages/node/test/index.test.ts | 27 +- packages/node/test/integrations/http.test.ts | 5 +- .../test/integrations/linkederrors.test.ts | 11 +- .../manual/express-scope-separation/start.js | 10 +- .../aggregates-disable-single-session.js | 15 +- .../caught-exception-errored-session.js | 50 +-- .../errors-in-session-capped-to-one.js | 48 +-- .../single-session/healthy-session.js | 18 +- .../terminal-state-sessions-sent-once.js | 32 +- .../uncaught-exception-crashed-session.js | 27 +- .../unhandled-rejection-crashed-session.js | 30 +- .../test/manual/release-health/test-utils.js | 20 +- .../node/test/manual/webpack-domain/index.js | 8 +- packages/node/test/transports/setup.test.ts | 62 ---- packages/tracing/src/transaction.ts | 11 +- .../test/browser/backgroundtab.test.ts | 5 +- .../test/browser/browsertracing.test.ts | 9 +- packages/tracing/test/browser/request.test.ts | 5 +- packages/tracing/test/errors.test.ts | 7 +- packages/tracing/test/hub.test.ts | 83 ++--- packages/tracing/test/idletransaction.test.ts | 29 +- packages/tracing/test/span.test.ts | 9 +- packages/tracing/test/testutils.ts | 13 +- packages/types/src/client.ts | 8 +- packages/types/src/index.ts | 14 +- packages/types/src/options.ts | 13 +- packages/types/src/session.ts | 3 - packages/types/src/transport.ts | 42 +++ 136 files changed, 932 insertions(+), 1494 deletions(-) delete mode 100644 packages/browser/src/transports/setup.ts delete mode 100644 packages/browser/test/unit/transports/setup.test.ts delete mode 100644 packages/integration-tests/suites/new-transports/fetch-captureException/subject.js delete mode 100644 packages/integration-tests/suites/new-transports/fetch-captureException/test.ts delete mode 100644 packages/integration-tests/suites/new-transports/fetch-startTransaction/subject.js delete mode 100644 packages/integration-tests/suites/new-transports/fetch-startTransaction/test.ts delete mode 100644 packages/integration-tests/suites/new-transports/init.js delete mode 100644 packages/integration-tests/suites/new-transports/xhr-captureException/subject.js delete mode 100644 packages/integration-tests/suites/new-transports/xhr-captureException/test.ts delete mode 100644 packages/integration-tests/suites/new-transports/xhr-startTransaction/subject.js delete mode 100644 packages/integration-tests/suites/new-transports/xhr-startTransaction/test.ts delete mode 100644 packages/node-integration-tests/suites/public-api/captureException/new-transport/scenario.ts delete mode 100644 packages/node-integration-tests/suites/public-api/captureException/new-transport/test.ts delete mode 100644 packages/node/src/transports/setup.ts delete mode 100644 packages/node/test/transports/setup.test.ts diff --git a/MIGRATION.md b/MIGRATION.md index b3a3a9eb7944..3c5b999f11a3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -115,12 +115,6 @@ For our efforts to reduce bundle size of the SDK we had to remove and refactor p [#4919](https://github.com/getsentry/sentry-javascript/pull/4919)). `Backend` was an unnecessary abstraction which is not present in other Sentry SDKs. For the sake of reducing complexity, increasing consistency with other Sentry SDKs and decreasing bundle-size, `Backend` was removed. - - -- Inject transport into client instead of initializing it in the client in `setupTransport` (see - [#4921](https://github.com/getsentry/sentry-javascript/pull/4921/)). If you are creating your own `Client` or - calling `initAndBind`, you will have to supply your desired transport. Either provide a custom one or call - `setupBrowserTransport` or `setupNodeTransport` for default transports, depending on your requirements. - Remove support for Opera browser pre v15 ## Sentry Angular SDK Changes diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 0679413da1c4..d57b35c02d31 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,5 +1,5 @@ -import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; -import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { BaseClient, Scope, SDK_VERSION } from '@sentry/core'; +import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel } from '@sentry/types'; import { getGlobalObject, logger } from '@sentry/utils'; import { eventFromException, eventFromMessage } from './eventbuilder'; @@ -47,7 +47,7 @@ export class BrowserClient extends BaseClient { * * @param options Configuration options for this SDK. */ - public constructor(options: BrowserClientOptions, transport: Transport, newTransport?: NewTransport) { + public constructor(options: BrowserClientOptions) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.browser', @@ -59,7 +59,7 @@ export class BrowserClient extends BaseClient { ], version: SDK_VERSION, }; - super(options, transport, newTransport); + super(options); } /** diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 1af8a7d8aaf5..0777d8124579 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -27,6 +27,7 @@ export { captureEvent, captureMessage, configureScope, + createTransport, getHubFromCarrier, getCurrentHub, Hub, diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index f8f233a1c230..9b138864515a 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -14,8 +14,7 @@ import { IS_DEBUG_BUILD } from './flags'; import { ReportDialogOptions, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, LinkedErrors, TryCatch, UserAgent } from './integrations'; import { defaultStackParsers } from './stack-parsers'; -import { FetchTransport, XHRTransport } from './transports'; -import { setupBrowserTransport } from './transports/setup'; +import { makeNewFetchTransport, makeNewXHRTransport } from './transports'; export const defaultIntegrations = [ new CoreIntegrations.InboundFilters(), @@ -102,17 +101,15 @@ export function init(options: BrowserOptions = {}): void { if (options.sendClientReports === undefined) { options.sendClientReports = true; } - const { transport, newTransport } = setupBrowserTransport(options); const clientOptions: BrowserClientOptions = { ...options, stackParser: stackParserFromOptions(options.stackParser || defaultStackParsers), integrations: getIntegrationsToSetup(options), - // TODO(v7): get rid of transport being passed down below - transport: options.transport || (supportsFetch() ? FetchTransport : XHRTransport), + transport: options.transport || (supportsFetch() ? makeNewFetchTransport : makeNewXHRTransport), }; - initAndBind(BrowserClient, clientOptions, transport, newTransport); + initAndBind(BrowserClient, clientOptions); if (options.autoSessionTracking) { startSessionTracking(); diff --git a/packages/browser/src/transports/index.ts b/packages/browser/src/transports/index.ts index 31871a76d01c..287e14e0ac50 100644 --- a/packages/browser/src/transports/index.ts +++ b/packages/browser/src/transports/index.ts @@ -4,5 +4,3 @@ export { XHRTransport } from './xhr'; export { makeNewFetchTransport } from './new-fetch'; export { makeNewXHRTransport } from './new-xhr'; - -export { setupBrowserTransport } from './setup'; diff --git a/packages/browser/src/transports/new-fetch.ts b/packages/browser/src/transports/new-fetch.ts index 47a85b517e77..9a9d7b14ae19 100644 --- a/packages/browser/src/transports/new-fetch.ts +++ b/packages/browser/src/transports/new-fetch.ts @@ -1,10 +1,5 @@ -import { - BaseTransportOptions, - createTransport, - NewTransport, - TransportMakeRequestResponse, - TransportRequest, -} from '@sentry/core'; +import { createTransport } from '@sentry/core'; +import { BaseTransportOptions, NewTransport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; import { FetchImpl, getNativeFetchImplementation } from './utils'; diff --git a/packages/browser/src/transports/new-xhr.ts b/packages/browser/src/transports/new-xhr.ts index cd19b1de0cd4..d45a0019914c 100644 --- a/packages/browser/src/transports/new-xhr.ts +++ b/packages/browser/src/transports/new-xhr.ts @@ -1,10 +1,5 @@ -import { - BaseTransportOptions, - createTransport, - NewTransport, - TransportMakeRequestResponse, - TransportRequest, -} from '@sentry/core'; +import { createTransport } from '@sentry/core'; +import { BaseTransportOptions, NewTransport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; import { SyncPromise } from '@sentry/utils'; /** diff --git a/packages/browser/src/transports/setup.ts b/packages/browser/src/transports/setup.ts deleted file mode 100644 index f72365e7dc94..000000000000 --- a/packages/browser/src/transports/setup.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { - BaseTransportOptions, - getEnvelopeEndpointWithUrlEncodedAuth, - initAPIDetails, - NewTransport, - NoopTransport, -} from '@sentry/core'; -import { Transport, TransportOptions } from '@sentry/types'; -import { supportsFetch } from '@sentry/utils'; - -import { BrowserOptions } from '../client'; -import { FetchTransport } from './fetch'; -import { makeNewFetchTransport } from './new-fetch'; -import { makeNewXHRTransport } from './new-xhr'; -import { XHRTransport } from './xhr'; - -export interface BrowserTransportOptions extends BaseTransportOptions { - // options to pass into fetch request - fetchParams: Record; - headers?: Record; - sendClientReports?: boolean; -} - -/** - * Sets up Browser transports based on the passed `options`. If available, the returned - * transport will use the fetch API. In case fetch is not supported, an XMLHttpRequest - * based transport is created. - * - * @returns an object currently still containing both, the old `Transport` and - * `NewTransport` which will eventually replace `Transport`. Once this is replaced, - * this function will return a ready to use `NewTransport`. - */ -// TODO(v7): Adjust return value when NewTransport is the default -export function setupBrowserTransport(options: BrowserOptions): { - transport: Transport; - newTransport?: NewTransport; -} { - if (!options.dsn) { - // We return the noop transport here in case there is no Dsn. - return { transport: new NoopTransport() }; - } - - const transportOptions: TransportOptions = { - ...options.transportOptions, - dsn: options.dsn, - tunnel: options.tunnel, - sendClientReports: options.sendClientReports, - _metadata: options._metadata, - }; - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - if (options.transport) { - return { transport: new options.transport(transportOptions) }; - } - - if (supportsFetch()) { - const requestOptions: RequestInit = { ...transportOptions.fetchParameters }; - const newTransport = makeNewFetchTransport({ requestOptions, url }); - const fetchTransport = new FetchTransport(transportOptions); - return { transport: fetchTransport, newTransport }; - } - - const newTransport = makeNewXHRTransport({ - url, - headers: transportOptions.headers, - }); - const transport = new XHRTransport(transportOptions); - return { transport, newTransport }; -} diff --git a/packages/browser/test/unit/helper/browser-client-options.ts b/packages/browser/test/unit/helper/browser-client-options.ts index aa763a5de06b..19d4a4cb8c05 100644 --- a/packages/browser/test/unit/helper/browser-client-options.ts +++ b/packages/browser/test/unit/helper/browser-client-options.ts @@ -1,11 +1,12 @@ -import { NoopTransport } from '@sentry/core'; +import { createTransport } from '@sentry/core'; +import { resolvedSyncPromise } from '@sentry/utils'; import { BrowserClientOptions } from '../../../src/client'; export function getDefaultBrowserClientOptions(options: Partial = {}): BrowserClientOptions { return { integrations: [], - transport: NoopTransport, + transport: () => createTransport({}, _ => resolvedSyncPromise({ statusCode: 200 })), stackParser: () => [], ...options, }; diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 434dea98977a..c8d1df23bac9 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -17,7 +17,7 @@ import { wrap, } from '../../src'; import { getDefaultBrowserClientOptions } from './helper/browser-client-options'; -import { SimpleTransport } from './mocks/simpletransport'; +import { makeSimpleTransport } from './mocks/simpletransport'; const dsn = 'https://53039209a22b4ec1bcc296a3c9fdecd6@sentry.io/4291'; @@ -31,7 +31,7 @@ describe('SentryBrowser', () => { init({ beforeSend, dsn, - transport: SimpleTransport, + transport: makeSimpleTransport, }); }); @@ -77,7 +77,7 @@ describe('SentryBrowser', () => { describe('user', () => { const EX_USER = { email: 'test@example.com' }; const options = getDefaultBrowserClientOptions({ dsn }); - const client = new BrowserClient(options, new SimpleTransport({ dsn })); + const client = new BrowserClient(options); const reportDialogSpy = jest.spyOn(client, 'showReportDialog'); beforeEach(() => { @@ -150,7 +150,7 @@ describe('SentryBrowser', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); + getCurrentHub().bindClient(new BrowserClient(options)); captureMessage('test'); }); @@ -164,7 +164,7 @@ describe('SentryBrowser', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); + getCurrentHub().bindClient(new BrowserClient(options)); captureEvent({ message: 'event' }); }); @@ -175,7 +175,7 @@ describe('SentryBrowser', () => { dsn, integrations: [], }); - getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); + getCurrentHub().bindClient(new BrowserClient(options)); captureMessage('event222'); captureMessage('event222'); @@ -192,7 +192,7 @@ describe('SentryBrowser', () => { dsn, integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })], }); - getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); + getCurrentHub().bindClient(new BrowserClient(options)); captureMessage('capture'); @@ -244,7 +244,7 @@ describe('SentryBrowser initialization', () => { it('should set SDK data when Sentry.init() is called', () => { init({ dsn }); - const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; expect(sdkData?.name).toBe('sentry.javascript.browser'); expect(sdkData?.packages[0].name).toBe('npm:@sentry/browser'); @@ -254,9 +254,9 @@ describe('SentryBrowser initialization', () => { it('should set SDK data when instantiating a client directly', () => { const options = getDefaultBrowserClientOptions({ dsn }); - const client = new BrowserClient(options, new SimpleTransport({ dsn })); + const client = new BrowserClient(options); - const sdkData = (client.getTransport() as any)._api.metadata?.sdk; + const sdkData = client.getOptions()._metadata?.sdk as any; expect(sdkData.name).toBe('sentry.javascript.browser'); expect(sdkData.packages[0].name).toBe('npm:@sentry/browser'); @@ -284,7 +284,7 @@ describe('SentryBrowser initialization', () => { }, }); - const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata?.sdk; expect(sdkData.name).toBe('sentry.javascript.angular'); expect(sdkData.packages[0].name).toBe('npm:@sentry/angular'); @@ -305,7 +305,7 @@ describe('wrap()', () => { }, dsn, }); - getCurrentHub().bindClient(new BrowserClient(options, new SimpleTransport({ dsn }))); + getCurrentHub().bindClient(new BrowserClient(options)); try { wrap(() => { diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts index 4b862705bccc..445a4fde8699 100644 --- a/packages/browser/test/unit/integrations/linkederrors.test.ts +++ b/packages/browser/test/unit/integrations/linkederrors.test.ts @@ -4,7 +4,6 @@ import { createStackParser } from '@sentry/utils'; import { BrowserClient } from '../../../src/client'; import * as LinkedErrorsModule from '../../../src/integrations/linkederrors'; import { defaultStackParsers } from '../../../src/stack-parsers'; -import { setupBrowserTransport } from '../../../src/transports'; import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; const parser = createStackParser(...defaultStackParsers); @@ -47,7 +46,7 @@ describe('LinkedErrors', () => { const originalException = one; const options = getDefaultBrowserClientOptions({ stackParser: parser }); - const client = new BrowserClient(options, setupBrowserTransport(options).transport); + const client = new BrowserClient(options); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, { originalException, @@ -78,7 +77,7 @@ describe('LinkedErrors', () => { const originalException = one; const options = getDefaultBrowserClientOptions({ stackParser: parser }); - const client = new BrowserClient(options, setupBrowserTransport(options).transport); + const client = new BrowserClient(options); return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, { originalException, @@ -105,7 +104,7 @@ describe('LinkedErrors', () => { two.cause = three; const options = getDefaultBrowserClientOptions({ stackParser: parser }); - const client = new BrowserClient(options, setupBrowserTransport(options).transport); + const client = new BrowserClient(options); const originalException = one; return client.eventFromException(originalException).then(event => { const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, { diff --git a/packages/browser/test/unit/mocks/simpletransport.ts b/packages/browser/test/unit/mocks/simpletransport.ts index 398feb1a3e6a..59a21aed4ac3 100644 --- a/packages/browser/test/unit/mocks/simpletransport.ts +++ b/packages/browser/test/unit/mocks/simpletransport.ts @@ -1,15 +1,6 @@ -import { eventStatusFromHttpCode, resolvedSyncPromise } from '@sentry/utils'; +import { createTransport } from '@sentry/core'; +import { resolvedSyncPromise } from '@sentry/utils'; -import { Event, Response } from '../../../src'; -import { BaseTransport } from '../../../src/transports'; - -// @ts-ignore It's okay that we're not implementing the `_sendRequest()` method because we don't use it in our tests -export class SimpleTransport extends BaseTransport { - public sendEvent(_: Event): PromiseLike { - return this._buffer.add(() => - resolvedSyncPromise({ - status: eventStatusFromHttpCode(200), - }), - ); - } +export function makeSimpleTransport() { + return createTransport({}, () => resolvedSyncPromise({ statusCode: 200 })); } diff --git a/packages/browser/test/unit/sdk.test.ts b/packages/browser/test/unit/sdk.test.ts index 8814329f16e9..85fa04b21612 100644 --- a/packages/browser/test/unit/sdk.test.ts +++ b/packages/browser/test/unit/sdk.test.ts @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import { NoopTransport, Scope } from '@sentry/core'; +import { Scope } from '@sentry/core'; +import { createTransport } from '@sentry/core'; import { MockIntegration } from '@sentry/core/test/lib/sdk.test'; import { Client, Integration } from '@sentry/types'; +import { resolvedSyncPromise } from '@sentry/utils'; import { BrowserOptions } from '../../src'; import { init } from '../../src/sdk'; @@ -13,7 +15,7 @@ const PUBLIC_DSN = 'https://username@domain/123'; function getDefaultBrowserOptions(options: Partial = {}): BrowserOptions { return { integrations: [], - transport: NoopTransport, + transport: () => createTransport({}, _ => resolvedSyncPromise({ statusCode: 200 })), stackParser: () => [], ...options, }; diff --git a/packages/browser/test/unit/transports/base.test.ts b/packages/browser/test/unit/transports/base.test.ts index 9df498352c1e..75894049c1ca 100644 --- a/packages/browser/test/unit/transports/base.test.ts +++ b/packages/browser/test/unit/transports/base.test.ts @@ -7,7 +7,8 @@ const envelopeEndpoint = 'https://sentry.io/api/42/envelope/?sentry_key=123&sent // assert on what the class provides and what it leaves to the concrete class to implement class SimpleTransport extends BaseTransport {} -describe('BaseTransport', () => { +// TODO(v7): Re-enable these tests with client reports +describe.skip('BaseTransport', () => { describe('Client Reports', () => { const sendBeaconSpy = jest.fn(); let visibilityState: string; diff --git a/packages/browser/test/unit/transports/setup.test.ts b/packages/browser/test/unit/transports/setup.test.ts deleted file mode 100644 index 41b361d684d5..000000000000 --- a/packages/browser/test/unit/transports/setup.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { NoopTransport } from '@sentry/core'; - -import { - FetchTransport, - makeNewFetchTransport, - makeNewXHRTransport, - setupBrowserTransport, - XHRTransport, -} from '../../../src/transports'; -import { getDefaultBrowserClientOptions } from '../helper/browser-client-options'; -import { SimpleTransport } from '../mocks/simpletransport'; - -const DSN = 'https://username@domain/123'; - -let fetchSupported = true; - -jest.mock('@sentry/utils', () => { - const original = jest.requireActual('@sentry/utils'); - return { - ...original, - supportsFetch(): boolean { - return fetchSupported; - }, - getGlobalObject(): any { - return { - fetch: () => {}, - }; - }, - }; -}); - -jest.mock('../../../src/transports/new-fetch', () => { - const original = jest.requireActual('../../../src/transports/new-fetch'); - return { - ...original, - makeNewFetchTransport: jest.fn(() => ({ - send: () => Promise.resolve({ status: 'success' }), - flush: () => Promise.resolve(true), - })), - }; -}); - -jest.mock('../../../src/transports/new-xhr', () => { - const original = jest.requireActual('../../../src/transports/new-xhr'); - return { - ...original, - makeNewXHRTransport: jest.fn(() => ({ - send: () => Promise.resolve({ status: 'success' }), - flush: () => Promise.resolve(true), - })), - }; -}); - -describe('setupBrowserTransport', () => { - afterEach(() => jest.clearAllMocks()); - - afterAll(() => jest.resetAllMocks()); - - it('returns NoopTransport if no dsn is passed', () => { - const { transport, newTransport } = setupBrowserTransport({}); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(NoopTransport); - expect(newTransport).toBeUndefined(); - }); - - it('returns the instantiated transport passed via the options', () => { - const options = getDefaultBrowserClientOptions({ dsn: DSN, transport: SimpleTransport }); - const { transport, newTransport } = setupBrowserTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(SimpleTransport); - expect(newTransport).toBeUndefined(); - }); - - it('returns fetchTransports if fetch is supported', () => { - const options = getDefaultBrowserClientOptions({ dsn: DSN }); - delete options.transport; - const { transport, newTransport } = setupBrowserTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(FetchTransport); - expect(newTransport).toBeDefined(); - expect(makeNewFetchTransport).toHaveBeenCalledTimes(1); - expect(makeNewXHRTransport).toHaveBeenCalledTimes(0); - }); - - it('returns xhrTransports if fetch is not supported', () => { - fetchSupported = false; - - const options = getDefaultBrowserClientOptions({ dsn: DSN }); - delete options.transport; - const { transport, newTransport } = setupBrowserTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(XHRTransport); - expect(newTransport).toBeDefined(); - expect(makeNewFetchTransport).toHaveBeenCalledTimes(0); - expect(makeNewXHRTransport).toHaveBeenCalledTimes(1); - }); -}); diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 314d3d6216a0..e2502289742a 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -4,10 +4,13 @@ import { Client, ClientOptions, DsnComponents, + Envelope, Event, EventHint, Integration, IntegrationClass, + NewTransport, + SessionAggregates, Severity, SeverityLevel, Transport, @@ -29,11 +32,10 @@ import { uuid4, } from '@sentry/utils'; -import { APIDetails, initAPIDetails } from './api'; +import { getEnvelopeEndpointWithUrlEncodedAuth } from './api'; import { IS_DEBUG_BUILD } from './flags'; import { IntegrationIndex, setupIntegrations } from './integration'; import { createEventEnvelope, createSessionEnvelope } from './request'; -import { NewTransport } from './transports/base'; const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; @@ -75,6 +77,8 @@ export abstract class BaseClient implements Client { /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */ protected readonly _dsn?: DsnComponents; + protected readonly _transport?: NewTransport; + /** Array of set up integrations. */ protected _integrations: IntegrationIndex = {}; @@ -84,12 +88,6 @@ export abstract class BaseClient implements Client { /** Number of calls being processed */ protected _numProcessing: number = 0; - /** Cached transport used internally. */ - protected _transport: Transport; - - /** New v7 Transport that is initialized alongside the old one */ - protected _newTransport?: NewTransport; - /** * Initializes this client instance. * @@ -97,25 +95,15 @@ export abstract class BaseClient implements Client { * @param transport The (old) Transport instance for the client to use (TODO(v7): remove) * @param newTransport The NewTransport instance for the client to use */ - protected constructor(options: O, transport: Transport, newTransport?: NewTransport) { + protected constructor(options: O) { this._options = options; - if (options.dsn) { this._dsn = makeDsn(options.dsn); + const url = getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options.tunnel); + this._transport = options.transport({ ...options.transportOptions, url }); } else { IS_DEBUG_BUILD && logger.warn('No DSN provided, client will not do anything.'); } - - // TODO(v7): remove old transport - this._transport = transport; - this._newTransport = newTransport; - - // TODO(v7): refactor this to keep metadata/api outside of transport. This hack is used to - // satisfy tests until we move to NewTransport where we have to revisit this. - (this._transport as unknown as { _api: Partial })._api = { - ...((this._transport as unknown as { _api: Partial })._api || {}), - metadata: options._metadata || {}, - }; } /** @@ -202,7 +190,7 @@ export abstract class BaseClient implements Client { if (!(typeof session.release === 'string')) { IS_DEBUG_BUILD && logger.warn('Discarded session because of missing or non-string release'); } else { - this._sendSession(session); + this.sendSession(session); // After sending, we set init false to indicate it's not the first occurrence session.update({ init: false }); } @@ -225,7 +213,7 @@ export abstract class BaseClient implements Client { /** * @inheritDoc */ - public getTransport(): Transport { + public getTransport(): NewTransport | undefined { return this._transport; } @@ -233,11 +221,14 @@ export abstract class BaseClient implements Client { * @inheritDoc */ public flush(timeout?: number): PromiseLike { - return this._isClientDoneProcessing(timeout).then(clientFinished => { - return this.getTransport() - .close(timeout) - .then(transportFlushed => clientFinished && transportFlushed); - }); + const transport = this._transport; + if (transport) { + return this._isClientDoneProcessing(timeout).then(clientFinished => { + return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed); + }); + } else { + return resolvedSyncPromise(true); + } } /** @@ -276,50 +267,32 @@ export abstract class BaseClient implements Client { * @inheritDoc */ public sendEvent(event: Event): void { - // TODO(v7): Remove the if-else - if ( - this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport - ) { - const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - const env = createEventEnvelope(event, api); - void this._newTransport.send(env).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); - }); - } else { - void this._transport.sendEvent(event).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); - }); + if (this._dsn) { + const env = createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel); + this.sendEnvelope(env); } } /** * @inheritDoc */ - public sendSession(session: Session): void { - if (!this._transport.sendSession) { - IS_DEBUG_BUILD && logger.warn("Dropping session because custom transport doesn't implement sendSession"); - return; + public sendSession(session: Session | SessionAggregates): void { + if (this._dsn) { + const [env] = createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel); + this.sendEnvelope(env); } + } - // TODO(v7): Remove the if-else - if ( - this._newTransport && - this._options.dsn && - this._options._experiments && - this._options._experiments.newTransport - ) { - const api = initAPIDetails(this._options.dsn, this._options._metadata, this._options.tunnel); - const [env] = createSessionEnvelope(session, api); - void this._newTransport.send(env).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); + /** + * @inheritdoc + */ + public sendEnvelope(env: Envelope): void { + if (this._transport && this._dsn) { + this._transport.send(env).then(null, reason => { + IS_DEBUG_BUILD && logger.error('Error while sending event:', reason); }); } else { - void this._transport.sendSession(session).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); - }); + IS_DEBUG_BUILD && logger.error('Transport disabled'); } } @@ -356,12 +329,6 @@ export abstract class BaseClient implements Client { } } - /** Deliver captured session to Sentry */ - // TODO(v7): should this be deleted? - protected _sendSession(session: Session): void { - this.sendSession(session); - } - /** * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying * "no" (resolving to `false`) in order to give the client a chance to potentially finish first. @@ -599,15 +566,16 @@ export abstract class BaseClient implements Client { protected _processEvent(event: Event, hint?: EventHint, scope?: Scope): PromiseLike { // eslint-disable-next-line @typescript-eslint/unbound-method const { beforeSend, sampleRate } = this.getOptions(); - const transport = this.getTransport(); type RecordLostEvent = NonNullable; type RecordLostEventParams = Parameters; - function recordLostEvent(outcome: RecordLostEventParams[0], category: RecordLostEventParams[1]): void { - if (transport.recordLostEvent) { - transport.recordLostEvent(outcome, category); - } + function recordLostEvent(_outcome: RecordLostEventParams[0], _category: RecordLostEventParams[1]): void { + // no-op as new transports don't have client outcomes + // TODO(v7): Re-add this functionality + // if (transport.recordLostEvent) { + // transport.recordLostEvent(outcome, category); + // } } if (!this._isEnabled()) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index da68917c936e..f5932bdbeaa4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,12 +1,5 @@ export type { APIDetails } from './api'; export type { ClientClass } from './sdk'; -export type { - BaseTransportOptions, - NewTransport, - TransportMakeRequestResponse, - TransportRequest, - TransportRequestExecutor, -} from './transports/base'; export { addBreadcrumb, diff --git a/packages/core/src/request.ts b/packages/core/src/request.ts index 2d65006272dd..9e58710af719 100644 --- a/packages/core/src/request.ts +++ b/packages/core/src/request.ts @@ -1,8 +1,10 @@ import { + DsnComponents, Event, EventEnvelope, EventItem, SdkInfo, + SdkMetadata, SentryRequest, SentryRequestType, Session, @@ -15,11 +17,11 @@ import { createEnvelope, dsnToString, normalize, serializeEnvelope } from '@sent import { APIDetails, getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth } from './api'; /** Extract sdk info from from the API metadata */ -function getSdkMetadataForEnvelopeHeader(api: APIDetails): SdkInfo | undefined { - if (!api.metadata || !api.metadata.sdk) { +function getSdkMetadataForEnvelopeHeader(metadata?: SdkMetadata): SdkInfo | undefined { + if (!metadata || !metadata.sdk) { return; } - const { name, version } = api.metadata.sdk; + const { name, version } = metadata.sdk; return { name, version }; } @@ -42,13 +44,15 @@ function enhanceEventWithSdkInfo(event: Event, sdkInfo?: SdkInfo): Event { /** Creates an envelope from a Session */ export function createSessionEnvelope( session: Session | SessionAggregates, - api: APIDetails, + dsn: DsnComponents, + metadata?: SdkMetadata, + tunnel?: string, ): [SessionEnvelope, SentryRequestType] { - const sdkInfo = getSdkMetadataForEnvelopeHeader(api); + const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata); const envelopeHeaders = { sent_at: new Date().toISOString(), ...(sdkInfo && { sdk: sdkInfo }), - ...(!!api.tunnel && { dsn: dsnToString(api.dsn) }), + ...(!!tunnel && { dsn: dsnToString(dsn) }), }; // I know this is hacky but we don't want to add `sessions` to request type since it's never rate limited @@ -63,7 +67,7 @@ export function createSessionEnvelope( /** Creates a SentryRequest from a Session. */ export function sessionToSentryRequest(session: Session | SessionAggregates, api: APIDetails): SentryRequest { - const [envelope, type] = createSessionEnvelope(session, api); + const [envelope, type] = createSessionEnvelope(session, api.dsn, api.metadata, api.tunnel); return { body: serializeEnvelope(envelope), type, @@ -75,8 +79,13 @@ export function sessionToSentryRequest(session: Session | SessionAggregates, api * Create an Envelope from an event. Note that this is duplicated from below, * but on purpose as this will be refactored in v7. */ -export function createEventEnvelope(event: Event, api: APIDetails): EventEnvelope { - const sdkInfo = getSdkMetadataForEnvelopeHeader(api); +export function createEventEnvelope( + event: Event, + dsn: DsnComponents, + metadata?: SdkMetadata, + tunnel?: string, +): EventEnvelope { + const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata); const eventType = event.type || 'event'; const { transactionSampling } = event.sdkProcessingMetadata || {}; @@ -96,7 +105,7 @@ export function createEventEnvelope(event: Event, api: APIDetails): EventEnvelop // 2. Restore the original version of the request body, which is commented out // 3. Search for either of the PR URLs above and pull out the companion hacks in the browser playwright tests and the // baseClient tests in this package - enhanceEventWithSdkInfo(event, api.metadata.sdk); + enhanceEventWithSdkInfo(event, metadata && metadata.sdk); event.tags = event.tags || {}; event.extra = event.extra || {}; @@ -115,7 +124,7 @@ export function createEventEnvelope(event: Event, api: APIDetails): EventEnvelop event_id: event.event_id as string, sent_at: new Date().toISOString(), ...(sdkInfo && { sdk: sdkInfo }), - ...(!!api.tunnel && { dsn: dsnToString(api.dsn) }), + ...(!!tunnel && { dsn: dsnToString(dsn) }), }; const eventItem: EventItem = [ { @@ -129,7 +138,7 @@ export function createEventEnvelope(event: Event, api: APIDetails): EventEnvelop /** Creates a SentryRequest from an event. */ export function eventToSentryRequest(event: Event, api: APIDetails): SentryRequest { - const sdkInfo = getSdkMetadataForEnvelopeHeader(api); + const sdkInfo = getSdkMetadataForEnvelopeHeader(api.metadata); const eventType = event.type || 'event'; const useEnvelope = eventType === 'transaction' || !!api.tunnel; diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index c7f7bb4916a3..b549163a1ecc 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -1,16 +1,11 @@ import { getCurrentHub } from '@sentry/hub'; -import { Client, ClientOptions, Transport } from '@sentry/types'; +import { Client, ClientOptions } from '@sentry/types'; import { logger } from '@sentry/utils'; import { IS_DEBUG_BUILD } from './flags'; -import { NewTransport } from './transports/base'; /** A class object that can instantiate Client objects. */ -export type ClientClass = new ( - options: O, - transport: Transport, - newTransport?: NewTransport, -) => F; +export type ClientClass = new (options: O) => F; /** * Internal function to create a new SDK client instance. The client is @@ -22,8 +17,6 @@ export type ClientClass = new ( export function initAndBind( clientClass: ClientClass, options: O, - transport: Transport, - newTransport?: NewTransport, ): void { if (options.debug === true) { if (IS_DEBUG_BUILD) { @@ -40,6 +33,6 @@ export function initAndBind( scope.update(options.initialScope); } - const client = new clientClass(options, transport, newTransport); + const client = new clientClass(options); hub.bindClient(client); } diff --git a/packages/core/src/transports/base.ts b/packages/core/src/transports/base.ts index 787e175b9985..8c6cfe373bfe 100644 --- a/packages/core/src/transports/base.ts +++ b/packages/core/src/transports/base.ts @@ -1,4 +1,12 @@ -import { Envelope, EventStatus } from '@sentry/types'; +import { + Envelope, + InternalBaseTransportOptions, + NewTransport, + TransportCategory, + TransportRequest, + TransportRequestExecutor, + TransportResponse, +} from '@sentry/types'; import { disabledUntil, eventStatusFromHttpCode, @@ -13,58 +21,6 @@ import { updateRateLimits, } from '@sentry/utils'; -export const ERROR_TRANSPORT_CATEGORY = 'error'; - -export const TRANSACTION_TRANSPORT_CATEGORY = 'transaction'; - -export const ATTACHMENT_TRANSPORT_CATEGORY = 'attachment'; - -export const SESSION_TRANSPORT_CATEGORY = 'session'; - -type TransportCategory = - | typeof ERROR_TRANSPORT_CATEGORY - | typeof TRANSACTION_TRANSPORT_CATEGORY - | typeof ATTACHMENT_TRANSPORT_CATEGORY - | typeof SESSION_TRANSPORT_CATEGORY; - -export type TransportRequest = { - body: string; - category: TransportCategory; -}; - -export type TransportMakeRequestResponse = { - body?: string; - headers?: { - [key: string]: string | null; - 'x-sentry-rate-limits': string | null; - 'retry-after': string | null; - }; - reason?: string; - statusCode: number; -}; - -export type TransportResponse = { - status: EventStatus; - reason?: string; -}; - -interface InternalBaseTransportOptions { - bufferSize?: number; -} -export interface BaseTransportOptions extends InternalBaseTransportOptions { - // url to send the event - // transport does not care about dsn specific - client should take care of - // parsing and figuring that out - url: string; -} - -export interface NewTransport { - send(request: Envelope): PromiseLike; - flush(timeout?: number): PromiseLike; -} - -export type TransportRequestExecutor = (request: TransportRequest) => PromiseLike; - export const DEFAULT_TRANSPORT_BUFFER_SIZE = 30; /** diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts index 47ec8ae70266..feb18390c3e8 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/base.test.ts @@ -1,12 +1,11 @@ import { Hub, Scope, Session } from '@sentry/hub'; -import { Event, Span, Transport } from '@sentry/types'; +import { Event, Span } from '@sentry/types'; import { dsnToString, logger, SentryError, SyncPromise } from '@sentry/utils'; import * as integrationModule from '../../src/integration'; -import { NoopTransport } from '../../src/transports/noop'; -import { getDefaultTestClientOptions, setupTestTransport, TestClient } from '../mocks/client'; +import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; import { TestIntegration } from '../mocks/integration'; -import { FakeTransport } from '../mocks/transport'; +import { makeFakeTransport } from '../mocks/transport'; const PUBLIC_DSN = 'https://username@domain/123'; // eslint-disable-next-line no-var @@ -68,7 +67,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); expect(dsnToString(client.getDsn()!)).toBe(PUBLIC_DSN); }); @@ -76,7 +75,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions(); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); expect(client.getDsn()).toBeUndefined(); }); @@ -85,7 +84,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: 'abc' }); - expect(() => new TestClient(options, setupTestTransport(options).transport)).toThrow(SentryError); + expect(() => new TestClient(options)).toThrow(SentryError); }); }); @@ -94,31 +93,20 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, test: true }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); expect(client.getOptions()).toEqual(options); }); }); describe('getTransport()', () => { - test('returns the transport from client', () => { - expect.assertions(2); - - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, transport: FakeTransport }); - const client = new TestClient(options, new FakeTransport()); - - expect(client.getTransport()).toBeInstanceOf(FakeTransport); - expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); - }); - - test('retruns NoopTransport when no transport is passed', () => { - expect.assertions(2); + test('returns undefined when no dsn is set', () => { + expect.assertions(1); - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const options = getDefaultTestClientOptions({}); + const client = new TestClient(options); - expect(client.getTransport()).toBeInstanceOf(NoopTransport); - expect(TestClient.instance!.getTransport()).toBe(client.getTransport()); + expect(client.getTransport()).toBeUndefined(); }); }); @@ -127,7 +115,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({}); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -141,7 +129,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({}); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -155,7 +143,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ maxBreadcrumbs: 1 }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -170,7 +158,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({}); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -185,7 +173,7 @@ describe('BaseClient', () => { const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); const options = getDefaultTestClientOptions({ beforeBreadcrumb }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -199,7 +187,7 @@ describe('BaseClient', () => { const beforeBreadcrumb = jest.fn(() => ({ message: 'changed' })); const options = getDefaultTestClientOptions({ beforeBreadcrumb }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -213,7 +201,7 @@ describe('BaseClient', () => { const beforeBreadcrumb = jest.fn(() => null); const options = getDefaultTestClientOptions({ beforeBreadcrumb }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -227,7 +215,7 @@ describe('BaseClient', () => { const beforeBreadcrumb = jest.fn((breadcrumb, hint) => ({ ...breadcrumb, data: hint.data })); const options = getDefaultTestClientOptions({ beforeBreadcrumb }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); @@ -241,7 +229,7 @@ describe('BaseClient', () => { describe('captureException', () => { test('captures and sends exceptions', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureException(new Error('test exception')); @@ -264,7 +252,7 @@ describe('BaseClient', () => { test('allows for providing explicit scope', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -292,7 +280,7 @@ describe('BaseClient', () => { test('allows for clearing data from existing scope if explicit one does so in a callback function', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -327,7 +315,7 @@ describe('BaseClient', () => { // is encountered, so this test doesn't apply. ])("doesn't capture the same exception twice - %s", (_name: string, thrown: any) => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); expect(thrown.__sentry_captured__).toBeUndefined(); @@ -346,7 +334,7 @@ describe('BaseClient', () => { describe('captureMessage', () => { test('captures and sends messages', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureMessage('test message'); @@ -363,7 +351,7 @@ describe('BaseClient', () => { test('should call eventFromException if input to captureMessage is not a primitive', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const spy = jest.spyOn(TestClient.instance!, 'eventFromException'); client.captureMessage('foo'); @@ -382,7 +370,7 @@ describe('BaseClient', () => { test('allows for providing explicit scope', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.setExtra('foo', 'wat'); @@ -416,7 +404,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ enabled: false, dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({}, undefined, scope); @@ -428,7 +416,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({}); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({}, undefined, scope); @@ -449,7 +437,7 @@ describe('BaseClient', () => { // Note: this is the same test as in `describe(captureException)`, except with the exception already wrapped in a // hint and accompanying an event. Duplicated here because some methods skip `captureException` and go straight to // `captureEvent`. - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const event = { exception: { values: [{ type: 'Error', message: 'Will I get caught twice?' }] } }; const hint = { originalException: thrown }; @@ -470,7 +458,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -490,7 +478,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message', timestamp: 1234 }, undefined, scope); @@ -510,7 +498,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope); @@ -529,7 +517,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -548,7 +536,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ environment: 'env', dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -567,7 +555,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, environment: undefined }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -586,7 +574,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, release: 'v1.0.0' }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); client.captureEvent({ message: 'message' }, undefined, scope); @@ -606,7 +594,7 @@ describe('BaseClient', () => { expect.assertions(4); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.addBreadcrumb({ message: 'breadcrumb' }, 100); @@ -622,7 +610,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, maxBreadcrumbs: 1 }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); const hub = new Hub(client, scope); hub.addBreadcrumb({ message: '1' }); @@ -638,7 +626,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.setExtra('b', 'b'); scope.setTag('a', 'a'); @@ -663,7 +651,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const scope = new Scope(); scope.setFingerprint(['abcd']); @@ -682,7 +670,7 @@ describe('BaseClient', () => { test('adds installed integrations to sdk info', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.setupIntegrations(); client.captureEvent({ message: 'message' }); @@ -696,7 +684,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const fourLevelsObject = { a: { b: { @@ -748,7 +736,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, normalizeDepth: 2 }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const fourLevelsObject = { a: { b: { @@ -797,7 +785,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, normalizeDepth: 0 }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const fourLevelsObject = { a: { b: { @@ -851,7 +839,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const transaction: Event = { contexts: { trace: { @@ -926,7 +914,7 @@ describe('BaseClient', () => { const beforeSend = jest.fn(event => event); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }); @@ -938,7 +926,7 @@ describe('BaseClient', () => { const beforeSend = jest.fn(() => ({ message: 'changed1' })); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }); @@ -950,7 +938,7 @@ describe('BaseClient', () => { const beforeSend = jest.fn(() => null); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); @@ -969,7 +957,7 @@ describe('BaseClient', () => { const beforeSend = jest.fn(() => val); // @ts-ignore we need to test regular-js behavior const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const loggerErrorSpy = jest.spyOn(logger, 'error'); client.captureEvent({ message: 'hello' }); @@ -994,7 +982,7 @@ describe('BaseClient', () => { }), ); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); @@ -1023,7 +1011,7 @@ describe('BaseClient', () => { }), ); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }); jest.runOnlyPendingTimers(); @@ -1052,7 +1040,7 @@ describe('BaseClient', () => { }), ); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }); jest.runAllTimers(); @@ -1065,7 +1053,7 @@ describe('BaseClient', () => { const beforeSend = jest.fn((event, hint) => ({ ...event, data: hint.data })); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSend }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.captureEvent({ message: 'hello' }, { data: 'someRandomThing' }); @@ -1073,38 +1061,35 @@ describe('BaseClient', () => { expect((TestClient.instance!.event! as any).data).toBe('someRandomThing'); }); - test('beforeSend records dropped events', () => { - expect.assertions(1); + // TODO(v7): Add back test with client reports + // test('beforeSend records dropped events', () => { + // expect.assertions(1); - const client = new TestClient( - getDefaultTestClientOptions({ - dsn: PUBLIC_DSN, - beforeSend() { - return null; - }, - }), - setupTestTransport(getDefaultTestClientOptions({ dsn: PUBLIC_DSN })).transport, - ); - const recordLostEventSpy = jest.fn(); - jest.spyOn(client, 'getTransport').mockImplementationOnce( - () => - ({ - recordLostEvent: recordLostEventSpy, - } as any as Transport), - ); + // const client = new TestClient( + // getDefaultTestClientOptions({ + // dsn: PUBLIC_DSN, + // beforeSend() { + // return null; + // }, + // }), + // ); + // const recordLostEventSpy = jest.fn(); + // jest.spyOn(client, 'getTransport').mockImplementationOnce( + // () => + // ({ + // recordLostEvent: recordLostEventSpy, + // } as any as Transport), + // ); - client.captureEvent({ message: 'hello' }, {}); + // client.captureEvent({ message: 'hello' }, {}); - expect(recordLostEventSpy).toHaveBeenCalledWith('before_send', 'event'); - }); + // expect(recordLostEventSpy).toHaveBeenCalledWith('before_send', 'event'); + // }); test('eventProcessor can drop the even when it returns null', () => { expect.assertions(3); - const client = new TestClient( - getDefaultTestClientOptions({ dsn: PUBLIC_DSN }), - setupTestTransport(getDefaultTestClientOptions({ dsn: PUBLIC_DSN })).transport, - ); + const client = new TestClient(getDefaultTestClientOptions({ dsn: PUBLIC_DSN })); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); const scope = new Scope(); @@ -1117,33 +1102,34 @@ describe('BaseClient', () => { expect(loggerErrorSpy).toBeCalledWith(new SentryError('An event processor returned null, will not send event.')); }); - test('eventProcessor records dropped events', () => { - expect.assertions(1); + // TODO(v7): Add back tests with client reports + // test('eventProcessor records dropped events', () => { + // expect.assertions(1); - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); - - const recordLostEventSpy = jest.fn(); - jest.spyOn(client, 'getTransport').mockImplementationOnce( - () => - ({ - recordLostEvent: recordLostEventSpy, - } as any as Transport), - ); + // const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + // const client = new TestClient(options); - const scope = new Scope(); - scope.addEventProcessor(() => null); + // const recordLostEventSpy = jest.fn(); + // jest.spyOn(client, 'getTransport').mockImplementationOnce( + // () => + // ({ + // recordLostEvent: recordLostEventSpy, + // } as any as Transport), + // ); - client.captureEvent({ message: 'hello' }, {}, scope); + // const scope = new Scope(); + // scope.addEventProcessor(() => null); - expect(recordLostEventSpy).toHaveBeenCalledWith('event_processor', 'event'); - }); + // client.captureEvent({ message: 'hello' }, {}, scope); + + // expect(recordLostEventSpy).toHaveBeenCalledWith('event_processor', 'event'); + // }); test('eventProcessor sends an event and logs when it crashes', () => { expect.assertions(3); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const captureExceptionSpy = jest.spyOn(client, 'captureException'); const loggerErrorSpy = jest.spyOn(logger, 'error'); const scope = new Scope(); @@ -1168,23 +1154,24 @@ describe('BaseClient', () => { ); }); - test('records events dropped due to sampleRate', () => { - expect.assertions(1); + // TODO(v7): Add back test with client reports + // test('records events dropped due to sampleRate', () => { + // expect.assertions(1); - const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, sampleRate: 0 }); - const client = new TestClient(options, setupTestTransport(options).transport); + // const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, sampleRate: 0 }); + // const client = new TestClient(options); - const recordLostEventSpy = jest.fn(); - jest.spyOn(client, 'getTransport').mockImplementationOnce( - () => - ({ - recordLostEvent: recordLostEventSpy, - } as any as Transport), - ); + // const recordLostEventSpy = jest.fn(); + // jest.spyOn(client, 'getTransport').mockImplementationOnce( + // () => + // ({ + // recordLostEvent: recordLostEventSpy, + // } as any as Transport), + // ); - client.captureEvent({ message: 'hello' }, {}); - expect(recordLostEventSpy).toHaveBeenCalledWith('sample_rate', 'event'); - }); + // client.captureEvent({ message: 'hello' }, {}); + // expect(recordLostEventSpy).toHaveBeenCalledWith('sample_rate', 'event'); + // }); }); describe('integrations', () => { @@ -1196,7 +1183,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(1); @@ -1207,7 +1194,7 @@ describe('BaseClient', () => { expect.assertions(2); const options = getDefaultTestClientOptions({ integrations: [new TestIntegration()] }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(0); @@ -1222,7 +1209,7 @@ describe('BaseClient', () => { enabled: false, integrations: [new TestIntegration()], }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); client.setupIntegrations(); expect(Object.keys((client as any)._integrations).length).toBe(0); @@ -1233,7 +1220,7 @@ describe('BaseClient', () => { expect.assertions(4); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations: [new TestIntegration()] }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); // note: not the `Client` method `setupIntegrations`, but the free-standing function which that method calls const setupIntegrationsHelper = jest.spyOn(integrationModule, 'setupIntegrations'); @@ -1254,47 +1241,43 @@ describe('BaseClient', () => { describe('flush/close', () => { test('flush', async () => { jest.useRealTimers(); - expect.assertions(5); + expect.assertions(4); + + const { makeTransport, getSendCalled, getSentCount, delay } = makeFakeTransport(1); const client = new TestClient( getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, - transport: FakeTransport, + transport: makeTransport, }), - new FakeTransport(), ); - const delay = 1; - const transportInstance = client.getTransport() as FakeTransport; - transportInstance.delay = delay; - client.captureMessage('test'); - expect(transportInstance).toBeInstanceOf(FakeTransport); - expect(transportInstance.sendCalled).toEqual(1); - expect(transportInstance.sentCount).toEqual(0); + expect(getSendCalled()).toEqual(1); + expect(getSentCount()).toEqual(0); await client.flush(delay); - expect(transportInstance.sentCount).toEqual(1); - expect(transportInstance.sendCalled).toEqual(1); + expect(getSentCount()).toEqual(1); + expect(getSendCalled()).toEqual(1); }); test('flush with some events being processed async', async () => { jest.useRealTimers(); - expect.assertions(5); + expect.assertions(4); + + const { makeTransport, getSendCalled, getSentCount, delay } = makeFakeTransport(300); const client = new TestClient( getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, - transport: FakeTransport, + transport: makeTransport, }), - new FakeTransport(), ); - const delay = 300; const spy = jest.spyOn(TestClient.instance!, 'eventFromMessage'); spy.mockImplementationOnce( (message, level) => @@ -1302,20 +1285,16 @@ describe('BaseClient', () => { setTimeout(() => resolve({ message, level }), 150); }), ); - const transportInstance = client.getTransport() as FakeTransport; - transportInstance.delay = delay; - client.captureMessage('test async'); client.captureMessage('test non-async'); - expect(transportInstance).toBeInstanceOf(FakeTransport); - expect(transportInstance.sendCalled).toEqual(1); - expect(transportInstance.sentCount).toEqual(0); + expect(getSendCalled()).toEqual(1); + expect(getSentCount()).toEqual(0); await client.flush(delay); - expect(transportInstance.sentCount).toEqual(2); - expect(transportInstance.sendCalled).toEqual(2); + expect(getSentCount()).toEqual(2); + expect(getSendCalled()).toEqual(2); spy.mockRestore(); }); @@ -1324,19 +1303,15 @@ describe('BaseClient', () => { jest.useRealTimers(); expect.assertions(2); + const { makeTransport, delay } = makeFakeTransport(300); + const client = new TestClient( getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableSend: true, - transport: FakeTransport, + transport: makeTransport, }), - new FakeTransport(), ); - - const delay = 1; - const transportInstance = client.getTransport() as FakeTransport; - transportInstance.delay = delay; - expect(client.captureMessage('test')).toBeTruthy(); await client.close(delay); @@ -1350,7 +1325,7 @@ describe('BaseClient', () => { expect.assertions(3); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); return Promise.all([ client.flush(1).then(() => { @@ -1371,7 +1346,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const session = new Session({ release: 'test' }); client.captureSession(session); @@ -1383,7 +1358,7 @@ describe('BaseClient', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ enabled: false, dsn: PUBLIC_DSN }); - const client = new TestClient(options, setupTestTransport(options).transport); + const client = new TestClient(options); const session = new Session({ release: 'test' }); client.captureSession(session); diff --git a/packages/core/test/lib/sdk.test.ts b/packages/core/test/lib/sdk.test.ts index 7dd3229c5c7e..d2857a2d83bd 100644 --- a/packages/core/test/lib/sdk.test.ts +++ b/packages/core/test/lib/sdk.test.ts @@ -3,7 +3,7 @@ import { Client, Integration } from '@sentry/types'; import { installedIntegrations } from '../../src/integration'; import { initAndBind } from '../../src/sdk'; -import { getDefaultTestClientOptions, setupTestTransport, TestClient } from '../mocks/client'; +import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; // eslint-disable-next-line no-var declare var global: any; @@ -56,7 +56,7 @@ describe('SDK', () => { new MockIntegration('MockIntegration 2'), ]; const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, integrations }); - initAndBind(TestClient, options, setupTestTransport(options).transport); + initAndBind(TestClient, options); expect((integrations[0].setupOnce as jest.Mock).mock.calls.length).toBe(1); expect((integrations[1].setupOnce as jest.Mock).mock.calls.length).toBe(1); }); diff --git a/packages/core/test/lib/transports/base.test.ts b/packages/core/test/lib/transports/base.test.ts index 2257a67165b1..78b40d0a4f7c 100644 --- a/packages/core/test/lib/transports/base.test.ts +++ b/packages/core/test/lib/transports/base.test.ts @@ -1,14 +1,11 @@ -import { EventEnvelope, EventItem } from '@sentry/types'; +import { EventEnvelope, EventItem, NewTransport, TransportMakeRequestResponse, TransportResponse } from '@sentry/types'; import { createEnvelope, PromiseBuffer, resolvedSyncPromise, serializeEnvelope } from '@sentry/utils'; -import { - createTransport, - ERROR_TRANSPORT_CATEGORY, - NewTransport, - TRANSACTION_TRANSPORT_CATEGORY, - TransportMakeRequestResponse, - TransportResponse, -} from '../../../src/transports/base'; +import { createTransport } from '../../../src/transports/base'; + +const ERROR_TRANSPORT_CATEGORY = 'error'; + +const TRANSACTION_TRANSPORT_CATEGORY = 'transaction'; const ERROR_ENVELOPE = createEnvelope({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, [ [{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }] as EventItem, diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 5778dcf5e193..9f02e5b6540d 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,16 +1,15 @@ import { Session } from '@sentry/hub'; -import { ClientOptions, Event, Integration, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { ClientOptions, Event, Integration, Severity, SeverityLevel } from '@sentry/types'; import { resolvedSyncPromise } from '@sentry/utils'; import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; -import { NewTransport } from '../../src/transports/base'; -import { NoopTransport } from '../../src/transports/noop'; +import { createTransport } from '../../src/transports/base'; export function getDefaultTestClientOptions(options: Partial = {}): TestClientOptions { return { integrations: [], - transport: NoopTransport, + transport: () => createTransport({}, _ => resolvedSyncPromise({ statusCode: 200 })), stackParser: () => [], ...options, }; @@ -30,8 +29,8 @@ export class TestClient extends BaseClient { public event?: Event; public session?: Session; - public constructor(options: TestClientOptions, transport: Transport, newTransport?: NewTransport) { - super(options, transport, newTransport); + public constructor(options: TestClientOptions) { + super(options); TestClient.instance = this; } @@ -74,23 +73,6 @@ export class TestClient extends BaseClient { } } -export function init(options: TestClientOptions, transport: Transport, newTransport?: NewTransport): void { - initAndBind(TestClient, options, transport, newTransport); -} - -export function setupTestTransport(options: TestClientOptions): { transport: Transport; newTransport?: NewTransport } { - const noop = { transport: new NoopTransport() }; - - if (!options.dsn) { - // We return the noop transport here in case there is no Dsn. - return noop; - } - - const transportOptions = options.transportOptions ? options.transportOptions : { dsn: options.dsn }; - - if (options.transport) { - return { transport: new options.transport(transportOptions) }; - } - - return noop; +export function init(options: TestClientOptions): void { + initAndBind(TestClient, options); } diff --git a/packages/core/test/mocks/transport.ts b/packages/core/test/mocks/transport.ts index 1037fada987d..c7fdb02e558a 100644 --- a/packages/core/test/mocks/transport.ts +++ b/packages/core/test/mocks/transport.ts @@ -1,31 +1,22 @@ -import { Event, Response, Transport } from '@sentry/types'; -import { makePromiseBuffer, PromiseBuffer, SyncPromise } from '@sentry/utils'; +import { SyncPromise } from '@sentry/utils'; + +import { createTransport } from '../../src/transports/base'; async function sleep(delay: number): Promise { return new SyncPromise(resolve => setTimeout(resolve, delay)); } -export class FakeTransport implements Transport { - public sendCalled: number = 0; - public sentCount: number = 0; - public delay: number = 2000; - - /** A simple buffer holding all requests. */ - protected readonly _buffer: PromiseBuffer = makePromiseBuffer(9999); - - public sendEvent(_event: Event): PromiseLike { - this.sendCalled += 1; - return this._buffer.add( - () => - new SyncPromise(async res => { - await sleep(this.delay); - this.sentCount += 1; - res({ status: 'success' }); - }), - ); - } - - public close(timeout?: number): PromiseLike { - return this._buffer.drain(timeout); - } +export function makeFakeTransport(delay: number = 2000) { + let sendCalled = 0; + let sentCount = 0; + const makeTransport = () => + createTransport({}, () => { + sendCalled += 1; + return new SyncPromise(async res => { + await sleep(delay); + sentCount += 1; + res({ statusCode: 200 }); + }); + }); + return { makeTransport, getSendCalled: () => sendCalled, getSentCount: () => sentCount, delay }; } diff --git a/packages/ember/tests/dummy/app/app.js b/packages/ember/tests/dummy/app/app.js index 25a843863e69..3479bd41f315 100644 --- a/packages/ember/tests/dummy/app/app.js +++ b/packages/ember/tests/dummy/app/app.js @@ -4,25 +4,7 @@ import loadInitializers from 'ember-load-initializers'; import config from './config/environment'; import * as Sentry from '@sentry/ember'; -import { Transports } from '@sentry/browser'; -import Ember from 'ember'; - -class TestFetchTransport extends Transports.FetchTransport { - sendEvent(event) { - if (Ember.testing) { - if (!window._sentryTestEvents) { - window._sentryTestEvents = []; - } - window._sentryTestEvents.push(event); - return Promise.resolve(); - } - return super.sendEvent(event); - } -} - -Sentry.init({ - transport: TestFetchTransport, -}); +Sentry.init(); export default class App extends Application { modulePrefix = config.modulePrefix; diff --git a/packages/ember/tests/test-helper.js b/packages/ember/tests/test-helper.js index eae0acb0b24e..da7c45929c8f 100644 --- a/packages/ember/tests/test-helper.js +++ b/packages/ember/tests/test-helper.js @@ -10,30 +10,17 @@ import Application from '../app'; import config from '../config/environment'; import { setApplication } from '@ember/test-helpers'; import { start } from 'ember-qunit'; -import { Transports } from '@sentry/browser'; import Ember from 'ember'; -import { getConfig } from '@embroider/macros'; - -function getSentryConfig() { - return getConfig('@sentry/ember').sentryConfig; -} - -export class TestFetchTransport extends Transports.FetchTransport { - sendEvent(event) { - if (Ember.testing) { - if (!window._sentryTestEvents) { - window._sentryTestEvents = []; - } - window._sentryTestEvents.push(event); - return Promise.resolve(); +Sentry.addGlobalEventProcessor((event) => { + if (Ember.testing) { + if (!window._sentryTestEvents) { + window._sentryTestEvents = []; } - return super.sendEvent(event); + window._sentryTestEvents.push(event); } -} - -const sentryConfig = getSentryConfig(); -sentryConfig.sentry['transport'] = TestFetchTransport; + return event; +}); setApplication(Application.create(config.APP)); diff --git a/packages/hub/src/sessionflusher.ts b/packages/hub/src/sessionflusher.ts index fcc4386c70d8..7b2bda98c4da 100644 --- a/packages/hub/src/sessionflusher.ts +++ b/packages/hub/src/sessionflusher.ts @@ -1,13 +1,6 @@ -import { - AggregationCounts, - RequestSessionStatus, - SessionAggregates, - SessionFlusherLike, - Transport, -} from '@sentry/types'; -import { dropUndefinedKeys, logger } from '@sentry/utils'; +import { AggregationCounts, Client, RequestSessionStatus, SessionAggregates, SessionFlusherLike } from '@sentry/types'; +import { dropUndefinedKeys } from '@sentry/utils'; -import { IS_DEBUG_BUILD } from './flags'; import { getCurrentHub } from './hub'; type ReleaseHealthAttributes = { @@ -24,34 +17,23 @@ export class SessionFlusher implements SessionFlusherLike { private _sessionAttrs: ReleaseHealthAttributes; private _intervalId: ReturnType; private _isEnabled: boolean = true; - private _transport: Transport; + private _client: Client; - public constructor(transport: Transport, attrs: ReleaseHealthAttributes) { - this._transport = transport; + public constructor(client: Client, attrs: ReleaseHealthAttributes) { + this._client = client; // Call to setInterval, so that flush is called every 60 seconds this._intervalId = setInterval(() => this.flush(), this.flushTimeout * 1000); this._sessionAttrs = attrs; } - /** Sends session aggregates to Transport */ - public sendSessionAggregates(sessionAggregates: SessionAggregates): void { - if (!this._transport.sendSession) { - IS_DEBUG_BUILD && logger.warn("Dropping session because custom transport doesn't implement sendSession"); - return; - } - void this._transport.sendSession(sessionAggregates).then(null, reason => { - IS_DEBUG_BUILD && logger.error('Error while sending session:', reason); - }); - } - - /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSessions` */ + /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSession` */ public flush(): void { const sessionAggregates = this.getSessionAggregates(); if (sessionAggregates.aggregates.length === 0) { return; } this._pendingAggregates = {}; - this.sendSessionAggregates(sessionAggregates); + this._client.sendSession(sessionAggregates); } /** Massages the entries in `pendingAggregates` and returns aggregated sessions */ diff --git a/packages/hub/test/sessionflusher.test.ts b/packages/hub/test/sessionflusher.test.ts index 3c7dc9782615..58ce3ee374ce 100644 --- a/packages/hub/test/sessionflusher.test.ts +++ b/packages/hub/test/sessionflusher.test.ts @@ -1,21 +1,17 @@ +import { Client } from '@sentry/types'; + import { SessionFlusher } from '../src/sessionflusher'; describe('Session Flusher', () => { let sendSession: jest.Mock; - let transport: { - sendEvent: jest.Mock; - sendSession: jest.Mock; - close: jest.Mock; - }; + let mockClient: Client; beforeEach(() => { jest.useFakeTimers(); sendSession = jest.fn(() => Promise.resolve({ status: 'success' })); - transport = { - sendEvent: jest.fn(), + mockClient = { sendSession, - close: jest.fn(), - }; + } as unknown as Client; }); afterEach(() => { @@ -23,7 +19,7 @@ describe('Session Flusher', () => { }); test('test incrementSessionStatusCount updates the internal SessionFlusher state', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.0', environment: 'dev' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.0', environment: 'dev' }); const date = new Date('2021-04-08T12:18:23.043Z'); let count = (flusher as any)._incrementSessionStatusCount('ok', date); @@ -46,7 +42,7 @@ describe('Session Flusher', () => { }); test('test undefined attributes are excluded, on incrementSessionStatusCount call', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.0' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.0' }); const date = new Date('2021-04-08T12:18:23.043Z'); (flusher as any)._incrementSessionStatusCount('ok', date); @@ -59,7 +55,7 @@ describe('Session Flusher', () => { }); test('flush is called every 60 seconds after initialisation of an instance of SessionFlusher', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.0', environment: 'dev' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.0', environment: 'dev' }); const flusherFlushFunc = jest.spyOn(flusher, 'flush'); jest.advanceTimersByTime(59000); expect(flusherFlushFunc).toHaveBeenCalledTimes(0); @@ -72,7 +68,7 @@ describe('Session Flusher', () => { }); test('sendSessions is called on flush if sessions were captured', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.0', environment: 'dev' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.0', environment: 'dev' }); const flusherFlushFunc = jest.spyOn(flusher, 'flush'); const date = new Date('2021-04-08T12:18:23.043Z'); (flusher as any)._incrementSessionStatusCount('ok', date); @@ -92,7 +88,7 @@ describe('Session Flusher', () => { }); test('sendSessions is not called on flush if no sessions were captured', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.0', environment: 'dev' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.0', environment: 'dev' }); const flusherFlushFunc = jest.spyOn(flusher, 'flush'); expect(sendSession).toHaveBeenCalledTimes(0); @@ -102,13 +98,13 @@ describe('Session Flusher', () => { }); test('calling close on SessionFlusher should disable SessionFlusher', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.x' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.x' }); flusher.close(); expect((flusher as any)._isEnabled).toEqual(false); }); test('calling close on SessionFlusher will force call flush', () => { - const flusher = new SessionFlusher(transport, { release: '1.0.x' }); + const flusher = new SessionFlusher(mockClient, { release: '1.0.x' }); const flusherFlushFunc = jest.spyOn(flusher, 'flush'); const date = new Date('2021-04-08T12:18:23.043Z'); (flusher as any)._incrementSessionStatusCount('ok', date); diff --git a/packages/integration-tests/suites/new-transports/fetch-captureException/subject.js b/packages/integration-tests/suites/new-transports/fetch-captureException/subject.js deleted file mode 100644 index 9cc217bdb087..000000000000 --- a/packages/integration-tests/suites/new-transports/fetch-captureException/subject.js +++ /dev/null @@ -1 +0,0 @@ -Sentry.captureException(new Error('this is an error')); diff --git a/packages/integration-tests/suites/new-transports/fetch-captureException/test.ts b/packages/integration-tests/suites/new-transports/fetch-captureException/test.ts deleted file mode 100644 index cb92e50e2dc5..000000000000 --- a/packages/integration-tests/suites/new-transports/fetch-captureException/test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { expect } from '@playwright/test'; -import { Event } from '@sentry/types'; - -import { sentryTest } from '../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; - -sentryTest('should capture an error with the new fetch transport', async ({ getLocalTestPath, page }) => { - const url = await getLocalTestPath({ testDir: __dirname }); - - const eventData = await getFirstSentryEnvelopeRequest(page, url); - - expect(eventData.exception?.values).toHaveLength(1); - expect(eventData.exception?.values?.[0]).toMatchObject({ - type: 'Error', - value: 'this is an error', - mechanism: { - type: 'generic', - handled: true, - }, - }); -}); diff --git a/packages/integration-tests/suites/new-transports/fetch-startTransaction/subject.js b/packages/integration-tests/suites/new-transports/fetch-startTransaction/subject.js deleted file mode 100644 index 78c7c33c654c..000000000000 --- a/packages/integration-tests/suites/new-transports/fetch-startTransaction/subject.js +++ /dev/null @@ -1,2 +0,0 @@ -const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); -transaction.finish(); diff --git a/packages/integration-tests/suites/new-transports/fetch-startTransaction/test.ts b/packages/integration-tests/suites/new-transports/fetch-startTransaction/test.ts deleted file mode 100644 index 8daef2e06b54..000000000000 --- a/packages/integration-tests/suites/new-transports/fetch-startTransaction/test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from '@playwright/test'; -import { Event } from '@sentry/types'; - -import { sentryTest } from '../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; - -sentryTest('should report a transaction with the new fetch transport', async ({ getLocalTestPath, page }) => { - const url = await getLocalTestPath({ testDir: __dirname }); - const transaction = await getFirstSentryEnvelopeRequest(page, url); - - expect(transaction.transaction).toBe('test_transaction_1'); - expect(transaction.spans).toBeDefined(); -}); diff --git a/packages/integration-tests/suites/new-transports/init.js b/packages/integration-tests/suites/new-transports/init.js deleted file mode 100644 index 6cc8110c0475..000000000000 --- a/packages/integration-tests/suites/new-transports/init.js +++ /dev/null @@ -1,13 +0,0 @@ -import * as Sentry from '@sentry/browser'; -// eslint-disable-next-line no-unused-vars -import * as _ from '@sentry/tracing'; - -window.Sentry = Sentry; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - _experiments: { - newTransport: true, - }, - tracesSampleRate: 1.0, -}); diff --git a/packages/integration-tests/suites/new-transports/xhr-captureException/subject.js b/packages/integration-tests/suites/new-transports/xhr-captureException/subject.js deleted file mode 100644 index e42102004dad..000000000000 --- a/packages/integration-tests/suites/new-transports/xhr-captureException/subject.js +++ /dev/null @@ -1,4 +0,0 @@ -// deactivate fetch s.t. the SDK falls back to XHR transport -window.fetch = undefined; - -Sentry.captureException(new Error('this is an error')); diff --git a/packages/integration-tests/suites/new-transports/xhr-captureException/test.ts b/packages/integration-tests/suites/new-transports/xhr-captureException/test.ts deleted file mode 100644 index cb92e50e2dc5..000000000000 --- a/packages/integration-tests/suites/new-transports/xhr-captureException/test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { expect } from '@playwright/test'; -import { Event } from '@sentry/types'; - -import { sentryTest } from '../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; - -sentryTest('should capture an error with the new fetch transport', async ({ getLocalTestPath, page }) => { - const url = await getLocalTestPath({ testDir: __dirname }); - - const eventData = await getFirstSentryEnvelopeRequest(page, url); - - expect(eventData.exception?.values).toHaveLength(1); - expect(eventData.exception?.values?.[0]).toMatchObject({ - type: 'Error', - value: 'this is an error', - mechanism: { - type: 'generic', - handled: true, - }, - }); -}); diff --git a/packages/integration-tests/suites/new-transports/xhr-startTransaction/subject.js b/packages/integration-tests/suites/new-transports/xhr-startTransaction/subject.js deleted file mode 100644 index 444e095ed3a1..000000000000 --- a/packages/integration-tests/suites/new-transports/xhr-startTransaction/subject.js +++ /dev/null @@ -1,5 +0,0 @@ -// deactivate fetch s.t. the SDK falls back to XHR transport -window.fetch = undefined; - -const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); -transaction.finish(); diff --git a/packages/integration-tests/suites/new-transports/xhr-startTransaction/test.ts b/packages/integration-tests/suites/new-transports/xhr-startTransaction/test.ts deleted file mode 100644 index 59ddfb00c6a1..000000000000 --- a/packages/integration-tests/suites/new-transports/xhr-startTransaction/test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect } from '@playwright/test'; -import { Event } from '@sentry/types'; - -import { sentryTest } from '../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; - -sentryTest('should report a transaction with the new XHR transport', async ({ getLocalTestPath, page }) => { - const url = await getLocalTestPath({ testDir: __dirname }); - const transaction = await getFirstSentryEnvelopeRequest(page, url); - - expect(transaction.transaction).toBe('test_transaction_1'); - expect(transaction.spans).toBeDefined(); -}); diff --git a/packages/integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts b/packages/integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts index e6e2b9a8f4dd..3fea4283b71e 100644 --- a/packages/integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts +++ b/packages/integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts @@ -1,14 +1,15 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest( 'should add an empty breadcrumb initialized with a timestamp, when an empty object is given', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.breadcrumbs).toHaveLength(1); expect(eventData.breadcrumbs?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts b/packages/integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts index c7bca64aafd5..d864be4f9073 100644 --- a/packages/integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts +++ b/packages/integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should add multiple breadcrumbs', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.breadcrumbs).toHaveLength(2); expect(eventData.breadcrumbs?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts b/packages/integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts index 98e36a254076..224d4dba0932 100644 --- a/packages/integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts +++ b/packages/integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should add a simple breadcrumb', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.breadcrumbs).toHaveLength(1); expect(eventData.breadcrumbs?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts b/packages/integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts index b41f527c58ed..5e5ec669a7dc 100644 --- a/packages/integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts +++ b/packages/integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts @@ -1,14 +1,15 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest( 'should add an empty breadcrumb initialized with a timestamp, when no argument is given', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.breadcrumbs).toHaveLength(1); expect(eventData.breadcrumbs?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/captureException/empty_obj/test.ts b/packages/integration-tests/suites/public-api/captureException/empty_obj/test.ts index 2606b2984d08..a41fdcc6a6e1 100644 --- a/packages/integration-tests/suites/public-api/captureException/empty_obj/test.ts +++ b/packages/integration-tests/suites/public-api/captureException/empty_obj/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should capture an empty object', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.exception?.values).toHaveLength(1); expect(eventData.exception?.values?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/captureException/simple_error/test.ts b/packages/integration-tests/suites/public-api/captureException/simple_error/test.ts index f52e951c20c6..49627e826726 100644 --- a/packages/integration-tests/suites/public-api/captureException/simple_error/test.ts +++ b/packages/integration-tests/suites/public-api/captureException/simple_error/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should capture a simple error with message', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.exception?.values).toHaveLength(1); expect(eventData.exception?.values?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/captureException/undefined_arg/test.ts b/packages/integration-tests/suites/public-api/captureException/undefined_arg/test.ts index 021af6f922f3..52e2ef5c21f8 100644 --- a/packages/integration-tests/suites/public-api/captureException/undefined_arg/test.ts +++ b/packages/integration-tests/suites/public-api/captureException/undefined_arg/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should capture an undefined error when no arguments are provided', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.exception?.values).toHaveLength(1); expect(eventData.exception?.values?.[0]).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/captureMessage/simple_message/test.ts b/packages/integration-tests/suites/public-api/captureMessage/simple_message/test.ts index 7b4b68f228d6..cfd5580653ac 100644 --- a/packages/integration-tests/suites/public-api/captureMessage/simple_message/test.ts +++ b/packages/integration-tests/suites/public-api/captureMessage/simple_message/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should capture a simple message string', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('foo'); expect(eventData.level).toBe('info'); diff --git a/packages/integration-tests/suites/public-api/captureMessage/with_level/test.ts b/packages/integration-tests/suites/public-api/captureMessage/with_level/test.ts index ba8bb18d729a..45eaeca66161 100644 --- a/packages/integration-tests/suites/public-api/captureMessage/with_level/test.ts +++ b/packages/integration-tests/suites/public-api/captureMessage/with_level/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getMultipleSentryRequests } from '../../../../utils/helpers'; +import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; sentryTest('should capture with different severity levels', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const events = await getMultipleSentryRequests(page, 7, url); + const events = await getMultipleSentryEnvelopeRequests(page, 7, { url }); expect(events[0].message).toBe('debug_message'); expect(events[0].level).toBe('debug'); diff --git a/packages/integration-tests/suites/public-api/configureScope/clear_scope/test.ts b/packages/integration-tests/suites/public-api/configureScope/clear_scope/test.ts index 4bbb0faf4c56..8626cf1adf66 100644 --- a/packages/integration-tests/suites/public-api/configureScope/clear_scope/test.ts +++ b/packages/integration-tests/suites/public-api/configureScope/clear_scope/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should clear previously set properties of a scope', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); // TODO: This is to compensate for a temporary debugging hack which adds data the tests aren't anticipating to the // event. The code can be restored to its original form (the commented-out line below) once that hack is diff --git a/packages/integration-tests/suites/public-api/configureScope/set_properties/test.ts b/packages/integration-tests/suites/public-api/configureScope/set_properties/test.ts index d4001c317d05..992dd7c31043 100644 --- a/packages/integration-tests/suites/public-api/configureScope/set_properties/test.ts +++ b/packages/integration-tests/suites/public-api/configureScope/set_properties/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should set different properties of a scope', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('configured_scope'); expect(eventData.user).toMatchObject({ id: 'baz' }); diff --git a/packages/integration-tests/suites/public-api/setContext/multiple_contexts/test.ts b/packages/integration-tests/suites/public-api/setContext/multiple_contexts/test.ts index 96eecdd38662..6d00519cbad4 100644 --- a/packages/integration-tests/suites/public-api/setContext/multiple_contexts/test.ts +++ b/packages/integration-tests/suites/public-api/setContext/multiple_contexts/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should record multiple contexts', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('multiple_contexts'); expect(eventData.contexts).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/setContext/non_serializable_context/test.ts b/packages/integration-tests/suites/public-api/setContext/non_serializable_context/test.ts index fe67bdaff3e7..54fea2c68908 100644 --- a/packages/integration-tests/suites/public-api/setContext/non_serializable_context/test.ts +++ b/packages/integration-tests/suites/public-api/setContext/non_serializable_context/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should normalize non-serializable context', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.contexts?.non_serializable).toMatchObject({}); expect(eventData.message).toBe('non_serializable'); diff --git a/packages/integration-tests/suites/public-api/setContext/simple_context/test.ts b/packages/integration-tests/suites/public-api/setContext/simple_context/test.ts index 05f534888796..a39f838f5b18 100644 --- a/packages/integration-tests/suites/public-api/setContext/simple_context/test.ts +++ b/packages/integration-tests/suites/public-api/setContext/simple_context/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should set a simple context', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('simple_context_object'); expect(eventData.contexts).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/setExtra/multiple_extras/test.ts b/packages/integration-tests/suites/public-api/setExtra/multiple_extras/test.ts index 13d8aa83d9c4..82a2b4ce21e5 100644 --- a/packages/integration-tests/suites/public-api/setExtra/multiple_extras/test.ts +++ b/packages/integration-tests/suites/public-api/setExtra/multiple_extras/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should record multiple extras of different types', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('multiple_extras'); expect(eventData.extra).toMatchObject({ extra_1: { foo: 'bar', baz: { qux: 'quux' } }, extra_2: false }); diff --git a/packages/integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts b/packages/integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts index eaa9d342e4e8..168bfc88e2c5 100644 --- a/packages/integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts +++ b/packages/integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should normalize non-serializable extra', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('non_serializable'); expect(eventData.extra).toMatchObject({}); diff --git a/packages/integration-tests/suites/public-api/setExtra/simple_extra/test.ts b/packages/integration-tests/suites/public-api/setExtra/simple_extra/test.ts index 352b01191e6e..95a6184e95a9 100644 --- a/packages/integration-tests/suites/public-api/setExtra/simple_extra/test.ts +++ b/packages/integration-tests/suites/public-api/setExtra/simple_extra/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should record a simple extra object', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('simple_extra'); expect(eventData.extra).toMatchObject({ simple_extra: { foo: 'bar', baz: { qux: 'quux' } } }); diff --git a/packages/integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts b/packages/integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts index 319afc32255b..641325affa34 100644 --- a/packages/integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts +++ b/packages/integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should set extras from multiple consecutive calls', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('consecutive_calls'); expect(eventData.extra).toMatchObject({ extra: [], Infinity: 2, null: null, obj: { foo: ['bar', 'baz', 1] } }); diff --git a/packages/integration-tests/suites/public-api/setExtras/multiple_extras/test.ts b/packages/integration-tests/suites/public-api/setExtras/multiple_extras/test.ts index 07a43458e94b..1e238739d8a1 100644 --- a/packages/integration-tests/suites/public-api/setExtras/multiple_extras/test.ts +++ b/packages/integration-tests/suites/public-api/setExtras/multiple_extras/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should record an extras object', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('multiple_extras'); expect(eventData.extra).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/setTag/with_non_primitives/test.ts b/packages/integration-tests/suites/public-api/setTag/with_non_primitives/test.ts index 56843d8f6652..e4a1f9b19bd4 100644 --- a/packages/integration-tests/suites/public-api/setTag/with_non_primitives/test.ts +++ b/packages/integration-tests/suites/public-api/setTag/with_non_primitives/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should not accept non-primitive tags', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('non_primitives'); expect(eventData.tags).toMatchObject({}); diff --git a/packages/integration-tests/suites/public-api/setTag/with_primitives/test.ts b/packages/integration-tests/suites/public-api/setTag/with_primitives/test.ts index b3c24a8cd2c9..ba2b648ad913 100644 --- a/packages/integration-tests/suites/public-api/setTag/with_primitives/test.ts +++ b/packages/integration-tests/suites/public-api/setTag/with_primitives/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should set primitive tags', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('primitive_tags'); expect(eventData.tags).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/setTags/with_non_primitives/test.ts b/packages/integration-tests/suites/public-api/setTags/with_non_primitives/test.ts index 56843d8f6652..e4a1f9b19bd4 100644 --- a/packages/integration-tests/suites/public-api/setTags/with_non_primitives/test.ts +++ b/packages/integration-tests/suites/public-api/setTags/with_non_primitives/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should not accept non-primitive tags', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('non_primitives'); expect(eventData.tags).toMatchObject({}); diff --git a/packages/integration-tests/suites/public-api/setTags/with_primitives/test.ts b/packages/integration-tests/suites/public-api/setTags/with_primitives/test.ts index b3c24a8cd2c9..ba2b648ad913 100644 --- a/packages/integration-tests/suites/public-api/setTags/with_primitives/test.ts +++ b/packages/integration-tests/suites/public-api/setTags/with_primitives/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getSentryRequest } from '../../../../utils/helpers'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; sentryTest('should set primitive tags', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getSentryRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); expect(eventData.message).toBe('primitive_tags'); expect(eventData.tags).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/setUser/unset_user/test.ts b/packages/integration-tests/suites/public-api/setUser/unset_user/test.ts index 045b79597b72..2aed7beb60aa 100644 --- a/packages/integration-tests/suites/public-api/setUser/unset_user/test.ts +++ b/packages/integration-tests/suites/public-api/setUser/unset_user/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getMultipleSentryRequests } from '../../../../utils/helpers'; +import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; sentryTest('should unset user', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getMultipleSentryRequests(page, 3, url); + const eventData = await getMultipleSentryEnvelopeRequests(page, 3, { url }); expect(eventData[0].message).toBe('no_user'); expect(eventData[0].user).toBeUndefined(); diff --git a/packages/integration-tests/suites/public-api/setUser/update_user/test.ts b/packages/integration-tests/suites/public-api/setUser/update_user/test.ts index 1520655c8363..fa846f0221c2 100644 --- a/packages/integration-tests/suites/public-api/setUser/update_user/test.ts +++ b/packages/integration-tests/suites/public-api/setUser/update_user/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getMultipleSentryRequests } from '../../../../utils/helpers'; +import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; sentryTest('should update user', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getMultipleSentryRequests(page, 2, url); + const eventData = await getMultipleSentryEnvelopeRequests(page, 2, { url }); expect(eventData[0].message).toBe('first_user'); expect(eventData[0].user).toMatchObject({ diff --git a/packages/integration-tests/suites/public-api/withScope/nested_scopes/test.ts b/packages/integration-tests/suites/public-api/withScope/nested_scopes/test.ts index 7175eb10ae52..1cc024e799fc 100644 --- a/packages/integration-tests/suites/public-api/withScope/nested_scopes/test.ts +++ b/packages/integration-tests/suites/public-api/withScope/nested_scopes/test.ts @@ -1,12 +1,13 @@ import { expect } from '@playwright/test'; +import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getMultipleSentryRequests } from '../../../../utils/helpers'; +import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; sentryTest('should allow nested scoping', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getMultipleSentryRequests(page, 5, url); + const eventData = await getMultipleSentryEnvelopeRequests(page, 5, { url }); expect(eventData[0].message).toBe('root_before'); expect(eventData[0].user).toMatchObject({ id: 'qux' }); diff --git a/packages/integration-tests/suites/tracing/request/fetch/test.ts b/packages/integration-tests/suites/tracing/request/fetch/test.ts index 77db6f8c18aa..88bbeaf2c00d 100644 --- a/packages/integration-tests/suites/tracing/request/fetch/test.ts +++ b/packages/integration-tests/suites/tracing/request/fetch/test.ts @@ -2,24 +2,36 @@ import { expect, Request } from '@playwright/test'; import { Event } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; +import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; sentryTest('should create spans for multiple fetch requests', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - const requestSpans = eventData.spans?.filter(({ op }) => op === 'http.client'); + // Because we fetch from http://example.com, fetch will throw a CORS error in firefox and webkit. + // Chromium does not throw for cors errors. + // This means that we will intercept a dynamic amount of envelopes here. + + // We will wait 500ms for all envelopes to be sent. Generally, in all browsers, the last sent + // envelope contains tracing data. + + // If we are on FF or webkit: + // 1st envelope contains CORS error + // 2nd envelope contains the tracing data we want to check here + const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, { url, timeout: 10000 }); + const tracingEvent = envelopes[envelopes.length - 1]; // last envelope contains tracing data on all browsers + + const requestSpans = tracingEvent.spans?.filter(({ op }) => op === 'http.client'); expect(requestSpans).toHaveLength(3); requestSpans?.forEach((span, index) => expect(span).toMatchObject({ description: `GET http://example.com/${index}`, - parent_span_id: eventData.contexts?.trace.span_id, + parent_span_id: tracingEvent.contexts?.trace.span_id, span_id: expect.any(String), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: eventData.contexts?.trace.trace_id, + trace_id: tracingEvent.contexts?.trace.trace_id, }), ); }); diff --git a/packages/integration-tests/utils/helpers.ts b/packages/integration-tests/utils/helpers.ts index 5218dc02c27c..8f6e06b97d5a 100644 --- a/packages/integration-tests/utils/helpers.ts +++ b/packages/integration-tests/utils/helpers.ts @@ -1,10 +1,8 @@ import { Page, Request } from '@playwright/test'; import { Event } from '@sentry/types'; -const storeUrlRegex = /\.sentry\.io\/api\/\d+\/store\//; const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//; -const storeRequestParser = (request: Request | null): Event => JSON.parse((request && request.postData()) || ''); const envelopeRequestParser = (request: Request | null): Event => { // https://develop.sentry.dev/sdk/envelopes/ const envelope = request?.postData() || ''; @@ -24,17 +22,6 @@ async function runScriptInSandbox(page: Page, path: string): Promise { await page.addScriptTag({ path }); } -/** - * Wait and get Sentry's request sending the event at the given URL, or the current page - * - * @param {Page} page - * @param {string} [url] - * @return {*} {Promise} - */ -async function getSentryRequest(page: Page, url?: string): Promise { - return (await getMultipleSentryRequests(page, 1, url))[0]; -} - /** * Get Sentry events at the given URL, or the current page. * @@ -52,27 +39,26 @@ async function getSentryEvents(page: Page, url?: string): Promise> } /** - * Wait and get multiple requests matching urlRgx at the given URL, or the current page - * - * @param {Page} page - * @param {number} count - * @param {RegExp} urlRgx - * @param {(req: Request) => Event} requestParser - * @param {string} [url] - * @return {*} {Promise} + * Waits until a number of requests matching urlRgx at the given URL arrive. + * If the timout option is configured, this function will abort waiting, even if it hasn't reveived the configured + * amount of requests, and returns all the events recieved up to that point in time. */ async function getMultipleRequests( page: Page, count: number, urlRgx: RegExp, requestParser: (req: Request) => Event, - url?: string, + options?: { + url?: string; + timeout?: number; + }, ): Promise { const requests: Promise = new Promise((resolve, reject) => { let reqCount = count; const requestData: Event[] = []; + let timeoutId: NodeJS.Timeout | undefined = undefined; - page.on('request', request => { + function requestHandler(request: Request): void { if (urlRgx.test(request.url())) { try { reqCount -= 1; @@ -98,47 +84,48 @@ async function getMultipleRequests( // requestData.push(requestParser(request)); if (reqCount === 0) { + if (timeoutId) { + clearTimeout(timeoutId); + } + page.off('request', requestHandler); resolve(requestData); } } catch (err) { reject(err); } } - }); + } + + page.on('request', requestHandler); + + if (options?.timeout) { + timeoutId = setTimeout(() => { + resolve(requestData); + }, options.timeout); + } }); - if (url) { - await page.goto(url); + if (options?.url) { + await page.goto(options.url); } return requests; } -/** - * Wait and get multiple event requests at the given URL, or the current page - * - * @param {Page} page - * @param {number} count - * @param {string} [url] - * @return {*} {Promise} - */ -async function getMultipleSentryRequests(page: Page, count: number, url?: string): Promise { - return getMultipleRequests(page, count, storeUrlRegex, storeRequestParser, url); -} - /** * Wait and get multiple envelope requests at the given URL, or the current page - * - * @template T - * @param {Page} page - * @param {number} count - * @param {string} [url] - * @return {*} {Promise} */ -async function getMultipleSentryEnvelopeRequests(page: Page, count: number, url?: string): Promise { +async function getMultipleSentryEnvelopeRequests( + page: Page, + count: number, + options?: { + url?: string; + timeout?: number; + }, +): Promise { // TODO: This is not currently checking the type of envelope, just casting for now. // We can update this to include optional type-guarding when we have types for Envelope. - return getMultipleRequests(page, count, envelopeUrlRegex, envelopeRequestParser, url) as Promise; + return getMultipleRequests(page, count, envelopeUrlRegex, envelopeRequestParser, options) as Promise; } /** @@ -150,7 +137,7 @@ async function getMultipleSentryEnvelopeRequests(page: Page, count: number, u * @return {*} {Promise} */ async function getFirstSentryEnvelopeRequest(page: Page, url?: string): Promise { - return (await getMultipleSentryEnvelopeRequests(page, 1, url))[0]; + return (await getMultipleSentryEnvelopeRequests(page, 1, { url }))[0]; } /** @@ -172,10 +159,8 @@ async function injectScriptAndGetEvents(page: Page, url: string, scriptPath: str export { runScriptInSandbox, - getMultipleSentryRequests, getMultipleSentryEnvelopeRequests, getFirstSentryEnvelopeRequest, - getSentryRequest, getSentryEvents, injectScriptAndGetEvents, }; diff --git a/packages/nextjs/test/index.client.test.ts b/packages/nextjs/test/index.client.test.ts index 44edf997ef50..5d7053c00def 100644 --- a/packages/nextjs/test/index.client.test.ts +++ b/packages/nextjs/test/index.client.test.ts @@ -68,12 +68,12 @@ describe('Client init()', () => { tracesSampleRate: 1.0, }); const hub = getCurrentHub(); - const sendEvent = jest.spyOn(hub.getClient()!.getTransport!(), 'sendEvent'); + const transportSend = jest.spyOn(hub.getClient()!.getTransport()!, 'send'); const transaction = hub.startTransaction({ name: '/404' }); transaction.finish(); - expect(sendEvent).not.toHaveBeenCalled(); + expect(transportSend).not.toHaveBeenCalled(); expect(captureEvent.mock.results[0].value).toBeUndefined(); expect(logError).toHaveBeenCalledWith(new SentryError('An event processor returned null, will not send event.')); }); diff --git a/packages/nextjs/test/index.server.test.ts b/packages/nextjs/test/index.server.test.ts index e4e359a10624..477ad252cd29 100644 --- a/packages/nextjs/test/index.server.test.ts +++ b/packages/nextjs/test/index.server.test.ts @@ -95,7 +95,7 @@ describe('Server init()', () => { tracesSampleRate: 1.0, }); const hub = getCurrentHub(); - const sendEvent = jest.spyOn(hub.getClient()!.getTransport!(), 'sendEvent'); + const transportSend = jest.spyOn(hub.getClient()!.getTransport()!, 'send'); const transaction = hub.startTransaction({ name: '/404' }); transaction.finish(); @@ -103,7 +103,7 @@ describe('Server init()', () => { // We need to flush because the event processor pipeline is async whereas transaction.finish() is sync. await SentryNode.flush(); - expect(sendEvent).not.toHaveBeenCalled(); + expect(transportSend).not.toHaveBeenCalled(); expect(logError).toHaveBeenCalledWith(new SentryError('An event processor returned null, will not send event.')); }); diff --git a/packages/nextjs/test/integration/test/utils/client.js b/packages/nextjs/test/integration/test/utils/client.js index d2c11837db3d..76d88832c863 100644 --- a/packages/nextjs/test/integration/test/utils/client.js +++ b/packages/nextjs/test/integration/test/utils/client.js @@ -20,7 +20,7 @@ const createRequestInterceptor = env => { } if (isEventRequest(request)) { - logIf(process.env.LOG_REQUESTS, 'Intercepted Event', extractEventFromRequest(request), env.argv.depth); + logIf(process.env.LOG_REQUESTS, 'Intercepted Event', extractEnvelopeFromRequest(request), env.argv.depth); env.requests.events.push(request); } else if (isSessionRequest(request)) { logIf(process.env.LOG_REQUESTS, 'Intercepted Session', extractEnvelopeFromRequest(request), env.argv.depth); @@ -38,14 +38,14 @@ const isSentryRequest = request => { return /sentry.io\/api/.test(request.url()); }; -const isEventRequest = request => { - return /sentry.io\/api\/\d+\/store/.test(request.url()); -}; - const isEnvelopeRequest = request => { return /sentry.io\/api\/\d+\/envelope/.test(request.url()); }; +const isEventRequest = request => { + return isEnvelopeRequest(request) && extractEnvelopeFromRequest(request).itemHeader.type === 'event'; +}; + const isSessionRequest = request => { return isEnvelopeRequest(request) && extractEnvelopeFromRequest(request).itemHeader.type === 'session'; }; @@ -54,21 +54,25 @@ const isTransactionRequest = request => { return isEnvelopeRequest(request) && extractEnvelopeFromRequest(request).itemHeader.type === 'transaction'; }; -const expectEvent = (request, expectedEvent) => { +const expectEvent = (request, expectedItem) => { if (!request) throw new Error('Event missing'); - return assertObjectMatches(extractEventFromRequest(request), expectedEvent); + const { itemHeader, item } = extractEnvelopeFromRequest(request); + strictEqual(itemHeader.type, 'event'); + assertObjectMatches(item, expectedItem); }; const expectSession = (request, expectedItem) => { if (!request) throw new Error('Session missing'); const { itemHeader, item } = extractEnvelopeFromRequest(request); - return itemHeader.type === 'session' && assertObjectMatches(item, expectedItem); + strictEqual(itemHeader.type, 'session'); + assertObjectMatches(item, expectedItem); }; const expectTransaction = (request, expectedItem) => { if (!request) throw new Error('Transaction missing'); const { itemHeader, item } = extractEnvelopeFromRequest(request); - return itemHeader.type === 'transaction' && assertObjectMatches(item, expectedItem); + strictEqual(itemHeader.type, 'transaction'); + assertObjectMatches(item, expectedItem); }; const expectRequestCount = (requests, expectedCount, timeout = 100) => { @@ -89,10 +93,6 @@ const expectRequestCount = (requests, expectedCount, timeout = 100) => { }); }; -const extractEventFromRequest = request => { - return JSON.parse(request.postData()); -}; - const extractEnvelopeFromRequest = request => { return parseEnvelope(request.postData()); }; @@ -111,8 +111,6 @@ const assertObjectMatches = (actual, expected) => { strictEqual(actual[key], expectedValue); } } - - return true; }; module.exports = { @@ -122,7 +120,6 @@ module.exports = { expectSession, expectTransaction, extractEnvelopeFromRequest, - extractEventFromRequest, isEnvelopeRequest, isEventRequest, isSentryRequest, diff --git a/packages/nextjs/test/integration/test/utils/server.js b/packages/nextjs/test/integration/test/utils/server.js index 8844c8cc1799..8c38446e3f41 100644 --- a/packages/nextjs/test/integration/test/utils/server.js +++ b/packages/nextjs/test/integration/test/utils/server.js @@ -35,15 +35,17 @@ const getAsync = (url, rewrap = false) => { const interceptEventRequest = (expectedEvent, argv, testName = '') => { return nock('https://dsn.ingest.sentry.io') - .post('/api/1337/store/', body => { + .post('/api/1337/envelope/', body => { + const { envelopeHeader, itemHeader, item } = parseEnvelope(body); logIf( process.env.LOG_REQUESTS, '\nIntercepted Event' + (testName.length ? ` (from test \`${testName}\`)` : ''), - body, + { envelopeHeader, itemHeader, item }, argv.depth, ); - return objectMatches(body, expectedEvent); + return itemHeader.type === 'event' && objectMatches(item, expectedEvent); }) + .query(true) // accept any query params - used for sentry_key param used by the envelope endpoint .reply(200); }; @@ -59,6 +61,7 @@ const interceptSessionRequest = (expectedItem, argv, testName = '') => { ); return itemHeader.type === 'session' && objectMatches(item, expectedItem); }) + .query(true) // accept any query params - used for sentry_key param used by the envelope endpoint .reply(200); }; @@ -74,6 +77,7 @@ const interceptTracingRequest = (expectedItem, argv, testName = '') => { ); return itemHeader.type === 'transaction' && objectMatches(item, expectedItem); }) + .query(true) // accept any query params - used for sentry_key param used by the envelope endpoint .reply(200); }; diff --git a/packages/node-integration-tests/suites/express/handle-error/test.ts b/packages/node-integration-tests/suites/express/handle-error/test.ts index 66cc1ec2d9ae..9ae4586f6510 100644 --- a/packages/node-integration-tests/suites/express/handle-error/test.ts +++ b/packages/node-integration-tests/suites/express/handle-error/test.ts @@ -1,12 +1,12 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../utils/index'; +import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../utils/index'; test('should capture and send Express controller error.', async () => { const url = await runServer(__dirname, `${__dirname}/server.ts`); - const event = await getEventRequest(`${url}/express`); + const event = await getEnvelopeRequest(`${url}/express`); - expect((event as any).exception.values[0].stacktrace.frames.length).toBeGreaterThan(0); + expect((event[2] as any).exception.values[0].stacktrace.frames.length).toBeGreaterThan(0); - assertSentryEvent(event, { + assertSentryEvent(event[2] as any, { exception: { values: [ { diff --git a/packages/node-integration-tests/suites/public-api/addBreadcrumb/empty-obj/test.ts b/packages/node-integration-tests/suites/public-api/addBreadcrumb/empty-obj/test.ts index dd9a8ca4fe87..be9c0b6c15b6 100644 --- a/packages/node-integration-tests/suites/public-api/addBreadcrumb/empty-obj/test.ts +++ b/packages/node-integration-tests/suites/public-api/addBreadcrumb/empty-obj/test.ts @@ -1,10 +1,13 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should add an empty breadcrumb, when an empty object is given', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + expect(errorEnvelope).toHaveLength(3); + + assertSentryEvent(errorEnvelope[2], { message: 'test-empty-obj', }); }); diff --git a/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts b/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts index b643a187bc6f..c8b894a62102 100644 --- a/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts +++ b/packages/node-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts @@ -1,10 +1,10 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should add multiple breadcrumbs', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); - assertSentryEvent(requestBody, { + assertSentryEvent(envelopes[1][2], { message: 'test_multi_breadcrumbs', breadcrumbs: [ { diff --git a/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts b/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts index 8bc0ee26fea2..a56f0711e086 100644 --- a/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts +++ b/packages/node-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts @@ -1,10 +1,10 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should add a simple breadcrumb', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); - assertSentryEvent(requestBody, { + assertSentryEvent(envelopes[1][2], { message: 'test_simple', breadcrumbs: [ { diff --git a/packages/node-integration-tests/suites/public-api/captureException/catched-error/test.ts b/packages/node-integration-tests/suites/public-api/captureException/catched-error/test.ts index f6fee1d8b819..2070199f77d9 100644 --- a/packages/node-integration-tests/suites/public-api/captureException/catched-error/test.ts +++ b/packages/node-integration-tests/suites/public-api/captureException/catched-error/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should work inside catch block', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { exception: { values: [ { diff --git a/packages/node-integration-tests/suites/public-api/captureException/empty-obj/test.ts b/packages/node-integration-tests/suites/public-api/captureException/empty-obj/test.ts index fb6ca293a27f..0df21996f08c 100644 --- a/packages/node-integration-tests/suites/public-api/captureException/empty-obj/test.ts +++ b/packages/node-integration-tests/suites/public-api/captureException/empty-obj/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should capture an empty object', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { exception: { values: [ { diff --git a/packages/node-integration-tests/suites/public-api/captureException/new-transport/scenario.ts b/packages/node-integration-tests/suites/public-api/captureException/new-transport/scenario.ts deleted file mode 100644 index a03dea7cbce5..000000000000 --- a/packages/node-integration-tests/suites/public-api/captureException/new-transport/scenario.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as Sentry from '@sentry/node'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - _experiments: { - newTransport: true, // use new transport - }, -}); - -Sentry.captureException(new Error('test_simple_error')); diff --git a/packages/node-integration-tests/suites/public-api/captureException/new-transport/test.ts b/packages/node-integration-tests/suites/public-api/captureException/new-transport/test.ts deleted file mode 100644 index 0424ac121dcd..000000000000 --- a/packages/node-integration-tests/suites/public-api/captureException/new-transport/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { getMultipleEnvelopeRequest, runServer } from '../../../../utils'; - -test('should correctly send envelope', async () => { - const url = await runServer(__dirname); - const envelopes = await getMultipleEnvelopeRequest(url, 2); - - const errorEnvelope = envelopes[1]; - - expect(errorEnvelope).toHaveLength(3); - expect(errorEnvelope[2]).toMatchObject({ - exception: { - values: [ - { - type: 'Error', - value: 'test_simple_error', - }, - ], - }, - release: '1.0', - event_id: expect.any(String), - timestamp: expect.any(Number), - }); -}); diff --git a/packages/node-integration-tests/suites/public-api/captureException/simple-error/test.ts b/packages/node-integration-tests/suites/public-api/captureException/simple-error/test.ts index 8553cb1be0d7..66ca0410377a 100644 --- a/packages/node-integration-tests/suites/public-api/captureException/simple-error/test.ts +++ b/packages/node-integration-tests/suites/public-api/captureException/simple-error/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should capture a simple error with message', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { exception: { values: [ { diff --git a/packages/node-integration-tests/suites/public-api/captureMessage/simple_message/test.ts b/packages/node-integration-tests/suites/public-api/captureMessage/simple_message/test.ts index 69fa8c27764b..2ecc0e86720d 100644 --- a/packages/node-integration-tests/suites/public-api/captureMessage/simple_message/test.ts +++ b/packages/node-integration-tests/suites/public-api/captureMessage/simple_message/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should capture a simple message string', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'Message', level: 'info', }); diff --git a/packages/node-integration-tests/suites/public-api/captureMessage/with_level/test.ts b/packages/node-integration-tests/suites/public-api/captureMessage/with_level/test.ts index e43c13db3711..5db1ef646168 100644 --- a/packages/node-integration-tests/suites/public-api/captureMessage/with_level/test.ts +++ b/packages/node-integration-tests/suites/public-api/captureMessage/with_level/test.ts @@ -1,40 +1,40 @@ -import { assertSentryEvent, getMultipleEventRequests, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should capture with different severity levels', async () => { const url = await runServer(__dirname); - const events = await getMultipleEventRequests(url, 7); + const envelopes = await getMultipleEnvelopeRequest(url, 14); - assertSentryEvent(events[0], { + assertSentryEvent(envelopes[1][2], { message: 'debug_message', level: 'debug', }); - assertSentryEvent(events[1], { + assertSentryEvent(envelopes[3][2], { message: 'info_message', level: 'info', }); - assertSentryEvent(events[2], { + assertSentryEvent(envelopes[5][2], { message: 'warning_message', level: 'warning', }); - assertSentryEvent(events[3], { + assertSentryEvent(envelopes[7][2], { message: 'error_message', level: 'error', }); - assertSentryEvent(events[4], { + assertSentryEvent(envelopes[9][2], { message: 'fatal_message', level: 'fatal', }); - assertSentryEvent(events[5], { + assertSentryEvent(envelopes[11][2], { message: 'critical_message', level: 'critical', }); - assertSentryEvent(events[6], { + assertSentryEvent(envelopes[13][2], { message: 'log_message', level: 'log', }); diff --git a/packages/node-integration-tests/suites/public-api/configureScope/clear_scope/test.ts b/packages/node-integration-tests/suites/public-api/configureScope/clear_scope/test.ts index 97437a4e7e90..e1cf213e2e4c 100644 --- a/packages/node-integration-tests/suites/public-api/configureScope/clear_scope/test.ts +++ b/packages/node-integration-tests/suites/public-api/configureScope/clear_scope/test.ts @@ -1,16 +1,16 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getEnvelopeRequest, runServer } from '../../../../utils'; test('should clear previously set properties of a scope', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelope = await getEnvelopeRequest(url); - assertSentryEvent(requestBody, { + assertSentryEvent(envelope[2], { message: 'cleared_scope', tags: {}, extra: {}, }); - expect((requestBody as Event).user).not.toBeDefined(); + expect((envelope[2] as Event).user).not.toBeDefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/configureScope/set_properties/test.ts b/packages/node-integration-tests/suites/public-api/configureScope/set_properties/test.ts index 6e482197470c..17d7c9b8df42 100644 --- a/packages/node-integration-tests/suites/public-api/configureScope/set_properties/test.ts +++ b/packages/node-integration-tests/suites/public-api/configureScope/set_properties/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set different properties of a scope', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'configured_scope', tags: { foo: 'bar', diff --git a/packages/node-integration-tests/suites/public-api/setContext/multiple-contexts/test.ts b/packages/node-integration-tests/suites/public-api/setContext/multiple-contexts/test.ts index 46d3de6bc2bf..f1c8981fad9a 100644 --- a/packages/node-integration-tests/suites/public-api/setContext/multiple-contexts/test.ts +++ b/packages/node-integration-tests/suites/public-api/setContext/multiple-contexts/test.ts @@ -1,12 +1,13 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should record multiple contexts', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'multiple_contexts', contexts: { context_1: { @@ -17,5 +18,5 @@ test('should record multiple contexts', async () => { }, }); - expect((requestBody as Event).contexts?.context_3).not.toBeDefined(); + expect((errorEnvelope[2] as Event).contexts?.context_3).not.toBeDefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/setContext/non-serializable-context/test.ts b/packages/node-integration-tests/suites/public-api/setContext/non-serializable-context/test.ts index 2ea859de480c..26b5fe8c7025 100644 --- a/packages/node-integration-tests/suites/public-api/setContext/non-serializable-context/test.ts +++ b/packages/node-integration-tests/suites/public-api/setContext/non-serializable-context/test.ts @@ -1,15 +1,16 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should normalize non-serializable context', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'non_serializable', contexts: {}, }); - expect((requestBody as Event).contexts?.context_3).not.toBeDefined(); + expect((errorEnvelope[2] as Event).contexts?.context_3).not.toBeDefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/setContext/simple-context/test.ts b/packages/node-integration-tests/suites/public-api/setContext/simple-context/test.ts index cdabe34d8680..362afb9e55e4 100644 --- a/packages/node-integration-tests/suites/public-api/setContext/simple-context/test.ts +++ b/packages/node-integration-tests/suites/public-api/setContext/simple-context/test.ts @@ -1,12 +1,13 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set a simple context', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'simple_context_object', contexts: { foo: { @@ -15,5 +16,5 @@ test('should set a simple context', async () => { }, }); - expect((requestBody as Event).contexts?.context_3).not.toBeDefined(); + expect((errorEnvelope[2] as Event).contexts?.context_3).not.toBeDefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/setExtra/multiple-extras/test.ts b/packages/node-integration-tests/suites/public-api/setExtra/multiple-extras/test.ts index 0bc530b13cef..428ebd7f45c4 100644 --- a/packages/node-integration-tests/suites/public-api/setExtra/multiple-extras/test.ts +++ b/packages/node-integration-tests/suites/public-api/setExtra/multiple-extras/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should record multiple extras of different types', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'multiple_extras', extra: { extra_1: { foo: 'bar', baz: { qux: 'quux' } }, diff --git a/packages/node-integration-tests/suites/public-api/setExtra/non-serializable-extra/test.ts b/packages/node-integration-tests/suites/public-api/setExtra/non-serializable-extra/test.ts index 24005031781b..3cd2ca078eeb 100644 --- a/packages/node-integration-tests/suites/public-api/setExtra/non-serializable-extra/test.ts +++ b/packages/node-integration-tests/suites/public-api/setExtra/non-serializable-extra/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should normalize non-serializable extra', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'non_serializable', extra: {}, }); diff --git a/packages/node-integration-tests/suites/public-api/setExtra/simple-extra/test.ts b/packages/node-integration-tests/suites/public-api/setExtra/simple-extra/test.ts index 23c0cbc6ad42..33bfe641bfa3 100644 --- a/packages/node-integration-tests/suites/public-api/setExtra/simple-extra/test.ts +++ b/packages/node-integration-tests/suites/public-api/setExtra/simple-extra/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set a simple extra', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'simple_extra', extra: { foo: { diff --git a/packages/node-integration-tests/suites/public-api/setExtras/consecutive-calls/test.ts b/packages/node-integration-tests/suites/public-api/setExtras/consecutive-calls/test.ts index 5126cde1a58f..464324c97fdf 100644 --- a/packages/node-integration-tests/suites/public-api/setExtras/consecutive-calls/test.ts +++ b/packages/node-integration-tests/suites/public-api/setExtras/consecutive-calls/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set extras from multiple consecutive calls', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'consecutive_calls', extra: { extra: [], Infinity: 2, null: 0, obj: { foo: ['bar', 'baz', 1] } }, }); diff --git a/packages/node-integration-tests/suites/public-api/setExtras/multiple-extras/test.ts b/packages/node-integration-tests/suites/public-api/setExtras/multiple-extras/test.ts index f1c653307e45..d23c8e815a06 100644 --- a/packages/node-integration-tests/suites/public-api/setExtras/multiple-extras/test.ts +++ b/packages/node-integration-tests/suites/public-api/setExtras/multiple-extras/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should record an extras object', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const errorEnvelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(errorEnvelope[2], { message: 'multiple_extras', extra: { extra_1: [1, ['foo'], 'bar'], diff --git a/packages/node-integration-tests/suites/public-api/setTag/with-primitives/test.ts b/packages/node-integration-tests/suites/public-api/setTag/with-primitives/test.ts index c6b94aca64d1..88d78b70c655 100644 --- a/packages/node-integration-tests/suites/public-api/setTag/with-primitives/test.ts +++ b/packages/node-integration-tests/suites/public-api/setTag/with-primitives/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set primitive tags', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const envelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(envelope[2], { message: 'primitive_tags', tags: { tag_1: 'foo', diff --git a/packages/node-integration-tests/suites/public-api/setTags/with-primitives/test.ts b/packages/node-integration-tests/suites/public-api/setTags/with-primitives/test.ts index c6b94aca64d1..88d78b70c655 100644 --- a/packages/node-integration-tests/suites/public-api/setTags/with-primitives/test.ts +++ b/packages/node-integration-tests/suites/public-api/setTags/with-primitives/test.ts @@ -1,10 +1,11 @@ -import { assertSentryEvent, getEventRequest, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should set primitive tags', async () => { const url = await runServer(__dirname); - const requestBody = await getEventRequest(url); + const envelopes = await getMultipleEnvelopeRequest(url, 2); + const envelope = envelopes[1]; - assertSentryEvent(requestBody, { + assertSentryEvent(envelope[2], { message: 'primitive_tags', tags: { tag_1: 'foo', diff --git a/packages/node-integration-tests/suites/public-api/setUser/unset_user/test.ts b/packages/node-integration-tests/suites/public-api/setUser/unset_user/test.ts index 8c804f3864b8..736ed1fdf38c 100644 --- a/packages/node-integration-tests/suites/public-api/setUser/unset_user/test.ts +++ b/packages/node-integration-tests/suites/public-api/setUser/unset_user/test.ts @@ -1,18 +1,18 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getMultipleEventRequests, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should unset user', async () => { const url = await runServer(__dirname); - const events = await getMultipleEventRequests(url, 3); + const envelopes = await getMultipleEnvelopeRequest(url, 6); - assertSentryEvent(events[0], { + assertSentryEvent(envelopes[1][2], { message: 'no_user', }); - expect((events[0] as Event).user).not.toBeDefined(); + expect((envelopes[0][2] as Event).user).not.toBeDefined(); - assertSentryEvent(events[1], { + assertSentryEvent(envelopes[3][2], { message: 'user', user: { id: 'foo', @@ -21,9 +21,9 @@ test('should unset user', async () => { }, }); - assertSentryEvent(events[2], { + assertSentryEvent(envelopes[5][2], { message: 'unset_user', }); - expect((events[2] as Event).user).not.toBeDefined(); + expect((envelopes[2][2] as Event).user).not.toBeDefined(); }); diff --git a/packages/node-integration-tests/suites/public-api/setUser/update_user/test.ts b/packages/node-integration-tests/suites/public-api/setUser/update_user/test.ts index 3f84a390cd05..27c7de89fe45 100644 --- a/packages/node-integration-tests/suites/public-api/setUser/update_user/test.ts +++ b/packages/node-integration-tests/suites/public-api/setUser/update_user/test.ts @@ -1,10 +1,10 @@ -import { assertSentryEvent, getMultipleEventRequests, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should update user', async () => { const url = await runServer(__dirname); - const events = await getMultipleEventRequests(url, 2); + const envelopes = await getMultipleEnvelopeRequest(url, 4); - assertSentryEvent(events[0], { + assertSentryEvent(envelopes[1][2], { message: 'first_user', user: { id: 'foo', @@ -12,7 +12,7 @@ test('should update user', async () => { }, }); - assertSentryEvent(events[1], { + assertSentryEvent(envelopes[3][2], { message: 'second_user', user: { id: 'baz', diff --git a/packages/node-integration-tests/suites/public-api/withScope/nested-scopes/test.ts b/packages/node-integration-tests/suites/public-api/withScope/nested-scopes/test.ts index 03a219470b0f..57047696cf0c 100644 --- a/packages/node-integration-tests/suites/public-api/withScope/nested-scopes/test.ts +++ b/packages/node-integration-tests/suites/public-api/withScope/nested-scopes/test.ts @@ -1,12 +1,12 @@ import { Event } from '@sentry/node'; -import { assertSentryEvent, getMultipleEventRequests, runServer } from '../../../../utils'; +import { assertSentryEvent, getMultipleEnvelopeRequest, runServer } from '../../../../utils'; test('should allow nested scoping', async () => { const url = await runServer(__dirname); - const events = await getMultipleEventRequests(url, 5); + const envelopes = await getMultipleEnvelopeRequest(url, 10); - assertSentryEvent(events[0], { + assertSentryEvent(envelopes[1][2], { message: 'root_before', user: { id: 'qux', @@ -14,7 +14,7 @@ test('should allow nested scoping', async () => { tags: {}, }); - assertSentryEvent(events[1], { + assertSentryEvent(envelopes[3][2], { message: 'outer_before', user: { id: 'qux', @@ -24,7 +24,7 @@ test('should allow nested scoping', async () => { }, }); - assertSentryEvent(events[2], { + assertSentryEvent(envelopes[5][2], { message: 'inner', tags: { foo: false, @@ -32,9 +32,9 @@ test('should allow nested scoping', async () => { }, }); - expect((events[2] as Event).user).toBeUndefined(); + expect((envelopes[4][2] as Event).user).toBeUndefined(); - assertSentryEvent(events[3], { + assertSentryEvent(envelopes[7][2], { message: 'outer_after', user: { id: 'baz', @@ -44,7 +44,7 @@ test('should allow nested scoping', async () => { }, }); - assertSentryEvent(events[4], { + assertSentryEvent(envelopes[9][2], { message: 'root_after', user: { id: 'qux', diff --git a/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts b/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts index 28ce0ba822c0..13051fd9c47a 100644 --- a/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts +++ b/packages/node-integration-tests/suites/sessions/crashed-session-aggregate/test.ts @@ -1,17 +1,17 @@ import path from 'path'; -import { getEnvelopeRequest, runServer } from '../../../utils'; +import { getMultipleEnvelopeRequest, runServer } from '../../../utils'; test('should aggregate successful and crashed sessions', async () => { const url = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`); - const envelope = await Promise.race([ - getEnvelopeRequest(`${url}/success`), - getEnvelopeRequest(`${url}/error_unhandled`), - getEnvelopeRequest(`${url}/success_next`), + const envelopes = await Promise.race([ + getMultipleEnvelopeRequest(`${url}/success`, 2), + getMultipleEnvelopeRequest(`${url}/error_unhandled`, 2), + getMultipleEnvelopeRequest(`${url}/success_next`, 2), ]); + const envelope = envelopes[1]; - expect(envelope).toHaveLength(3); expect(envelope[0]).toMatchObject({ sent_at: expect.any(String), sdk: { diff --git a/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts b/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts index ad1cf46f2704..0f3130cd9b09 100644 --- a/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts +++ b/packages/node-integration-tests/suites/sessions/errored-session-aggregate/test.ts @@ -1,18 +1,19 @@ import path from 'path'; -import { getEnvelopeRequest, runServer } from '../../../utils'; +import { getMultipleEnvelopeRequest, runServer } from '../../../utils'; test('should aggregate successful, crashed and erroneous sessions', async () => { const url = await runServer(__dirname, `${path.resolve(__dirname, '..')}/server.ts`); - const envelope = await Promise.race([ - getEnvelopeRequest(`${url}/success`), - getEnvelopeRequest(`${url}/error_handled`), - getEnvelopeRequest(`${url}/error_unhandled`), + const envelopes = await Promise.race([ + getMultipleEnvelopeRequest(`${url}/success`, 3), + getMultipleEnvelopeRequest(`${url}/error_handled`, 3), + getMultipleEnvelopeRequest(`${url}/error_unhandled`, 3), ]); - expect(envelope).toHaveLength(3); - expect(envelope[0]).toMatchObject({ + expect(envelopes).toHaveLength(3); + const aggregateSessionEnvelope = envelopes[2]; + expect(aggregateSessionEnvelope[0]).toMatchObject({ sent_at: expect.any(String), sdk: { name: 'sentry.javascript.node', @@ -20,11 +21,11 @@ test('should aggregate successful, crashed and erroneous sessions', async () => }, }); - expect(envelope[1]).toMatchObject({ + expect(aggregateSessionEnvelope[1]).toMatchObject({ type: 'sessions', }); - expect(envelope[2]).toMatchObject({ + expect(aggregateSessionEnvelope[2]).toMatchObject({ aggregates: [ { started: expect.any(String), diff --git a/packages/node-integration-tests/utils/index.ts b/packages/node-integration-tests/utils/index.ts index d652f63185b0..fba8bb7d52de 100644 --- a/packages/node-integration-tests/utils/index.ts +++ b/packages/node-integration-tests/utils/index.ts @@ -65,42 +65,6 @@ export const parseEnvelope = (body: string): Array> => { return body.split('\n').map(e => JSON.parse(e)); }; -/** - * Intercepts and extracts multiple requests containing a Sentry Event - * - * @param {string} url - * @param {number} count - * @return {*} {Promise>>} - */ -export const getMultipleEventRequests = async (url: string, count: number): Promise>> => { - const events: Record[] = []; - - return new Promise(resolve => { - nock('https://dsn.ingest.sentry.io') - .post('/api/1337/store/', body => { - events.push(body); - - if (events.length === count) { - resolve(events); - } - return true; - }) - .times(7) - .reply(200); - http.get(url); - }); -}; - -/** - * Intercepts and extracts a single request containing a Sentry Event - * - * @param {string} url - * @return {*} {Promise>} - */ -export const getEventRequest = async (url: string): Promise> => { - return (await getMultipleEventRequests(url, 1))[0]; -}; - /** * Intercepts and extracts up to a number of requests containing Sentry envelopes. * diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 4ba91d0db9a2..e6a0fc7a43a0 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -1,6 +1,6 @@ -import { BaseClient, NewTransport, Scope, SDK_VERSION } from '@sentry/core'; +import { BaseClient, Scope, SDK_VERSION } from '@sentry/core'; import { SessionFlusher } from '@sentry/hub'; -import { Event, EventHint, Severity, SeverityLevel, Transport } from '@sentry/types'; +import { Event, EventHint, Severity, SeverityLevel } from '@sentry/types'; import { logger, resolvedSyncPromise } from '@sentry/utils'; import { eventFromMessage, eventFromUnknownInput } from './eventbuilder'; @@ -20,7 +20,7 @@ export class NodeClient extends BaseClient { * Creates a new Node SDK instance. * @param options Configuration options for this SDK. */ - public constructor(options: NodeClientOptions, transport: Transport, newTransport?: NewTransport) { + public constructor(options: NodeClientOptions) { options._metadata = options._metadata || {}; options._metadata.sdk = options._metadata.sdk || { name: 'sentry.javascript.node', @@ -33,7 +33,7 @@ export class NodeClient extends BaseClient { version: SDK_VERSION, }; - super(options, transport, newTransport); + super(options); } /** @@ -99,7 +99,7 @@ export class NodeClient extends BaseClient { if (!release) { IS_DEBUG_BUILD && logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!'); } else { - this._sessionFlusher = new SessionFlusher(this.getTransport(), { + this._sessionFlusher = new SessionFlusher(this, { release, environment, }); diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 0e8febd8a92a..ec659b543bff 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -26,6 +26,7 @@ export { captureEvent, captureMessage, configureScope, + createTransport, getHubFromCarrier, getCurrentHub, Hub, diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index 4b1e503e851a..5658257776b1 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -8,7 +8,7 @@ import { NodeClient } from './client'; import { IS_DEBUG_BUILD } from './flags'; import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations'; import { nodeStackParser } from './stack-parser'; -import { HTTPSTransport, HTTPTransport, setupNodeTransport } from './transports'; +import { makeNodeTransport } from './transports'; import { NodeClientOptions, NodeOptions } from './types'; export const defaultIntegrations = [ @@ -127,18 +127,15 @@ export function init(options: NodeOptions = {}): void { setHubOnCarrier(carrier, getCurrentHub()); } - const { transport, newTransport } = setupNodeTransport(options); - // TODO(v7): Refactor this to reduce the logic above const clientOptions: NodeClientOptions = { ...options, stackParser: stackParserFromOptions(options.stackParser || [nodeStackParser]), integrations: getIntegrationsToSetup(options), - // TODO(v7): Fix me when we switch to new transports entirely. - transport: options.transport || (transport instanceof HTTPTransport ? HTTPTransport : HTTPSTransport), + transport: options.transport || makeNodeTransport, }; - initAndBind(NodeClient, clientOptions, transport, newTransport); + initAndBind(NodeClient, clientOptions); if (options.autoSessionTracking) { startSessionTracking(); diff --git a/packages/node/src/transports/index.ts b/packages/node/src/transports/index.ts index 01877029269e..958562933321 100644 --- a/packages/node/src/transports/index.ts +++ b/packages/node/src/transports/index.ts @@ -4,4 +4,3 @@ export { BaseTransport } from './base'; export { HTTPTransport } from './http'; export { HTTPSTransport } from './https'; export { makeNodeTransport } from './new'; -export { setupNodeTransport } from './setup'; diff --git a/packages/node/src/transports/new.ts b/packages/node/src/transports/new.ts index b30dc3ffe36f..e31a58b03b7b 100644 --- a/packages/node/src/transports/new.ts +++ b/packages/node/src/transports/new.ts @@ -1,11 +1,11 @@ +import { createTransport } from '@sentry/core'; import { BaseTransportOptions, - createTransport, NewTransport, TransportMakeRequestResponse, TransportRequest, TransportRequestExecutor, -} from '@sentry/core'; +} from '@sentry/types'; import { eventStatusFromHttpCode } from '@sentry/utils'; import * as http from 'http'; import * as https from 'https'; @@ -91,7 +91,6 @@ function createRequestExecutor( agent: http.Agent, ): TransportRequestExecutor { const { hostname, pathname, port, protocol, search } = new URL(options.url); - return function makeRequest(request: TransportRequest): Promise { return new Promise((resolve, reject) => { const req = httpModule.request( diff --git a/packages/node/src/transports/setup.ts b/packages/node/src/transports/setup.ts deleted file mode 100644 index 2cffd2d43ecd..000000000000 --- a/packages/node/src/transports/setup.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { getEnvelopeEndpointWithUrlEncodedAuth, initAPIDetails, NewTransport, NoopTransport } from '@sentry/core'; -import { Transport, TransportOptions } from '@sentry/types'; -import { makeDsn } from '@sentry/utils'; - -import { NodeOptions } from '../types'; -import { HTTPSTransport, HTTPTransport, makeNodeTransport } from '.'; - -/** - * Sets up Node transport based on the passed `options`. - * - * @returns an object currently still containing both, the old `Transport` and - * `NewTransport` which will eventually replace `Transport`. Once this is replaced, - * this function will return a ready to use `NewTransport`. - */ -// TODO(v7): Adjust return value when NewTransport is the default -export function setupNodeTransport(options: NodeOptions): { transport: Transport; newTransport?: NewTransport } { - if (!options.dsn) { - // We return the noop transport here in case there is no Dsn. - return { transport: new NoopTransport() }; - } - - const dsn = makeDsn(options.dsn); - - const transportOptions: TransportOptions = { - ...options.transportOptions, - ...(options.httpProxy && { httpProxy: options.httpProxy }), - ...(options.httpsProxy && { httpsProxy: options.httpsProxy }), - ...(options.caCerts && { caCerts: options.caCerts }), - dsn: options.dsn, - tunnel: options.tunnel, - _metadata: options._metadata, - }; - - if (options.transport) { - return { transport: new options.transport(transportOptions) }; - } - - const api = initAPIDetails(transportOptions.dsn, transportOptions._metadata, transportOptions.tunnel); - const url = getEnvelopeEndpointWithUrlEncodedAuth(api.dsn, api.tunnel); - - const newTransport = makeNodeTransport({ - url, - headers: transportOptions.headers, - proxy: transportOptions.httpProxy, - caCerts: transportOptions.caCerts, - }); - - if (dsn.protocol === 'http') { - return { transport: new HTTPTransport(transportOptions), newTransport }; - } - return { transport: new HTTPSTransport(transportOptions), newTransport }; -} diff --git a/packages/node/test/client.test.ts b/packages/node/test/client.test.ts index bb3d13ca4122..2aafb8a2544e 100644 --- a/packages/node/test/client.test.ts +++ b/packages/node/test/client.test.ts @@ -1,7 +1,6 @@ import { Scope, SessionFlusher } from '@sentry/hub'; import { NodeClient } from '../src'; -import { setupNodeTransport } from '../src/transports'; import { getDefaultNodeClientOptions } from './helper/node-client-options'; const PUBLIC_DSN = 'https://username@domain/123'; @@ -17,7 +16,7 @@ describe('NodeClient', () => { describe('captureException', () => { test('when autoSessionTracking is enabled, and requestHandler is not used -> requestStatus should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const scope = new Scope(); scope.setRequestSession({ status: 'ok' }); @@ -28,7 +27,7 @@ describe('NodeClient', () => { }); test('when autoSessionTracking is disabled -> requestStatus should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -43,7 +42,7 @@ describe('NodeClient', () => { }); test('when autoSessionTracking is enabled + requestSession status is Crashed -> requestStatus should not be overridden', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -58,7 +57,7 @@ describe('NodeClient', () => { }); test('when autoSessionTracking is enabled + error occurs within request bounds -> requestStatus should be set to Errored', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -73,7 +72,7 @@ describe('NodeClient', () => { }); test('when autoSessionTracking is enabled + error occurs outside of request bounds -> requestStatus should not be set to Errored', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -90,7 +89,7 @@ describe('NodeClient', () => { describe('captureEvent()', () => { test('If autoSessionTracking is disabled, requestSession status should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: false, release: '1.4' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -109,7 +108,7 @@ describe('NodeClient', () => { test('When captureEvent is called with an exception, requestSession status should be set to Errored', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -125,7 +124,7 @@ describe('NodeClient', () => { test('When captureEvent is called without an exception, requestSession status should not be set to Errored', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -141,7 +140,7 @@ describe('NodeClient', () => { test('When captureEvent is called with an exception but outside of a request, then requestStatus should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '2.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -159,7 +158,7 @@ describe('NodeClient', () => { test('When captureEvent is called with a transaction, then requestSession status should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -174,7 +173,7 @@ describe('NodeClient', () => { test('When captureEvent is called with an exception but requestHandler is not used, then requestSession status should not be set', () => { const options = getDefaultNodeClientOptions({ dsn: PUBLIC_DSN, autoSessionTracking: true, release: '1.3' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const scope = new Scope(); scope.setRequestSession({ status: 'ok' }); @@ -198,7 +197,7 @@ describe('flush/close', () => { autoSessionTracking: true, release: '1.1', }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); client.initSessionFlusher(); // Clearing interval is important here to ensure that the flush function later on is called by the `client.close()` // not due to the interval running every 60s diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index b857e1b74bf5..a423a92aa3d0 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -18,7 +18,6 @@ import { tracingHandler, } from '../src/handlers'; import * as SDK from '../src/sdk'; -import { setupNodeTransport } from '../src/transports'; import { getDefaultNodeClientOptions } from './helper/node-client-options'; describe('parseRequest', () => { @@ -226,7 +225,7 @@ describe('requestHandler', () => { it('autoSessionTracking is enabled, sets requestSession status to ok, when handling a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -239,7 +238,7 @@ describe('requestHandler', () => { it('autoSessionTracking is disabled, does not set requestSession, when handling a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -252,7 +251,7 @@ describe('requestHandler', () => { it('autoSessionTracking is enabled, calls _captureRequestSession, on response finish', done => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -273,7 +272,7 @@ describe('requestHandler', () => { it('autoSessionTracking is disabled, does not call _captureRequestSession, on response finish', done => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '1.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const hub = new Hub(client); jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -374,7 +373,7 @@ describe('tracingHandler', () => { it('extracts request data for sampling context', () => { const tracesSampler = jest.fn(); const options = getDefaultNodeClientOptions({ tracesSampler }); - const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); + const hub = new Hub(new NodeClient(options)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -397,7 +396,7 @@ describe('tracingHandler', () => { it('puts its transaction on the scope', () => { const options = getDefaultNodeClientOptions({ tracesSampleRate: 1.0 }); - const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); + const hub = new Hub(new NodeClient(options)); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on // `@sentry/hub`, and mocking breaks the link between the two jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); @@ -729,7 +728,7 @@ describe('errorHandler()', () => { }); it('when autoSessionTracking is disabled, does not set requestSession status on Crash', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '3.3' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -749,7 +748,7 @@ describe('errorHandler()', () => { it('autoSessionTracking is enabled + requestHandler is not used -> does not set requestSession status on Crash', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: false, release: '3.3' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); const scope = sentryCore.getCurrentHub().getScope(); const hub = new Hub(client); @@ -766,7 +765,7 @@ describe('errorHandler()', () => { it('when autoSessionTracking is enabled, should set requestSession status to Crashed when an unhandled error occurs within the bounds of a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '1.1' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); @@ -785,7 +784,7 @@ describe('errorHandler()', () => { it('when autoSessionTracking is enabled, should not set requestSession status on Crash when it occurs outside the bounds of a request', () => { const options = getDefaultNodeClientOptions({ autoSessionTracking: true, release: '2.2' }); - client = new NodeClient(options, setupNodeTransport(options).transport); + client = new NodeClient(options); // It is required to initialise SessionFlusher to capture Session Aggregates (it is usually initialised // by the`requestHandler`) client.initSessionFlusher(); diff --git a/packages/node/test/helper/node-client-options.ts b/packages/node/test/helper/node-client-options.ts index c2bb1d42a871..a010c18f5811 100644 --- a/packages/node/test/helper/node-client-options.ts +++ b/packages/node/test/helper/node-client-options.ts @@ -1,11 +1,12 @@ -import { NoopTransport } from '@sentry/core'; +import { createTransport } from '@sentry/core'; +import { resolvedSyncPromise } from '@sentry/utils'; import { NodeClientOptions } from '../../src/types'; export function getDefaultNodeClientOptions(options: Partial = {}): NodeClientOptions { return { integrations: [], - transport: NoopTransport, + transport: () => createTransport({}, _ => resolvedSyncPromise({ statusCode: 200 })), stackParser: () => [], ...options, }; diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts index 2bdf8497097c..502542a25491 100644 --- a/packages/node/test/index.test.ts +++ b/packages/node/test/index.test.ts @@ -18,7 +18,6 @@ import { } from '../src'; import { ContextLines, LinkedErrors } from '../src/integrations'; import { nodeStackParser } from '../src/stack-parser'; -import { setupNodeTransport } from '../src/transports'; import { getDefaultNodeClientOptions } from './helper/node-client-options'; const stackParser = createStackParser(nodeStackParser); @@ -102,7 +101,7 @@ describe('SentryNode', () => { dsn, stackParser, }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); getCurrentHub().bindClient(client); addBreadcrumb({ message: 'test1' }); addBreadcrumb({ message: 'test2' }); @@ -137,7 +136,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -164,7 +163,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -195,7 +194,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); configureScope((scope: Scope) => { scope.setTag('test', '1'); }); @@ -233,7 +232,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); try { throw new Error('test'); } catch (e) { @@ -258,7 +257,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); captureMessage('test'); }); @@ -274,7 +273,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); captureEvent({ message: 'test event' }); }); @@ -291,7 +290,7 @@ describe('SentryNode', () => { }, dsn, }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); d.run(() => { getCurrentHub().bindClient(client); @@ -314,7 +313,7 @@ describe('SentryNode', () => { }, dsn, }); - getCurrentHub().bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + getCurrentHub().bindClient(new NodeClient(options)); try { // @ts-ignore allow function declarations in strict mode // eslint-disable-next-line no-inner-declarations @@ -368,7 +367,7 @@ describe('SentryNode initialization', () => { init({ dsn }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; expect(sdkData.name).toEqual('sentry.javascript.node'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/node'); @@ -378,10 +377,10 @@ describe('SentryNode initialization', () => { it('should set SDK data when instantiating a client directly', () => { const options = getDefaultNodeClientOptions({ dsn }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (client as any).getTransport()._api.metadata?.sdk; + const sdkData = (client as any).getOptions()._metadata.sdk; expect(sdkData.name).toEqual('sentry.javascript.node'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/node'); @@ -410,7 +409,7 @@ describe('SentryNode initialization', () => { }); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sdkData = (getCurrentHub().getClient() as any).getTransport()._api.metadata?.sdk; + const sdkData = (getCurrentHub().getClient() as any).getOptions()._metadata.sdk; expect(sdkData.name).toEqual('sentry.javascript.serverless'); expect(sdkData.packages[0].name).toEqual('npm:@sentry/serverless'); diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 30a923524a3e..ff0af8b65acf 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -11,7 +11,6 @@ import * as nock from 'nock'; import { Breadcrumb } from '../../src'; import { NodeClient } from '../../src/client'; import { Http as HttpIntegration } from '../../src/integrations/http'; -import { setupNodeTransport } from '../../src/transports'; import { getDefaultNodeClientOptions } from '../helper/node-client-options'; const NODE_VERSION = parseSemver(process.versions.node); @@ -23,7 +22,7 @@ describe('tracing', () => { tracesSampleRate: 1.0, integrations: [new HttpIntegration({ tracing: true })], }); - const hub = new Hub(new NodeClient(options, setupNodeTransport(options).transport)); + const hub = new Hub(new NodeClient(options)); addExtensionMethods(); // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on @@ -108,7 +107,7 @@ describe('default protocols', () => { return b; }, }); - hub.bindClient(new NodeClient(options, setupNodeTransport(options).transport)); + hub.bindClient(new NodeClient(options)); return p; } diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts index 4d18707be904..6b01faa11614 100644 --- a/packages/node/test/integrations/linkederrors.test.ts +++ b/packages/node/test/integrations/linkederrors.test.ts @@ -4,7 +4,6 @@ import { createStackParser } from '@sentry/utils'; import { Event, NodeClient } from '../../src'; import { LinkedErrors } from '../../src/integrations/linkederrors'; import { nodeStackParser } from '../../src/stack-parser'; -import { setupNodeTransport } from '../../src/transports'; import { getDefaultNodeClientOptions } from '../helper/node-client-options'; const stackParser = createStackParser(nodeStackParser); @@ -34,7 +33,7 @@ describe('LinkedErrors', () => { const spy = jest.spyOn(linkedErrors, '_walkErrorTree'); const one = new Error('originalException'); const options = getDefaultNodeClientOptions({ stackParser }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); let event: Event | undefined; return client .eventFromException(one) @@ -58,7 +57,7 @@ describe('LinkedErrors', () => { ); const one = new Error('originalException'); const options = getDefaultNodeClientOptions({ stackParser }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -79,7 +78,7 @@ describe('LinkedErrors', () => { two.cause = three; const options = getDefaultNodeClientOptions({ stackParser }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -113,7 +112,7 @@ describe('LinkedErrors', () => { two.reason = three; const options = getDefaultNodeClientOptions({ stackParser }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { @@ -147,7 +146,7 @@ describe('LinkedErrors', () => { two.cause = three; const options = getDefaultNodeClientOptions({ stackParser }); - const client = new NodeClient(options, setupNodeTransport(options).transport); + const client = new NodeClient(options); return client.eventFromException(one).then(event => linkedErrors ._handler(stackParser, event, { diff --git a/packages/node/test/manual/express-scope-separation/start.js b/packages/node/test/manual/express-scope-separation/start.js index 9146c3ab2eba..689c9ef358e8 100644 --- a/packages/node/test/manual/express-scope-separation/start.js +++ b/packages/node/test/manual/express-scope-separation/start.js @@ -12,8 +12,8 @@ function assertTags(actual, expected) { let remaining = 3; -class DummyTransport { - sendEvent(event) { +function makeDummyTransport() { + return Sentry.createTransport({}, req => { --remaining; if (!remaining) { @@ -23,14 +23,14 @@ class DummyTransport { } return Promise.resolve({ - status: 'success', + statusCode: 200, }); - } + }) } Sentry.init({ dsn: 'http://test@example.com/1337', - transport: DummyTransport, + transport: makeDummyTransport, beforeSend(event) { if (event.transaction === 'GET /foo') { assertTags(event.tags, { diff --git a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js index 0c536e0accae..f02788174ea0 100644 --- a/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js +++ b/packages/node/test/manual/release-health/session-aggregates/aggregates-disable-single-session.js @@ -2,7 +2,7 @@ const http = require('http'); const express = require('express'); const app = express(); const Sentry = require('../../../../build/cjs'); -const { assertSessions, BaseDummyTransport } = require('../test-utils'); +const { assertSessions } = require('../test-utils'); function cleanUpAndExitSuccessfully() { server.close(); @@ -27,9 +27,10 @@ function assertSessionAggregates(session, expected) { assertSessions(session, expected); } -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - assertSessionAggregates(session, { +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); + assertSessionAggregates(sessionEnv[2], { attrs: { release: '1.1' }, aggregates: [{ crashed: 2, errored: 1, exited: 1 }], }); @@ -37,15 +38,15 @@ class DummyTransport extends BaseDummyTransport { cleanUpAndExitSuccessfully(); return Promise.resolve({ - status: 'success', + statusCode: 200, }); - } + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); /** diff --git a/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js b/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js index db052b2bc508..8f5634163f25 100644 --- a/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js +++ b/packages/node/test/manual/release-health/single-session/caught-exception-errored-session.js @@ -2,7 +2,6 @@ const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, - BaseDummyTransport, validateSessionCountFunction, } = require('../test-utils'); @@ -13,36 +12,41 @@ const sessionCounts = { validateSessionCountFunction(sessionCounts); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - sessionCounts.sessionCounter++; - - if (sessionCounts.sessionCounter === 1) { - assertSessions(constructStrippedSessionObject(session), { - init: true, - status: 'ok', - errors: 1, - release: '1.1', - }); - } +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + if (req.category === 'session') { + sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); + + if (sessionCounts.sessionCounter === 1) { + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: true, + status: 'ok', + errors: 1, + release: '1.1', + }); + } - if (sessionCounts.sessionCounter === 2) { - assertSessions(constructStrippedSessionObject(session), { - init: false, - status: 'exited', - errors: 1, - release: '1.1', - }); + if (sessionCounts.sessionCounter === 2) { + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: false, + status: 'exited', + errors: 1, + release: '1.1', + }); + } } - return super.sendSession(session); - } + return Promise.resolve({ + statusCode: 200, + }); + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); diff --git a/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js b/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js index 983f10e9b294..6d230292d180 100644 --- a/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js +++ b/packages/node/test/manual/release-health/single-session/errors-in-session-capped-to-one.js @@ -2,7 +2,6 @@ const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, - BaseDummyTransport, validateSessionCountFunction, } = require('../test-utils'); @@ -13,36 +12,41 @@ const sessionCounts = { validateSessionCountFunction(sessionCounts); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - sessionCounts.sessionCounter++; +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + if (req.category === 'session') { + sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); - if (sessionCounts.sessionCounter === 1) { - assertSessions(constructStrippedSessionObject(session), { - init: true, - status: 'ok', - errors: 1, - release: '1.1', - }); - } + if (sessionCounts.sessionCounter === 1) { + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: true, + status: 'ok', + errors: 1, + release: '1.1', + }); + } - if (sessionCounts.sessionCounter === 2) { - assertSessions(constructStrippedSessionObject(session), { - init: false, - status: 'exited', - errors: 1, - release: '1.1', - }); + if (sessionCounts.sessionCounter === 2) { + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: false, + status: 'exited', + errors: 1, + release: '1.1', + }); + } } - return super.sendSession(session); - } + return Promise.resolve({ + statusCode: 200, + }); + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); /** diff --git a/packages/node/test/manual/release-health/single-session/healthy-session.js b/packages/node/test/manual/release-health/single-session/healthy-session.js index 1906b8196bf5..cfc3909449ef 100644 --- a/packages/node/test/manual/release-health/single-session/healthy-session.js +++ b/packages/node/test/manual/release-health/single-session/healthy-session.js @@ -2,7 +2,6 @@ const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, - BaseDummyTransport, validateSessionCountFunction, } = require('../test-utils'); @@ -13,25 +12,28 @@ const sessionCounts = { validateSessionCountFunction(sessionCounts); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { +function makeDummyTransport() { + return Sentry.createTransport({}, req => { sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); - assertSessions(constructStrippedSessionObject(session), { + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { init: true, status: 'exited', errors: 0, - release: '1.1', + release: '1.1' }); - return super.sendSession(session); - } + return Promise.resolve({ + statusCode: 200, + }); + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); diff --git a/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js b/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js index b2692957aa70..d0b8f72f4af4 100644 --- a/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js +++ b/packages/node/test/manual/release-health/single-session/terminal-state-sessions-sent-once.js @@ -2,7 +2,6 @@ const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, - BaseDummyTransport, validateSessionCountFunction, } = require('../test-utils'); @@ -13,25 +12,30 @@ const sessionCounts = { validateSessionCountFunction(sessionCounts); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - sessionCounts.sessionCounter++; - - assertSessions(constructStrippedSessionObject(session), { - init: true, - status: 'crashed', - errors: 1, - release: '1.1', +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + if (req.category === 'session') { + sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); + + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: true, + status: 'crashed', + errors: 1, + release: '1.1', + }); + } + + return Promise.resolve({ + statusCode: 200, }); - - return super.sendSession(session); - } + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); diff --git a/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js b/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js index eaf247aa080a..5cee4449c23a 100644 --- a/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js +++ b/packages/node/test/manual/release-health/single-session/uncaught-exception-crashed-session.js @@ -1,24 +1,29 @@ const Sentry = require('../../../../build/cjs'); -const { assertSessions, constructStrippedSessionObject, BaseDummyTransport } = require('../test-utils'); +const { assertSessions, constructStrippedSessionObject } = require('../test-utils'); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - assertSessions(constructStrippedSessionObject(session), { - init: true, - status: 'crashed', - errors: 1, - release: '1.1', - }); +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + if (req.category === 'session') { + sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); + + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: true, + status: 'crashed', + errors: 1, + release: '1.1', + }); + } // We need to explicitly exit process early here to allow for 0 exit code process.exit(0); - } + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); diff --git a/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js b/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js index c5a1874024ba..d94b6add0c00 100644 --- a/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js +++ b/packages/node/test/manual/release-health/single-session/unhandled-rejection-crashed-session.js @@ -2,7 +2,6 @@ const Sentry = require('../../../../build/cjs'); const { assertSessions, constructStrippedSessionObject, - BaseDummyTransport, validateSessionCountFunction, } = require('../test-utils'); @@ -13,25 +12,30 @@ const sessionCounts = { validateSessionCountFunction(sessionCounts); -class DummyTransport extends BaseDummyTransport { - sendSession(session) { - sessionCounts.sessionCounter++; +function makeDummyTransport() { + return Sentry.createTransport({}, req => { + if (req.category === 'session') { + sessionCounts.sessionCounter++; + const sessionEnv = req.body.split('\n').map(e => JSON.parse(e)); - assertSessions(constructStrippedSessionObject(session), { - init: true, - status: 'crashed', - errors: 1, - release: '1.1', - }); + assertSessions(constructStrippedSessionObject(sessionEnv[2]), { + init: true, + status: 'crashed', + errors: 1, + release: '1.1', + }); + } - return super.sendSession(session); - } + return Promise.resolve({ + statusCode: 200, + }); + }) } Sentry.init({ dsn: 'http://test@example.com/1337', release: '1.1', - transport: DummyTransport, + transport: makeDummyTransport, autoSessionTracking: true, }); diff --git a/packages/node/test/manual/release-health/test-utils.js b/packages/node/test/manual/release-health/test-utils.js index 668923e74dd3..2b3f88a440b9 100644 --- a/packages/node/test/manual/release-health/test-utils.js +++ b/packages/node/test/manual/release-health/test-utils.js @@ -8,26 +8,10 @@ function assertSessions(actual, expected) { } function constructStrippedSessionObject(actual) { - const { init, status, errors, release, did } = actual; + const { init, status, errors, attrs: { release }, did } = actual; return { init, status, errors, release, did }; } -class BaseDummyTransport { - sendEvent(event) { - return Promise.resolve({ - status: 'success', - }); - } - sendSession(session) { - return Promise.resolve({ - status: 'success', - }); - } - close(timeout) { - return Promise.resolve(true); - } -} - function validateSessionCountFunction(sessionCounts) { process.on('exit', () => { const { sessionCounter, expectedSessions } = sessionCounts; @@ -38,4 +22,4 @@ function validateSessionCountFunction(sessionCounts) { }); } -module.exports = { assertSessions, constructStrippedSessionObject, BaseDummyTransport, validateSessionCountFunction }; +module.exports = { assertSessions, constructStrippedSessionObject, validateSessionCountFunction }; diff --git a/packages/node/test/manual/webpack-domain/index.js b/packages/node/test/manual/webpack-domain/index.js index 521699a6349a..b970c95d2a98 100644 --- a/packages/node/test/manual/webpack-domain/index.js +++ b/packages/node/test/manual/webpack-domain/index.js @@ -2,8 +2,8 @@ const Sentry = require('../../../build/cjs'); let remaining = 2; -class DummyTransport { - sendEvent(event) { +function makeDummyTransport() { + return Sentry.createTransport({}, req => { --remaining; if (!remaining) { @@ -14,12 +14,12 @@ class DummyTransport { return Promise.resolve({ status: 'success', }); - } + }) } Sentry.init({ dsn: 'https://a@example.com/1', - transport: DummyTransport, + transport: makeDummyTransport, beforeSend(event) { if (event.message === 'inside') { if (event.tags.a !== 'x' && event.tags.b !== 'c') { diff --git a/packages/node/test/transports/setup.test.ts b/packages/node/test/transports/setup.test.ts deleted file mode 100644 index 38f99a4c95f3..000000000000 --- a/packages/node/test/transports/setup.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { NoopTransport } from '@sentry/core'; -import { FakeTransport } from '@sentry/core/test/mocks/transport'; -import { HTTPSTransport, HTTPTransport, setupNodeTransport } from '@sentry/node/src/transports'; - -import { makeNodeTransport } from '../../src/transports/new'; -import { getDefaultNodeClientOptions } from '../helper/node-client-options'; - -jest.mock('../../src/transports/new', () => { - const original = jest.requireActual('../../src/transports/new'); - return { - ...original, - makeNodeTransport: jest.fn(() => ({ - send: () => Promise.resolve({ status: 'success' }), - flush: () => Promise.resolve(true), - })), - }; -}); - -const DSN = 'https://username@domain/123'; - -describe('setupNodeTransport', () => { - afterEach(() => jest.clearAllMocks()); - - afterAll(() => jest.resetAllMocks()); - - it('returns NoopTransport if no dsn is passed', () => { - const { transport, newTransport } = setupNodeTransport({}); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(NoopTransport); - expect(newTransport).toBeUndefined(); - }); - - it('returns the instantiated transport passed via the options', () => { - const options = getDefaultNodeClientOptions({ dsn: DSN, transport: FakeTransport }); - const { transport, newTransport } = setupNodeTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(FakeTransport); - expect(newTransport).toBeUndefined(); - }); - - it('returns HTTPS transport as a default', () => { - const options = { dsn: DSN }; - const { transport, newTransport } = setupNodeTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(HTTPSTransport); - expect(newTransport).toBeDefined(); - expect(makeNodeTransport).toHaveBeenCalledTimes(1); - }); - - it('returns HTTP transport if specified in the dsn', () => { - const options = { dsn: 'http://username@domain/123' }; - const { transport, newTransport } = setupNodeTransport(options); - - expect(transport).toBeDefined(); - expect(transport).toBeInstanceOf(HTTPTransport); - expect(newTransport).toBeDefined(); - expect(makeNodeTransport).toHaveBeenCalledTimes(1); - }); -}); diff --git a/packages/tracing/src/transaction.ts b/packages/tracing/src/transaction.ts index 91fa4d3c435b..3e3c148fd5d3 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/tracing/src/transaction.ts @@ -103,11 +103,12 @@ export class Transaction extends SpanClass implements TransactionInterface { // At this point if `sampled !== true` we want to discard the transaction. IS_DEBUG_BUILD && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); - const client = this._hub.getClient(); - const transport = client && client.getTransport && client.getTransport(); - if (transport && transport.recordLostEvent) { - transport.recordLostEvent('sample_rate', 'transaction'); - } + // TODO(v7): Add back client reports functionality + // const client = this._hub.getClient(); + // const transport = client && client.getTransport && client.getTransport(); + // if (transport && transport.recordLostEvent) { + // transport.recordLostEvent('sample_rate', 'transaction'); + // } return undefined; } diff --git a/packages/tracing/test/browser/backgroundtab.test.ts b/packages/tracing/test/browser/backgroundtab.test.ts index 29612b410322..3e332033d74d 100644 --- a/packages/tracing/test/browser/backgroundtab.test.ts +++ b/packages/tracing/test/browser/backgroundtab.test.ts @@ -1,11 +1,10 @@ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import { JSDOM } from 'jsdom'; import { registerBackgroundTabDetection } from '../../src/browser/backgroundtab'; import { addExtensionMethods } from '../../src/hubextensions'; +import { getDefaultBrowserClientOptions } from '../testutils'; describe('registerBackgroundTabDetection', () => { let events: Record = {}; @@ -16,7 +15,7 @@ describe('registerBackgroundTabDetection', () => { global.document = dom.window.document; const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + hub = new Hub(new BrowserClient(options)); makeMain(hub); // If we do not add extension methods, invoking hub.startTransaction returns undefined diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index 76ccaf947271..5cb144cfd207 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,6 +1,4 @@ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import { getGlobalObject, InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; @@ -18,6 +16,7 @@ import { instrumentRoutingWithDefaults } from '../../src/browser/router'; import * as hubExtensions from '../../src/hubextensions'; import { DEFAULT_IDLE_TIMEOUT, IdleTransaction } from '../../src/idletransaction'; import { getActiveTransaction, secToMs } from '../../src/utils'; +import { getDefaultBrowserClientOptions } from '../testutils'; let mockChangeHistory: ({ to, from }: { to: string; from?: string }) => void = () => undefined; @@ -54,7 +53,7 @@ describe('BrowserTracing', () => { beforeEach(() => { jest.useFakeTimers(); const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + hub = new Hub(new BrowserClient(options)); makeMain(hub); document.head.innerHTML = ''; @@ -476,7 +475,7 @@ describe('BrowserTracing', () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); + hub.bindClient(new BrowserClient(options)); // setting up the BrowserTracing integration automatically starts a pageload transaction createBrowserTracing(true); @@ -493,7 +492,7 @@ describe('BrowserTracing', () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - hub.bindClient(new BrowserClient(options, setupBrowserTransport(options).transport)); + hub.bindClient(new BrowserClient(options)); // setting up the BrowserTracing integration normally automatically starts a pageload transaction, but that's not // what we're testing here createBrowserTracing(true, { startTransactionOnPageLoad: false }); diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index 4ead6fe5bb9b..e77a0ae15c36 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -1,6 +1,4 @@ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import * as utils from '@sentry/utils'; @@ -8,6 +6,7 @@ import { Span, spanStatusfromHttpCode, Transaction } from '../../src'; import { fetchCallback, FetchData, instrumentOutgoingRequests, xhrCallback } from '../../src/browser/request'; import { addExtensionMethods } from '../../src/hubextensions'; import * as tracingUtils from '../../src/utils'; +import { getDefaultBrowserClientOptions } from '../testutils'; beforeAll(() => { addExtensionMethods(); @@ -75,7 +74,7 @@ describe('callbacks', () => { beforeAll(() => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + hub = new Hub(new BrowserClient(options)); makeMain(hub); }); diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index 8dbcb2454539..6d3a3fa50768 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,11 +1,10 @@ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { NoopTransport } from '@sentry/core/src/transports/noop'; import { Hub, makeMain } from '@sentry/hub'; import { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { registerErrorInstrumentation } from '../src/errors'; import { _addTracingExtensions } from '../src/hubextensions'; +import { getDefaultBrowserClientOptions } from './testutils'; const mockAddInstrumentationHandler = jest.fn(); let mockErrorCallback: InstrumentHandlerCallback = () => undefined; @@ -36,8 +35,8 @@ describe('registerErrorHandlers()', () => { let hub: Hub; beforeEach(() => { mockAddInstrumentationHandler.mockClear(); - const options = { tracesSampleRate: 1, transport: NoopTransport, integrations: [], stackParser: () => [] }; - hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const options = getDefaultBrowserClientOptions(); + hub = new Hub(new BrowserClient(options)); makeMain(hub); }); diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 6df8bad175c1..5fe7d84066ab 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -1,7 +1,5 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain } from '@sentry/hub'; import * as utilsModule from '@sentry/utils'; // for mocking import { logger } from '@sentry/utils'; @@ -10,7 +8,12 @@ import { BrowserTracing } from '../src/browser/browsertracing'; import { addExtensionMethods } from '../src/hubextensions'; import { Transaction } from '../src/transaction'; import { extractTraceparentData, TRACEPARENT_REGEXP } from '../src/utils'; -import { addDOMPropertiesToGlobal, getSymbolObjectKeyByName, testOnlyIfNodeVersionAtLeast } from './testutils'; +import { + addDOMPropertiesToGlobal, + getDefaultBrowserClientOptions, + getSymbolObjectKeyByName, + testOnlyIfNodeVersionAtLeast, +} from './testutils'; addExtensionMethods(); @@ -35,7 +38,7 @@ describe('Hub', () => { describe('getTransaction()', () => { it('should find a transaction which has been set on the scope if sampled = true', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); transaction.sampled = true; @@ -49,7 +52,7 @@ describe('Hub', () => { it('should find a transaction which has been set on the scope if sampled = false', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -62,7 +65,7 @@ describe('Hub', () => { it("should not find an open transaction if it's not on the scope", () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -75,7 +78,7 @@ describe('Hub', () => { it('should add transaction context data to default sample context', () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transactionContext = { @@ -92,7 +95,7 @@ describe('Hub', () => { it("should add parent's sampling decision to default sample context", () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const parentSamplingDecsion = false; @@ -112,7 +115,7 @@ describe('Hub', () => { it('should set sampled = false when tracing is disabled', () => { const options = getDefaultBrowserClientOptions({}); // neither tracesSampleRate nor tracesSampler is defined -> tracing disabled - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -121,7 +124,7 @@ describe('Hub', () => { it('should set sampled = false if tracesSampleRate is 0', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -130,7 +133,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampleRate is 1', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -139,7 +142,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampleRate is 1 (without global hub)', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); const transaction = hub.startTransaction({ name: 'dogpark' }); expect(transaction.sampled).toBe(true); @@ -148,7 +151,7 @@ describe('Hub', () => { it("should call tracesSampler if it's defined", () => { const tracesSampler = jest.fn(); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -158,7 +161,7 @@ describe('Hub', () => { it('should set sampled = false if tracesSampler returns 0', () => { const tracesSampler = jest.fn().mockReturnValue(0); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -169,7 +172,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1', () => { const tracesSampler = jest.fn().mockReturnValue(1); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -180,7 +183,7 @@ describe('Hub', () => { it('should set sampled = true if tracesSampler returns 1 (without global hub)', () => { const tracesSampler = jest.fn().mockReturnValue(1); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); const transaction = hub.startTransaction({ name: 'dogpark' }); expect(tracesSampler).toHaveBeenCalled(); @@ -191,7 +194,7 @@ describe('Hub', () => { // so that the decision otherwise would be false const tracesSampler = jest.fn().mockReturnValue(0); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -202,7 +205,7 @@ describe('Hub', () => { // so that the decision otherwise would be true const tracesSampler = jest.fn().mockReturnValue(1); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -213,7 +216,7 @@ describe('Hub', () => { // make the two options do opposite things to prove precedence const tracesSampler = jest.fn().mockReturnValue(true); const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0, tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -224,7 +227,7 @@ describe('Hub', () => { it('should tolerate tracesSampler returning a boolean', () => { const tracesSampler = jest.fn().mockReturnValue(true); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -235,7 +238,7 @@ describe('Hub', () => { it('should record sampling method when sampling decision is explicitly set', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark', sampled: true }); @@ -247,7 +250,7 @@ describe('Hub', () => { it('should record sampling method and rate when sampling decision comes from tracesSampler', () => { const tracesSampler = jest.fn().mockReturnValue(0.1121); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -258,7 +261,7 @@ describe('Hub', () => { it('should record sampling method when sampling decision is inherited', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark', parentSampled: true }); @@ -269,7 +272,7 @@ describe('Hub', () => { it('should record sampling method and rate when sampling decision comes from traceSampleRate', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -282,7 +285,7 @@ describe('Hub', () => { describe('isValidSampleRate()', () => { it("should reject tracesSampleRates which aren't numbers or booleans", () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -291,7 +294,7 @@ describe('Hub', () => { it('should reject tracesSampleRates which are NaN', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -301,7 +304,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates less than 0', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: -26 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -311,7 +314,7 @@ describe('Hub', () => { // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 it('should reject tracesSampleRates greater than 1', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 26 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -321,7 +324,7 @@ describe('Hub', () => { it("should reject tracesSampler return values which aren't numbers or booleans", () => { const tracesSampler = jest.fn().mockReturnValue('dogs!'); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -331,7 +334,7 @@ describe('Hub', () => { it('should reject tracesSampler return values which are NaN', () => { const tracesSampler = jest.fn().mockReturnValue(NaN); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -342,7 +345,7 @@ describe('Hub', () => { it('should reject tracesSampler return values less than 0', () => { const tracesSampler = jest.fn().mockReturnValue(-12); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -353,7 +356,7 @@ describe('Hub', () => { it('should reject tracesSampler return values greater than 1', () => { const tracesSampler = jest.fn().mockReturnValue(31); const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); hub.startTransaction({ name: 'dogpark' }); @@ -363,7 +366,7 @@ describe('Hub', () => { it('should drop transactions with sampled = false', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); - const client = new BrowserClient(options, setupBrowserTransport(options).transport); + const client = new BrowserClient(options); jest.spyOn(client, 'captureEvent'); const hub = new Hub(client); @@ -381,7 +384,7 @@ describe('Hub', () => { describe('sampling inheritance', () => { it('should propagate sampling decision to child spans', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: Math.random() }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); const child = transaction.startChild({ op: 'ball.chase' }); @@ -398,7 +401,7 @@ describe('Hub', () => { tracesSampleRate: 1, integrations: [new BrowserTracing()], }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark' }); @@ -439,7 +442,7 @@ describe('Hub', () => { tracesSampleRate: 1, integrations: [new BrowserTracing()], }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); @@ -485,7 +488,7 @@ describe('Hub', () => { // tracesSampleRate mathRandom.mockReturnValueOnce(1); const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.5 }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const parentSamplingDecsion = true; @@ -502,7 +505,7 @@ describe('Hub', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); // tracesSampleRate = 1 means every transaction should end up with sampled = true, so make parent's decision the // opposite to prove that inheritance takes precedence over tracesSampleRate - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const parentSamplingDecsion = false; @@ -522,7 +525,7 @@ describe('Hub', () => { const parentSamplingDecsion = false; const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ @@ -541,7 +544,7 @@ describe('Hub', () => { const parentSamplingDecsion = true; const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const hub = new Hub(new BrowserClient(options)); makeMain(hub); const transaction = hub.startTransaction({ diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index b040f4adbd9b..e6035ad491a1 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -1,5 +1,4 @@ -import { BrowserClient, Transports } from '@sentry/browser'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; +import { BrowserClient } from '@sentry/browser'; import { Hub } from '@sentry/hub'; import { @@ -9,16 +8,13 @@ import { IdleTransactionSpanRecorder, } from '../src/idletransaction'; import { Span } from '../src/span'; - -// @ts-ignore It's okay that we're not implementing the methods of the abstract `BaseTransport` class, because it's not -// what we're testing here -class SimpleTransport extends Transports.BaseTransport {} +import { getDefaultBrowserClientOptions } from './testutils'; const dsn = 'https://123@sentry.io/42'; let hub: Hub; beforeEach(() => { - const options = getDefaultBrowserClientOptions({ dsn, tracesSampleRate: 1, transport: SimpleTransport }); - hub = new Hub(new BrowserClient(options, new SimpleTransport({ dsn }))); + const options = getDefaultBrowserClientOptions({ dsn, tracesSampleRate: 1 }); + hub = new Hub(new BrowserClient(options)); }); describe('IdleTransaction', () => { @@ -167,18 +163,19 @@ describe('IdleTransaction', () => { } }); - it('should record dropped transactions', async () => { - const transaction = new IdleTransaction({ name: 'foo', startTimestamp: 1234, sampled: false }, hub, 1000); + // TODO(v7): Add with client reports + // it('should record dropped transactions', async () => { + // const transaction = new IdleTransaction({ name: 'foo', startTimestamp: 1234, sampled: false }, hub, 1000); - const transport = hub.getClient()!.getTransport!(); + // const transport = hub.getClient()!.getTransport!(); - const spy = jest.spyOn(transport, 'recordLostEvent'); + // const spy = jest.spyOn(transport, 'recordLostEvent'); - transaction.initSpanRecorder(10); - transaction.finish(transaction.startTimestamp + 10); + // transaction.initSpanRecorder(10); + // transaction.finish(transaction.startTimestamp + 10); - expect(spy).toHaveBeenCalledWith('sample_rate', 'transaction'); - }); + // expect(spy).toHaveBeenCalledWith('sample_rate', 'transaction'); + // }); describe('_initTimeout', () => { it('finishes if no activities are added to the transaction', () => { diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index 13f47c51ae7b..27df400ffc9e 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -1,10 +1,9 @@ import { BrowserClient } from '@sentry/browser'; -import { setupBrowserTransport } from '@sentry/browser/src/transports'; -import { getDefaultBrowserClientOptions } from '@sentry/browser/test/unit/helper/browser-client-options'; import { Hub, makeMain, Scope } from '@sentry/hub'; import { Span, Transaction } from '../src'; import { TRACEPARENT_REGEXP } from '../src/utils'; +import { getDefaultBrowserClientOptions } from './testutils'; describe('Span', () => { let hub: Hub; @@ -12,7 +11,7 @@ describe('Span', () => { beforeEach(() => { const myScope = new Scope(); const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport), myScope); + hub = new Hub(new BrowserClient(options), myScope); makeMain(hub); }); @@ -223,7 +222,7 @@ describe('Span', () => { _experiments: { maxSpans: 3 }, tracesSampleRate: 1, }); - const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const _hub = new Hub(new BrowserClient(options)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test' }); for (let i = 0; i < 10; i++) { @@ -238,7 +237,7 @@ describe('Span', () => { const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1, }); - const _hub = new Hub(new BrowserClient(options, setupBrowserTransport(options).transport)); + const _hub = new Hub(new BrowserClient(options)); const spy = jest.spyOn(_hub as any, 'captureEvent') as any; const transaction = _hub.startTransaction({ name: 'test', sampled: false }); for (let i = 0; i < 10; i++) { diff --git a/packages/tracing/test/testutils.ts b/packages/tracing/test/testutils.ts index a8f42f84b9b8..2c0aef189b57 100644 --- a/packages/tracing/test/testutils.ts +++ b/packages/tracing/test/testutils.ts @@ -1,4 +1,6 @@ -import { getGlobalObject } from '@sentry/utils'; +import { createTransport } from '@sentry/browser'; +import { ClientOptions } from '@sentry/types'; +import { getGlobalObject, resolvedSyncPromise } from '@sentry/utils'; import { JSDOM } from 'jsdom'; /** @@ -56,3 +58,12 @@ export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => { return it; }; + +export function getDefaultBrowserClientOptions(options: Partial = {}): ClientOptions { + return { + integrations: [], + transport: () => createTransport({}, _ => resolvedSyncPromise({ statusCode: 200 })), + stackParser: () => [], + ...options, + }; +} diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index f0cdc8b3a988..b1cadf971197 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -3,9 +3,9 @@ import { Event, EventHint } from './event'; import { Integration, IntegrationClass } from './integration'; import { ClientOptions } from './options'; import { Scope } from './scope'; -import { Session } from './session'; +import { Session, SessionAggregates } from './session'; import { Severity, SeverityLevel } from './severity'; -import { Transport } from './transport'; +import { NewTransport } from './transport'; /** * User-Facing Sentry SDK Client. @@ -72,7 +72,7 @@ export interface Client { * * @returns The transport. */ - getTransport?(): Transport; + getTransport(): NewTransport | undefined; /** * Flush the event queue and set the client to `enabled = false`. See {@link Client.flush}. @@ -116,5 +116,5 @@ export interface Client { sendEvent(event: Event): void; /** Submits the session to Sentry */ - sendSession(session: Session): void; + sendSession(session: Session | SessionAggregates): void; } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 5fe4ced6375b..3c066e3cc0bf 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -62,6 +62,18 @@ export type { TransactionSamplingMethod, } from './transaction'; export type { Thread } from './thread'; -export type { Outcome, Transport, TransportOptions, TransportClass } from './transport'; +export type { + Outcome, + Transport, + TransportOptions, + TransportCategory, + TransportRequest, + TransportMakeRequestResponse, + TransportResponse, + InternalBaseTransportOptions, + BaseTransportOptions, + NewTransport, + TransportRequestExecutor, +} from './transport'; export type { User, UserFeedback } from './user'; export type { WrappedFunction } from './wrappedfunction'; diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 8bd273752700..61188d6c099f 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -5,9 +5,9 @@ import { CaptureContext } from './scope'; import { SdkMetadata } from './sdkmetadata'; import { StackLineParser, StackParser } from './stacktrace'; import { SamplingContext } from './transaction'; -import { Transport, TransportClass, TransportOptions } from './transport'; +import { BaseTransportOptions, NewTransport } from './transport'; -export interface ClientOptions { +export interface ClientOptions { /** * Enable debug functionality in the SDK itself */ @@ -61,7 +61,7 @@ export interface ClientOptions { /** * Transport object that should be used to send events to Sentry */ - transport: TransportClass; + transport: (transportOptions: TO) => NewTransport; /** * A stack parser implementation @@ -72,7 +72,7 @@ export interface ClientOptions { /** * Options for the default transport that the SDK uses. */ - transportOptions?: TransportOptions; + transportOptions?: Partial; /** * Sample rate to determine trace sampling. @@ -202,7 +202,8 @@ export interface ClientOptions { } /** Base configuration options for every SDK. */ -export interface Options extends Omit, 'integrations' | 'transport' | 'stackParser'> { +export interface Options + extends Omit>, 'integrations' | 'transport' | 'stackParser'> { /** * If this is set to false, default integrations will not be added, otherwise this will internally be set to the * recommended default integrations. @@ -220,7 +221,7 @@ export interface Options extends Omit, 'integrations' | ' /** * Transport object that should be used to send events to Sentry */ - transport?: TransportClass; + transport?: (transportOptions: TO) => NewTransport; /** * A stack parser implementation or an array of stack line parsers diff --git a/packages/types/src/session.ts b/packages/types/src/session.ts index 552dda002531..237e4c41808d 100644 --- a/packages/types/src/session.ts +++ b/packages/types/src/session.ts @@ -74,9 +74,6 @@ export interface SessionFlusherLike { */ incrementSessionStatusCount(): void; - /** Submits the aggregates request mode sessions to Sentry */ - sendSessionAggregates(sessionAggregates: SessionAggregates): void; - /** Empties Aggregate Buckets and Sends them to Transport Buffer */ flush(): void; diff --git a/packages/types/src/transport.ts b/packages/types/src/transport.ts index a1ba2983b1a3..1250d4cb01d5 100644 --- a/packages/types/src/transport.ts +++ b/packages/types/src/transport.ts @@ -1,5 +1,7 @@ import { DsnLike } from './dsn'; +import { Envelope } from './envelope'; import { Event } from './event'; +import { EventStatus } from './eventstatus'; import { SentryRequestType } from './request'; import { Response } from './response'; import { SdkMetadata } from './sdkmetadata'; @@ -13,6 +15,46 @@ export type Outcome = | 'ratelimit_backoff' | 'sample_rate'; +export type TransportCategory = 'error' | 'transaction' | 'attachment' | 'session'; + +export type TransportRequest = { + body: string; + category: TransportCategory; +}; + +export type TransportMakeRequestResponse = { + body?: string; + headers?: { + [key: string]: string | null; + 'x-sentry-rate-limits': string | null; + 'retry-after': string | null; + }; + reason?: string; + statusCode: number; +}; + +export type TransportResponse = { + status: EventStatus; + reason?: string; +}; + +export interface InternalBaseTransportOptions { + bufferSize?: number; +} +export interface BaseTransportOptions extends InternalBaseTransportOptions { + // url to send the event + // transport does not care about dsn specific - client should take care of + // parsing and figuring that out + url: string; +} + +export interface NewTransport { + send(request: Envelope): PromiseLike; + flush(timeout?: number): PromiseLike; +} + +export type TransportRequestExecutor = (request: TransportRequest) => PromiseLike; + /** Transport used sending data to Sentry */ export interface Transport { /** From c930bf0a41891f2775fc6d60ad7d665c8ffdaf91 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:23:06 -0400 Subject: [PATCH 72/94] port CaptureException --- packages/hub/src/exports.ts | 29 +++++++++++++++++++++++++++++ packages/hub/src/hub.ts | 26 ++++++++------------------ packages/minimal/src/index.ts | 17 ----------------- 3 files changed, 37 insertions(+), 35 deletions(-) create mode 100644 packages/hub/src/exports.ts diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts new file mode 100644 index 000000000000..e90ffcde6962 --- /dev/null +++ b/packages/hub/src/exports.ts @@ -0,0 +1,29 @@ +import { CaptureContext, Hub } from '@sentry/types'; + +import { getCurrentHub } from './hub'; + +/** + * This calls a function on the current hub. + * @param method function to call on hub. + * @param args to pass to function. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function callOnHub(method: string, ...args: any[]): T { + const hub = getCurrentHub(); + if (hub && hub[method as keyof Hub]) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (hub[method as keyof Hub] as any)(...args); + } + throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); +} + +/** + * Captures an exception event and sends it to Sentry. + * + * @param exception An exception-like object. + * @returns The generated eventId. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types +export function captureException(exception: any, captureContext?: CaptureContext): string { + return getCurrentHub().captureException(exception, { captureContext }); +} diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index 74a810fafeea..071e89ef4e8b 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -185,27 +185,17 @@ export class Hub implements HubInterface { // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types public captureException(exception: any, hint?: EventHint): string { const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4()); - let finalHint = hint; - // If there's no explicit hint provided, mimic the same thing that would happen - // in the minimal itself to create a consistent behavior. - // We don't do this in the client, as it's the lowest level API, and doing this, - // would prevent user from having full control over direct calls. - if (!hint) { - let syntheticException: Error; - try { - throw new Error('Sentry syntheticException'); - } catch (exception) { - syntheticException = exception as Error; - } - finalHint = { - originalException: exception, - syntheticException, - }; + let syntheticException: Error; + try { + throw new Error('Sentry syntheticException'); + } catch (exception) { + syntheticException = exception as Error; } - this._invokeClient('captureException', exception, { - ...finalHint, + originalException: exception, + syntheticException, + ...hint, event_id: eventId, }); return eventId; diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 7cb0271786ab..3c203d618fd6 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,23 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Captures an exception event and sends it to Sentry. - * - * @param exception An exception-like object. - * @returns The generated eventId. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -export function captureException(exception: any, captureContext?: CaptureContext): string { - const syntheticException = new Error('Sentry syntheticException'); - - return callOnHub('captureException', exception, { - captureContext, - originalException: exception, - syntheticException, - }); -} - /** * Captures a message event and sends it to Sentry. * From b4b722194f2afe5d4dbbf5b88e978efa8193d3a0 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:26:49 -0400 Subject: [PATCH 73/94] port captureMessage --- packages/hub/src/exports.ts | 21 ++++++++++++++++++++- packages/hub/src/hub.ts | 27 +++++++++------------------ packages/minimal/src/index.ts | 26 -------------------------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index e90ffcde6962..8148e9e92d6c 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { CaptureContext, Hub } from '@sentry/types'; +import { CaptureContext, Hub, Severity, SeverityLevel } from '@sentry/types'; import { getCurrentHub } from './hub'; @@ -27,3 +27,22 @@ export function callOnHub(method: string, ...args: any[]): T { export function captureException(exception: any, captureContext?: CaptureContext): string { return getCurrentHub().captureException(exception, { captureContext }); } + +/** + * Captures a message event and sends it to Sentry. + * + * @param message The message to send to Sentry. + * @param Severity Define the level of the message. + * @returns The generated eventId. + */ +export function captureMessage( + message: string, + // eslint-disable-next-line deprecation/deprecation + captureContext?: CaptureContext | Severity | SeverityLevel, +): string { + // This is necessary to provide explicit scopes upgrade, without changing the original + // arity of the `captureMessage(message, level)` method. + const level = typeof captureContext === 'string' ? captureContext : undefined; + const context = typeof captureContext !== 'string' ? { captureContext } : undefined; + return getCurrentHub().captureMessage(message, level, context); +} diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index 071e89ef4e8b..c54bcf7b6414 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -211,27 +211,18 @@ export class Hub implements HubInterface { hint?: EventHint, ): string { const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4()); - let finalHint = hint; - - // If there's no explicit hint provided, mimic the same thing that would happen - // in the minimal itself to create a consistent behavior. - // We don't do this in the client, as it's the lowest level API, and doing this, - // would prevent user from having full control over direct calls. - if (!hint) { - let syntheticException: Error; - try { - throw new Error(message); - } catch (exception) { - syntheticException = exception as Error; - } - finalHint = { - originalException: message, - syntheticException, - }; + + let syntheticException: Error; + try { + throw new Error('Sentry syntheticException'); + } catch (exception) { + syntheticException = exception as Error; } this._invokeClient('captureMessage', message, level, { - ...finalHint, + originalException: message, + syntheticException, + ...hint, event_id: eventId, }); return eventId; diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 3c203d618fd6..caa96fd0eb32 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,32 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Captures a message event and sends it to Sentry. - * - * @param message The message to send to Sentry. - * @param Severity Define the level of the message. - * @returns The generated eventId. - */ -export function captureMessage( - message: string, - // eslint-disable-next-line deprecation/deprecation - captureContext?: CaptureContext | Severity | SeverityLevel, -): string { - const syntheticException = new Error(message); - - // This is necessary to provide explicit scopes upgrade, without changing the original - // arity of the `captureMessage(message, level)` method. - const level = typeof captureContext === 'string' ? captureContext : undefined; - const context = typeof captureContext !== 'string' ? { captureContext } : undefined; - - return callOnHub('captureMessage', message, level, { - originalException: message, - syntheticException, - ...context, - }); -} - /** * Captures a manually created event and sends it to Sentry. * From 091524bf3b87604f2e63803acc32b3e6227e7d7d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:27:43 -0400 Subject: [PATCH 74/94] port captureEvent --- packages/hub/src/exports.ts | 12 +++++++++++- packages/minimal/src/index.ts | 10 ---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 8148e9e92d6c..619d9b3692d2 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { CaptureContext, Hub, Severity, SeverityLevel } from '@sentry/types'; +import { CaptureContext, Event, Hub, Severity, SeverityLevel } from '@sentry/types'; import { getCurrentHub } from './hub'; @@ -46,3 +46,13 @@ export function captureMessage( const context = typeof captureContext !== 'string' ? { captureContext } : undefined; return getCurrentHub().captureMessage(message, level, context); } + +/** + * Captures a manually created event and sends it to Sentry. + * + * @param event The event to send to Sentry. + * @returns The generated eventId. + */ +export function captureEvent(event: Event): string { + return getCurrentHub().captureEvent(event); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index caa96fd0eb32..efbe46cbc63c 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,16 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Captures a manually created event and sends it to Sentry. - * - * @param event The event to send to Sentry. - * @returns The generated eventId. - */ -export function captureEvent(event: Event): string { - return callOnHub('captureEvent', event); -} - /** * Callback to set context information onto the scope. * @param callback Callback function that receives Scope. From 99c9af0df0c5c99e9a0ef9efa7afc3b731b18e6d Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:41:11 -0400 Subject: [PATCH 75/94] port configureScope --- packages/hub/src/exports.ts | 19 ++++++++++++++----- packages/minimal/src/index.ts | 8 -------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 619d9b3692d2..274a71cd907c 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,6 +1,7 @@ -import { CaptureContext, Event, Hub, Severity, SeverityLevel } from '@sentry/types'; +import { CaptureContext, Event, Severity, SeverityLevel } from '@sentry/types'; -import { getCurrentHub } from './hub'; +import { getCurrentHub, Hub } from './hub'; +import { Scope } from './scope'; /** * This calls a function on the current hub. @@ -24,7 +25,7 @@ export function callOnHub(method: string, ...args: any[]): T { * @returns The generated eventId. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -export function captureException(exception: any, captureContext?: CaptureContext): string { +export function captureException(exception: any, captureContext?: CaptureContext): ReturnType { return getCurrentHub().captureException(exception, { captureContext }); } @@ -39,7 +40,7 @@ export function captureMessage( message: string, // eslint-disable-next-line deprecation/deprecation captureContext?: CaptureContext | Severity | SeverityLevel, -): string { +): ReturnType { // This is necessary to provide explicit scopes upgrade, without changing the original // arity of the `captureMessage(message, level)` method. const level = typeof captureContext === 'string' ? captureContext : undefined; @@ -53,6 +54,14 @@ export function captureMessage( * @param event The event to send to Sentry. * @returns The generated eventId. */ -export function captureEvent(event: Event): string { +export function captureEvent(event: Event): ReturnType { return getCurrentHub().captureEvent(event); } + +/** + * Callback to set context information onto the scope. + * @param callback Callback function that receives Scope. + */ +export function configureScope(callback: (scope: Scope) => void): ReturnType { + return getCurrentHub().configureScope(callback); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index efbe46cbc63c..9b6212864809 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,14 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Callback to set context information onto the scope. - * @param callback Callback function that receives Scope. - */ -export function configureScope(callback: (scope: Scope) => void): void { - callOnHub('configureScope', callback); -} - /** * Records a new breadcrumb which will be attached to future events. * From 3d3dd2b2dc8ee99c499d0607a6a000ef8d272148 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:52:33 -0400 Subject: [PATCH 76/94] port addBreadcrumb --- packages/hub/src/exports.ts | 14 +++++++++++++- packages/minimal/src/index.ts | 12 ------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 274a71cd907c..5b3559b9993d 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { CaptureContext, Event, Severity, SeverityLevel } from '@sentry/types'; +import { Breadcrumb, CaptureContext, Event, Severity, SeverityLevel } from '@sentry/types'; import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; @@ -65,3 +65,15 @@ export function captureEvent(event: Event): ReturnType { export function configureScope(callback: (scope: Scope) => void): ReturnType { return getCurrentHub().configureScope(callback); } + +/** + * Records a new breadcrumb which will be attached to future events. + * + * Breadcrumbs will be added to subsequent events to provide more context on + * user's actions prior to an error or crash. + * + * @param breadcrumb The breadcrumb to record. + */ +export function addBreadcrumb(breadcrumb: Breadcrumb): ReturnType { + return getCurrentHub().addBreadcrumb(breadcrumb); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 9b6212864809..dd5909bbb5f5 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,18 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Records a new breadcrumb which will be attached to future events. - * - * Breadcrumbs will be added to subsequent events to provide more context on - * user's actions prior to an error or crash. - * - * @param breadcrumb The breadcrumb to record. - */ -export function addBreadcrumb(breadcrumb: Breadcrumb): void { - callOnHub('addBreadcrumb', breadcrumb); -} - /** * Sets context data with the given name. * @param name of the context From f5023740d170a0473787e58a6515bfc9613b0c47 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:53:52 -0400 Subject: [PATCH 77/94] port setContext --- packages/hub/src/exports.ts | 10 ++++++++++ packages/minimal/src/index.ts | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 5b3559b9993d..1dec47917e70 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -77,3 +77,13 @@ export function configureScope(callback: (scope: Scope) => void): ReturnType { return getCurrentHub().addBreadcrumb(breadcrumb); } + +/** + * Sets context data with the given name. + * @param name of the context + * @param context Any kind of data. This data will be normalized. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function setContext(name: string, context: { [key: string]: any } | null): ReturnType { + return getCurrentHub().setContext(name, context); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index dd5909bbb5f5..afe9f546de88 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,16 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Sets context data with the given name. - * @param name of the context - * @param context Any kind of data. This data will be normalized. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function setContext(name: string, context: { [key: string]: any } | null): void { - callOnHub('setContext', name, context); -} - /** * Set an object that will be merged sent as extra data with the event. * @param extras Extras object to merge into current context. From fb505be2dbfbeb444af3d6274ff7fe128ffe5d20 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:55:07 -0400 Subject: [PATCH 78/94] port setExtras --- packages/hub/src/exports.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 1dec47917e70..2c02f4385d79 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { Breadcrumb, CaptureContext, Event, Severity, SeverityLevel } from '@sentry/types'; +import { Breadcrumb, CaptureContext, Event, Severity, SeverityLevel, Extras } from '@sentry/types'; import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; @@ -63,7 +63,7 @@ export function captureEvent(event: Event): ReturnType { * @param callback Callback function that receives Scope. */ export function configureScope(callback: (scope: Scope) => void): ReturnType { - return getCurrentHub().configureScope(callback); + getCurrentHub().configureScope(callback); } /** @@ -75,7 +75,7 @@ export function configureScope(callback: (scope: Scope) => void): ReturnType { - return getCurrentHub().addBreadcrumb(breadcrumb); + getCurrentHub().addBreadcrumb(breadcrumb); } /** @@ -85,5 +85,13 @@ export function addBreadcrumb(breadcrumb: Breadcrumb): ReturnType { - return getCurrentHub().setContext(name, context); + getCurrentHub().setContext(name, context); +} + +/** + * Set an object that will be merged sent as extra data with the event. + * @param extras Extras object to merge into current context. + */ +export function setExtras(extras: Extras): ReturnType { + getCurrentHub().setExtras(extras); } From 79470f054829742e6efbc1d4f3c2d6da8ed63dc4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:56:24 -0400 Subject: [PATCH 79/94] port setTags --- packages/hub/src/exports.ts | 10 +++++++++- packages/minimal/src/index.ts | 16 ---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 2c02f4385d79..66f277e10bda 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { Breadcrumb, CaptureContext, Event, Severity, SeverityLevel, Extras } from '@sentry/types'; +import { Breadcrumb, CaptureContext, Event, Extras, Primitive, Severity, SeverityLevel } from '@sentry/types'; import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; @@ -95,3 +95,11 @@ export function setContext(name: string, context: { [key: string]: any } | null) export function setExtras(extras: Extras): ReturnType { getCurrentHub().setExtras(extras); } + +/** + * Set an object that will be merged sent as tags data with the event. + * @param tags Tags context object to merge into current context. + */ +export function setTags(tags: { [key: string]: Primitive }): ReturnType { + getCurrentHub().setTags(tags); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index afe9f546de88..8be95962387c 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,22 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Set an object that will be merged sent as extra data with the event. - * @param extras Extras object to merge into current context. - */ -export function setExtras(extras: Extras): void { - callOnHub('setExtras', extras); -} - -/** - * Set an object that will be merged sent as tags data with the event. - * @param tags Tags context object to merge into current context. - */ -export function setTags(tags: { [key: string]: Primitive }): void { - callOnHub('setTags', tags); -} - /** * Set key:value that will be sent as extra data with the event. * @param key String of extra From 03d08b09b43c6e11deafcdf561ff4465a597d7ea Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:57:07 -0400 Subject: [PATCH 80/94] port setExtra --- packages/hub/src/exports.ts | 11 ++++++++++- packages/minimal/src/index.ts | 9 --------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 66f277e10bda..f385f4bc3f83 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,4 @@ -import { Breadcrumb, CaptureContext, Event, Extras, Primitive, Severity, SeverityLevel } from '@sentry/types'; +import { Breadcrumb, CaptureContext, Event, Extra, Extras, Primitive, Severity, SeverityLevel } from '@sentry/types'; import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; @@ -96,6 +96,15 @@ export function setExtras(extras: Extras): ReturnType { getCurrentHub().setExtras(extras); } +/** + * Set key:value that will be sent as extra data with the event. + * @param key String of extra + * @param extra Any kind of data. This data will be normalized. + */ +export function setExtra(key: string, extra: Extra): ReturnType { + getCurrentHub().setExtra(key, extra); +} + /** * Set an object that will be merged sent as tags data with the event. * @param tags Tags context object to merge into current context. diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 8be95962387c..a54cd7dbb3e9 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,15 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Set key:value that will be sent as extra data with the event. - * @param key String of extra - * @param extra Any kind of data. This data will be normalized. - */ -export function setExtra(key: string, extra: Extra): void { - callOnHub('setExtra', key, extra); -} - /** * Set key:value that will be sent as tags data with the event. * From e44b2590d6787ff34883341a42a633e2190a6175 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:57:43 -0400 Subject: [PATCH 81/94] port setTag --- packages/hub/src/exports.ts | 12 ++++++++++++ packages/minimal/src/index.ts | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index f385f4bc3f83..4d163b0556bc 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -112,3 +112,15 @@ export function setExtra(key: string, extra: Extra): ReturnType export function setTags(tags: { [key: string]: Primitive }): ReturnType { getCurrentHub().setTags(tags); } + +/** + * 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 + */ +export function setTag(key: string, value: Primitive): ReturnType { + getCurrentHub().setTag(key, value); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index a54cd7dbb3e9..7789b7628d69 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,18 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * 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 - */ -export function setTag(key: string, value: Primitive): void { - callOnHub('setTag', key, value); -} - /** * Updates user context information for future events. * From 764be243de43aa5baa873b3ed6d04f4a57c7ac5f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:59:11 -0400 Subject: [PATCH 82/94] port setUser --- packages/hub/src/exports.ts | 21 ++++++++++++++++++++- packages/minimal/src/index.ts | 9 --------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 4d163b0556bc..0c2d7f3ed83e 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,4 +1,14 @@ -import { Breadcrumb, CaptureContext, Event, Extra, Extras, Primitive, Severity, SeverityLevel } from '@sentry/types'; +import { + Breadcrumb, + CaptureContext, + Event, + Extra, + Extras, + Primitive, + Severity, + SeverityLevel, + User, +} from '@sentry/types'; import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; @@ -124,3 +134,12 @@ export function setTags(tags: { [key: string]: Primitive }): ReturnType { getCurrentHub().setTag(key, value); } + +/** + * Updates user context information for future events. + * + * @param user User context object to be set in the current context. Pass `null` to unset the user. + */ +export function setUser(user: User | null): ReturnType { + getCurrentHub().setUser(user); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 7789b7628d69..85f8708092e3 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,15 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Updates user context information for future events. - * - * @param user User context object to be set in the current context. Pass `null` to unset the user. - */ -export function setUser(user: User | null): void { - callOnHub('setUser', user); -} - /** * Creates a new scope with and executes the given operation within. * The scope is automatically removed once the operation From 38eabe3a7ff331505307a8ab75f02fd8d06e7be2 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 10:59:57 -0400 Subject: [PATCH 83/94] port withScope --- packages/hub/src/exports.ts | 17 +++++++++++++++++ packages/minimal/src/index.ts | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 0c2d7f3ed83e..f9918b2df109 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -143,3 +143,20 @@ export function setTag(key: string, value: Primitive): ReturnType export function setUser(user: User | null): ReturnType { getCurrentHub().setUser(user); } + +/** + * Creates a new scope with and executes the given operation within. + * The scope is automatically removed once the operation + * finishes or throws. + * + * This is essentially a convenience function for: + * + * pushScope(); + * callback(); + * popScope(); + * + * @param callback that will be enclosed into push/popScope. + */ +export function withScope(callback: (scope: Scope) => void): ReturnType { + getCurrentHub().withScope(callback); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 85f8708092e3..5d7cec9f13e9 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,23 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Creates a new scope with and executes the given operation within. - * The scope is automatically removed once the operation - * finishes or throws. - * - * This is essentially a convenience function for: - * - * pushScope(); - * callback(); - * popScope(); - * - * @param callback that will be enclosed into push/popScope. - */ -export function withScope(callback: (scope: Scope) => void): void { - callOnHub('withScope', callback); -} - /** * Calls a function on the latest client. Use this with caution, it's meant as * in "internal" helper so we don't need to expose every possible function in From 97d161a09696ebad421b29a639a6b8776a335b0b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:00:38 -0400 Subject: [PATCH 84/94] delete invokeClient --- packages/minimal/src/index.ts | 15 --------------- packages/minimal/test/lib/minimal.test.ts | 12 ------------ 2 files changed, 27 deletions(-) diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index 5d7cec9f13e9..fd5519089b17 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -29,21 +29,6 @@ function callOnHub(method: string, ...args: any[]): T { throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } -/** - * Calls a function on the latest client. Use this with caution, it's meant as - * in "internal" helper so we don't need to expose every possible function in - * the shim. It is not guaranteed that the client actually implements the - * function. - * - * @param method The method to call on the client/client. - * @param args Arguments to pass to the client/fontend. - * @hidden - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function _callOnClient(method: string, ...args: any[]): void { - callOnHub('_invokeClient', method, ...args); -} - /** * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. * diff --git a/packages/minimal/test/lib/minimal.test.ts b/packages/minimal/test/lib/minimal.test.ts index 48a117cd5c5d..764ebbb2e728 100644 --- a/packages/minimal/test/lib/minimal.test.ts +++ b/packages/minimal/test/lib/minimal.test.ts @@ -1,7 +1,6 @@ import { getCurrentHub, getHubFromCarrier, Scope } from '@sentry/hub'; import { - _callOnClient, captureEvent, captureException, captureMessage, @@ -196,17 +195,6 @@ describe('Minimal', () => { expect(getCurrentHub().getClient()).toBe(TestClient.instance); }); - test('Calls function on the client', done => { - const s = jest.spyOn(TestClient.prototype, 'mySecretPublicMethod'); - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(new TestClient({}) as any); - _callOnClient('mySecretPublicMethod', 'test'); - expect(s.mock.calls[0][0]).toBe('test'); - s.mockRestore(); - done(); - }); - }); - test('does not throw an error when pushing different clients', () => { init({}); expect(() => { From e9ce4791081052a7828006b1f7a08c50876e9b71 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:02:13 -0400 Subject: [PATCH 85/94] port startTransaction --- packages/hub/src/exports.ts | 26 ++++++++++++++++++++++++++ packages/minimal/src/index.ts | 24 ------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index f9918b2df109..194826090f3c 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -1,12 +1,14 @@ import { Breadcrumb, CaptureContext, + CustomSamplingContext, Event, Extra, Extras, Primitive, Severity, SeverityLevel, + TransactionContext, User, } from '@sentry/types'; @@ -160,3 +162,27 @@ export function setUser(user: User | null): ReturnType { export function withScope(callback: (scope: Scope) => void): ReturnType { getCurrentHub().withScope(callback); } + +/** + * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. + * + * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a + * new child span within the transaction or any span, call the respective `.startChild()` method. + * + * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. + * + * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its + * finished child spans will be sent to Sentry. + * + * @param context Properties of the new `Transaction`. + * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent + * default values). See {@link Options.tracesSampler}. + * + * @returns The transaction which was just started + */ +export function startTransaction( + context: TransactionContext, + customSamplingContext?: CustomSamplingContext, +): ReturnType { + return getCurrentHub().startTransaction({ ...context }, customSamplingContext); +} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts index fd5519089b17..ec203aec4403 100644 --- a/packages/minimal/src/index.ts +++ b/packages/minimal/src/index.ts @@ -28,27 +28,3 @@ function callOnHub(method: string, ...args: any[]): T { } throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); } - -/** - * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation. - * - * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a - * new child span within the transaction or any span, call the respective `.startChild()` method. - * - * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded. - * - * The transaction must be finished with a call to its `.finish()` method, at which point the transaction with all its - * finished child spans will be sent to Sentry. - * - * @param context Properties of the new `Transaction`. - * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent - * default values). See {@link Options.tracesSampler}. - * - * @returns The transaction which was just started - */ -export function startTransaction( - context: TransactionContext, - customSamplingContext?: CustomSamplingContext, -): Transaction { - return callOnHub('startTransaction', { ...context }, customSamplingContext); -} From 596bafceb9d9d76378be5f9a115e194eb3cbbfba Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:02:24 -0400 Subject: [PATCH 86/94] delete callOnHub --- packages/hub/src/exports.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 194826090f3c..5e2fedb37250 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -15,21 +15,6 @@ import { import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; -/** - * This calls a function on the current hub. - * @param method function to call on hub. - * @param args to pass to function. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function callOnHub(method: string, ...args: any[]): T { - const hub = getCurrentHub(); - if (hub && hub[method as keyof Hub]) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (hub[method as keyof Hub] as any)(...args); - } - throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); -} - /** * Captures an exception event and sends it to Sentry. * From f76d41db0c9ae1a4fdd1e307f90c35cb35e3a6ac Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:05:30 -0400 Subject: [PATCH 87/94] write exports tests --- packages/hub/test/exports.test.ts | 309 ++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 packages/hub/test/exports.test.ts diff --git a/packages/hub/test/exports.test.ts b/packages/hub/test/exports.test.ts new file mode 100644 index 000000000000..8d9549014414 --- /dev/null +++ b/packages/hub/test/exports.test.ts @@ -0,0 +1,309 @@ +import { getCurrentHub, getHubFromCarrier, Scope } from '../src'; + +import { + captureEvent, + captureException, + captureMessage, + configureScope, + setContext, + setExtra, + setExtras, + setTag, + setTags, + setUser, + withScope, +} from '../src/exports'; + +export class TestClient { + public static instance?: TestClient; + + public constructor(public options: Record) { + TestClient.instance = this; + } + + public mySecretPublicMethod(str: string): string { + return `secret: ${str}`; + } +} + +export class TestClient2 {} + +export function init(options: Record): void { + getCurrentHub().bindClient(new TestClient(options) as any); +} + +// eslint-disable-next-line no-var +declare var global: any; + +describe('Top Level API', () => { + beforeEach(() => { + global.__SENTRY__ = { + hub: undefined, + }; + }); + + describe('Capture', () => { + test('Return an event_id', () => { + const client: any = { + captureException: jest.fn(async () => Promise.resolve()), + }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const e = new Error('test exception'); + const eventId = captureException(e); + expect(eventId).toBeTruthy(); + }); + }); + + test('Exception', () => { + const client: any = { + captureException: jest.fn(async () => Promise.resolve()), + }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const e = new Error('test exception'); + captureException(e); + expect(client.captureException.mock.calls[0][0]).toBe(e); + }); + }); + + test('Exception with explicit scope', () => { + const client: any = { + captureException: jest.fn(async () => Promise.resolve()), + }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const e = new Error('test exception'); + const captureContext = { extra: { foo: 'wat' } }; + captureException(e, captureContext); + expect(client.captureException.mock.calls[0][0]).toBe(e); + expect(client.captureException.mock.calls[0][1].captureContext).toBe(captureContext); + }); + }); + + test('Message', () => { + const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const message = 'yo'; + captureMessage(message); + expect(client.captureMessage.mock.calls[0][0]).toBe(message); + }); + }); + + test('Message with explicit scope', () => { + const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const message = 'yo'; + const captureContext = { extra: { foo: 'wat' } }; + captureMessage(message, captureContext); + expect(client.captureMessage.mock.calls[0][0]).toBe(message); + // Skip the level if explicit content is provided + expect(client.captureMessage.mock.calls[0][1]).toBe(undefined); + expect(client.captureMessage.mock.calls[0][2].captureContext).toBe(captureContext); + }); + }); + + // NOTE: We left custom level as 2nd argument to not break the API. Should be removed and unified in v6. + test('Message with custom level', () => { + const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const message = 'yo'; + const level = 'warning'; + captureMessage(message, level); + expect(client.captureMessage.mock.calls[0][0]).toBe(message); + expect(client.captureMessage.mock.calls[0][1]).toBe('warning'); + }); + }); + + test('Event', () => { + const client: any = { captureEvent: jest.fn(async () => Promise.resolve()) }; + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + const e = { message: 'test' }; + captureEvent(e); + expect(client.captureEvent.mock.calls[0][0]).toBe(e); + }); + }); + }); + + describe('configureScope', () => { + test('User Context', () => { + const client: any = new TestClient({}); + getCurrentHub().pushScope(); + getCurrentHub().bindClient(client); + configureScope((scope: Scope) => { + scope.setUser({ id: '1234' }); + }); + expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ + id: '1234', + }); + getCurrentHub().popScope(); + }); + + test('Extra Context', () => { + const client: any = new TestClient({}); + getCurrentHub().pushScope(); + getCurrentHub().bindClient(client); + configureScope((scope: Scope) => { + scope.setExtra('id', '1234'); + }); + expect(global.__SENTRY__.hub._stack[1].scope._extra).toEqual({ + id: '1234', + }); + getCurrentHub().popScope(); + }); + + test('Tags Context', () => { + init({}); + configureScope((scope: Scope) => { + scope.setTag('id', '1234'); + }); + expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ + id: '1234', + }); + }); + + test('Fingerprint', () => { + const client: any = new TestClient({}); + getCurrentHub().pushScope(); + getCurrentHub().bindClient(client); + configureScope((scope: Scope) => { + scope.setFingerprint(['abcd']); + }); + expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['abcd']); + }); + + test('Level', () => { + const client: any = new TestClient({}); + const scope = getCurrentHub().pushScope(); + getCurrentHub().bindClient(client); + scope.setLevel('warning'); + expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); + }); + }); + + test('Clear Scope', () => { + const client: any = new TestClient({}); + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(client); + expect(global.__SENTRY__.hub._stack.length).toBe(2); + configureScope((scope: Scope) => { + scope.setUser({ id: '1234' }); + }); + expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ + id: '1234', + }); + configureScope((scope: Scope) => { + scope.clear(); + }); + expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({}); + }); + }); + + test('returns undefined before binding a client', () => { + expect(getCurrentHub().getClient()).toBeUndefined(); + }); + + test('returns the bound client', () => { + init({}); + expect(getCurrentHub().getClient()).toBe(TestClient.instance); + }); + + test('does not throw an error when pushing different clients', () => { + init({}); + expect(() => { + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(new TestClient2() as any); + }); + }).not.toThrow(); + }); + + test('does not throw an error when pushing same clients', () => { + init({}); + expect(() => { + getCurrentHub().withScope(() => { + getCurrentHub().bindClient(new TestClient({}) as any); + }); + }).not.toThrow(); + }); + + test('custom carrier', () => { + const iAmSomeGlobalVarTheUserHasToManage = { + state: {}, + }; + const hub = getHubFromCarrier(iAmSomeGlobalVarTheUserHasToManage.state); + hub.pushScope(); + hub.bindClient(new TestClient({}) as any); + hub.configureScope((scope: Scope) => { + scope.setUser({ id: '1234' }); + }); + expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1].scope._user).toEqual({ + id: '1234', + }); + hub.popScope(); + expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1]).toBeUndefined(); + }); + + test('withScope', () => { + withScope(scope => { + scope.setLevel('warning'); + scope.setFingerprint(['1']); + withScope(scope2 => { + scope2.setLevel('info'); + scope2.setFingerprint(['2']); + withScope(scope3 => { + scope3.clear(); + expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); + expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['1']); + expect(global.__SENTRY__.hub._stack[2].scope._level).toEqual('info'); + expect(global.__SENTRY__.hub._stack[2].scope._fingerprint).toEqual(['2']); + expect(global.__SENTRY__.hub._stack[3].scope._level).toBeUndefined(); + }); + expect(global.__SENTRY__.hub._stack).toHaveLength(3); + }); + expect(global.__SENTRY__.hub._stack).toHaveLength(2); + }); + expect(global.__SENTRY__.hub._stack).toHaveLength(1); + }); + + test('setExtras', () => { + init({}); + setExtras({ a: 'b' }); + expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ a: 'b' }); + }); + + test('setTags', () => { + init({}); + setTags({ a: 'b' }); + expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' }); + }); + + test('setExtra', () => { + init({}); + setExtra('a', 'b'); + // prettier-ignore + expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ 'a': 'b' }); + }); + + test('setTag', () => { + init({}); + setTag('a', 'b'); + // prettier-ignore + expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ 'a': 'b' }); + }); + + test('setUser', () => { + init({}); + setUser({ id: 'b' }); + expect(global.__SENTRY__.hub._stack[0].scope._user).toEqual({ id: 'b' }); + }); + + test('setContext', () => { + init({}); + setContext('test', { id: 'b' }); + expect(global.__SENTRY__.hub._stack[0].scope._contexts).toEqual({ test: { id: 'b' } }); + }); +}); From 719fa7fd54954a15a1a89074db85863cde513756 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:06:30 -0400 Subject: [PATCH 88/94] re-org exports --- packages/core/src/index.ts | 10 ++++++++-- packages/hub/src/index.ts | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f5932bdbeaa4..0cd660fdd6b4 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -15,8 +15,14 @@ export { setTags, setUser, withScope, -} from '@sentry/minimal'; -export { addGlobalEventProcessor, getCurrentHub, getHubFromCarrier, Hub, makeMain, Scope, Session } from '@sentry/hub'; + addGlobalEventProcessor, + getCurrentHub, + getHubFromCarrier, + Hub, + makeMain, + Scope, + Session, +} from '@sentry/hub'; export { getEnvelopeEndpointWithUrlEncodedAuth, getStoreEndpointWithUrlEncodedAuth, diff --git a/packages/hub/src/index.ts b/packages/hub/src/index.ts index 16c99ec7bc89..92b85f370d80 100644 --- a/packages/hub/src/index.ts +++ b/packages/hub/src/index.ts @@ -4,3 +4,18 @@ export { addGlobalEventProcessor, Scope } from './scope'; export { Session } from './session'; export { SessionFlusher } from './sessionflusher'; export { getCurrentHub, getHubFromCarrier, getMainCarrier, Hub, makeMain, setHubOnCarrier } from './hub'; +export { + addBreadcrumb, + captureException, + captureEvent, + captureMessage, + configureScope, + startTransaction, + setContext, + setExtra, + setExtras, + setTag, + setTags, + setUser, + withScope, +} from './exports'; From 74aed53e3658da62935ac83a50811e522c078871 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:06:48 -0400 Subject: [PATCH 89/94] delete minimal --- packages/minimal/.eslintrc.js | 3 - packages/minimal/LICENSE | 29 --- packages/minimal/README.md | 63 ----- packages/minimal/jest.config.js | 1 - packages/minimal/package.json | 53 ---- packages/minimal/src/index.ts | 30 --- packages/minimal/test/lib/minimal.test.ts | 292 ---------------------- packages/minimal/test/mocks/client.ts | 19 -- packages/minimal/tsconfig.cjs.json | 8 - packages/minimal/tsconfig.esm.json | 8 - packages/minimal/tsconfig.json | 9 - packages/minimal/tsconfig.test.json | 12 - packages/minimal/tsconfig.types.json | 10 - 13 files changed, 537 deletions(-) delete mode 100644 packages/minimal/.eslintrc.js delete mode 100644 packages/minimal/LICENSE delete mode 100644 packages/minimal/README.md delete mode 100644 packages/minimal/jest.config.js delete mode 100644 packages/minimal/package.json delete mode 100644 packages/minimal/src/index.ts delete mode 100644 packages/minimal/test/lib/minimal.test.ts delete mode 100644 packages/minimal/test/mocks/client.ts delete mode 100644 packages/minimal/tsconfig.cjs.json delete mode 100644 packages/minimal/tsconfig.esm.json delete mode 100644 packages/minimal/tsconfig.json delete mode 100644 packages/minimal/tsconfig.test.json delete mode 100644 packages/minimal/tsconfig.types.json diff --git a/packages/minimal/.eslintrc.js b/packages/minimal/.eslintrc.js deleted file mode 100644 index 5a2cc7f1ec08..000000000000 --- a/packages/minimal/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.js'], -}; diff --git a/packages/minimal/LICENSE b/packages/minimal/LICENSE deleted file mode 100644 index 8b42db873c95..000000000000 --- a/packages/minimal/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2019, Sentry -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/minimal/README.md b/packages/minimal/README.md deleted file mode 100644 index 4204f58846d4..000000000000 --- a/packages/minimal/README.md +++ /dev/null @@ -1,63 +0,0 @@ -

- - - -
-

- -# Sentry JavaScript SDK Minimal - -[![npm version](https://img.shields.io/npm/v/@sentry/minimal.svg)](https://www.npmjs.com/package/@sentry/minimal) -[![npm dm](https://img.shields.io/npm/dm/@sentry/minimal.svg)](https://www.npmjs.com/package/@sentry/minimal) -[![npm dt](https://img.shields.io/npm/dt/@sentry/minimal.svg)](https://www.npmjs.com/package/@sentry/minimal) -[![typedoc](https://img.shields.io/badge/docs-typedoc-blue.svg)](http://getsentry.github.io/sentry-javascript/) - -## Links - -- [Official SDK Docs](https://docs.sentry.io/quickstart/) -- [TypeDoc](http://getsentry.github.io/sentry-javascript/) - -## General - -A minimal Sentry SDK that uses a configured client when embedded into an application. It allows library authors add -support for a Sentry SDK without having to bundle the entire SDK or being dependent on a specific platform. If the user -is using Sentry in their application and your library uses `@sentry/minimal`, the user receives all -breadcrumbs/messages/events you added to your libraries codebase. - -## Usage - -To use the minimal, you do not have to initialize an SDK. This should be handled by the user of your library. Instead, -directly use the exported functions of `@sentry/minimal` to add breadcrumbs or capture events: - -```javascript -import * as Sentry from '@sentry/minimal'; - -// Add a breadcrumb for future events -Sentry.addBreadcrumb({ - message: 'My Breadcrumb', - // ... -}); - -// Capture exceptions, messages or manual events -Sentry.captureMessage('Hello, world!'); -Sentry.captureException(new Error('Good bye')); -Sentry.captureEvent({ - message: 'Manual', - stacktrace: [ - // ... - ], -}); -``` - -Note that while strictly possible, it is discouraged to interfere with the event context. If for some reason your -library needs to inject context information, beware that this might override the user's context values: - -```javascript -// Set user information, as well as tags and further extras -Sentry.configureScope(scope => { - scope.setExtra('battery', 0.7); - scope.setTag('user_mode', 'admin'); - scope.setUser({ id: '4711' }); - // scope.clear(); -}); -``` diff --git a/packages/minimal/jest.config.js b/packages/minimal/jest.config.js deleted file mode 100644 index 58141f076dc4..000000000000 --- a/packages/minimal/jest.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../jest.config.js'); diff --git a/packages/minimal/package.json b/packages/minimal/package.json deleted file mode 100644 index 3ca8889512a2..000000000000 --- a/packages/minimal/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@sentry/minimal", - "version": "7.0.0-alpha.1", - "description": "Sentry minimal library that can be used in other packages", - "repository": "git://github.com/getsentry/sentry-javascript.git", - "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/minimal", - "author": "Sentry", - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - }, - "main": "build/cjs/index.js", - "module": "build/esm/index.js", - "types": "build/types/index.d.ts", - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@sentry/hub": "7.0.0-alpha.1", - "@sentry/types": "7.0.0-alpha.1", - "tslib": "^1.9.3" - }, - "scripts": { - "build": "run-p build:cjs build:esm build:types", - "build:cjs": "tsc -p tsconfig.cjs.json", - "build:dev": "run-s build", - "build:es5": "yarn build:cjs # *** backwards compatibility - remove in v7 ***", - "build:esm": "tsc -p tsconfig.esm.json", - "build:types": "tsc -p tsconfig.types.json", - "build:watch": "run-p build:cjs:watch build:esm:watch build:types:watch", - "build:cjs:watch": "tsc -p tsconfig.cjs.json --watch", - "build:dev:watch": "run-s build:watch", - "build:es5:watch": "yarn build:cjs:watch # *** backwards compatibility - remove in v7 ***", - "build:esm:watch": "tsc -p tsconfig.esm.json --watch", - "build:types:watch": "tsc -p tsconfig.types.json --watch", - "build:npm": "ts-node ../../scripts/prepack.ts && npm pack ./build", - "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf build coverage", - "fix": "run-s fix:eslint fix:prettier", - "fix:eslint": "eslint . --format stylish --fix", - "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", - "link:yarn": "yarn link", - "lint": "run-s lint:prettier lint:eslint", - "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", - "lint:prettier": "prettier --check \"{src,test,scripts}/**/*.ts\"", - "test": "jest", - "test:watch": "jest --watch" - }, - "volta": { - "extends": "../../package.json" - }, - "sideEffects": false -} diff --git a/packages/minimal/src/index.ts b/packages/minimal/src/index.ts deleted file mode 100644 index ec203aec4403..000000000000 --- a/packages/minimal/src/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getCurrentHub, Hub, Scope } from '@sentry/hub'; -import { - Breadcrumb, - CaptureContext, - CustomSamplingContext, - Event, - Extra, - Extras, - Primitive, - Severity, - SeverityLevel, - Transaction, - TransactionContext, - User, -} from '@sentry/types'; - -/** - * This calls a function on the current hub. - * @param method function to call on hub. - * @param args to pass to function. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function callOnHub(method: string, ...args: any[]): T { - const hub = getCurrentHub(); - if (hub && hub[method as keyof Hub]) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (hub[method as keyof Hub] as any)(...args); - } - throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`); -} diff --git a/packages/minimal/test/lib/minimal.test.ts b/packages/minimal/test/lib/minimal.test.ts deleted file mode 100644 index 764ebbb2e728..000000000000 --- a/packages/minimal/test/lib/minimal.test.ts +++ /dev/null @@ -1,292 +0,0 @@ -import { getCurrentHub, getHubFromCarrier, Scope } from '@sentry/hub'; - -import { - captureEvent, - captureException, - captureMessage, - configureScope, - setContext, - setExtra, - setExtras, - setTag, - setTags, - setUser, - withScope, -} from '../../src'; -import { init, TestClient, TestClient2 } from '../mocks/client'; - -// eslint-disable-next-line no-var -declare var global: any; - -describe('Minimal', () => { - beforeEach(() => { - global.__SENTRY__ = { - hub: undefined, - }; - }); - - describe('Capture', () => { - test('Return an event_id', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - const eventId = captureException(e); - expect(eventId).toBeTruthy(); - }); - }); - - test('Exception', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - captureException(e); - expect(client.captureException.mock.calls[0][0]).toBe(e); - }); - }); - - test('Exception with explicit scope', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - const captureContext = { extra: { foo: 'wat' } }; - captureException(e, captureContext); - expect(client.captureException.mock.calls[0][0]).toBe(e); - expect(client.captureException.mock.calls[0][1].captureContext).toBe(captureContext); - }); - }); - - test('Message', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - captureMessage(message); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - }); - }); - - test('Message with explicit scope', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - const captureContext = { extra: { foo: 'wat' } }; - captureMessage(message, captureContext); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - // Skip the level if explicit content is provided - expect(client.captureMessage.mock.calls[0][1]).toBe(undefined); - expect(client.captureMessage.mock.calls[0][2].captureContext).toBe(captureContext); - }); - }); - - // NOTE: We left custom level as 2nd argument to not break the API. Should be removed and unified in v6. - test('Message with custom level', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - const level = 'warning'; - captureMessage(message, level); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - expect(client.captureMessage.mock.calls[0][1]).toBe('warning'); - }); - }); - - test('Event', () => { - const client: any = { captureEvent: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = { message: 'test' }; - captureEvent(e); - expect(client.captureEvent.mock.calls[0][0]).toBe(e); - }); - }); - }); - - describe('configureScope', () => { - test('User Context', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - getCurrentHub().popScope(); - }); - - test('Extra Context', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setExtra('id', '1234'); - }); - expect(global.__SENTRY__.hub._stack[1].scope._extra).toEqual({ - id: '1234', - }); - getCurrentHub().popScope(); - }); - - test('Tags Context', () => { - init({}); - configureScope((scope: Scope) => { - scope.setTag('id', '1234'); - }); - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ - id: '1234', - }); - }); - - test('Fingerprint', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setFingerprint(['abcd']); - }); - expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['abcd']); - }); - - test('Level', () => { - const client: any = new TestClient({}); - const scope = getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - scope.setLevel('warning'); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); - }); - }); - - test('Clear Scope', () => { - const client: any = new TestClient({}); - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - expect(global.__SENTRY__.hub._stack.length).toBe(2); - configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - configureScope((scope: Scope) => { - scope.clear(); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({}); - }); - }); - - test('returns undefined before binding a client', () => { - expect(getCurrentHub().getClient()).toBeUndefined(); - }); - - test('returns the bound client', () => { - init({}); - expect(getCurrentHub().getClient()).toBe(TestClient.instance); - }); - - test('does not throw an error when pushing different clients', () => { - init({}); - expect(() => { - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(new TestClient2() as any); - }); - }).not.toThrow(); - }); - - test('does not throw an error when pushing same clients', () => { - init({}); - expect(() => { - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(new TestClient({}) as any); - }); - }).not.toThrow(); - }); - - test('custom carrier', () => { - const iAmSomeGlobalVarTheUserHasToManage = { - state: {}, - }; - const hub = getHubFromCarrier(iAmSomeGlobalVarTheUserHasToManage.state); - hub.pushScope(); - hub.bindClient(new TestClient({}) as any); - hub.configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - hub.popScope(); - expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1]).toBeUndefined(); - }); - - test('withScope', () => { - withScope(scope => { - scope.setLevel('warning'); - scope.setFingerprint(['1']); - withScope(scope2 => { - scope2.setLevel('info'); - scope2.setFingerprint(['2']); - withScope(scope3 => { - scope3.clear(); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); - expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['1']); - expect(global.__SENTRY__.hub._stack[2].scope._level).toEqual('info'); - expect(global.__SENTRY__.hub._stack[2].scope._fingerprint).toEqual(['2']); - expect(global.__SENTRY__.hub._stack[3].scope._level).toBeUndefined(); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(3); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(2); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(1); - }); - - test('setExtras', () => { - init({}); - setExtras({ a: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ a: 'b' }); - }); - - test('setTags', () => { - init({}); - setTags({ a: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' }); - }); - - test('setExtra', () => { - init({}); - setExtra('a', 'b'); - // prettier-ignore - expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ 'a': 'b' }); - }); - - test('setTag', () => { - init({}); - setTag('a', 'b'); - // prettier-ignore - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ 'a': 'b' }); - }); - - test('setUser', () => { - init({}); - setUser({ id: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._user).toEqual({ id: 'b' }); - }); - - test('setContext', () => { - init({}); - setContext('test', { id: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._contexts).toEqual({ test: { id: 'b' } }); - }); -}); diff --git a/packages/minimal/test/mocks/client.ts b/packages/minimal/test/mocks/client.ts deleted file mode 100644 index 813fd694c38a..000000000000 --- a/packages/minimal/test/mocks/client.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { getCurrentHub } from '@sentry/hub'; - -export class TestClient { - public static instance?: TestClient; - - public constructor(public options: Record) { - TestClient.instance = this; - } - - public mySecretPublicMethod(str: string): string { - return `secret: ${str}`; - } -} - -export class TestClient2 {} - -export function init(options: Record): void { - getCurrentHub().bindClient(new TestClient(options) as any); -} diff --git a/packages/minimal/tsconfig.cjs.json b/packages/minimal/tsconfig.cjs.json deleted file mode 100644 index c1edc81a9657..000000000000 --- a/packages/minimal/tsconfig.cjs.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "module": "commonjs", - "outDir": "build/cjs" - } -} diff --git a/packages/minimal/tsconfig.esm.json b/packages/minimal/tsconfig.esm.json deleted file mode 100644 index 0b86c52918cc..000000000000 --- a/packages/minimal/tsconfig.esm.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "module": "es6", - "outDir": "build/esm" - } -} diff --git a/packages/minimal/tsconfig.json b/packages/minimal/tsconfig.json deleted file mode 100644 index bf45a09f2d71..000000000000 --- a/packages/minimal/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - - "include": ["src/**/*"], - - "compilerOptions": { - // package-specific options - } -} diff --git a/packages/minimal/tsconfig.test.json b/packages/minimal/tsconfig.test.json deleted file mode 100644 index 87f6afa06b86..000000000000 --- a/packages/minimal/tsconfig.test.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "include": ["test/**/*"], - - "compilerOptions": { - // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["node", "jest"] - - // other package-specific, test-specific options - } -} diff --git a/packages/minimal/tsconfig.types.json b/packages/minimal/tsconfig.types.json deleted file mode 100644 index 65455f66bd75..000000000000 --- a/packages/minimal/tsconfig.types.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "outDir": "build/types" - } -} From fe8e51bc7723a4484ae2594d7eaf283b2335c3bb Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:08:38 -0400 Subject: [PATCH 90/94] remove minimal from the repo --- README.md | 2 -- package.json | 1 - packages/core/package.json | 1 - packages/core/test/mocks/integration.ts | 3 +-- packages/nextjs/test/integration/package.json | 1 - packages/react/package.json | 1 - packages/react/src/redux.ts | 2 +- packages/react/test/redux.test.ts | 5 +++-- packages/serverless/package.json | 1 - packages/tracing/package.json | 1 - packages/vue/package.json | 1 - rollup/plugins/bundlePlugins.js | 1 - 12 files changed, 5 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 84e46f6b362a..369c363e3599 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,6 @@ below: extensions for Performance Monitoring / Tracing - [`@sentry/hub`](https://github.com/getsentry/sentry-javascript/tree/master/packages/hub): Global state management of SDKs -- [`@sentry/minimal`](https://github.com/getsentry/sentry-javascript/tree/master/packages/minimal): Minimal SDK for - library authors to add Sentry support - [`@sentry/core`](https://github.com/getsentry/sentry-javascript/tree/master/packages/core): The base for all JavaScript SDKs with interfaces, type definitions and base classes. - [`@sentry/utils`](https://github.com/getsentry/sentry-javascript/tree/master/packages/utils): A set of helpers and diff --git a/package.json b/package.json index bf91547479aa..0e077fb82a65 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "packages/hub", "packages/integration-tests", "packages/integrations", - "packages/minimal", "packages/nextjs", "packages/node", "packages/node-integration-tests", diff --git a/packages/core/package.json b/packages/core/package.json index 8a53ffca97e3..737007cf648b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -17,7 +17,6 @@ }, "dependencies": { "@sentry/hub": "7.0.0-alpha.1", - "@sentry/minimal": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 8b95b5673af8..2e192fb12227 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -1,5 +1,4 @@ -import { getCurrentHub } from '@sentry/hub'; -import { configureScope } from '@sentry/minimal'; +import { configureScope, getCurrentHub } from '@sentry/hub'; import { Event, EventProcessor, Integration } from '@sentry/types'; export class TestIntegration implements Integration { diff --git a/packages/nextjs/test/integration/package.json b/packages/nextjs/test/integration/package.json index 5523ee933d20..2d8588dbf1a3 100644 --- a/packages/nextjs/test/integration/package.json +++ b/packages/nextjs/test/integration/package.json @@ -28,7 +28,6 @@ "@sentry/core": "file:../../../core", "@sentry/hub": "file:../../../hub", "@sentry/integrations": "file:../../../integrations", - "@sentry/minimal": "file:../../../minimal", "@sentry/node": "file:../../../node", "@sentry/react": "file:../../../react", "@sentry/tracing": "file:../../../tracing", diff --git a/packages/react/package.json b/packages/react/package.json index 2fea1d64d5be..0365a6968bc5 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -17,7 +17,6 @@ }, "dependencies": { "@sentry/browser": "7.0.0-alpha.1", - "@sentry/minimal": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", "@sentry/utils": "7.0.0-alpha.1", "hoist-non-react-statics": "^3.3.2", diff --git a/packages/react/src/redux.ts b/packages/react/src/redux.ts index e1d0f42c3046..eb67a0a05a7f 100644 --- a/packages/react/src/redux.ts +++ b/packages/react/src/redux.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { configureScope } from '@sentry/minimal'; +import { configureScope } from '@sentry/browser'; import { Scope } from '@sentry/types'; interface Action { diff --git a/packages/react/test/redux.test.ts b/packages/react/test/redux.test.ts index 55729ddc860b..9c75bc944d91 100644 --- a/packages/react/test/redux.test.ts +++ b/packages/react/test/redux.test.ts @@ -1,4 +1,4 @@ -import * as Sentry from '@sentry/minimal'; +import * as Sentry from '@sentry/browser'; import { Scope } from '@sentry/types'; import * as Redux from 'redux'; @@ -7,7 +7,8 @@ import { createReduxEnhancer } from '../src/redux'; const mockAddBreadcrumb = jest.fn(); const mockSetContext = jest.fn(); -jest.mock('@sentry/minimal', () => ({ +jest.mock('@sentry/browser', () => ({ + ...jest.requireActual('@sentry/browser'), configureScope: (callback: (scope: any) => Partial) => callback({ addBreadcrumb: mockAddBreadcrumb, diff --git a/packages/serverless/package.json b/packages/serverless/package.json index d77177b66c1a..c7a83cfdaa20 100644 --- a/packages/serverless/package.json +++ b/packages/serverless/package.json @@ -16,7 +16,6 @@ "access": "public" }, "dependencies": { - "@sentry/minimal": "7.0.0-alpha.1", "@sentry/node": "7.0.0-alpha.1", "@sentry/tracing": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", diff --git a/packages/tracing/package.json b/packages/tracing/package.json index e77bfbadc5fa..8ea80cb33e0b 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -17,7 +17,6 @@ }, "dependencies": { "@sentry/hub": "7.0.0-alpha.1", - "@sentry/minimal": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" diff --git a/packages/vue/package.json b/packages/vue/package.json index b6eefc1ab6f3..406f335f05de 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -18,7 +18,6 @@ "dependencies": { "@sentry/browser": "7.0.0-alpha.1", "@sentry/core": "7.0.0-alpha.1", - "@sentry/minimal": "7.0.0-alpha.1", "@sentry/types": "7.0.0-alpha.1", "@sentry/utils": "7.0.0-alpha.1", "tslib": "^1.9.3" diff --git a/rollup/plugins/bundlePlugins.js b/rollup/plugins/bundlePlugins.js index 17c8d5977044..c678152a7b63 100644 --- a/rollup/plugins/bundlePlugins.js +++ b/rollup/plugins/bundlePlugins.js @@ -109,7 +109,6 @@ export function makeTSPlugin(jsVersion) { '@sentry/browser': ['../browser/src'], '@sentry/core': ['../core/src'], '@sentry/hub': ['../hub/src'], - '@sentry/minimal': ['../minimal/src'], '@sentry/types': ['../types/src'], '@sentry/utils': ['../utils/src'], }, From 215d57deb989b4c1fb81e23f884d8ddac5bdc11c Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 25 Apr 2022 11:38:05 -0400 Subject: [PATCH 91/94] improve synthetic exception in hub --- packages/hub/src/hub.ts | 19 ++----------------- packages/hub/test/exports.test.ts | 1 - 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/packages/hub/src/hub.ts b/packages/hub/src/hub.ts index c54bcf7b6414..4e97cd8aa9b3 100644 --- a/packages/hub/src/hub.ts +++ b/packages/hub/src/hub.ts @@ -185,16 +185,9 @@ export class Hub implements HubInterface { // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types public captureException(exception: any, hint?: EventHint): string { const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4()); - - let syntheticException: Error; - try { - throw new Error('Sentry syntheticException'); - } catch (exception) { - syntheticException = exception as Error; - } this._invokeClient('captureException', exception, { originalException: exception, - syntheticException, + syntheticException: new Error('Sentry syntheticException'), ...hint, event_id: eventId, }); @@ -211,17 +204,9 @@ export class Hub implements HubInterface { hint?: EventHint, ): string { const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4()); - - let syntheticException: Error; - try { - throw new Error('Sentry syntheticException'); - } catch (exception) { - syntheticException = exception as Error; - } - this._invokeClient('captureMessage', message, level, { originalException: message, - syntheticException, + syntheticException: new Error(message), ...hint, event_id: eventId, }); diff --git a/packages/hub/test/exports.test.ts b/packages/hub/test/exports.test.ts index 8d9549014414..91b7450b66eb 100644 --- a/packages/hub/test/exports.test.ts +++ b/packages/hub/test/exports.test.ts @@ -1,5 +1,4 @@ import { getCurrentHub, getHubFromCarrier, Scope } from '../src'; - import { captureEvent, captureException, From 8477f97b73c8e83ff0b2d189e902bbb74290615f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 26 Apr 2022 09:40:06 -0400 Subject: [PATCH 92/94] add docs about minimal deletion --- MIGRATION.md | 22 ++++++++++++++++++++++ packages/hub/src/exports.ts | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 3c5b999f11a3..0a1141cf5cac 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -10,6 +10,28 @@ Node.js version 6 has reached end of life in April 2019. For Sentry JavaScript S As far as SDK development goes, dropping support means no longer running integration tests for Node.js version 6, and also no longer handling edge cases specific to version 6. Running the new SDK version on Node.js v6 is therefore highly discouraged. +## Removal of `@sentry/minimal` + +The `@sentry/minimal` package was deleted and it's functionality was moved to `@sentry/hub`. All exports from `@sentry/minimal` should be avaliable in `@sentry/hub` other than `_callOnClient` function which was removed. + +```ts +// New in v7: +import { + addBreadcrumb, + captureException, + configureScope, + setTag, +} from '@sentry/hub'; + +// Before: +import { + addBreadcrumb, + captureException, + configureScope, + setTag, +} from '@sentry/minimal'; +``` + ## Removal Of Old Platform Integrations From `@sentry/integrations` Package The following classes will be removed from the `@sentry/integrations` package and can no longer be used: diff --git a/packages/hub/src/exports.ts b/packages/hub/src/exports.ts index 5e2fedb37250..451b2b13e9ed 100644 --- a/packages/hub/src/exports.ts +++ b/packages/hub/src/exports.ts @@ -15,6 +15,13 @@ import { import { getCurrentHub, Hub } from './hub'; import { Scope } from './scope'; +// Note: All functions in this file are typed with a return value of `ReturnType`, +// where HUB_FUNCTION is some method on the Hub class. +// +// This is done to make sure the top level SDK methods stay in sync with the hub methods. +// Although every method here has an explicit return type, some of them (that map to void returns) do not +// contain `return` keywords. This is done to save on bundle size, as `return` is not minifiable. + /** * Captures an exception event and sends it to Sentry. * From 8d66cba5a6ca7954fad7bac385b07e094ef6182a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 26 Apr 2022 09:53:17 -0400 Subject: [PATCH 93/94] clean up hub mocks --- packages/node/test/handlers.test.ts | 45 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts index a423a92aa3d0..57f6528139f9 100644 --- a/packages/node/test/handlers.test.ts +++ b/packages/node/test/handlers.test.ts @@ -374,24 +374,21 @@ describe('tracingHandler', () => { const tracesSampler = jest.fn(); const options = getDefaultNodeClientOptions({ tracesSampler }); const hub = new Hub(new NodeClient(options)); - // we need to mock both of these because the tracing handler relies on `@sentry/core` while the sampler relies on - // `@sentry/hub`, and mocking breaks the link between the two - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - jest.spyOn(sentryHub, 'getCurrentHub').mockReturnValue(hub); - - sentryTracingMiddleware(req, res, next); - - expect(tracesSampler).toHaveBeenCalledWith( - expect.objectContaining({ - request: { - headers, - method, - url: `http://${hostname}${path}?${queryString}`, - cookies: { favorite: 'zukes' }, - query_string: queryString, - }, - }), - ); + hub.run(() => { + sentryTracingMiddleware(req, res, next); + + expect(tracesSampler).toHaveBeenCalledWith( + expect.objectContaining({ + request: { + headers, + method, + url: `http://${hostname}${path}?${queryString}`, + cookies: { favorite: 'zukes' }, + query_string: queryString, + }, + }), + ); + }); }); it('puts its transaction on the scope', () => { @@ -773,13 +770,13 @@ describe('errorHandler()', () => { const hub = new Hub(client, scope); jest.spyOn(client, '_captureRequestSession'); - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - jest.spyOn(sentryHub, 'getCurrentHub').mockReturnValue(hub); - scope?.setRequestSession({ status: 'ok' }); - sentryErrorMiddleware({ name: 'error', message: 'this is an error' }, req, res, next); - const requestSession = scope?.getRequestSession(); - expect(requestSession).toEqual({ status: 'crashed' }); + hub.run(() => { + scope?.setRequestSession({ status: 'ok' }); + sentryErrorMiddleware({ name: 'error', message: 'this is an error' }, req, res, next); + const requestSession = scope?.getRequestSession(); + expect(requestSession).toEqual({ status: 'crashed' }); + }); }); it('when autoSessionTracking is enabled, should not set requestSession status on Crash when it occurs outside the bounds of a request', () => { From 7a3b90f0fd41a419b936e9f5f9328117cd7a4919 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 26 Apr 2022 12:20:25 -0400 Subject: [PATCH 94/94] add back missing changelog entry --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52accc5e665a..dcd8824f2d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,14 @@ - **(breaking)** feat(types): Delete Status enum (#4891) - **(breaking)** feat(types): Delete SessionStatus enum (#4890) +## 6.19.7 + +- fix(react): Add children prop type to ErrorBoundary component (#4966) +- fix(serverless): Re-add missing modules in Node AWS Lambda Layer (#4982) +- fix(tracing): Target tracing bundles for side effects (#4955) + +Work in this release contributed by @cameronaziz and @kpdecker. Thank you for your contributions! + ## 6.19.6 - fix(typing): Fix typing API in CaptureConsle (#4879)