From 97e04a08587e2c0a92df9732239b2d78828fd306 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 27 Nov 2023 16:03:06 +0100 Subject: [PATCH 01/10] ref: Replace global `__DEBUG_BUILD__` type with `DEBUG_BUILD` const in individual packages (#9657) --- CONTRIBUTING.md | 2 +- packages/browser/src/client.ts | 9 +++--- packages/browser/src/debug-build.ts | 8 ++++++ .../browser/src/integrations/breadcrumbs.ts | 3 +- packages/browser/src/integrations/dedupe.ts | 4 ++- .../src/integrations/globalhandlers.ts | 3 +- .../browser/src/profiling/hubextensions.ts | 15 +++++----- packages/browser/src/profiling/integration.ts | 9 +++--- packages/browser/src/profiling/utils.ts | 28 +++++++++---------- packages/browser/src/sdk.ts | 10 +++---- packages/browser/src/transports/utils.ts | 4 +-- packages/core/src/baseclient.ts | 19 +++++++------ packages/core/src/debug-build.ts | 8 ++++++ packages/core/src/eventProcessors.ts | 7 ++--- packages/core/src/exports.ts | 9 +++--- packages/core/src/hub.ts | 7 +++-- packages/core/src/integration.ts | 5 ++-- .../core/src/integrations/inboundfilters.ts | 16 ++++++----- packages/core/src/sdk.ts | 3 +- packages/core/src/server-runtime-client.ts | 9 +++--- packages/core/src/tracing/errors.ts | 3 +- packages/core/src/tracing/hubextensions.ts | 3 +- packages/core/src/tracing/idletransaction.ts | 27 +++++++++--------- packages/core/src/tracing/sampling.ts | 13 +++++---- packages/core/src/tracing/span.ts | 6 ++-- packages/core/src/tracing/trace.ts | 3 +- packages/core/src/tracing/transaction.ts | 9 +++--- packages/core/src/transports/base.ts | 6 ++-- packages/core/src/transports/offline.ts | 4 ++- packages/feedback/src/debug-build.ts | 8 ++++++ packages/feedback/src/integration.ts | 11 ++++---- .../feedback/src/util/handleFeedbackSubmit.ts | 3 +- packages/integrations/src/debug-build.ts | 8 ++++++ packages/integrations/src/dedupe.ts | 4 ++- packages/integrations/src/extraerrordata.ts | 4 ++- packages/integrations/src/httpclient.ts | 10 ++++--- packages/integrations/src/offline.ts | 16 ++++++----- .../pagesRouterRoutingInstrumentation.ts | 4 ++- packages/nextjs/src/client/tunnelRoute.ts | 6 ++-- packages/nextjs/src/common/debug-build.ts | 8 ++++++ .../src/common/utils/edgeWrapperUtils.ts | 3 +- .../nextjs/src/common/utils/responseEnd.ts | 7 +++-- .../common/withServerActionInstrumentation.ts | 3 +- .../src/common/wrapApiHandlerWithSentry.ts | 3 +- packages/nextjs/src/config/webpack.ts | 5 ++-- packages/nextjs/src/server/index.ts | 9 +++--- packages/node-experimental/src/debug-build.ts | 8 ++++++ .../node-experimental/src/sdk/initOtel.ts | 3 +- packages/node/src/debug-build.ts | 8 ++++++ packages/node/src/handlers.ts | 3 +- packages/node/src/integrations/http.ts | 7 +++-- .../src/integrations/onuncaughtexception.ts | 3 +- .../src/integrations/utils/errorhandling.ts | 7 +++-- .../opentelemetry-node/src/debug-build.ts | 8 ++++++ .../opentelemetry-node/src/spanprocessor.ts | 4 +-- packages/opentelemetry/src/custom/scope.ts | 6 ++-- packages/opentelemetry/src/debug-build.ts | 8 ++++++ packages/opentelemetry/src/sampler.ts | 16 +++++------ packages/opentelemetry/src/spanExporter.ts | 5 ++-- packages/opentelemetry/src/spanProcessor.ts | 5 ++-- .../opentelemetry/test/helpers/initOtel.ts | 3 +- packages/react/src/debug-build.ts | 8 ++++++ packages/react/src/errorboundary.tsx | 4 ++- packages/react/src/reactrouterv6.tsx | 5 ++-- packages/remix/src/client/performance.tsx | 3 +- packages/remix/src/index.server.ts | 3 +- packages/remix/src/utils/debug-build.ts | 8 ++++++ packages/remix/src/utils/instrumentServer.ts | 13 ++++----- .../remix/src/utils/serverAdapters/express.ts | 9 +++--- packages/remix/src/utils/web-fetch.ts | 3 +- .../src/coreHandlers/handleGlobalEvent.ts | 3 +- .../coreHandlers/handleNetworkBreadcrumbs.ts | 3 +- .../src/coreHandlers/util/fetchUtils.ts | 9 +++--- .../src/coreHandlers/util/networkUtils.ts | 5 ++-- .../replay/src/coreHandlers/util/xhrUtils.ts | 5 ++-- packages/replay/src/debug-build.ts | 8 ++++++ .../src/eventBuffer/EventBufferProxy.ts | 3 +- .../replay/src/eventBuffer/WorkerHandler.ts | 3 +- packages/replay/src/replay.ts | 11 ++++---- packages/replay/src/util/addEvent.ts | 5 ++-- .../replay/src/util/handleRecordingEmit.ts | 3 +- packages/replay/src/util/log.ts | 6 ++-- packages/replay/src/util/sendReplay.ts | 3 +- .../replay/src/util/shouldFilterRequest.ts | 3 +- packages/serverless/src/awslambda.ts | 11 ++++---- packages/serverless/src/debug-build.ts | 8 ++++++ .../src/gcpfunction/cloud_events.ts | 3 +- packages/serverless/src/gcpfunction/events.ts | 3 +- packages/serverless/src/gcpfunction/http.ts | 3 +- packages/sveltekit/src/common/debug-build.ts | 8 ++++++ packages/sveltekit/src/server/utils.ts | 7 +++-- .../src/browser/backgroundtab.ts | 6 ++-- .../src/browser/browsertracing.ts | 19 ++++++------- .../src/browser/instrument.ts | 3 +- .../src/browser/metrics/index.ts | 22 +++++++-------- .../tracing-internal/src/browser/router.ts | 5 ++-- .../src/common/debug-build.ts | 8 ++++++ .../src/node/integrations/apollo.ts | 9 +++--- .../src/node/integrations/express.ts | 9 +++--- .../src/node/integrations/graphql.ts | 5 ++-- .../src/node/integrations/mongo.ts | 5 ++-- .../src/node/integrations/mysql.ts | 7 +++-- .../src/node/integrations/postgres.ts | 7 +++-- .../src/node/integrations/prisma.ts | 3 +- packages/types/src/globals.ts | 18 ------------ packages/types/src/index.ts | 4 --- packages/utils/src/baggage.ts | 3 +- packages/utils/src/debug-build.ts | 8 ++++++ packages/utils/src/dsn.ts | 3 +- packages/utils/src/instrument/_handlers.ts | 3 +- packages/utils/src/instrument/index.ts | 3 +- packages/utils/src/logger.ts | 3 +- packages/utils/src/object.ts | 3 +- packages/utils/src/requestdata.ts | 3 +- packages/utils/src/supports.ts | 3 +- packages/utils/test/dsn.test.ts | 11 ++++---- packages/vercel-edge/src/async.ts | 4 ++- packages/vercel-edge/src/debug-build.ts | 8 ++++++ packages/vue/src/debug-build.ts | 8 ++++++ packages/vue/src/tracing.ts | 3 +- 120 files changed, 521 insertions(+), 302 deletions(-) create mode 100644 packages/browser/src/debug-build.ts create mode 100644 packages/core/src/debug-build.ts create mode 100644 packages/feedback/src/debug-build.ts create mode 100644 packages/integrations/src/debug-build.ts create mode 100644 packages/nextjs/src/common/debug-build.ts create mode 100644 packages/node-experimental/src/debug-build.ts create mode 100644 packages/node/src/debug-build.ts create mode 100644 packages/opentelemetry-node/src/debug-build.ts create mode 100644 packages/opentelemetry/src/debug-build.ts create mode 100644 packages/react/src/debug-build.ts create mode 100644 packages/remix/src/utils/debug-build.ts create mode 100644 packages/replay/src/debug-build.ts create mode 100644 packages/serverless/src/debug-build.ts create mode 100644 packages/sveltekit/src/common/debug-build.ts create mode 100644 packages/tracing-internal/src/common/debug-build.ts delete mode 100644 packages/types/src/globals.ts create mode 100644 packages/utils/src/debug-build.ts create mode 100644 packages/vercel-edge/src/debug-build.ts create mode 100644 packages/vue/src/debug-build.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9af7a880a407..717e548c5a9a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ Pro tip: If any of your breakpoints are in code run by multiple tests, and you r ## Debug Build Flags -Throughout the codebase, you will find the `__DEBUG_BUILD__` flag guarding various code sections. This flag serves two purposes: +Throughout the codebase, you will find a `__DEBUG_BUILD__` constant. This flag serves two purposes: 1. It enables us to remove debug code from our minified CDN bundles during build, by replacing the flag with `false` before tree-shaking occurs. 2. It enables users to remove Sentry debug code from their production bundles during their own build. When we build our npm packages, we replace the flag with `(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)`. If the user does nothing, this evaluates to `true` and logging is included. But if the user runs their own replacement during build (again replacing the flag with `false`), the build will tree-shake the logging away, just as our bundle builds do. diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 4c0ace57547b..4e46314f6711 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -13,6 +13,7 @@ import type { } from '@sentry/types'; import { createClientReportEnvelope, dsnToString, getSDKSource, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { WINDOW } from './helpers'; import type { BrowserTransportOptions } from './transports/types'; @@ -96,7 +97,7 @@ export class BrowserClient extends BaseClient { */ public captureUserFeedback(feedback: UserFeedback): void { if (!this._isEnabled()) { - __DEBUG_BUILD__ && logger.warn('SDK not enabled, will not capture user feedback.'); + DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.'); return; } @@ -123,17 +124,17 @@ export class BrowserClient extends BaseClient { const outcomes = this._clearOutcomes(); if (outcomes.length === 0) { - __DEBUG_BUILD__ && logger.log('No outcomes to send'); + DEBUG_BUILD && logger.log('No outcomes to send'); return; } // This is really the only place where we want to check for a DSN and only send outcomes then if (!this._dsn) { - __DEBUG_BUILD__ && logger.log('No dsn provided, will not send outcomes'); + DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes'); return; } - __DEBUG_BUILD__ && logger.log('Sending outcomes:', outcomes); + DEBUG_BUILD && logger.log('Sending outcomes:', outcomes); const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn)); void this._sendEnvelope(envelope); diff --git a/packages/browser/src/debug-build.ts b/packages/browser/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/browser/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index 83db8af4fc63..2679cabed5f5 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -30,6 +30,7 @@ import { severityLevelFromString, } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { getClient } from '../exports'; import { WINDOW } from '../helpers'; @@ -148,7 +149,7 @@ function _domBreadcrumb(dom: BreadcrumbsOptions['dom']): (handlerData: HandlerDa let maxStringLength = typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined; if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `\`dom.maxStringLength\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`, ); diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index c7a5cb5470b3..74d22d5a462c 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -1,6 +1,8 @@ import type { Event, Exception, Integration, StackFrame } from '@sentry/types'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + /** Deduplication filter */ export class Dedupe implements Integration { /** @@ -40,7 +42,7 @@ export class Dedupe implements Integration { // Juuust in case something goes wrong try { if (_shouldDropEvent(currentEvent, this._previousEvent)) { - __DEBUG_BUILD__ && logger.warn('Event dropped due to being a duplicate of previously captured event.'); + DEBUG_BUILD && logger.warn('Event dropped due to being a duplicate of previously captured event.'); return null; } } catch (_oO) {} // eslint-disable-line no-empty diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 47acd2a75140..0c3f3be60e2d 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -12,6 +12,7 @@ import { } from '@sentry/utils'; import type { BrowserClient } from '../client'; +import { DEBUG_BUILD } from '../debug-build'; import { eventFromUnknownInput } from '../eventbuilder'; import { shouldIgnoreOnError } from '../helpers'; @@ -254,7 +255,7 @@ function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column } function globalHandlerLog(type: string): void { - __DEBUG_BUILD__ && logger.log(`Global Handler attached: ${type}`); + DEBUG_BUILD && logger.log(`Global Handler attached: ${type}`); } function getHubAndOptions(): [Hub, StackParser, boolean | undefined] { diff --git a/packages/browser/src/profiling/hubextensions.ts b/packages/browser/src/profiling/hubextensions.ts index 0c23b5e5f128..82492081b924 100644 --- a/packages/browser/src/profiling/hubextensions.ts +++ b/packages/browser/src/profiling/hubextensions.ts @@ -2,6 +2,7 @@ import type { Transaction } from '@sentry/types'; import { logger, timestampInSeconds, uuid4 } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; import type { JSSelfProfile } from './jsSelfProfiling'; import { @@ -21,7 +22,7 @@ import { */ export function onProfilingStartRouteTransaction(transaction: Transaction | undefined): Transaction | undefined { if (!transaction) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log('[Profiling] Transaction is undefined, skipping profiling'); } return transaction; @@ -54,7 +55,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio return transaction; } - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log(`[Profiling] started profiling transaction: ${transaction.name || transaction.description}`); } @@ -85,7 +86,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio return null; } if (processedProfile) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log( '[Profiling] profile for:', transaction.name || transaction.description, @@ -103,13 +104,13 @@ export function startProfileForTransaction(transaction: Transaction): Transactio maxDurationTimeoutID = undefined; } - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log(`[Profiling] stopped profiling of transaction: ${transaction.name || transaction.description}`); } // In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile. if (!profile) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log( `[Profiling] profiler returned null profile for: ${transaction.name || transaction.description}`, 'this may indicate an overlapping transaction or a call to stopProfiling with a profile title that was never started', @@ -122,7 +123,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio return null; }) .catch(error => { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log('[Profiling] error while stopping profiler:', error); } return null; @@ -131,7 +132,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio // Enqueue a timeout to prevent profiles from running over max duration. let maxDurationTimeoutID: number | undefined = WINDOW.setTimeout(() => { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log( '[Profiling] max profile duration elapsed, stopping profiling for:', transaction.name || transaction.description, diff --git a/packages/browser/src/profiling/integration.ts b/packages/browser/src/profiling/integration.ts index 1ccfd63cf798..3f5251c4583f 100644 --- a/packages/browser/src/profiling/integration.ts +++ b/packages/browser/src/profiling/integration.ts @@ -2,6 +2,7 @@ import type { EventProcessor, Hub, Integration, Transaction } from '@sentry/type import type { Profile } from '@sentry/types/src/profiling'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { startProfileForTransaction } from './hubextensions'; import type { ProfiledEvent } from './utils'; import { @@ -78,14 +79,12 @@ export class BrowserProfilingIntegration implements Integration { const start_timestamp = context && context['profile'] && context['profile']['start_timestamp']; if (typeof profile_id !== 'string') { - __DEBUG_BUILD__ && - logger.log('[Profiling] cannot find profile for a transaction without a profile context'); + DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a transaction without a profile context'); continue; } if (!profile_id) { - __DEBUG_BUILD__ && - logger.log('[Profiling] cannot find profile for a transaction without a profile context'); + DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a transaction without a profile context'); continue; } @@ -96,7 +95,7 @@ export class BrowserProfilingIntegration implements Integration { const profile = takeProfileFromGlobalCache(profile_id); if (!profile) { - __DEBUG_BUILD__ && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`); + DEBUG_BUILD && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`); continue; } diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index 4c8a74adf247..ddf966d86deb 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -5,6 +5,7 @@ import type { DebugImage, Envelope, Event, StackFrame, StackParser, Transaction import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling'; import { browserPerformanceTimeOrigin, forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { getClient } from '../exports'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfiler, JSSelfProfilerConstructor, JSSelfProfileStack } from './jsSelfProfiling'; @@ -96,7 +97,7 @@ function getTraceId(event: Event): string { // All profiles and transactions are rejected if this is the case and we want to // warn users that this is happening if they enable debug flag if (typeof traceId === 'string' && traceId.length !== 32) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log(`[Profiling] Invalid traceId: ${traceId} on profiled event`); } } @@ -418,7 +419,7 @@ export function applyDebugMetadata(resource_paths: ReadonlyArray): Debug export function isValidSampleRate(rate: unknown): boolean { // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck if ((typeof rate !== 'number' && typeof rate !== 'boolean') || (typeof rate === 'number' && isNaN(rate))) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `[Profiling] Invalid sample rate. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify( rate, @@ -434,8 +435,7 @@ export function isValidSampleRate(rate: unknown): boolean { // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false if (rate < 0 || rate > 1) { - __DEBUG_BUILD__ && - logger.warn(`[Profiling] Invalid sample rate. Sample rate must be between 0 and 1. Got ${rate}.`); + DEBUG_BUILD && logger.warn(`[Profiling] Invalid sample rate. Sample rate must be between 0 and 1. Got ${rate}.`); return false; } return true; @@ -443,7 +443,7 @@ export function isValidSampleRate(rate: unknown): boolean { function isValidProfile(profile: JSSelfProfile): profile is JSSelfProfile & { profile_id: string } { if (profile.samples.length < 2) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { // Log a warning if the profile has less than 2 samples so users can know why // they are not seeing any profiling data and we cant avoid the back and forth // of asking them to provide us with a dump of the profile data. @@ -453,7 +453,7 @@ function isValidProfile(profile: JSSelfProfile): profile is JSSelfProfile & { pr } if (!profile.frames.length) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log('[Profiling] Discarding profile because it contains no frames'); } return false; @@ -483,7 +483,7 @@ export function startJSSelfProfile(): JSSelfProfiler | undefined { const JSProfilerConstructor = WINDOW.Profiler; if (!isJSProfilerSupported(JSProfilerConstructor)) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log( '[Profiling] Profiling is not supported by this browser, Profiler interface missing on window object.', ); @@ -502,7 +502,7 @@ export function startJSSelfProfile(): JSSelfProfiler | undefined { try { return new JSProfilerConstructor({ sampleInterval: samplingIntervalMS, maxBufferSize: maxSamples }); } catch (e) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log( "[Profiling] Failed to initialize the Profiling constructor, this is likely due to a missing 'Document-Policy': 'js-profiling' header.", ); @@ -520,14 +520,14 @@ export function startJSSelfProfile(): JSSelfProfiler | undefined { export function shouldProfileTransaction(transaction: Transaction): boolean { // If constructor failed once, it will always fail, so we can early return. if (PROFILING_CONSTRUCTOR_FAILED) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log('[Profiling] Profiling has been disabled for the duration of the current user session.'); } return false; } if (!transaction.sampled) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.log('[Profiling] Discarding profile because transaction was not sampled.'); } return false; @@ -536,7 +536,7 @@ export function shouldProfileTransaction(transaction: Transaction): boolean { const client = getClient(); const options = client && client.getOptions(); if (!options) { - __DEBUG_BUILD__ && logger.log('[Profiling] Profiling disabled, no options found.'); + DEBUG_BUILD && logger.log('[Profiling] Profiling disabled, no options found.'); return false; } @@ -546,13 +546,13 @@ export function shouldProfileTransaction(transaction: Transaction): boolean { // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The // only valid values are booleans or numbers between 0 and 1.) if (!isValidSampleRate(profilesSampleRate)) { - __DEBUG_BUILD__ && logger.warn('[Profiling] Discarding profile because of invalid sample rate.'); + DEBUG_BUILD && logger.warn('[Profiling] Discarding profile because of invalid sample rate.'); return false; } // if the function returned 0 (or false), or if `profileSampleRate` is 0, it's a sign the profile should be dropped if (!profilesSampleRate) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( '[Profiling] Discarding profile because a negative sampling decision was inherited or profileSampleRate is set to 0', ); @@ -564,7 +564,7 @@ export function shouldProfileTransaction(transaction: Transaction): boolean { const sampled = profilesSampleRate === true ? true : Math.random() < profilesSampleRate; // Check if we should sample this profile if (!sampled) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Profiling] Discarding profile because it's not included in the random sample (sampling rate = ${Number( profilesSampleRate, diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 0244af0ba98e..2bee5912e15e 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -17,6 +17,7 @@ import { import type { BrowserClientOptions, BrowserOptions } from './client'; import { BrowserClient } from './client'; +import { DEBUG_BUILD } from './debug-build'; import type { ReportDialogOptions } from './helpers'; import { WINDOW, wrap as internalWrap } from './helpers'; import { Breadcrumbs, Dedupe, GlobalHandlers, HttpContext, LinkedErrors, TryCatch } from './integrations'; @@ -140,14 +141,14 @@ export function init(options: BrowserOptions = {}): void { export function showReportDialog(options: ReportDialogOptions = {}, hub: Hub = getCurrentHub()): void { // doesn't work without a document (React Native) if (!WINDOW.document) { - __DEBUG_BUILD__ && logger.error('Global document not defined in showReportDialog call'); + DEBUG_BUILD && logger.error('Global document not defined in showReportDialog call'); return; } const { client, scope } = hub.getStackTop(); const dsn = options.dsn || (client && client.getDsn()); if (!dsn) { - __DEBUG_BUILD__ && logger.error('DSN not configured for showReportDialog call'); + DEBUG_BUILD && logger.error('DSN not configured for showReportDialog call'); return; } @@ -189,7 +190,7 @@ export function showReportDialog(options: ReportDialogOptions = {}, hub: Hub = g if (injectionPoint) { injectionPoint.appendChild(script); } else { - __DEBUG_BUILD__ && logger.error('Not injecting report dialog. No injection point found in HTML'); + DEBUG_BUILD && logger.error('Not injecting report dialog. No injection point found in HTML'); } } @@ -236,8 +237,7 @@ function startSessionOnHub(hub: Hub): void { */ function startSessionTracking(): void { if (typeof WINDOW.document === 'undefined') { - __DEBUG_BUILD__ && - logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.'); + DEBUG_BUILD && logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.'); return; } diff --git a/packages/browser/src/transports/utils.ts b/packages/browser/src/transports/utils.ts index 9852d754ec7b..6b42ae77b480 100644 --- a/packages/browser/src/transports/utils.ts +++ b/packages/browser/src/transports/utils.ts @@ -1,5 +1,6 @@ import { isNativeFetch, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; let cachedFetchImpl: FetchImpl | undefined = undefined; @@ -70,8 +71,7 @@ export function getNativeFetchImplementation(): FetchImpl { } document.head.removeChild(sandbox); } catch (e) { - __DEBUG_BUILD__ && - logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e); + DEBUG_BUILD && logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e); } } diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 915bafffa9bc..df3444126e8d 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -44,6 +44,7 @@ import { } from '@sentry/utils'; import { getEnvelopeEndpointWithUrlEncodedAuth } from './api'; +import { DEBUG_BUILD } from './debug-build'; import { createEventEnvelope, createSessionEnvelope } from './envelope'; import type { IntegrationIndex } from './integration'; import { setupIntegration, setupIntegrations } from './integration'; @@ -128,7 +129,7 @@ export abstract class BaseClient implements Client { if (options.dsn) { this._dsn = makeDsn(options.dsn); } else { - __DEBUG_BUILD__ && logger.warn('No DSN provided, client will not send events.'); + DEBUG_BUILD && logger.warn('No DSN provided, client will not send events.'); } if (this._dsn) { @@ -148,7 +149,7 @@ export abstract class BaseClient implements Client { public captureException(exception: any, hint?: EventHint, scope?: Scope): string | undefined { // ensure we haven't captured this very object before if (checkOrSetAlreadyCaught(exception)) { - __DEBUG_BUILD__ && logger.log(ALREADY_SEEN_ERROR); + DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR); return; } @@ -198,7 +199,7 @@ export abstract class BaseClient implements Client { public captureEvent(event: Event, hint?: EventHint, scope?: Scope): string | undefined { // ensure we haven't captured this very object before if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) { - __DEBUG_BUILD__ && logger.log(ALREADY_SEEN_ERROR); + DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR); return; } @@ -218,7 +219,7 @@ export abstract class BaseClient implements Client { */ public captureSession(session: Session): void { if (!(typeof session.release === 'string')) { - __DEBUG_BUILD__ && logger.warn('Discarded session because of missing or non-string release'); + DEBUG_BUILD && logger.warn('Discarded session because of missing or non-string release'); } else { this.sendSession(session); // After sending, we set init false to indicate it's not the first occurrence @@ -316,7 +317,7 @@ export abstract class BaseClient implements Client { try { return (this._integrations[integration.id] as T) || null; } catch (_oO) { - __DEBUG_BUILD__ && logger.warn(`Cannot retrieve integration ${integration.id} from the current Client`); + DEBUG_BUILD && logger.warn(`Cannot retrieve integration ${integration.id} from the current Client`); return null; } } @@ -374,7 +375,7 @@ export abstract class BaseClient implements Client { // would be `Partial>>>` // With typescript 4.1 we could even use template literal types const key = `${reason}:${category}`; - __DEBUG_BUILD__ && logger.log(`Adding outcome: "${key}"`); + DEBUG_BUILD && logger.log(`Adding outcome: "${key}"`); // The following works because undefined + 1 === NaN and NaN is falsy this._outcomes[key] = this._outcomes[key] + 1 || 1; @@ -604,7 +605,7 @@ export abstract class BaseClient implements Client { return finalEvent.event_id; }, reason => { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for // control flow, log just the message (no stack) as a log-level log. const sentryError = reason as SentryError; @@ -739,10 +740,10 @@ export abstract class BaseClient implements Client { if (this._isEnabled() && this._transport) { return this._transport.send(envelope).then(null, reason => { - __DEBUG_BUILD__ && logger.error('Error while sending event:', reason); + DEBUG_BUILD && logger.error('Error while sending event:', reason); }); } else { - __DEBUG_BUILD__ && logger.error('Transport disabled'); + DEBUG_BUILD && logger.error('Transport disabled'); } } diff --git a/packages/core/src/debug-build.ts b/packages/core/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/core/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/core/src/eventProcessors.ts b/packages/core/src/eventProcessors.ts index 4596788b9dcb..cc4a39cc84ea 100644 --- a/packages/core/src/eventProcessors.ts +++ b/packages/core/src/eventProcessors.ts @@ -1,6 +1,8 @@ import type { Event, EventHint, EventProcessor } from '@sentry/types'; import { getGlobalSingleton, isThenable, logger, SyncPromise } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; + /** * Returns the global event processors. */ @@ -32,10 +34,7 @@ export function notifyEventProcessors( } else { const result = processor({ ...event }, hint) as Event | null; - __DEBUG_BUILD__ && - processor.id && - result === null && - logger.log(`Event processor "${processor.id}" dropped event`); + DEBUG_BUILD && processor.id && result === null && logger.log(`Event processor "${processor.id}" dropped event`); if (isThenable(result)) { void result diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts index 6d1d52e60863..6d1e80600a75 100644 --- a/packages/core/src/exports.ts +++ b/packages/core/src/exports.ts @@ -18,6 +18,7 @@ import type { } from '@sentry/types'; import { isThenable, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import type { Hub } from './hub'; import { getCurrentHub } from './hub'; import type { Scope } from './scope'; @@ -205,9 +206,9 @@ export function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorCo const scope = hub.getScope(); const client = hub.getClient(); if (!client) { - __DEBUG_BUILD__ && logger.warn('Cannot capture check-in. No client defined.'); + DEBUG_BUILD && logger.warn('Cannot capture check-in. No client defined.'); } else if (!client.captureCheckIn) { - __DEBUG_BUILD__ && logger.warn('Cannot capture check-in. Client does not support sending check-ins.'); + DEBUG_BUILD && logger.warn('Cannot capture check-in. Client does not support sending check-ins.'); } else { return client.captureCheckIn(checkIn, upsertMonitorConfig, scope); } @@ -271,7 +272,7 @@ export async function flush(timeout?: number): Promise { if (client) { return client.flush(timeout); } - __DEBUG_BUILD__ && logger.warn('Cannot flush events. No client defined.'); + DEBUG_BUILD && logger.warn('Cannot flush events. No client defined.'); return Promise.resolve(false); } @@ -288,7 +289,7 @@ export async function close(timeout?: number): Promise { if (client) { return client.close(timeout); } - __DEBUG_BUILD__ && logger.warn('Cannot flush events and disable SDK. No client defined.'); + DEBUG_BUILD && logger.warn('Cannot flush events and disable SDK. No client defined.'); return Promise.resolve(false); } diff --git a/packages/core/src/hub.ts b/packages/core/src/hub.ts index c25f9fe00f67..892ecf7b3b52 100644 --- a/packages/core/src/hub.ts +++ b/packages/core/src/hub.ts @@ -23,6 +23,7 @@ import type { import { consoleSandbox, dateTimestampInSeconds, getGlobalSingleton, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; import { DEFAULT_ENVIRONMENT } from './constants'; +import { DEBUG_BUILD } from './debug-build'; import { Scope } from './scope'; import { closeSession, makeSession, updateSession } from './session'; @@ -362,7 +363,7 @@ export class Hub implements HubInterface { try { return client.getIntegration(integration); } catch (_oO) { - __DEBUG_BUILD__ && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`); + DEBUG_BUILD && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`); return null; } } @@ -373,7 +374,7 @@ export class Hub implements HubInterface { public startTransaction(context: TransactionContext, customSamplingContext?: CustomSamplingContext): Transaction { const result = this._callExtensionMethod('startTransaction', context, customSamplingContext); - if (__DEBUG_BUILD__ && !result) { + if (DEBUG_BUILD && !result) { const client = this.getClient(); if (!client) { // eslint-disable-next-line no-console @@ -505,7 +506,7 @@ Sentry.init({...}); if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') { return sentry.extensions[method].apply(this, args); } - __DEBUG_BUILD__ && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`); + DEBUG_BUILD && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`); } } diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index 8b05139af74b..2f21339a0842 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,6 +1,7 @@ import type { Client, Event, EventHint, Integration, Options } from '@sentry/types'; import { arrayify, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import { addGlobalEventProcessor } from './eventProcessors'; import { getClient } from './exports'; import { getCurrentHub } from './hub'; @@ -128,7 +129,7 @@ export function setupIntegration(client: Client, integration: Integration, integ client.addEventProcessor(processor); } - __DEBUG_BUILD__ && logger.log(`Integration installed: ${integration.name}`); + DEBUG_BUILD && logger.log(`Integration installed: ${integration.name}`); } /** Add an integration to the current hub's client. */ @@ -136,7 +137,7 @@ export function addIntegration(integration: Integration): void { const client = getClient(); if (!client || !client.addIntegration) { - __DEBUG_BUILD__ && logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`); + DEBUG_BUILD && logger.warn(`Cannot add integration "${integration.name}" because no SDK Client is available.`); return; } diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 20721d9dbcec..c1fcadb1076b 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -1,6 +1,8 @@ import type { Client, Event, EventHint, Integration, StackFrame } from '@sentry/types'; import { getEventDescription, logger, stringMatchesSomePattern } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + // "Script error." is hard coded into browsers for errors that it can't read. // this is the result of a script being pulled in from an external domain and CORS. const DEFAULT_IGNORE_ERRORS = [/^Script error\.?$/, /^Javascript error: Script error\.? on line 0$/]; @@ -85,26 +87,26 @@ export function _mergeOptions( /** JSDoc */ export function _shouldDropEvent(event: Event, options: Partial): boolean { if (options.ignoreInternal && _isSentryError(event)) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn(`Event dropped due to being internal Sentry Error.\nEvent: ${getEventDescription(event)}`); return true; } if (_isIgnoredError(event, options.ignoreErrors)) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `Event dropped due to being matched by \`ignoreErrors\` option.\nEvent: ${getEventDescription(event)}`, ); return true; } if (_isIgnoredTransaction(event, options.ignoreTransactions)) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `Event dropped due to being matched by \`ignoreTransactions\` option.\nEvent: ${getEventDescription(event)}`, ); return true; } if (_isDeniedUrl(event, options.denyUrls)) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `Event dropped due to being matched by \`denyUrls\` option.\nEvent: ${getEventDescription( event, @@ -113,7 +115,7 @@ export function _shouldDropEvent(event: Event, options: Partial( options: O, ): void { if (options.debug === true) { - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { logger.enable(); } else { // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped diff --git a/packages/core/src/server-runtime-client.ts b/packages/core/src/server-runtime-client.ts index 67d7055a1623..398a4224ef6d 100644 --- a/packages/core/src/server-runtime-client.ts +++ b/packages/core/src/server-runtime-client.ts @@ -15,6 +15,7 @@ import { eventFromMessage, eventFromUnknownInput, logger, resolvedSyncPromise, u import { BaseClient } from './baseclient'; import { createCheckInEnvelope } from './checkin'; +import { DEBUG_BUILD } from './debug-build'; import { getCurrentHub } from './hub'; import type { Scope } from './scope'; import { SessionFlusher } from './sessionflusher'; @@ -129,7 +130,7 @@ export class ServerRuntimeClient< public initSessionFlusher(): void { const { release, environment } = this._options; if (!release) { - __DEBUG_BUILD__ && logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!'); + DEBUG_BUILD && logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!'); } else { this._sessionFlusher = new SessionFlusher(this, { release, @@ -148,7 +149,7 @@ export class ServerRuntimeClient< public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string { const id = checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn.checkInId : uuid4(); if (!this._isEnabled()) { - __DEBUG_BUILD__ && logger.warn('SDK not enabled, will not capture checkin.'); + DEBUG_BUILD && logger.warn('SDK not enabled, will not capture checkin.'); return id; } @@ -191,7 +192,7 @@ export class ServerRuntimeClient< this.getDsn(), ); - __DEBUG_BUILD__ && logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status); + DEBUG_BUILD && logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status); void this._sendEnvelope(envelope); return id; } @@ -202,7 +203,7 @@ export class ServerRuntimeClient< */ protected _captureRequestSession(): void { if (!this._sessionFlusher) { - __DEBUG_BUILD__ && logger.warn('Discarded request mode session because autoSessionTracking option was disabled'); + DEBUG_BUILD && logger.warn('Discarded request mode session because autoSessionTracking option was disabled'); } else { this._sessionFlusher.incrementSessionStatusCount(); } diff --git a/packages/core/src/tracing/errors.ts b/packages/core/src/tracing/errors.ts index 477629cb7f9e..9030f02efadc 100644 --- a/packages/core/src/tracing/errors.ts +++ b/packages/core/src/tracing/errors.ts @@ -4,6 +4,7 @@ import { logger, } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { SpanStatusType } from './span'; import { getActiveTransaction } from './utils'; @@ -29,7 +30,7 @@ function errorCallback(): void { const activeTransaction = getActiveTransaction(); if (activeTransaction) { const status: SpanStatusType = 'internal_error'; - __DEBUG_BUILD__ && logger.log(`[Tracing] Transaction: ${status} -> Global error occured`); + DEBUG_BUILD && logger.log(`[Tracing] Transaction: ${status} -> Global error occured`); activeTransaction.setStatus(status); } } diff --git a/packages/core/src/tracing/hubextensions.ts b/packages/core/src/tracing/hubextensions.ts index 007612d8fb34..7cd8286860b2 100644 --- a/packages/core/src/tracing/hubextensions.ts +++ b/packages/core/src/tracing/hubextensions.ts @@ -1,6 +1,7 @@ import type { ClientOptions, CustomSamplingContext, TransactionContext } from '@sentry/types'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getMainCarrier } from '../hub'; import { registerErrorInstrumentation } from './errors'; @@ -47,7 +48,7 @@ function _startTransaction( const transactionInstrumenter = transactionContext.instrumenter || 'sentry'; if (configInstrumenter !== transactionInstrumenter) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.error( `A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter. The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`, diff --git a/packages/core/src/tracing/idletransaction.ts b/packages/core/src/tracing/idletransaction.ts index 1c4086ceecb7..b49b1d15e9b1 100644 --- a/packages/core/src/tracing/idletransaction.ts +++ b/packages/core/src/tracing/idletransaction.ts @@ -2,6 +2,7 @@ import type { TransactionContext } from '@sentry/types'; import { logger, timestampInSeconds } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import type { Span } from './span'; import { SpanRecorder } from './span'; @@ -119,7 +120,7 @@ export class IdleTransaction extends Transaction { if (_onScope) { // We set the transaction here on the scope so error events pick up the trace // context and attach it to the error. - __DEBUG_BUILD__ && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanId}`); + DEBUG_BUILD && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanId}`); _idleHub.configureScope(scope => scope.setSpan(this)); } @@ -143,7 +144,7 @@ export class IdleTransaction extends Transaction { } if (this.spanRecorder) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString(), this.op); for (const callback of this._beforeFinishCallbacks) { @@ -160,7 +161,7 @@ export class IdleTransaction extends Transaction { if (!span.endTimestamp) { span.endTimestamp = endTimestamp; span.setStatus('cancelled'); - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2)); } @@ -170,7 +171,7 @@ export class IdleTransaction extends Transaction { const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000; const spanEndedBeforeFinalTimeout = span.endTimestamp - this.startTimestamp < timeoutWithMarginOfError; - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { const stringifiedSpan = JSON.stringify(span, undefined, 2); if (!spanStartedBeforeTransactionFinish) { logger.log('[Tracing] discarding Span since it happened after Transaction was finished', stringifiedSpan); @@ -182,9 +183,9 @@ export class IdleTransaction extends Transaction { return spanStartedBeforeTransactionFinish && spanEndedBeforeFinalTimeout; }); - __DEBUG_BUILD__ && logger.log('[Tracing] flushing IdleTransaction'); + DEBUG_BUILD && logger.log('[Tracing] flushing IdleTransaction'); } else { - __DEBUG_BUILD__ && logger.log('[Tracing] No active IdleTransaction'); + DEBUG_BUILD && logger.log('[Tracing] No active IdleTransaction'); } // if `this._onScope` is `true`, the transaction put itself on the scope when it started @@ -230,7 +231,7 @@ export class IdleTransaction extends Transaction { this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanId, maxlen); // Start heartbeat so that transactions do not run forever. - __DEBUG_BUILD__ && logger.log('Starting heartbeat'); + DEBUG_BUILD && logger.log('Starting heartbeat'); this._pingHeartbeat(); } this.spanRecorder.add(this); @@ -296,9 +297,9 @@ export class IdleTransaction extends Transaction { */ private _pushActivity(spanId: string): void { this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently }); - __DEBUG_BUILD__ && logger.log(`[Tracing] pushActivity: ${spanId}`); + DEBUG_BUILD && logger.log(`[Tracing] pushActivity: ${spanId}`); this.activities[spanId] = true; - __DEBUG_BUILD__ && logger.log('[Tracing] new activities count', Object.keys(this.activities).length); + DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length); } /** @@ -307,10 +308,10 @@ export class IdleTransaction extends Transaction { */ private _popActivity(spanId: string): void { if (this.activities[spanId]) { - __DEBUG_BUILD__ && logger.log(`[Tracing] popActivity ${spanId}`); + DEBUG_BUILD && logger.log(`[Tracing] popActivity ${spanId}`); // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.activities[spanId]; - __DEBUG_BUILD__ && logger.log('[Tracing] new activities count', Object.keys(this.activities).length); + DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length); } if (Object.keys(this.activities).length === 0) { @@ -347,7 +348,7 @@ export class IdleTransaction extends Transaction { this._prevHeartbeatString = heartbeatString; if (this._heartbeatCounter >= 3) { - __DEBUG_BUILD__ && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats'); + DEBUG_BUILD && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats'); this.setStatus('deadline_exceeded'); this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0]; this.finish(); @@ -360,7 +361,7 @@ export class IdleTransaction extends Transaction { * Pings the heartbeat */ private _pingHeartbeat(): void { - __DEBUG_BUILD__ && logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`); + DEBUG_BUILD && logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`); setTimeout(() => { this._beat(); }, this._heartbeatInterval); diff --git a/packages/core/src/tracing/sampling.ts b/packages/core/src/tracing/sampling.ts index 4b357b7bf1be..6c6ab19bf7c9 100644 --- a/packages/core/src/tracing/sampling.ts +++ b/packages/core/src/tracing/sampling.ts @@ -1,6 +1,7 @@ import type { Options, SamplingContext } from '@sentry/types'; import { isNaN, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; import type { Transaction } from './transaction'; @@ -58,14 +59,14 @@ export function sampleTransaction( // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The // only valid values are booleans or numbers between 0 and 1.) if (!isValidSampleRate(sampleRate)) { - __DEBUG_BUILD__ && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.'); + DEBUG_BUILD && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.'); transaction.sampled = false; return transaction; } // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped if (!sampleRate) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Discarding transaction because ${ typeof options.tracesSampler === 'function' @@ -83,7 +84,7 @@ export function sampleTransaction( // if we're not going to keep it, we're done if (!transaction.sampled) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number( sampleRate, @@ -92,7 +93,7 @@ export function sampleTransaction( return transaction; } - __DEBUG_BUILD__ && logger.log(`[Tracing] starting ${transaction.op} transaction - ${transaction.name}`); + DEBUG_BUILD && logger.log(`[Tracing] starting ${transaction.op} transaction - ${transaction.name}`); return transaction; } @@ -103,7 +104,7 @@ function isValidSampleRate(rate: unknown): boolean { // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck // eslint-disable-next-line @typescript-eslint/no-explicit-any if (isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify( rate, @@ -114,7 +115,7 @@ function isValidSampleRate(rate: unknown): boolean { // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false if (rate < 0 || rate > 1) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`); return false; } diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts index be4e420fc8bc..4b341a71e2c2 100644 --- a/packages/core/src/tracing/span.ts +++ b/packages/core/src/tracing/span.ts @@ -10,6 +10,8 @@ import type { } from '@sentry/types'; import { dropUndefinedKeys, generateSentryTraceHeader, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + /** * Keeps track of finished spans for a given transaction * @internal @@ -190,7 +192,7 @@ export class Span implements SpanInterface { childSpan.transaction = this.transaction; - if (__DEBUG_BUILD__ && childSpan.transaction) { + if (DEBUG_BUILD && childSpan.transaction) { const opStr = (spanContext && spanContext.op) || '< unknown op >'; const nameStr = childSpan.transaction.name || '< unknown name >'; const idStr = childSpan.transaction.spanId; @@ -260,7 +262,7 @@ export class Span implements SpanInterface { */ public finish(endTimestamp?: number): void { if ( - __DEBUG_BUILD__ && + DEBUG_BUILD && // Don't call this for transactions this.transaction && this.transaction.spanId !== this.spanId diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index 33e19ec7ecb4..99d706f0585e 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,6 +1,7 @@ import type { TransactionContext } from '@sentry/types'; import { dropUndefinedKeys, isThenable, logger, tracingContextFromHeaders } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; @@ -248,7 +249,7 @@ export function continueTrace( currentScope.setPropagationContext(propagationContext); - if (__DEBUG_BUILD__ && traceparentData) { + if (DEBUG_BUILD && traceparentData) { logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`); } diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index 73bfb16996bb..da2ccb32d30b 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -11,6 +11,7 @@ import type { } from '@sentry/types'; import { dropUndefinedKeys, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; import { getDynamicSamplingContextFromClient } from './dynamicSamplingContext'; @@ -226,7 +227,7 @@ export class Transaction extends SpanClass implements TransactionInterface { } if (!this.name) { - __DEBUG_BUILD__ && logger.warn('Transaction has no name, falling back to ``.'); + DEBUG_BUILD && logger.warn('Transaction has no name, falling back to ``.'); this.name = ''; } @@ -240,7 +241,7 @@ export class Transaction extends SpanClass implements TransactionInterface { if (this.sampled !== true) { // At this point if `sampled !== true` we want to discard the transaction. - __DEBUG_BUILD__ && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); + DEBUG_BUILD && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); if (client) { client.recordDroppedEvent('sample_rate', 'transaction'); @@ -288,7 +289,7 @@ export class Transaction extends SpanClass implements TransactionInterface { const hasMeasurements = Object.keys(this._measurements).length > 0; if (hasMeasurements) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( '[Measurements] Adding measurements to transaction', JSON.stringify(this._measurements, undefined, 2), @@ -296,7 +297,7 @@ export class Transaction extends SpanClass implements TransactionInterface { transaction.measurements = this._measurements; } - __DEBUG_BUILD__ && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this.name}.`); + DEBUG_BUILD && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this.name}.`); return transaction; } diff --git a/packages/core/src/transports/base.ts b/packages/core/src/transports/base.ts index 3111f5f15fca..199cad6c545b 100644 --- a/packages/core/src/transports/base.ts +++ b/packages/core/src/transports/base.ts @@ -24,6 +24,8 @@ import { updateRateLimits, } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + export const DEFAULT_TRANSPORT_BUFFER_SIZE = 30; /** @@ -77,7 +79,7 @@ export function createTransport( response => { // We don't want to throw on NOK responses, but we want to at least log them if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) { - __DEBUG_BUILD__ && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`); + DEBUG_BUILD && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`); } rateLimits = updateRateLimits(rateLimits, response); @@ -93,7 +95,7 @@ export function createTransport( result => result, error => { if (error instanceof SentryError) { - __DEBUG_BUILD__ && logger.error('Skipped sending event because buffer is full.'); + DEBUG_BUILD && logger.error('Skipped sending event because buffer is full.'); recordEnvelopeLoss('queue_overflow'); return resolvedSyncPromise(); } else { diff --git a/packages/core/src/transports/offline.ts b/packages/core/src/transports/offline.ts index c3864ead7ec5..c628e538a071 100644 --- a/packages/core/src/transports/offline.ts +++ b/packages/core/src/transports/offline.ts @@ -1,12 +1,14 @@ import type { Envelope, InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '@sentry/types'; import { envelopeContainsItemType, logger, parseRetryAfterHeader } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + export const MIN_DELAY = 100; // 100 ms export const START_DELAY = 5_000; // 5 seconds const MAX_DELAY = 3.6e6; // 1 hour function log(msg: string, error?: Error): void { - __DEBUG_BUILD__ && logger.info(`[Offline]: ${msg}`, error); + DEBUG_BUILD && logger.info(`[Offline]: ${msg}`, error); } export interface OfflineStore { diff --git a/packages/feedback/src/debug-build.ts b/packages/feedback/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/feedback/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/feedback/src/integration.ts b/packages/feedback/src/integration.ts index 13f155d1ced5..6b1e0fb1b2c4 100644 --- a/packages/feedback/src/integration.ts +++ b/packages/feedback/src/integration.ts @@ -16,6 +16,7 @@ import { SUCCESS_MESSAGE_TEXT, WINDOW, } from './constants'; +import { DEBUG_BUILD } from './debug-build'; import type { FeedbackInternalOptions, FeedbackWidget, OptionalFeedbackConfiguration } from './types'; import { mergeOptions } from './util/mergeOptions'; import { createActorStyles } from './widget/Actor.css'; @@ -173,7 +174,7 @@ export class Feedback implements Integration { this._createWidget(this.options); } catch (err) { - __DEBUG_BUILD__ && logger.error(err); + DEBUG_BUILD && logger.error(err); } } @@ -218,7 +219,7 @@ export class Feedback implements Integration { typeof el === 'string' ? doc.querySelector(el) : typeof el.addEventListener === 'function' ? el : null; if (!targetEl) { - __DEBUG_BUILD__ && logger.error('[Feedback] Unable to attach to target element'); + DEBUG_BUILD && logger.error('[Feedback] Unable to attach to target element'); return null; } @@ -232,7 +233,7 @@ export class Feedback implements Integration { return widget; }); } catch (err) { - __DEBUG_BUILD__ && logger.error(err); + DEBUG_BUILD && logger.error(err); return null; } } @@ -246,7 +247,7 @@ export class Feedback implements Integration { try { return this._createWidget(mergeOptions(this.options, optionOverrides || {})); } catch (err) { - __DEBUG_BUILD__ && logger.error(err); + DEBUG_BUILD && logger.error(err); return null; } } @@ -273,7 +274,7 @@ export class Feedback implements Integration { return true; } } catch (err) { - __DEBUG_BUILD__ && logger.error(err); + DEBUG_BUILD && logger.error(err); } return false; diff --git a/packages/feedback/src/util/handleFeedbackSubmit.ts b/packages/feedback/src/util/handleFeedbackSubmit.ts index eef28c8a2f29..abb3aeb1368d 100644 --- a/packages/feedback/src/util/handleFeedbackSubmit.ts +++ b/packages/feedback/src/util/handleFeedbackSubmit.ts @@ -2,6 +2,7 @@ import type { TransportMakeRequestResponse } from '@sentry/types'; import { logger } from '@sentry/utils'; import { FEEDBACK_WIDGET_SOURCE } from '../constants'; +import { DEBUG_BUILD } from '../debug-build'; import { sendFeedback } from '../sendFeedback'; import type { FeedbackFormData, SendFeedbackOptions } from '../types'; import type { DialogComponent } from '../widget/Dialog'; @@ -35,7 +36,7 @@ export async function handleFeedbackSubmit( // Success! return resp; } catch (err) { - __DEBUG_BUILD__ && logger.error(err); + DEBUG_BUILD && logger.error(err); showFetchError(); } } diff --git a/packages/integrations/src/debug-build.ts b/packages/integrations/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/integrations/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 49865de3cd79..06ff147a76cb 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -1,6 +1,8 @@ import type { Event, Exception, Integration, StackFrame } from '@sentry/types'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; + /** Deduplication filter */ export class Dedupe implements Integration { /** @@ -40,7 +42,7 @@ export class Dedupe implements Integration { // Juuust in case something goes wrong try { if (_shouldDropEvent(currentEvent, this._previousEvent)) { - __DEBUG_BUILD__ && logger.warn('Event dropped due to being a duplicate of previously captured event.'); + DEBUG_BUILD && logger.warn('Event dropped due to being a duplicate of previously captured event.'); return null; } } catch (_oO) { diff --git a/packages/integrations/src/extraerrordata.ts b/packages/integrations/src/extraerrordata.ts index 0ac2729e3baf..a5222fb84833 100644 --- a/packages/integrations/src/extraerrordata.ts +++ b/packages/integrations/src/extraerrordata.ts @@ -1,6 +1,8 @@ import type { Contexts, Event, EventHint, ExtendedError, Integration } from '@sentry/types'; import { addNonEnumerableProperty, isError, isPlainObject, logger, normalize } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; + /** JSDoc */ interface ExtraErrorDataOptions { depth: number; @@ -127,7 +129,7 @@ function _extractErrorData(error: ExtendedError): Record | null return extraErrorInfo; } catch (oO) { - __DEBUG_BUILD__ && logger.error('Unable to extract extra data from the Error object:', oO); + DEBUG_BUILD && logger.error('Unable to extract extra data from the Error object:', oO); } return null; diff --git a/packages/integrations/src/httpclient.ts b/packages/integrations/src/httpclient.ts index 623b216e22fa..02918151817b 100644 --- a/packages/integrations/src/httpclient.ts +++ b/packages/integrations/src/httpclient.ts @@ -16,6 +16,8 @@ import { supportsNativeFetch, } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; + export type HttpStatusCodeRange = [number, number] | number; export type HttpRequestTarget = string | RegExp; interface HttpClientOptions { @@ -113,7 +115,7 @@ export class HttpClient implements Integration { cookies = this._parseCookieString(cookieString); } } catch (e) { - __DEBUG_BUILD__ && logger.log(`Could not extract cookies from header ${cookieHeader}`); + DEBUG_BUILD && logger.log(`Could not extract cookies from header ${cookieHeader}`); } return { @@ -157,13 +159,13 @@ export class HttpClient implements Integration { responseCookies = this._parseCookieString(cookieString); } } catch (e) { - __DEBUG_BUILD__ && logger.log('Could not extract cookies from response headers'); + DEBUG_BUILD && logger.log('Could not extract cookies from response headers'); } try { responseHeaders = this._getXHRResponseHeaders(xhr); } catch (e) { - __DEBUG_BUILD__ && logger.log('Could not extract headers from response'); + DEBUG_BUILD && logger.log('Could not extract headers from response'); } requestHeaders = headers; @@ -333,7 +335,7 @@ export class HttpClient implements Integration { try { this._xhrResponseHandler(xhr, method, headers); } catch (e) { - __DEBUG_BUILD__ && logger.warn('Error while extracting response event form XHR response', e); + DEBUG_BUILD && logger.warn('Error while extracting response event form XHR response', e); } }); } diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index bdb3d8324333..9708ffbdc050 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -5,6 +5,8 @@ import type { Event, EventProcessor, Hub, Integration } from '@sentry/types'; import { GLOBAL_OBJ, logger, normalize, uuid4 } from '@sentry/utils'; import localForage from 'localforage'; +import { DEBUG_BUILD } from './debug-build'; + const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; type LocalForage = { @@ -73,7 +75,7 @@ export class Offline implements Integration { if ('addEventListener' in WINDOW) { WINDOW.addEventListener('online', () => { void this._sendEvents().catch(() => { - __DEBUG_BUILD__ && logger.warn('could not send cached events'); + DEBUG_BUILD && logger.warn('could not send cached events'); }); }); } @@ -82,12 +84,12 @@ export class Offline implements Integration { if (this.hub && this.hub.getIntegration(Offline)) { // cache if we are positively offline if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && !WINDOW.navigator.onLine) { - __DEBUG_BUILD__ && logger.log('Event dropped due to being a offline - caching instead'); + 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 => { - __DEBUG_BUILD__ && logger.warn('could not cache event while offline'); + DEBUG_BUILD && logger.warn('could not cache event while offline'); }); // return null on success or failure, because being offline will still result in an error @@ -104,7 +106,7 @@ export class Offline implements Integration { // if online now, send any events stored in a previous offline session if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && WINDOW.navigator.onLine) { void this._sendEvents().catch(() => { - __DEBUG_BUILD__ && logger.warn('could not send cached events'); + DEBUG_BUILD && logger.warn('could not send cached events'); }); } } @@ -140,7 +142,7 @@ export class Offline implements Integration { ), ) .catch((_error): void => { - __DEBUG_BUILD__ && logger.warn('could not enforce max events'); + DEBUG_BUILD && logger.warn('could not enforce max events'); }); } @@ -168,10 +170,10 @@ export class Offline implements Integration { this.hub.captureEvent(event); void this._purgeEvent(cacheKey).catch((_error): void => { - __DEBUG_BUILD__ && logger.warn('could not purge event from cache'); + DEBUG_BUILD && logger.warn('could not purge event from cache'); }); } else { - __DEBUG_BUILD__ && logger.warn('no hub found - could not send cached event'); + DEBUG_BUILD && logger.warn('no hub found - could not send cached event'); } }); } diff --git a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts index c1f8bdc5ccfe..2f5995b8354b 100644 --- a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts @@ -11,6 +11,8 @@ import type { NEXT_DATA as NextData } from 'next/dist/next-server/lib/utils'; import { default as Router } from 'next/router'; import type { ParsedUrlQuery } from 'querystring'; +import { DEBUG_BUILD } from '../../common/debug-build'; + const globalObject = WINDOW as typeof WINDOW & { __BUILD_MANIFEST?: { sortedPages?: string[]; @@ -62,7 +64,7 @@ function extractNextDataTagInformation(): NextDataTagInfo { try { nextData = JSON.parse(nextDataTag.innerHTML); } catch (e) { - __DEBUG_BUILD__ && logger.warn('Could not extract __NEXT_DATA__'); + DEBUG_BUILD && logger.warn('Could not extract __NEXT_DATA__'); } } diff --git a/packages/nextjs/src/client/tunnelRoute.ts b/packages/nextjs/src/client/tunnelRoute.ts index 6f10b190727a..6ac5fb50a640 100644 --- a/packages/nextjs/src/client/tunnelRoute.ts +++ b/packages/nextjs/src/client/tunnelRoute.ts @@ -1,6 +1,8 @@ import type { BrowserOptions } from '@sentry/react'; import { dsnFromString, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../common/debug-build'; + const globalWithInjectedValues = global as typeof global & { __sentryRewritesTunnelPath__?: string; }; @@ -20,9 +22,9 @@ export function applyTunnelRouteOption(options: BrowserOptions): void { const orgId = sentrySaasDsnMatch[1]; const tunnelPath = `${tunnelRouteOption}?o=${orgId}&p=${dsnComponents.projectId}`; options.tunnel = tunnelPath; - __DEBUG_BUILD__ && logger.info(`Tunneling events to "${tunnelPath}"`); + DEBUG_BUILD && logger.info(`Tunneling events to "${tunnelPath}"`); } else { - __DEBUG_BUILD__ && logger.warn('Provided DSN is not a Sentry SaaS DSN. Will not tunnel events.'); + DEBUG_BUILD && logger.warn('Provided DSN is not a Sentry SaaS DSN. Will not tunnel events.'); } } } diff --git a/packages/nextjs/src/common/debug-build.ts b/packages/nextjs/src/common/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/nextjs/src/common/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts index bdf7b389fa00..72dc2f142365 100644 --- a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts +++ b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts @@ -9,6 +9,7 @@ import { } from '@sentry/utils'; import type { EdgeRouteHandler } from '../../edge/types'; +import { DEBUG_BUILD } from '../debug-build'; /** * Wraps a function on the edge runtime with error and performance monitoring. @@ -41,7 +42,7 @@ export function withEdgeWrapping( ); currentScope.setPropagationContext(propagationContext); if (traceparentData) { - __DEBUG_BUILD__ && logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`); + DEBUG_BUILD && logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`); } span = startTransaction({ diff --git a/packages/nextjs/src/common/utils/responseEnd.ts b/packages/nextjs/src/common/utils/responseEnd.ts index 4cc31de89fb5..35f227261089 100644 --- a/packages/nextjs/src/common/utils/responseEnd.ts +++ b/packages/nextjs/src/common/utils/responseEnd.ts @@ -3,6 +3,7 @@ import type { Transaction } from '@sentry/types'; import { fill, logger } from '@sentry/utils'; import type { ServerResponse } from 'http'; +import { DEBUG_BUILD } from '../debug-build'; import type { ResponseEndMethod, WrappedResponseEndMethod } from '../types'; /** @@ -48,10 +49,10 @@ export async function finishTransaction(transaction: Transaction | undefined, re /** Flush the event queue to ensure that events get sent to Sentry before the response is finished and the lambda ends */ export async function flushQueue(): Promise { try { - __DEBUG_BUILD__ && logger.log('Flushing events...'); + DEBUG_BUILD && logger.log('Flushing events...'); await flush(2000); - __DEBUG_BUILD__ && logger.log('Done flushing events'); + DEBUG_BUILD && logger.log('Done flushing events'); } catch (e) { - __DEBUG_BUILD__ && logger.log('Error while flushing events:\n', e); + DEBUG_BUILD && logger.log('Error while flushing events:\n', e); } } diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 8f458fc728a6..dcc1c7d29382 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -1,6 +1,7 @@ import { addTracingExtensions, captureException, flush, getCurrentHub, runWithAsyncContext, trace } from '@sentry/core'; import { logger, tracingContextFromHeaders } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import { platformSupportsStreaming } from './utils/platformSupportsStreaming'; interface Options { @@ -60,7 +61,7 @@ async function withServerActionInstrumentationImplementation key in userOptions); if (sentryWebpackPluginOptionOverrides.length > 0) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( '[Sentry] You are overriding the following automatically-set SentryWebpackPlugin config options:\n' + `\t${sentryWebpackPluginOptionOverrides.toString()},\n` + diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index 822f2619d127..a672d814bc78 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -7,6 +7,7 @@ import type { IntegrationWithExclusionOption } from '@sentry/utils'; import { addOrUpdateIntegration, escapeStringForRegex, logger } from '@sentry/utils'; import * as path from 'path'; +import { DEBUG_BUILD } from '../common/debug-build'; import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor'; import { getVercelEnv } from '../common/getVercelEnv'; import { buildMetadata } from '../common/metadata'; @@ -77,14 +78,14 @@ export function init(options: NodeOptions): void { autoSessionTracking: false, }; - if (__DEBUG_BUILD__ && opts.debug) { + if (DEBUG_BUILD && opts.debug) { logger.enable(); } - __DEBUG_BUILD__ && logger.log('Initializing SDK...'); + DEBUG_BUILD && logger.log('Initializing SDK...'); if (sdkAlreadyInitialized()) { - __DEBUG_BUILD__ && logger.log('SDK already initialized'); + DEBUG_BUILD && logger.log('SDK already initialized'); return; } @@ -113,7 +114,7 @@ export function init(options: NodeOptions): void { } }); - __DEBUG_BUILD__ && logger.log('SDK successfully initialized'); + DEBUG_BUILD && logger.log('SDK successfully initialized'); } function sdkAlreadyInitialized(): boolean { diff --git a/packages/node-experimental/src/debug-build.ts b/packages/node-experimental/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/node-experimental/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/node-experimental/src/sdk/initOtel.ts b/packages/node-experimental/src/sdk/initOtel.ts index 7b33df8431f1..285938b92c90 100644 --- a/packages/node-experimental/src/sdk/initOtel.ts +++ b/packages/node-experimental/src/sdk/initOtel.ts @@ -13,6 +13,7 @@ import { } from '@sentry/opentelemetry'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import type { NodeExperimentalClient } from '../types'; import { NodeExperimentalSentrySpanProcessor } from './spanProcessor'; @@ -23,7 +24,7 @@ export function initOtel(): void { const client = getClient(); if (!client) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( 'No client available, skipping OpenTelemetry setup. This probably means that `Sentry.init()` was not called before `initOtel()`.', ); diff --git a/packages/node/src/debug-build.ts b/packages/node/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/node/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 1a75a76a20ab..339c9553bf26 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -25,6 +25,7 @@ import { import type * as http from 'http'; import type { NodeClient } from './client'; +import { DEBUG_BUILD } from './debug-build'; // TODO (v8 / XXX) Remove this import import type { ParseRequestOptions } from './requestDataDeprecated'; import { isAutoSessionTrackingEnabled } from './sdk'; @@ -178,7 +179,7 @@ export function requestHandler( _end.call(this, chunk, encoding, cb); }) .then(null, e => { - __DEBUG_BUILD__ && logger.error(e); + DEBUG_BUILD && logger.error(e); _end.call(this, chunk, encoding, cb); }); }; diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 4fd2e702bb44..be5f061e62e5 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -19,6 +19,7 @@ import type * as http from 'http'; import type * as https from 'https'; import type { NodeClient } from '../client'; +import { DEBUG_BUILD } from '../debug-build'; import { NODE_VERSION } from '../nodeVersion'; import type { RequestMethod, RequestMethodArgs, RequestOptions } from './utils/http'; import { cleanSpanDescription, extractRawUrl, extractUrl, normalizeRequestArgs } from './utils/http'; @@ -106,7 +107,7 @@ export class Http implements Integration { // Do not auto-instrument for other instrumenter if (clientOptions && clientOptions.instrumenter !== 'sentry') { - __DEBUG_BUILD__ && logger.log('HTTP Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('HTTP Integration is skipped because of instrumenter configuration.'); return; } @@ -271,7 +272,7 @@ function _createWrappedRequestMethodFactory( addHeadersToRequestOptions(requestOptions, requestUrl, sentryTraceHeader, dynamicSamplingContext); } } else { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`, ); @@ -323,7 +324,7 @@ function addHeadersToRequestOptions( return; } - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log(`[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `); const sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); const sentryBaggageHeader = diff --git a/packages/node/src/integrations/onuncaughtexception.ts b/packages/node/src/integrations/onuncaughtexception.ts index b1699f464960..9fcd2fe5fa26 100644 --- a/packages/node/src/integrations/onuncaughtexception.ts +++ b/packages/node/src/integrations/onuncaughtexception.ts @@ -4,6 +4,7 @@ import type { Integration } from '@sentry/types'; import { logger } from '@sentry/utils'; import type { NodeClient } from '../client'; +import { DEBUG_BUILD } from '../debug-build'; import { logAndExitProcess } from './utils/errorhandling'; type OnFatalErrorHandler = (firstError: Error, secondError?: Error) => void; @@ -148,7 +149,7 @@ export class OnUncaughtException implements Integration { if (shouldApplyFatalHandlingLogic) { if (calledFatalError) { // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown', ); diff --git a/packages/node/src/integrations/utils/errorhandling.ts b/packages/node/src/integrations/utils/errorhandling.ts index e3f03f064421..86d55c2c8086 100644 --- a/packages/node/src/integrations/utils/errorhandling.ts +++ b/packages/node/src/integrations/utils/errorhandling.ts @@ -2,6 +2,7 @@ import { getClient } from '@sentry/core'; import { logger } from '@sentry/utils'; import type { NodeClient } from '../../client'; +import { DEBUG_BUILD } from '../../debug-build'; const DEFAULT_SHUTDOWN_TIMEOUT = 2000; @@ -15,7 +16,7 @@ export function logAndExitProcess(error: Error): void { const client = getClient(); if (client === undefined) { - __DEBUG_BUILD__ && logger.warn('No NodeClient was defined, we are exiting the process now.'); + DEBUG_BUILD && logger.warn('No NodeClient was defined, we are exiting the process now.'); global.process.exit(1); } @@ -26,12 +27,12 @@ export function logAndExitProcess(error: Error): void { client.close(timeout).then( (result: boolean) => { if (!result) { - __DEBUG_BUILD__ && logger.warn('We reached the timeout for emptying the request buffer, still exiting now!'); + DEBUG_BUILD && logger.warn('We reached the timeout for emptying the request buffer, still exiting now!'); } global.process.exit(1); }, error => { - __DEBUG_BUILD__ && logger.error(error); + DEBUG_BUILD && logger.error(error); }, ); } diff --git a/packages/opentelemetry-node/src/debug-build.ts b/packages/opentelemetry-node/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/opentelemetry-node/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts index 98ab46c405cb..571871e1e3f0 100644 --- a/packages/opentelemetry-node/src/spanprocessor.ts +++ b/packages/opentelemetry-node/src/spanprocessor.ts @@ -7,6 +7,7 @@ import type { DynamicSamplingContext, Span as SentrySpan, TraceparentData, Trans import { logger } from '@sentry/utils'; import { SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, SENTRY_TRACE_PARENT_CONTEXT_KEY } from './constants'; +import { DEBUG_BUILD } from './debug-build'; import { maybeCaptureExceptionForTimedEvent } from './utils/captureExceptionForTimedEvent'; import { isSentryRequestSpan } from './utils/isSentryRequest'; import { mapOtelStatus } from './utils/mapOtelStatus'; @@ -85,8 +86,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { const sentrySpan = getSentrySpan(otelSpanId); if (!sentrySpan) { - __DEBUG_BUILD__ && - logger.error(`SentrySpanProcessor could not find span with OTEL-spanId ${otelSpanId} to finish.`); + DEBUG_BUILD && logger.error(`SentrySpanProcessor could not find span with OTEL-spanId ${otelSpanId} to finish.`); clearSpan(otelSpanId); return; } diff --git a/packages/opentelemetry/src/custom/scope.ts b/packages/opentelemetry/src/custom/scope.ts index 9c544b018134..b65aa437b14f 100644 --- a/packages/opentelemetry/src/custom/scope.ts +++ b/packages/opentelemetry/src/custom/scope.ts @@ -4,6 +4,7 @@ import { Scope } from '@sentry/core'; import type { Breadcrumb, SeverityLevel, Span as SentrySpan } from '@sentry/types'; import { dateTimestampInSeconds, dropUndefinedKeys, logger, normalize } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { InternalSentrySemanticAttributes } from '../semanticAttributes'; import { convertOtelTimeToSeconds } from '../utils/convertOtelTimeToSeconds'; import { getActiveSpan, getRootSpan } from '../utils/getActiveSpan'; @@ -48,8 +49,7 @@ export class OpenTelemetryScope extends Scope { * Instead, use the global `getActiveSpan()`. */ public getSpan(): undefined { - __DEBUG_BUILD__ && - logger.warn('Calling getSpan() is a noop in @sentry/opentelemetry. Use `getActiveSpan()` instead.'); + DEBUG_BUILD && logger.warn('Calling getSpan() is a noop in @sentry/opentelemetry. Use `getActiveSpan()` instead.'); return undefined; } @@ -59,7 +59,7 @@ export class OpenTelemetryScope extends Scope { * Instead, use the global `startSpan()` to define the active span. */ public setSpan(_span: SentrySpan): this { - __DEBUG_BUILD__ && logger.warn('Calling setSpan() is a noop in @sentry/opentelemetry. Use `startSpan()` instead.'); + DEBUG_BUILD && logger.warn('Calling setSpan() is a noop in @sentry/opentelemetry. Use `startSpan()` instead.'); return this; } diff --git a/packages/opentelemetry/src/debug-build.ts b/packages/opentelemetry/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/opentelemetry/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/opentelemetry/src/sampler.ts b/packages/opentelemetry/src/sampler.ts index 03f82f100a87..f07dc4f8f1e4 100644 --- a/packages/opentelemetry/src/sampler.ts +++ b/packages/opentelemetry/src/sampler.ts @@ -7,6 +7,7 @@ import { hasTracingEnabled } from '@sentry/core'; import type { Client, ClientOptions, SamplingContext } from '@sentry/types'; import { isNaN, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import { InternalSentrySemanticAttributes } from './semanticAttributes'; import { getPropagationContextFromContext } from './utils/contextData'; @@ -44,12 +45,11 @@ export class SentrySampler implements Sampler { if (parentContext && isSpanContextValid(parentContext) && parentContext.traceId === traceId) { if (parentContext.isRemote) { parentSampled = getParentRemoteSampled(parentContext, context); - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log(`[Tracing] Inheriting remote parent's sampled decision for ${spanName}: ${parentSampled}`); } else { parentSampled = Boolean(parentContext.traceFlags & TraceFlags.SAMPLED); - __DEBUG_BUILD__ && - logger.log(`[Tracing] Inheriting parent's sampled decision for ${spanName}: ${parentSampled}`); + DEBUG_BUILD && logger.log(`[Tracing] Inheriting parent's sampled decision for ${spanName}: ${parentSampled}`); } } @@ -72,7 +72,7 @@ export class SentrySampler implements Sampler { // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The // only valid values are booleans or numbers between 0 and 1.) if (!isValidSampleRate(sampleRate)) { - __DEBUG_BUILD__ && logger.warn('[Tracing] Discarding span because of invalid sample rate.'); + DEBUG_BUILD && logger.warn('[Tracing] Discarding span because of invalid sample rate.'); return { decision: SamplingDecision.NOT_RECORD, @@ -82,7 +82,7 @@ export class SentrySampler implements Sampler { // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped if (!sampleRate) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Discarding span because ${ typeof options.tracesSampler === 'function' @@ -103,7 +103,7 @@ export class SentrySampler implements Sampler { // if we're not going to keep it, we're done if (!isSampled) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Discarding span because it's not included in the random sample (sampling rate = ${Number( sampleRate, @@ -159,7 +159,7 @@ function isValidSampleRate(rate: unknown): boolean { // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck // eslint-disable-next-line @typescript-eslint/no-explicit-any if (isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify( rate, @@ -170,7 +170,7 @@ function isValidSampleRate(rate: unknown): boolean { // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false if (rate < 0 || rate > 1) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`); return false; } diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index f2094d132733..d3c3b5b3da90 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -12,6 +12,7 @@ import { getCurrentHub } from './custom/hub'; import { OpenTelemetryScope } from './custom/scope'; import type { OpenTelemetryTransaction } from './custom/transaction'; import { startTransaction } from './custom/transaction'; +import { DEBUG_BUILD } from './debug-build'; import { InternalSentrySemanticAttributes } from './semanticAttributes'; import { convertOtelTimeToSeconds } from './utils/convertOtelTimeToSeconds'; import { getRequestSpanData } from './utils/getRequestSpanData'; @@ -54,12 +55,12 @@ export class SentrySpanExporter implements SpanExporter { const remainingOpenSpanCount = remainingSpans.length; const sentSpanCount = openSpanCount + newSpanCount - remainingOpenSpanCount; - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log(`SpanExporter exported ${sentSpanCount} spans, ${remainingOpenSpanCount} unsent spans remaining`); this._finishedSpans = remainingSpans.filter(span => { const shouldDrop = shouldCleanupSpan(span, 5 * 60); - __DEBUG_BUILD__ && + DEBUG_BUILD && shouldDrop && logger.log( `SpanExporter dropping span ${span.name} (${ diff --git a/packages/opentelemetry/src/spanProcessor.ts b/packages/opentelemetry/src/spanProcessor.ts index dc8bf53cf83f..a2d7de69fb00 100644 --- a/packages/opentelemetry/src/spanProcessor.ts +++ b/packages/opentelemetry/src/spanProcessor.ts @@ -5,6 +5,7 @@ import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { logger } from '@sentry/utils'; import { getCurrentHub } from './custom/hub'; +import { DEBUG_BUILD } from './debug-build'; import { SentrySpanExporter } from './spanExporter'; import { maybeCaptureExceptionForTimedEvent } from './utils/captureExceptionForTimedEvent'; import { getHubFromContext } from './utils/contextData'; @@ -57,14 +58,14 @@ export class SentrySpanProcessor extends BatchSpanProcessor implements SpanProce public onStart(span: Span, parentContext: Context): void { onSpanStart(span, parentContext); - __DEBUG_BUILD__ && logger.log(`[Tracing] Starting span "${span.name}" (${span.spanContext().spanId})`); + DEBUG_BUILD && logger.log(`[Tracing] Starting span "${span.name}" (${span.spanContext().spanId})`); return super.onStart(span, parentContext); } /** @inheritDoc */ public onEnd(span: Span): void { - __DEBUG_BUILD__ && logger.log(`[Tracing] Finishing span "${span.name}" (${span.spanContext().spanId})`); + DEBUG_BUILD && logger.log(`[Tracing] Finishing span "${span.name}" (${span.spanContext().spanId})`); if (!this._shouldSendSpanToSentry(span)) { // Prevent this being called to super.onEnd(), which would pass this to the span exporter diff --git a/packages/opentelemetry/test/helpers/initOtel.ts b/packages/opentelemetry/test/helpers/initOtel.ts index 91be948b2f9d..e69420242a09 100644 --- a/packages/opentelemetry/test/helpers/initOtel.ts +++ b/packages/opentelemetry/test/helpers/initOtel.ts @@ -8,6 +8,7 @@ import { logger } from '@sentry/utils'; import { wrapContextManagerClass } from '../../src/contextManager'; import { getCurrentHub } from '../../src/custom/hub'; +import { DEBUG_BUILD } from '../../src/debug-build'; import { SentryPropagator } from '../../src/propagator'; import { SentrySampler } from '../../src/sampler'; import { setupEventContextTrace } from '../../src/setupEventContextTrace'; @@ -21,7 +22,7 @@ export function initOtel(): void { const client = getCurrentHub().getClient(); if (!client) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( 'No client available, skipping OpenTelemetry setup. This probably means that `Sentry.init()` was not called before `initOtel()`.', ); diff --git a/packages/react/src/debug-build.ts b/packages/react/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/react/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/react/src/errorboundary.tsx b/packages/react/src/errorboundary.tsx index 61dd976050f6..dacc30b5d85a 100644 --- a/packages/react/src/errorboundary.tsx +++ b/packages/react/src/errorboundary.tsx @@ -4,6 +4,8 @@ import { isError, logger } from '@sentry/utils'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; +import { DEBUG_BUILD } from './debug-build'; + export function isAtLeastReact17(version: string): boolean { const major = version.match(/^([^.]+)/); return major !== null && parseInt(major[0]) >= 17; @@ -208,7 +210,7 @@ class ErrorBoundary extends React.Component, R !_matchRoutes || !_customStartTransaction ) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters. useEffect: ${_useEffect}. useLocation: ${_useLocation}. useNavigationType: ${_useNavigationType}. createRoutesFromChildren: ${_createRoutesFromChildren}. matchRoutes: ${_matchRoutes}. customStartTransaction: ${_customStartTransaction}.`); @@ -218,7 +219,7 @@ export function withSentryReactRouterV6Routing

, R export function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes { if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.', ); diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 97c455a80a94..2e597d10fa2b 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -4,6 +4,7 @@ import type { Transaction, TransactionContext } from '@sentry/types'; import { isNodeEnv, logger } from '@sentry/utils'; import * as React from 'react'; +import { DEBUG_BUILD } from '../utils/debug-build'; import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags'; const DEFAULT_TAGS = { @@ -108,7 +109,7 @@ export function withSentry

, R extends React.Co const SentryRoot: React.FC

= (props: P) => { // Early return when any of the required functions is not available. if (!_useEffect || !_useLocation || !_useMatches || !_customStartTransaction) { - __DEBUG_BUILD__ && + DEBUG_BUILD && !isNodeEnv() && logger.warn('Remix SDK was unable to wrap your root because of one or more missing parameters.'); diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 80c6602e4938..747634603bc0 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -3,6 +3,7 @@ import type { NodeOptions } from '@sentry/node'; import { configureScope, getCurrentHub, init as nodeInit } from '@sentry/node'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './utils/debug-build'; import { instrumentServer } from './utils/instrumentServer'; import { buildMetadata } from './utils/metadata'; import type { RemixOptions } from './utils/remixOptions'; @@ -75,7 +76,7 @@ export function init(options: RemixOptions): void { buildMetadata(options, ['remix', 'node']); if (sdkAlreadyInitialized()) { - __DEBUG_BUILD__ && logger.log('SDK already initialized'); + DEBUG_BUILD && logger.log('SDK already initialized'); return; } diff --git a/packages/remix/src/utils/debug-build.ts b/packages/remix/src/utils/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/remix/src/utils/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 714b6b51e09f..f4676a3e8845 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -13,6 +13,7 @@ import { tracingContextFromHeaders, } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; import { getFutureFlagsServer, getRemixVersionFromBuild } from './futureFlags'; import { extractData, @@ -103,7 +104,7 @@ export async function captureRemixServerException(err: unknown, name: string, re // eslint-disable-next-line @typescript-eslint/no-explicit-any normalizedRequest = normalizeRemixRequest(request as unknown as any); } catch (e) { - __DEBUG_BUILD__ && logger.warn('Failed to normalize Remix request'); + DEBUG_BUILD && logger.warn('Failed to normalize Remix request'); } captureException(isResponse(err) ? await extractResponseError(err) : err, scope => { @@ -278,8 +279,7 @@ function makeWrappedRootLoader(remixVersion: number) { // We skip injection of trace and baggage in those cases. // For `redirect`, a valid internal redirection target will have the trace and baggage injected. if (isRedirectResponse(res) || isCatchResponse(res)) { - __DEBUG_BUILD__ && - logger.warn('Skipping injection of trace and baggage as the response does not have a body'); + DEBUG_BUILD && logger.warn('Skipping injection of trace and baggage as the response does not have a body'); return res; } else { const data = await extractData(res); @@ -290,8 +290,7 @@ function makeWrappedRootLoader(remixVersion: number) { { headers: res.headers, statusText: res.statusText, status: res.status }, ); } else { - __DEBUG_BUILD__ && - logger.warn('Skipping injection of trace and baggage as the response body is not an object'); + DEBUG_BUILD && logger.warn('Skipping injection of trace and baggage as the response body is not an object'); return res; } } @@ -388,7 +387,7 @@ function wrapRequestHandler(origRequestHandler: RequestHandler, build: ServerBui try { normalizedRequest = normalizeRemixRequest(request); } catch (e) { - __DEBUG_BUILD__ && logger.warn('Failed to normalize Remix request'); + DEBUG_BUILD && logger.warn('Failed to normalize Remix request'); } const url = new URL(request.url); @@ -502,7 +501,7 @@ export function instrumentServer(): void { const pkg = loadModule<{ createRequestHandler: CreateRequestHandlerFunction }>('@remix-run/server-runtime'); if (!pkg) { - __DEBUG_BUILD__ && logger.warn('Remix SDK was unable to require `@remix-run/server-runtime` package.'); + DEBUG_BUILD && logger.warn('Remix SDK was unable to require `@remix-run/server-runtime` package.'); return; } diff --git a/packages/remix/src/utils/serverAdapters/express.ts b/packages/remix/src/utils/serverAdapters/express.ts index 78affeaaa9ac..ab638866ffd4 100644 --- a/packages/remix/src/utils/serverAdapters/express.ts +++ b/packages/remix/src/utils/serverAdapters/express.ts @@ -4,6 +4,7 @@ import type { Transaction } from '@sentry/types'; import { extractRequestData, isString, logger } from '@sentry/utils'; import { cwd } from 'process'; +import { DEBUG_BUILD } from '../debug-build'; import { createRoutes, getTransactionName, @@ -48,7 +49,7 @@ function wrapExpressRequestHandler( pkg = await import(`${cwd()}/node_modules/react-router-dom`); } finally { if (!pkg) { - __DEBUG_BUILD__ && logger.error('Could not find `react-router-dom` package.'); + DEBUG_BUILD && logger.error('Could not find `react-router-dom` package.'); } } } @@ -151,10 +152,10 @@ async function finishSentryProcessing(res: AugmentedExpressResponse): Promise { // If this is false, it means session is expired, create and a new session and wait for checkout if (!replay.checkAndHandleExpiredSession()) { - __DEBUG_BUILD__ && logger.warn('[Replay] Received replay event after session expired.'); + DEBUG_BUILD && logger.warn('[Replay] Received replay event after session expired.'); return; } diff --git a/packages/replay/src/util/log.ts b/packages/replay/src/util/log.ts index 9aa650a81264..96b6e76dc498 100644 --- a/packages/replay/src/util/log.ts +++ b/packages/replay/src/util/log.ts @@ -1,11 +1,13 @@ import { getCurrentHub } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; + /** * Log a message in debug mode, and add a breadcrumb when _experiment.traceInternals is enabled. */ export function logInfo(message: string, shouldAddBreadcrumb?: boolean): void { - if (!__DEBUG_BUILD__) { + if (!DEBUG_BUILD) { return; } @@ -21,7 +23,7 @@ export function logInfo(message: string, shouldAddBreadcrumb?: boolean): void { * This is necessary when the breadcrumb may be added before the replay is initialized. */ export function logInfoNextTick(message: string, shouldAddBreadcrumb?: boolean): void { - if (!__DEBUG_BUILD__) { + if (!DEBUG_BUILD) { return; } diff --git a/packages/replay/src/util/sendReplay.ts b/packages/replay/src/util/sendReplay.ts index 645a6573e727..9aea14be4a16 100644 --- a/packages/replay/src/util/sendReplay.ts +++ b/packages/replay/src/util/sendReplay.ts @@ -1,6 +1,7 @@ import { captureException, setContext } from '@sentry/core'; import { RETRY_BASE_INTERVAL, RETRY_MAX_COUNT, UNABLE_TO_SEND_REPLAY } from '../constants'; +import { DEBUG_BUILD } from '../debug-build'; import type { SendReplayData } from '../types'; import { RateLimitError, sendReplayRequest, TransportStatusCodeError } from './sendReplayRequest'; @@ -34,7 +35,7 @@ export async function sendReplay( _retryCount: retryConfig.count, }); - if (__DEBUG_BUILD__ && options._experiments && options._experiments.captureExceptions) { + if (DEBUG_BUILD && options._experiments && options._experiments.captureExceptions) { captureException(err); } diff --git a/packages/replay/src/util/shouldFilterRequest.ts b/packages/replay/src/util/shouldFilterRequest.ts index fcfd75b1b048..274ad4ee488a 100644 --- a/packages/replay/src/util/shouldFilterRequest.ts +++ b/packages/replay/src/util/shouldFilterRequest.ts @@ -1,5 +1,6 @@ import { getCurrentHub, isSentryRequestUrl } from '@sentry/core'; +import { DEBUG_BUILD } from '../debug-build'; import type { ReplayContainer } from '../types'; /** @@ -8,7 +9,7 @@ import type { ReplayContainer } from '../types'; */ export function shouldFilterRequest(replay: ReplayContainer, url: string): boolean { // If we enabled the `traceInternals` experiment, we want to trace everything - if (__DEBUG_BUILD__ && replay.getOptions()._experiments.traceInternals) { + if (DEBUG_BUILD && replay.getOptions()._experiments.traceInternals) { return false; } diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index 78578083ee72..97dec35a6113 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -14,6 +14,7 @@ import { performance } from 'perf_hooks'; import { types } from 'util'; import { AWSServices } from './awsservices'; +import { DEBUG_BUILD } from './debug-build'; import { markEventUnhandled } from './utils'; export * from '@sentry/node'; @@ -131,7 +132,7 @@ export function tryPatchHandler(taskRoot: string, handlerPath: string): void { const handlerDesc = basename(handlerPath); const match = handlerDesc.match(/^([^.]*)\.(.*)$/); if (!match) { - __DEBUG_BUILD__ && logger.error(`Bad handler ${handlerDesc}`); + DEBUG_BUILD && logger.error(`Bad handler ${handlerDesc}`); return; } @@ -142,7 +143,7 @@ export function tryPatchHandler(taskRoot: string, handlerPath: string): void { const handlerDir = handlerPath.substring(0, handlerPath.indexOf(handlerDesc)); obj = tryRequire(taskRoot, handlerDir, handlerMod); } catch (e) { - __DEBUG_BUILD__ && logger.error(`Cannot require ${handlerPath} in ${taskRoot}`, e); + DEBUG_BUILD && logger.error(`Cannot require ${handlerPath} in ${taskRoot}`, e); return; } @@ -154,11 +155,11 @@ export function tryPatchHandler(taskRoot: string, handlerPath: string): void { functionName = name; }); if (!obj) { - __DEBUG_BUILD__ && logger.error(`${handlerPath} is undefined or not exported`); + DEBUG_BUILD && logger.error(`${handlerPath} is undefined or not exported`); return; } if (typeof obj !== 'function') { - __DEBUG_BUILD__ && logger.error(`${handlerPath} is not a function`); + DEBUG_BUILD && logger.error(`${handlerPath} is not a function`); return; } @@ -345,7 +346,7 @@ export function wrapHandler( transaction?.finish(); hub.popScope(); await flush(options.flushTimeout).catch(e => { - __DEBUG_BUILD__ && logger.error(e); + DEBUG_BUILD && logger.error(e); }); } return rv; diff --git a/packages/serverless/src/debug-build.ts b/packages/serverless/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/serverless/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/serverless/src/gcpfunction/cloud_events.ts b/packages/serverless/src/gcpfunction/cloud_events.ts index a0d843e71abe..05595867c191 100644 --- a/packages/serverless/src/gcpfunction/cloud_events.ts +++ b/packages/serverless/src/gcpfunction/cloud_events.ts @@ -1,6 +1,7 @@ import { captureException, flush, getCurrentHub } from '@sentry/node'; import { isThenable, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { domainify, markEventUnhandled, proxyFunction } from '../utils'; import type { CloudEventFunction, CloudEventFunctionWithCallback, WrapperOptions } from './general'; @@ -56,7 +57,7 @@ function _wrapCloudEventFunction( void flush(options.flushTimeout) .then(null, e => { - __DEBUG_BUILD__ && logger.error(e); + DEBUG_BUILD && logger.error(e); }) .then(() => { callback(...args); diff --git a/packages/serverless/src/gcpfunction/events.ts b/packages/serverless/src/gcpfunction/events.ts index 9c98fcb8c485..c3be42c6a6c2 100644 --- a/packages/serverless/src/gcpfunction/events.ts +++ b/packages/serverless/src/gcpfunction/events.ts @@ -1,6 +1,7 @@ import { captureException, flush, getCurrentHub } from '@sentry/node'; import { isThenable, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { domainify, markEventUnhandled, proxyFunction } from '../utils'; import type { EventFunction, EventFunctionWithCallback, WrapperOptions } from './general'; @@ -58,7 +59,7 @@ function _wrapEventFunction void flush(options.flushTimeout) .then(null, e => { - __DEBUG_BUILD__ && logger.error(e); + DEBUG_BUILD && logger.error(e); }) .then(() => { if (typeof callback === 'function') { diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts index eea492bb8dab..8f4a77099696 100644 --- a/packages/serverless/src/gcpfunction/http.ts +++ b/packages/serverless/src/gcpfunction/http.ts @@ -2,6 +2,7 @@ import type { AddRequestDataToEventOptions } from '@sentry/node'; import { captureException, flush, getCurrentHub } from '@sentry/node'; import { isString, isThenable, logger, stripUrlQueryAndFragment, tracingContextFromHeaders } from '@sentry/utils'; +import { DEBUG_BUILD } from '../debug-build'; import { domainify, markEventUnhandled, proxyFunction } from './../utils'; import type { HttpFunction, WrapperOptions } from './general'; @@ -111,7 +112,7 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial { - __DEBUG_BUILD__ && logger.error(e); + DEBUG_BUILD && logger.error(e); }) .then(() => { _end.call(this, chunk, encoding, cb); diff --git a/packages/sveltekit/src/common/debug-build.ts b/packages/sveltekit/src/common/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/sveltekit/src/common/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/sveltekit/src/server/utils.ts b/packages/sveltekit/src/server/utils.ts index cf591568486b..719771d50c57 100644 --- a/packages/sveltekit/src/server/utils.ts +++ b/packages/sveltekit/src/server/utils.ts @@ -3,6 +3,7 @@ import type { StackFrame } from '@sentry/types'; import { basename, escapeStringForRegex, GLOBAL_OBJ, join, logger, tracingContextFromHeaders } from '@sentry/utils'; import type { RequestEvent } from '@sveltejs/kit'; +import { DEBUG_BUILD } from '../common/debug-build'; import { WRAPPED_MODULE_SUFFIX } from '../vite/autoInstrument'; import type { GlobalWithSentryValues } from '../vite/injectGlobalValues'; @@ -76,11 +77,11 @@ export async function flushIfServerless(): Promise { if (!platformSupportsStreaming) { try { - __DEBUG_BUILD__ && logger.log('Flushing events...'); + DEBUG_BUILD && logger.log('Flushing events...'); await flush(2000); - __DEBUG_BUILD__ && logger.log('Done flushing events'); + DEBUG_BUILD && logger.log('Done flushing events'); } catch (e) { - __DEBUG_BUILD__ && logger.log('Error while flushing events:\n', e); + DEBUG_BUILD && logger.log('Error while flushing events:\n', e); } } } diff --git a/packages/tracing-internal/src/browser/backgroundtab.ts b/packages/tracing-internal/src/browser/backgroundtab.ts index e061f39925a1..7d65941c8d43 100644 --- a/packages/tracing-internal/src/browser/backgroundtab.ts +++ b/packages/tracing-internal/src/browser/backgroundtab.ts @@ -2,6 +2,7 @@ import type { IdleTransaction, SpanStatusType } from '@sentry/core'; import { getActiveTransaction } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../common/debug-build'; import { WINDOW } from './types'; /** @@ -15,7 +16,7 @@ export function registerBackgroundTabDetection(): void { if (WINDOW.document.hidden && activeTransaction) { const statusType: SpanStatusType = 'cancelled'; - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.log( `[Tracing] Transaction: ${statusType} -> since tab moved to the background, op: ${activeTransaction.op}`, ); @@ -29,7 +30,6 @@ export function registerBackgroundTabDetection(): void { } }); } else { - __DEBUG_BUILD__ && - logger.warn('[Tracing] Could not set up background tab detection due to lack of global document'); + DEBUG_BUILD && logger.warn('[Tracing] Could not set up background tab detection due to lack of global document'); } } diff --git a/packages/tracing-internal/src/browser/browsertracing.ts b/packages/tracing-internal/src/browser/browsertracing.ts index a11ea7ff2cf2..f1ee79c39679 100644 --- a/packages/tracing-internal/src/browser/browsertracing.ts +++ b/packages/tracing-internal/src/browser/browsertracing.ts @@ -4,6 +4,7 @@ import { addTracingExtensions, getActiveTransaction, startIdleTransaction, TRACI import type { EventProcessor, Integration, Transaction, TransactionContext, TransactionSource } from '@sentry/types'; import { getDomElement, logger, tracingContextFromHeaders } from '@sentry/utils'; +import { DEBUG_BUILD } from '../common/debug-build'; import { registerBackgroundTabDetection } from './backgroundtab'; import { addPerformanceEntries, @@ -179,7 +180,7 @@ export class BrowserTracing implements Integration { addTracingExtensions(); - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { this._hasSetTracePropagationTargets = !!( _options && // eslint-disable-next-line deprecation/deprecation @@ -250,7 +251,7 @@ export class BrowserTracing implements Integration { // If both 1 and either one of 2 or 3 are set (from above), we log out a warning. // eslint-disable-next-line deprecation/deprecation const tracePropagationTargets = clientOptionsTracePropagationTargets || this.options.tracePropagationTargets; - if (__DEBUG_BUILD__ && this._hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) { + if (DEBUG_BUILD && this._hasSetTracePropagationTargets && clientOptionsTracePropagationTargets) { logger.warn( '[Tracing] The `tracePropagationTargets` option was set in the BrowserTracing integration and top level `Sentry.init`. The top level `Sentry.init` value is being used.', ); @@ -289,7 +290,7 @@ export class BrowserTracing implements Integration { /** Create routing idle transaction. */ private _createRouteTransaction(context: TransactionContext): Transaction | undefined { if (!this._getCurrentHub) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${context.op} transaction because _getCurrentHub is invalid.`); return undefined; } @@ -333,11 +334,10 @@ export class BrowserTracing implements Integration { this._latestRouteSource = finalContext.metadata && finalContext.metadata.source; if (finalContext.sampled === false) { - __DEBUG_BUILD__ && - logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`); + DEBUG_BUILD && logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`); } - __DEBUG_BUILD__ && logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`); + DEBUG_BUILD && logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`); const { location } = WINDOW; @@ -385,7 +385,7 @@ export class BrowserTracing implements Integration { const currentTransaction = getActiveTransaction(); if (currentTransaction && currentTransaction.op && ['navigation', 'pageload'].includes(currentTransaction.op)) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `[Tracing] Did not create ${op} transaction because a pageload or navigation transaction is in progress.`, ); @@ -399,13 +399,12 @@ export class BrowserTracing implements Integration { } if (!this._getCurrentHub) { - __DEBUG_BUILD__ && logger.warn(`[Tracing] Did not create ${op} transaction because _getCurrentHub is invalid.`); + DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _getCurrentHub is invalid.`); return undefined; } if (!this._latestRouteName) { - __DEBUG_BUILD__ && - logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); + DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`); return undefined; } diff --git a/packages/tracing-internal/src/browser/instrument.ts b/packages/tracing-internal/src/browser/instrument.ts index 85c2aeccb43e..ae4532259f94 100644 --- a/packages/tracing-internal/src/browser/instrument.ts +++ b/packages/tracing-internal/src/browser/instrument.ts @@ -1,5 +1,6 @@ import { getFunctionName, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../common/debug-build'; import { onCLS } from './web-vitals/getCLS'; import { onFID } from './web-vitals/getFID'; import { onLCP } from './web-vitals/getLCP'; @@ -148,7 +149,7 @@ function triggerHandlers(type: InstrumentHandlerType, data: unknown): void { try { handler(data); } catch (e) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.error( `Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError:`, e, diff --git a/packages/tracing-internal/src/browser/metrics/index.ts b/packages/tracing-internal/src/browser/metrics/index.ts index 4d28f6102cde..c7a37a210d80 100644 --- a/packages/tracing-internal/src/browser/metrics/index.ts +++ b/packages/tracing-internal/src/browser/metrics/index.ts @@ -4,6 +4,7 @@ import { getActiveTransaction } from '@sentry/core'; import type { Measurements } from '@sentry/types'; import { browserPerformanceTimeOrigin, htmlTreeAsString, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import { addClsInstrumentationHandler, addFidInstrumentationHandler, @@ -121,7 +122,7 @@ function _trackCLS(): () => void { return; } - __DEBUG_BUILD__ && logger.log('[Measurements] Adding CLS'); + DEBUG_BUILD && logger.log('[Measurements] Adding CLS'); _measurements['cls'] = { value: metric.value, unit: '' }; _clsEntry = entry as LayoutShift; }); @@ -135,7 +136,7 @@ function _trackLCP(): () => void { return; } - __DEBUG_BUILD__ && logger.log('[Measurements] Adding LCP'); + DEBUG_BUILD && logger.log('[Measurements] Adding LCP'); _measurements['lcp'] = { value: metric.value, unit: 'millisecond' }; _lcpEntry = entry as LargestContentfulPaint; }); @@ -151,7 +152,7 @@ function _trackFID(): () => void { const timeOrigin = msToSec(browserPerformanceTimeOrigin as number); const startTime = msToSec(entry.startTime); - __DEBUG_BUILD__ && logger.log('[Measurements] Adding FID'); + DEBUG_BUILD && logger.log('[Measurements] Adding FID'); _measurements['fid'] = { value: metric.value, unit: 'millisecond' }; _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' }; }); @@ -165,7 +166,7 @@ export function addPerformanceEntries(transaction: Transaction): void { return; } - __DEBUG_BUILD__ && logger.log('[Tracing] Adding & adjusting spans using Performance API'); + DEBUG_BUILD && logger.log('[Tracing] Adding & adjusting spans using Performance API'); const timeOrigin = msToSec(browserPerformanceTimeOrigin); const performanceEntries = performance.getEntries(); @@ -200,11 +201,11 @@ export function addPerformanceEntries(transaction: Transaction): void { const shouldRecord = entry.startTime < firstHidden.firstHiddenTime; if (entry.name === 'first-paint' && shouldRecord) { - __DEBUG_BUILD__ && logger.log('[Measurements] Adding FP'); + DEBUG_BUILD && logger.log('[Measurements] Adding FP'); _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' }; } if (entry.name === 'first-contentful-paint' && shouldRecord) { - __DEBUG_BUILD__ && logger.log('[Measurements] Adding FCP'); + DEBUG_BUILD && logger.log('[Measurements] Adding FCP'); _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' }; } break; @@ -228,7 +229,7 @@ export function addPerformanceEntries(transaction: Transaction): void { // Generate TTFB (Time to First Byte), which measured as the time between the beginning of the transaction and the // start of the response in milliseconds if (typeof responseStartTimestamp === 'number') { - __DEBUG_BUILD__ && logger.log('[Measurements] Adding TTFB'); + DEBUG_BUILD && logger.log('[Measurements] Adding TTFB'); _measurements['ttfb'] = { value: (responseStartTimestamp - transaction.startTimestamp) * 1000, unit: 'millisecond', @@ -258,8 +259,7 @@ export function addPerformanceEntries(transaction: Transaction): void { const normalizedValue = Math.abs((measurementTimestamp - transaction.startTimestamp) * 1000); const delta = normalizedValue - oldValue; - __DEBUG_BUILD__ && - logger.log(`[Measurements] Normalized ${name} from ${oldValue} to ${normalizedValue} (${delta})`); + DEBUG_BUILD && logger.log(`[Measurements] Normalized ${name} from ${oldValue} to ${normalizedValue} (${delta})`); _measurements[name].value = normalizedValue; }); @@ -461,7 +461,7 @@ function _trackNavigator(transaction: Transaction): void { /** Add LCP / CLS data to transaction to allow debugging */ function _tagMetricInfo(transaction: Transaction): void { if (_lcpEntry) { - __DEBUG_BUILD__ && logger.log('[Measurements] Adding LCP Data'); + DEBUG_BUILD && logger.log('[Measurements] Adding LCP Data'); // Capture Properties of the LCP element that contributes to the LCP. @@ -483,7 +483,7 @@ function _tagMetricInfo(transaction: Transaction): void { // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift if (_clsEntry && _clsEntry.sources) { - __DEBUG_BUILD__ && logger.log('[Measurements] Adding CLS Data'); + DEBUG_BUILD && logger.log('[Measurements] Adding CLS Data'); _clsEntry.sources.forEach((source, index) => transaction.setTag(`cls.source.${index + 1}`, htmlTreeAsString(source.node)), ); diff --git a/packages/tracing-internal/src/browser/router.ts b/packages/tracing-internal/src/browser/router.ts index 98656d4d3f2a..472c2e9fec05 100644 --- a/packages/tracing-internal/src/browser/router.ts +++ b/packages/tracing-internal/src/browser/router.ts @@ -1,6 +1,7 @@ import type { Transaction, TransactionContext } from '@sentry/types'; import { addHistoryInstrumentationHandler, browserPerformanceTimeOrigin, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../common/debug-build'; import { WINDOW } from './types'; /** @@ -12,7 +13,7 @@ export function instrumentRoutingWithDefaults( startTransactionOnLocationChange: boolean = true, ): void { if (!WINDOW || !WINDOW.location) { - __DEBUG_BUILD__ && logger.warn('Could not initialize routing instrumentation due to invalid location'); + DEBUG_BUILD && logger.warn('Could not initialize routing instrumentation due to invalid location'); return; } @@ -49,7 +50,7 @@ export function instrumentRoutingWithDefaults( if (from !== to) { startingUrl = undefined; if (activeTransaction) { - __DEBUG_BUILD__ && logger.log(`[Tracing] Finishing current transaction with op: ${activeTransaction.op}`); + DEBUG_BUILD && logger.log(`[Tracing] Finishing current transaction with op: ${activeTransaction.op}`); // If there's an open transaction on the scope, we need to finish it before creating an new one. activeTransaction.finish(); } diff --git a/packages/tracing-internal/src/common/debug-build.ts b/packages/tracing-internal/src/common/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/tracing-internal/src/common/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/tracing-internal/src/node/integrations/apollo.ts b/packages/tracing-internal/src/node/integrations/apollo.ts index e4c64a299925..033e0648d624 100644 --- a/packages/tracing-internal/src/node/integrations/apollo.ts +++ b/packages/tracing-internal/src/node/integrations/apollo.ts @@ -2,6 +2,7 @@ import type { Hub } from '@sentry/core'; import type { EventProcessor } from '@sentry/types'; import { arrayify, fill, isThenable, loadModule, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import type { LazyLoadedIntegration } from './lazy'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; @@ -77,7 +78,7 @@ export class Apollo implements LazyLoadedIntegration void, getCurrentHub: () => Hub): void { if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('Apollo Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('Apollo Integration is skipped because of instrumenter configuration.'); return; } @@ -85,7 +86,7 @@ export class Apollo implements LazyLoadedIntegration Hub): void { if (!this._router) { - __DEBUG_BUILD__ && logger.error('ExpressIntegration is missing an Express instance'); + DEBUG_BUILD && logger.error('ExpressIntegration is missing an Express instance'); return; } if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('Express Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('Express Integration is skipped because of instrumenter configuration.'); return; } @@ -293,8 +294,8 @@ function instrumentRouter(appOrRouter: ExpressRouter): void { TODO: Proper Express 5 support */ - __DEBUG_BUILD__ && logger.debug('Cannot instrument router for URL Parameterization (did not find a valid router).'); - __DEBUG_BUILD__ && logger.debug('Routing instrumentation is currently only supported in Express 4.'); + DEBUG_BUILD && logger.debug('Cannot instrument router for URL Parameterization (did not find a valid router).'); + DEBUG_BUILD && logger.debug('Routing instrumentation is currently only supported in Express 4.'); return; } diff --git a/packages/tracing-internal/src/node/integrations/graphql.ts b/packages/tracing-internal/src/node/integrations/graphql.ts index 3fdf6e8ede4c..1fafae134ad7 100644 --- a/packages/tracing-internal/src/node/integrations/graphql.ts +++ b/packages/tracing-internal/src/node/integrations/graphql.ts @@ -2,6 +2,7 @@ import type { Hub } from '@sentry/core'; import type { EventProcessor } from '@sentry/types'; import { fill, isThenable, loadModule, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import type { LazyLoadedIntegration } from './lazy'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; @@ -37,14 +38,14 @@ export class GraphQL implements LazyLoadedIntegration { */ public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('GraphQL Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('GraphQL Integration is skipped because of instrumenter configuration.'); return; } const pkg = this.loadDependency(); if (!pkg) { - __DEBUG_BUILD__ && logger.error('GraphQL Integration was unable to require graphql/execution package.'); + DEBUG_BUILD && logger.error('GraphQL Integration was unable to require graphql/execution package.'); return; } diff --git a/packages/tracing-internal/src/node/integrations/mongo.ts b/packages/tracing-internal/src/node/integrations/mongo.ts index a3bc810be7a3..fe6bc971d72e 100644 --- a/packages/tracing-internal/src/node/integrations/mongo.ts +++ b/packages/tracing-internal/src/node/integrations/mongo.ts @@ -2,6 +2,7 @@ import type { Hub } from '@sentry/core'; import type { EventProcessor, SpanContext } from '@sentry/types'; import { fill, isThenable, loadModule, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import type { LazyLoadedIntegration } from './lazy'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; @@ -140,7 +141,7 @@ export class Mongo implements LazyLoadedIntegration { */ public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('Mongo Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('Mongo Integration is skipped because of instrumenter configuration.'); return; } @@ -148,7 +149,7 @@ export class Mongo implements LazyLoadedIntegration { if (!pkg) { const moduleName = this._useMongoose ? 'mongoose' : 'mongodb'; - __DEBUG_BUILD__ && logger.error(`Mongo Integration was unable to require \`${moduleName}\` package.`); + DEBUG_BUILD && logger.error(`Mongo Integration was unable to require \`${moduleName}\` package.`); return; } diff --git a/packages/tracing-internal/src/node/integrations/mysql.ts b/packages/tracing-internal/src/node/integrations/mysql.ts index d176730f5847..18038982c03d 100644 --- a/packages/tracing-internal/src/node/integrations/mysql.ts +++ b/packages/tracing-internal/src/node/integrations/mysql.ts @@ -2,6 +2,7 @@ import type { Hub } from '@sentry/core'; import type { EventProcessor, Span } from '@sentry/types'; import { fill, loadModule, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import type { LazyLoadedIntegration } from './lazy'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; @@ -46,14 +47,14 @@ export class Mysql implements LazyLoadedIntegration { */ public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('Mysql Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('Mysql Integration is skipped because of instrumenter configuration.'); return; } const pkg = this.loadDependency(); if (!pkg) { - __DEBUG_BUILD__ && logger.error('Mysql Integration was unable to require `mysql` package.'); + DEBUG_BUILD && logger.error('Mysql Integration was unable to require `mysql` package.'); return; } @@ -69,7 +70,7 @@ export class Mysql implements LazyLoadedIntegration { }, }); } catch (e) { - __DEBUG_BUILD__ && logger.error('Mysql Integration was unable to instrument `mysql` config.'); + DEBUG_BUILD && logger.error('Mysql Integration was unable to instrument `mysql` config.'); } function spanDataFromConfig(): Record { diff --git a/packages/tracing-internal/src/node/integrations/postgres.ts b/packages/tracing-internal/src/node/integrations/postgres.ts index a3d94653477f..918f20664b92 100644 --- a/packages/tracing-internal/src/node/integrations/postgres.ts +++ b/packages/tracing-internal/src/node/integrations/postgres.ts @@ -2,6 +2,7 @@ import type { Hub } from '@sentry/core'; import type { EventProcessor } from '@sentry/types'; import { fill, isThenable, loadModule, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import type { LazyLoadedIntegration } from './lazy'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; @@ -76,21 +77,21 @@ export class Postgres implements LazyLoadedIntegration { */ public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { if (shouldDisableAutoInstrumentation(getCurrentHub)) { - __DEBUG_BUILD__ && logger.log('Postgres Integration is skipped because of instrumenter configuration.'); + DEBUG_BUILD && logger.log('Postgres Integration is skipped because of instrumenter configuration.'); return; } const pkg = this.loadDependency(); if (!pkg) { - __DEBUG_BUILD__ && logger.error('Postgres Integration was unable to require `pg` package.'); + DEBUG_BUILD && logger.error('Postgres Integration was unable to require `pg` package.'); return; } const Client = this._usePgNative ? pkg.native?.Client : pkg.Client; if (!Client) { - __DEBUG_BUILD__ && logger.error("Postgres Integration was unable to access 'pg-native' bindings."); + DEBUG_BUILD && logger.error("Postgres Integration was unable to access 'pg-native' bindings."); return; } diff --git a/packages/tracing-internal/src/node/integrations/prisma.ts b/packages/tracing-internal/src/node/integrations/prisma.ts index df43ec441391..b13fa2af7f53 100644 --- a/packages/tracing-internal/src/node/integrations/prisma.ts +++ b/packages/tracing-internal/src/node/integrations/prisma.ts @@ -2,6 +2,7 @@ import { getCurrentHub, trace } from '@sentry/core'; import type { Integration } from '@sentry/types'; import { addNonEnumerableProperty, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from '../../common/debug-build'; import { shouldDisableAutoInstrumentation } from './utils/node-utils'; type PrismaAction = @@ -109,7 +110,7 @@ export class Prisma implements Integration { ); }); } else { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn('Unsupported Prisma client provided to PrismaIntegration. Provided client:', options.client); } } diff --git a/packages/types/src/globals.ts b/packages/types/src/globals.ts deleted file mode 100644 index 4a3e239f8a2f..000000000000 --- a/packages/types/src/globals.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This file adds variables to the global namespace when it's loaded. We do this in order to be able to use flags and - * constants to facilitate tree shaking for users without having to import them, since the imports can confuse some - * tree-shaking algorithms. - * - * "Magic strings" like `__DEBUG_BUILD__` are declared here, but only replaced with actual values during our build - * process. - * - * See https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html and - * the Debug Build Flags section in CONTRIBUTING.md. - */ - -declare global { - const __DEBUG_BUILD__: boolean; -} - -// We need this empty export because of --isolatedModules -export type {}; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index cf7d801dee8b..627879493365 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -48,10 +48,6 @@ export type { Event, EventHint, EventType, ErrorEvent, TransactionEvent } from ' export type { EventProcessor } from './eventprocessor'; export type { Exception } from './exception'; export type { Extra, Extras } from './extra'; -// This is a dummy export, purely for the purpose of loading `globals.ts`, in order to take advantage of its side effect -// of putting variables into the global namespace. See -// https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html. -export type {} from './globals'; export type { Hub } from './hub'; export type { Integration, IntegrationClass } from './integration'; export type { Mechanism } from './mechanism'; diff --git a/packages/utils/src/baggage.ts b/packages/utils/src/baggage.ts index 674e7f60f7ef..0202f0ec00f5 100644 --- a/packages/utils/src/baggage.ts +++ b/packages/utils/src/baggage.ts @@ -1,5 +1,6 @@ import type { DynamicSamplingContext } from '@sentry/types'; +import { DEBUG_BUILD } from './debug-build'; import { isString } from './is'; import { logger } from './logger'; @@ -136,7 +137,7 @@ function objectToBaggageHeader(object: Record): string | undefin const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`; const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`; if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`, ); diff --git a/packages/utils/src/debug-build.ts b/packages/utils/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/utils/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index f149b67a9386..574e9c78b4eb 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -1,5 +1,6 @@ import type { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types'; +import { DEBUG_BUILD } from './debug-build'; import { logger } from './logger'; /** Regular expression used to parse a Dsn. */ @@ -75,7 +76,7 @@ function dsnFromComponents(components: DsnComponents): DsnComponents { } function validateDsn(dsn: DsnComponents): boolean { - if (!__DEBUG_BUILD__) { + if (!DEBUG_BUILD) { return true; } diff --git a/packages/utils/src/instrument/_handlers.ts b/packages/utils/src/instrument/_handlers.ts index e86ab677ed39..520d258ae1ac 100644 --- a/packages/utils/src/instrument/_handlers.ts +++ b/packages/utils/src/instrument/_handlers.ts @@ -1,3 +1,4 @@ +import { DEBUG_BUILD } from '../debug-build'; import { logger } from '../logger'; import { getFunctionName } from '../stacktrace'; @@ -44,7 +45,7 @@ export function triggerHandlers(type: InstrumentHandlerType, data: unknown): voi try { handler(data); } catch (e) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.error( `Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError:`, e, diff --git a/packages/utils/src/instrument/index.ts b/packages/utils/src/instrument/index.ts index 800f2ec6540d..e74f6788f6e2 100644 --- a/packages/utils/src/instrument/index.ts +++ b/packages/utils/src/instrument/index.ts @@ -1,3 +1,4 @@ +import { DEBUG_BUILD } from '../debug-build'; import type { InstrumentHandlerCallback as _InstrumentHandlerCallback, InstrumentHandlerType as _InstrumentHandlerType, @@ -35,7 +36,7 @@ export function addInstrumentationHandler(type: _InstrumentHandlerType, callback case 'unhandledrejection': return addGlobalUnhandledRejectionInstrumentationHandler(callback); default: - __DEBUG_BUILD__ && logger.warn('unknown instrumentation type:', type); + DEBUG_BUILD && logger.warn('unknown instrumentation type:', type); } } diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 1784aa179bb1..e996d87202b2 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -1,5 +1,6 @@ import type { ConsoleLevel } from '@sentry/types'; +import { DEBUG_BUILD } from './debug-build'; import { GLOBAL_OBJ } from './worldwide'; /** Prefix for logging strings */ @@ -76,7 +77,7 @@ function makeLogger(): Logger { isEnabled: () => enabled, }; - if (__DEBUG_BUILD__) { + if (DEBUG_BUILD) { CONSOLE_LEVELS.forEach(name => { // eslint-disable-next-line @typescript-eslint/no-explicit-any logger[name] = (...args: any[]) => { diff --git a/packages/utils/src/object.ts b/packages/utils/src/object.ts index e4e866bf2763..f6dd9a1a7166 100644 --- a/packages/utils/src/object.ts +++ b/packages/utils/src/object.ts @@ -3,6 +3,7 @@ import type { WrappedFunction } from '@sentry/types'; import { htmlTreeAsString } from './browser'; +import { DEBUG_BUILD } from './debug-build'; import { isElement, isError, isEvent, isInstanceOf, isPlainObject, isPrimitive } from './is'; import { logger } from './logger'; import { truncate } from './string'; @@ -51,7 +52,7 @@ export function addNonEnumerableProperty(obj: object, name: string, value: unkno configurable: true, }); } catch (o_O) { - __DEBUG_BUILD__ && logger.log(`Failed to add non-enumerable property "${name}" to object`, obj); + DEBUG_BUILD && logger.log(`Failed to add non-enumerable property "${name}" to object`, obj); } } diff --git a/packages/utils/src/requestdata.ts b/packages/utils/src/requestdata.ts index a138ecf3141b..7106a42a5a60 100644 --- a/packages/utils/src/requestdata.ts +++ b/packages/utils/src/requestdata.ts @@ -9,6 +9,7 @@ import type { } from '@sentry/types'; import { parseCookie } from './cookie'; +import { DEBUG_BUILD } from './debug-build'; import { isPlainObject, isString } from './is'; import { logger } from './logger'; import { normalize } from './normalize'; @@ -379,7 +380,7 @@ export function winterCGHeadersToDict(winterCGHeaders: WebFetchHeaders): Record< } }); } catch (e) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn('Sentry failed extracting headers from a request object. If you see this, please file an issue.'); } diff --git a/packages/utils/src/supports.ts b/packages/utils/src/supports.ts index 2e555ee2efb5..01d4627d2892 100644 --- a/packages/utils/src/supports.ts +++ b/packages/utils/src/supports.ts @@ -1,3 +1,4 @@ +import { DEBUG_BUILD } from './debug-build'; import { logger } from './logger'; import { getGlobalObject } from './worldwide'; @@ -121,7 +122,7 @@ export function supportsNativeFetch(): boolean { } doc.head.removeChild(sandbox); } catch (err) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err); } } diff --git a/packages/utils/test/dsn.test.ts b/packages/utils/test/dsn.test.ts index 3de435bf5fcf..e1aadb893e8e 100644 --- a/packages/utils/test/dsn.test.ts +++ b/packages/utils/test/dsn.test.ts @@ -1,3 +1,4 @@ +import { DEBUG_BUILD } from '../src/debug-build'; import { dsnToString, makeDsn } from '../src/dsn'; import { logger } from '../src/logger'; @@ -48,7 +49,7 @@ describe('Dsn', () => { expect(dsn?.projectId).toBe('123'); }); - testIf(__DEBUG_BUILD__)('returns `undefined` for missing components', () => { + testIf(DEBUG_BUILD)('returns `undefined` for missing components', () => { expect( makeDsn({ host: '', @@ -85,7 +86,7 @@ describe('Dsn', () => { expect(loggerErrorSpy).toHaveBeenCalledTimes(4); }); - testIf(__DEBUG_BUILD__)('returns `undefined` if components are invalid', () => { + testIf(DEBUG_BUILD)('returns `undefined` if components are invalid', () => { expect( makeDsn({ host: 'sentry.io', @@ -164,12 +165,12 @@ describe('Dsn', () => { expect(dsn?.projectId).toBe('321'); }); - testIf(__DEBUG_BUILD__)('returns undefined when provided invalid Dsn', () => { + testIf(DEBUG_BUILD)('returns undefined when provided invalid Dsn', () => { expect(makeDsn('some@random.dsn')).toBeUndefined(); expect(consoleErrorSpy).toHaveBeenCalledTimes(1); }); - testIf(__DEBUG_BUILD__)('returns undefined if mandatory fields are missing', () => { + testIf(DEBUG_BUILD)('returns undefined if mandatory fields are missing', () => { expect(makeDsn('://abc@sentry.io/123')).toBeUndefined(); expect(makeDsn('https://@sentry.io/123')).toBeUndefined(); expect(makeDsn('https://abc@123')).toBeUndefined(); @@ -177,7 +178,7 @@ describe('Dsn', () => { expect(consoleErrorSpy).toHaveBeenCalledTimes(4); }); - testIf(__DEBUG_BUILD__)('returns undefined if fields are invalid', () => { + testIf(DEBUG_BUILD)('returns undefined if fields are invalid', () => { expect(makeDsn('httpx://abc@sentry.io/123')).toBeUndefined(); expect(makeDsn('httpx://abc@sentry.io:xxx/123')).toBeUndefined(); expect(makeDsn('http://abc@sentry.io/abc')).toBeUndefined(); diff --git a/packages/vercel-edge/src/async.ts b/packages/vercel-edge/src/async.ts index 36c6317248b4..336494dfbf3e 100644 --- a/packages/vercel-edge/src/async.ts +++ b/packages/vercel-edge/src/async.ts @@ -2,6 +2,8 @@ import type { Carrier, Hub, RunWithAsyncContextOptions } from '@sentry/core'; import { ensureHubOnCarrier, getHubFromCarrier, setAsyncContextStrategy } from '@sentry/core'; import { GLOBAL_OBJ, logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; + interface AsyncLocalStorage { getStore(): T | undefined; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -18,7 +20,7 @@ let asyncStorage: AsyncLocalStorage; */ export function setAsyncLocalStorageAsyncContextStrategy(): void { if (!MaybeGlobalAsyncLocalStorage) { - __DEBUG_BUILD__ && + DEBUG_BUILD && logger.warn( "Tried to register AsyncLocalStorage async context strategy in a runtime that doesn't support AsyncLocalStorage.", ); diff --git a/packages/vercel-edge/src/debug-build.ts b/packages/vercel-edge/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/vercel-edge/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/vue/src/debug-build.ts b/packages/vue/src/debug-build.ts new file mode 100644 index 000000000000..60aa50940582 --- /dev/null +++ b/packages/vue/src/debug-build.ts @@ -0,0 +1,8 @@ +declare const __DEBUG_BUILD__: boolean; + +/** + * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code. + * + * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking. + */ +export const DEBUG_BUILD = __DEBUG_BUILD__; diff --git a/packages/vue/src/tracing.ts b/packages/vue/src/tracing.ts index 312ee076ba25..82000b9799a4 100644 --- a/packages/vue/src/tracing.ts +++ b/packages/vue/src/tracing.ts @@ -3,6 +3,7 @@ import type { Span, Transaction } from '@sentry/types'; import { logger, timestampInSeconds } from '@sentry/utils'; import { DEFAULT_HOOKS } from './constants'; +import { DEBUG_BUILD } from './debug-build'; import type { Hook, Operation, TracingOptions, ViewModel, Vue } from './types'; import { formatComponentName } from './vendor/components'; @@ -63,7 +64,7 @@ export const createTracingMixins = (options: TracingOptions): Mixins => { // eg. mount => ['beforeMount', 'mounted'] const internalHooks = HOOKS[operation]; if (!internalHooks) { - __DEBUG_BUILD__ && logger.warn(`Unknown hook: ${operation}`); + DEBUG_BUILD && logger.warn(`Unknown hook: ${operation}`); continue; } From 8ee1aa508474c46cb76dd9bbd691f381114e3b75 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 27 Nov 2023 17:48:21 +0100 Subject: [PATCH 02/10] fix: Wrap all console log instances in console sandbox (#9662) --- packages/core/src/hub.ts | 6 ++--- packages/core/src/sdk.ts | 8 ++++--- packages/deno/src/transports/index.ts | 10 ++++---- packages/integration-shims/package.json | 3 ++- .../integration-shims/src/BrowserTracing.ts | 7 ++++-- packages/integration-shims/src/Replay.ts | 7 ++++-- .../src/common/wrapApiHandlerWithSentry.ts | 23 +++++++++++++------ packages/nextjs/src/config/webpack.ts | 6 ++--- .../src/integrations/utils/errorhandling.ts | 8 ++++--- packages/node/src/transports/http.ts | 11 +++++---- .../opentelemetry/src/custom/hubextensions.ts | 7 ++++-- packages/remix/src/utils/instrumentServer.ts | 2 +- packages/replay/src/integration.ts | 18 +++++++++------ packages/replay/src/util/getPrivacyOptions.ts | 12 ++++++---- packages/sveltekit/src/client/handleError.ts | 7 ++++-- packages/utils/src/dsn.ts | 8 ++++--- packages/vue/src/errorhandler.ts | 7 ++++-- packages/vue/src/integration.ts | 22 ++++++++++-------- 18 files changed, 109 insertions(+), 63 deletions(-) diff --git a/packages/core/src/hub.ts b/packages/core/src/hub.ts index 892ecf7b3b52..6d19b463b73b 100644 --- a/packages/core/src/hub.ts +++ b/packages/core/src/hub.ts @@ -377,13 +377,11 @@ export class Hub implements HubInterface { if (DEBUG_BUILD && !result) { const client = this.getClient(); if (!client) { - // eslint-disable-next-line no-console - console.warn( + logger.warn( "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'", ); } else { - // eslint-disable-next-line no-console - console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init': + logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init': Sentry.addTracingExtensions(); Sentry.init({...}); `); diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index 451a94df335c..a7131df5528d 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -1,5 +1,5 @@ import type { Client, ClientOptions } from '@sentry/types'; -import { logger } from '@sentry/utils'; +import { consoleSandbox, logger } from '@sentry/utils'; import { DEBUG_BUILD } from './debug-build'; import { getCurrentHub } from './hub'; @@ -23,8 +23,10 @@ export function initAndBind( logger.enable(); } else { // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped - // eslint-disable-next-line no-console - console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.'); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.'); + }); } } const hub = getCurrentHub(); diff --git a/packages/deno/src/transports/index.ts b/packages/deno/src/transports/index.ts index 62da327c5d83..964c1a9347af 100644 --- a/packages/deno/src/transports/index.ts +++ b/packages/deno/src/transports/index.ts @@ -1,6 +1,6 @@ import { createTransport } from '@sentry/core'; import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; -import { rejectedSyncPromise } from '@sentry/utils'; +import { consoleSandbox, rejectedSyncPromise } from '@sentry/utils'; export interface DenoTransportOptions extends BaseTransportOptions { /** Custom headers for the transport. Used by the XHRTransport and FetchTransport */ @@ -14,9 +14,11 @@ export function makeFetchTransport(options: DenoTransportOptions): Transport { const url = new URL(options.url); if (Deno.permissions.querySync({ name: 'net', host: url.host }).state !== 'granted') { - // eslint-disable-next-line no-console - console.warn(`Sentry SDK requires 'net' permission to send events. -Run with '--allow-net=${url.host}' to grant the requires permissions.`); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn(`Sentry SDK requires 'net' permission to send events. + Run with '--allow-net=${url.host}' to grant the requires permissions.`); + }); } function makeRequest(request: TransportRequest): PromiseLike { diff --git a/packages/integration-shims/package.json b/packages/integration-shims/package.json index 15ca58cb6a73..0dfe2f331d89 100644 --- a/packages/integration-shims/package.json +++ b/packages/integration-shims/package.json @@ -43,7 +43,8 @@ "url": "https://github.com/getsentry/sentry-javascript/issues" }, "dependencies": { - "@sentry/types": "7.81.1" + "@sentry/types": "7.81.1", + "@sentry/utils": "7.81.1" }, "engines": { "node": ">=12" diff --git a/packages/integration-shims/src/BrowserTracing.ts b/packages/integration-shims/src/BrowserTracing.ts index 4b2d90d029b6..60acf4fc5df5 100644 --- a/packages/integration-shims/src/BrowserTracing.ts +++ b/packages/integration-shims/src/BrowserTracing.ts @@ -1,4 +1,5 @@ import type { Integration } from '@sentry/types'; +import { consoleSandbox } from '@sentry/utils'; /** * This is a shim for the BrowserTracing integration. @@ -20,8 +21,10 @@ class BrowserTracingShim implements Integration { public constructor(_options: any) { this.name = BrowserTracingShim.id; - // eslint-disable-next-line no-console - console.error('You are using new BrowserTracing() even though this bundle does not include tracing.'); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error('You are using new BrowserTracing() even though this bundle does not include tracing.'); + }); } /** jsdoc */ diff --git a/packages/integration-shims/src/Replay.ts b/packages/integration-shims/src/Replay.ts index a6983344ce6f..921a25c4bdfa 100644 --- a/packages/integration-shims/src/Replay.ts +++ b/packages/integration-shims/src/Replay.ts @@ -1,4 +1,5 @@ import type { Integration } from '@sentry/types'; +import { consoleSandbox } from '@sentry/utils'; /** * This is a shim for the Replay integration. @@ -20,8 +21,10 @@ class ReplayShim implements Integration { public constructor(_options: any) { this.name = ReplayShim.id; - // eslint-disable-next-line no-console - console.error('You are using new Replay() even though this bundle does not include replay.'); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error('You are using new Replay() even though this bundle does not include replay.'); + }); } /** jsdoc */ diff --git a/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts index da5094f03834..fb83b60a360d 100644 --- a/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts @@ -6,7 +6,14 @@ import { startTransaction, } from '@sentry/core'; import type { Transaction } from '@sentry/types'; -import { isString, logger, objectify, stripUrlQueryAndFragment, tracingContextFromHeaders } from '@sentry/utils'; +import { + consoleSandbox, + isString, + logger, + objectify, + stripUrlQueryAndFragment, + tracingContextFromHeaders, +} from '@sentry/utils'; import { DEBUG_BUILD } from './debug-build'; import type { AugmentedNextApiRequest, AugmentedNextApiResponse, NextApiHandler } from './types'; @@ -165,12 +172,14 @@ export function withSentry(apiHandler: NextApiHandler, parameterizedRoute?: stri // This can only happen (not always) when the user is using `withSentry` manually, which we're deprecating. // Warning suppression on Next.JS is only necessary in that case. ) { - // eslint-disable-next-line no-console - console.warn( - `[sentry] If Next.js logs a warning "API resolved without sending a response", it's a false positive, which may happen when you use \`withSentry\` manually to wrap your routes. - To suppress this warning, set \`SENTRY_IGNORE_API_RESOLUTION_ERROR\` to 1 in your env. - To suppress the nextjs warning, use the \`externalResolver\` API route option (see https://nextjs.org/docs/api-routes/api-middlewares#custom-config for details).`, - ); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + `[sentry] If Next.js logs a warning "API resolved without sending a response", it's a false positive, which may happen when you use \`withSentry\` manually to wrap your routes. + To suppress this warning, set \`SENTRY_IGNORE_API_RESOLUTION_ERROR\` to 1 in your env. + To suppress the nextjs warning, use the \`externalResolver\` API route option (see https://nextjs.org/docs/api-routes/api-middlewares#custom-config for details).`, + ); + }); } return handlerResult; diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index d8ce23b802d7..5c29b2884f41 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -1071,7 +1071,7 @@ class SentryCliDownloadPlugin implements WebpackPluginInstance { if (!downloadingCliAttempted) { downloadingCliAttempted = true; // eslint-disable-next-line no-console - console.log( + logger.info( `\n${chalk.cyan('info')} - ${chalk.bold( 'Sentry binary to upload source maps not found.', )} Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`, @@ -1087,12 +1087,12 @@ class SentryCliDownloadPlugin implements WebpackPluginInstance { cliDownloadPromise.then( () => { // eslint-disable-next-line no-console - console.log(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`); + logger.info(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`); return callback(); }, e => { // eslint-disable-next-line no-console - console.error(`${chalk.red('error')} - Sentry binary download failed:`, e); + logger.error(`${chalk.red('error')} - Sentry binary download failed:`, e); return callback(); }, ); diff --git a/packages/node/src/integrations/utils/errorhandling.ts b/packages/node/src/integrations/utils/errorhandling.ts index 86d55c2c8086..5d3abb90afce 100644 --- a/packages/node/src/integrations/utils/errorhandling.ts +++ b/packages/node/src/integrations/utils/errorhandling.ts @@ -1,5 +1,5 @@ import { getClient } from '@sentry/core'; -import { logger } from '@sentry/utils'; +import { consoleSandbox, logger } from '@sentry/utils'; import type { NodeClient } from '../../client'; import { DEBUG_BUILD } from '../../debug-build'; @@ -10,8 +10,10 @@ const DEFAULT_SHUTDOWN_TIMEOUT = 2000; * @hidden */ export function logAndExitProcess(error: Error): void { - // eslint-disable-next-line no-console - console.error(error); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error(error); + }); const client = getClient(); diff --git a/packages/node/src/transports/http.ts b/packages/node/src/transports/http.ts index 340bcf4800f0..7a2cd50df319 100644 --- a/packages/node/src/transports/http.ts +++ b/packages/node/src/transports/http.ts @@ -6,6 +6,7 @@ import type { TransportRequest, TransportRequestExecutor, } from '@sentry/types'; +import { consoleSandbox } from '@sentry/utils'; import * as http from 'http'; import * as https from 'https'; import { HttpsProxyAgent } from 'https-proxy-agent'; @@ -53,10 +54,12 @@ export function makeNodeTransport(options: NodeTransportOptions): Transport { try { urlSegments = new URL(options.url); } catch (e) { - // eslint-disable-next-line no-console - console.warn( - '[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.', - ); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + '[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.', + ); + }); return createTransport(options, () => Promise.resolve({})); } diff --git a/packages/opentelemetry/src/custom/hubextensions.ts b/packages/opentelemetry/src/custom/hubextensions.ts index 4e839a9f3314..a70cb1aaca33 100644 --- a/packages/opentelemetry/src/custom/hubextensions.ts +++ b/packages/opentelemetry/src/custom/hubextensions.ts @@ -1,5 +1,6 @@ import { addTracingExtensions as _addTracingExtensions, getMainCarrier } from '@sentry/core'; import type { CustomSamplingContext, TransactionContext } from '@sentry/types'; +import { consoleSandbox } from '@sentry/utils'; /** * Add tracing extensions, ensuring a patched `startTransaction` to work with OTEL. @@ -22,8 +23,10 @@ function startTransactionNoop( _transactionContext: TransactionContext, _customSamplingContext?: CustomSamplingContext, ): unknown { - // eslint-disable-next-line no-console - console.warn('startTransaction is a noop in @sentry/opentelemetry. Use `startSpan` instead.'); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn('startTransaction is a noop in @sentry/opentelemetry. Use `startSpan` instead.'); + }); // We return an object here as hub.ts checks for the result of this // and renders a different warning if this is empty return {}; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index f4676a3e8845..47d48f4a9d9c 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -93,7 +93,7 @@ export async function captureRemixServerException(err: unknown, name: string, re // Skip capturing if the request is aborted as Remix docs suggest // Ref: https://remix.run/docs/en/main/file-conventions/entry.server#handleerror if (request.signal.aborted) { - __DEBUG_BUILD__ && logger.warn('Skipping capture of aborted request'); + DEBUG_BUILD && logger.warn('Skipping capture of aborted request'); return; } diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts index b94907d44938..80bbeca5fdf3 100644 --- a/packages/replay/src/integration.ts +++ b/packages/replay/src/integration.ts @@ -1,6 +1,6 @@ import { getClient } from '@sentry/core'; import type { BrowserClientReplayOptions, Integration } from '@sentry/types'; -import { dropUndefinedKeys, isBrowser } from '@sentry/utils'; +import { consoleSandbox, dropUndefinedKeys, isBrowser } from '@sentry/utils'; import { DEFAULT_FLUSH_MAX_DELAY, @@ -349,8 +349,10 @@ function loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions) const finalOptions = { sessionSampleRate: 0, errorSampleRate: 0, ...dropUndefinedKeys(initialOptions) }; if (!opt) { - // eslint-disable-next-line no-console - console.warn('SDK client is not available.'); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn('SDK client is not available.'); + }); return finalOptions; } @@ -360,10 +362,12 @@ function loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions) opt.replaysSessionSampleRate == null && opt.replaysOnErrorSampleRate == null ) { - // eslint-disable-next-line no-console - console.warn( - 'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.', - ); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + 'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.', + ); + }); } if (typeof opt.replaysSessionSampleRate === 'number') { diff --git a/packages/replay/src/util/getPrivacyOptions.ts b/packages/replay/src/util/getPrivacyOptions.ts index c37075923d90..7d0584b7ba7b 100644 --- a/packages/replay/src/util/getPrivacyOptions.ts +++ b/packages/replay/src/util/getPrivacyOptions.ts @@ -1,3 +1,5 @@ +import { consoleSandbox } from '@sentry/utils'; + import type { DeprecatedPrivacyOptions, ReplayIntegrationPrivacyOptions } from '../types'; type GetPrivacyOptions = Required> & @@ -37,10 +39,12 @@ function getOption( allSelectors.push(`.${deprecatedClassOption}`); } - // eslint-disable-next-line no-console - console.warn( - '[Replay] You are using a deprecated configuration item for privacy. Read the documentation on how to use the new privacy configuration.', - ); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + '[Replay] You are using a deprecated configuration item for privacy. Read the documentation on how to use the new privacy configuration.', + ); + }); } return allSelectors.join(','); diff --git a/packages/sveltekit/src/client/handleError.ts b/packages/sveltekit/src/client/handleError.ts index 6c8a30fb1e03..6c16cee0ebbd 100644 --- a/packages/sveltekit/src/client/handleError.ts +++ b/packages/sveltekit/src/client/handleError.ts @@ -1,4 +1,5 @@ import { captureException } from '@sentry/svelte'; +import { consoleSandbox } from '@sentry/utils'; // For now disable the import/no-unresolved rule, because we don't have a way to // tell eslint that we are only importing types from the @sveltejs/kit package without // adding a custom resolver, which will take too much time. @@ -8,8 +9,10 @@ import type { HandleClientError, NavigationEvent } from '@sveltejs/kit'; // The SvelteKit default error handler just logs the error to the console // see: https://github.com/sveltejs/kit/blob/369e7d6851f543a40c947e033bfc4a9506fdc0a8/packages/kit/src/core/sync/write_client_manifest.js#LL127C2-L127C2 function defaultErrorHandler({ error }: Parameters[0]): ReturnType { - // eslint-disable-next-line no-console - console.error(error); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error(error); + }); } /** diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 574e9c78b4eb..7bf735c10780 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -1,7 +1,7 @@ import type { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types'; import { DEBUG_BUILD } from './debug-build'; -import { logger } from './logger'; +import { consoleSandbox, logger } from './logger'; /** Regular expression used to parse a Dsn. */ const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)([\w.-]+)(?::(\d+))?\/(.+)/; @@ -38,8 +38,10 @@ export function dsnFromString(str: string): DsnComponents | undefined { if (!match) { // This should be logged to the console - // eslint-disable-next-line no-console - console.error(`Invalid Sentry Dsn: ${str}`); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error(`Invalid Sentry Dsn: ${str}`); + }); return undefined; } diff --git a/packages/vue/src/errorhandler.ts b/packages/vue/src/errorhandler.ts index 40a950ae9374..9d09bdf8c181 100644 --- a/packages/vue/src/errorhandler.ts +++ b/packages/vue/src/errorhandler.ts @@ -1,4 +1,5 @@ import { getCurrentHub } from '@sentry/browser'; +import { consoleSandbox } from '@sentry/utils'; import type { ViewModel, Vue, VueOptions } from './types'; import { formatComponentName, generateComponentTrace } from './vendor/components'; @@ -46,8 +47,10 @@ export const attachErrorHandler = (app: Vue, options: VueOptions): void => { if (warnHandler) { (warnHandler as UnknownFunc).call(null, message, vm, trace); } else if (hasConsole && !silent) { - // eslint-disable-next-line no-console - console.error(`[Vue warn]: ${message}${trace}`); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.error(`[Vue warn]: ${message}${trace}`); + }); } } }; diff --git a/packages/vue/src/integration.ts b/packages/vue/src/integration.ts index 9a3969f5c415..3f35c66fe554 100644 --- a/packages/vue/src/integration.ts +++ b/packages/vue/src/integration.ts @@ -1,6 +1,6 @@ import { hasTracingEnabled } from '@sentry/core'; import type { Hub, Integration } from '@sentry/types'; -import { arrayify, GLOBAL_OBJ } from '@sentry/utils'; +import { arrayify, consoleSandbox, GLOBAL_OBJ } from '@sentry/utils'; import { DEFAULT_HOOKS } from './constants'; import { attachErrorHandler } from './errorhandler'; @@ -50,12 +50,14 @@ export class VueIntegration implements Integration { const options: Options = { ...DEFAULT_CONFIG, ...(client && client.getOptions()), ...this._options }; if (!options.Vue && !options.app) { - // eslint-disable-next-line no-console - console.warn( - `[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured. + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + `[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured. Update your \`Sentry.init\` call with an appropriate config option: \`app\` (Application Instance - Vue 3) or \`Vue\` (Vue Constructor - Vue 2).`, - ); + ); + }); return; } @@ -80,10 +82,12 @@ const vueInit = (app: Vue, options: Options): void => { const isMounted = appWithInstance._instance && appWithInstance._instance.isMounted; if (isMounted === true) { - // eslint-disable-next-line no-console - console.warn( - '[@sentry/vue]: Misconfigured SDK. Vue app is already mounted. Make sure to call `app.mount()` after `Sentry.init()`.', - ); + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + '[@sentry/vue]: Misconfigured SDK. Vue app is already mounted. Make sure to call `app.mount()` after `Sentry.init()`.', + ); + }); } attachErrorHandler(app, options); From 0c8aee387d3377ad6ce52d164667720fa50262a4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 27 Nov 2023 14:00:07 -0500 Subject: [PATCH 03/10] chore: Remove scenarios (#9667) This is code that isn't being used anywhere, and the code snippets are out of date (look at custom transport code). We can explore adding this back for v8. --- .../browser/basic-capture-exception/index.js | 7 - .../basic-capture-exception/package.json | 5 - .../browser/basic-capture-message/index.js | 7 - .../basic-capture-message/package.json | 5 - .../browser/basic-custom-integration/index.js | 23 - .../basic-custom-integration/package.json | 5 - .../browser/basic-custom-transport/index.js | 22 - .../basic-custom-transport/package.json | 5 - .../browser/basic-no-client-reports/index.js | 6 - .../basic-no-client-reports/package.json | 5 - .../basic-no-default-integrations/index.js | 6 - .../package.json | 5 - scenarios/browser/basic-no-dsn/index.js | 3 - scenarios/browser/basic-no-dsn/package.json | 5 - scenarios/browser/basic-no-sessions/index.js | 7 - .../browser/basic-no-sessions/package.json | 5 - scenarios/browser/basic-with-debug/index.js | 6 - .../browser/basic-with-debug/package.json | 5 - .../browser/basic-with-sessions/index.js | 6 - .../browser/basic-with-sessions/package.json | 5 - scenarios/browser/basic-with-tunnel/index.js | 6 - .../browser/basic-with-tunnel/package.json | 5 - scenarios/browser/basic/index.js | 5 - scenarios/browser/basic/package.json | 5 - scenarios/browser/nextjs-client/index.js | 5 - scenarios/browser/nextjs-client/package.json | 8 - scenarios/browser/package.json | 12 - scenarios/browser/perf-auto/index.js | 8 - scenarios/browser/perf-auto/package.json | 5 - scenarios/browser/perf-manual/index.js | 13 - scenarios/browser/perf-manual/package.json | 5 - scenarios/browser/react/index.js | 19 - scenarios/browser/react/package.json | 9 - scenarios/browser/webpack.js | 82 -- scenarios/browser/yarn.lock | 1123 ----------------- 35 files changed, 1453 deletions(-) delete mode 100644 scenarios/browser/basic-capture-exception/index.js delete mode 100644 scenarios/browser/basic-capture-exception/package.json delete mode 100644 scenarios/browser/basic-capture-message/index.js delete mode 100644 scenarios/browser/basic-capture-message/package.json delete mode 100644 scenarios/browser/basic-custom-integration/index.js delete mode 100644 scenarios/browser/basic-custom-integration/package.json delete mode 100644 scenarios/browser/basic-custom-transport/index.js delete mode 100644 scenarios/browser/basic-custom-transport/package.json delete mode 100644 scenarios/browser/basic-no-client-reports/index.js delete mode 100644 scenarios/browser/basic-no-client-reports/package.json delete mode 100644 scenarios/browser/basic-no-default-integrations/index.js delete mode 100644 scenarios/browser/basic-no-default-integrations/package.json delete mode 100644 scenarios/browser/basic-no-dsn/index.js delete mode 100644 scenarios/browser/basic-no-dsn/package.json delete mode 100644 scenarios/browser/basic-no-sessions/index.js delete mode 100644 scenarios/browser/basic-no-sessions/package.json delete mode 100644 scenarios/browser/basic-with-debug/index.js delete mode 100644 scenarios/browser/basic-with-debug/package.json delete mode 100644 scenarios/browser/basic-with-sessions/index.js delete mode 100644 scenarios/browser/basic-with-sessions/package.json delete mode 100644 scenarios/browser/basic-with-tunnel/index.js delete mode 100644 scenarios/browser/basic-with-tunnel/package.json delete mode 100644 scenarios/browser/basic/index.js delete mode 100644 scenarios/browser/basic/package.json delete mode 100644 scenarios/browser/nextjs-client/index.js delete mode 100644 scenarios/browser/nextjs-client/package.json delete mode 100644 scenarios/browser/package.json delete mode 100644 scenarios/browser/perf-auto/index.js delete mode 100644 scenarios/browser/perf-auto/package.json delete mode 100644 scenarios/browser/perf-manual/index.js delete mode 100644 scenarios/browser/perf-manual/package.json delete mode 100644 scenarios/browser/react/index.js delete mode 100644 scenarios/browser/react/package.json delete mode 100644 scenarios/browser/webpack.js delete mode 100644 scenarios/browser/yarn.lock diff --git a/scenarios/browser/basic-capture-exception/index.js b/scenarios/browser/basic-capture-exception/index.js deleted file mode 100644 index d8f49c6e8f91..000000000000 --- a/scenarios/browser/basic-capture-exception/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { init, captureException } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", -}); - -captureException(new Error("error here!")); diff --git a/scenarios/browser/basic-capture-exception/package.json b/scenarios/browser/basic-capture-exception/package.json deleted file mode 100644 index 648f2811682c..000000000000 --- a/scenarios/browser/basic-capture-exception/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-capture-exception", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-capture-message/index.js b/scenarios/browser/basic-capture-message/index.js deleted file mode 100644 index cc1c36996db1..000000000000 --- a/scenarios/browser/basic-capture-message/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { init, captureMessage } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", -}); - -captureMessage("this is a message"); diff --git a/scenarios/browser/basic-capture-message/package.json b/scenarios/browser/basic-capture-message/package.json deleted file mode 100644 index 8ef15e0872fe..000000000000 --- a/scenarios/browser/basic-capture-message/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-capture-message", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-custom-integration/index.js b/scenarios/browser/basic-custom-integration/index.js deleted file mode 100644 index 2ef4864e2c78..000000000000 --- a/scenarios/browser/basic-custom-integration/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import { init } from "@sentry/browser"; - -class CustomIntegration { - static id = 'CustomIntegration'; - - name = CustomIntegration.id; - options = undefined; - - constructor(options) { - this.options = options; - } - - setupOnce(addGlobalEventProcessor, getCurrentHub) { - addGlobalEventProcessor(event => event); - const hub = getCurrentHub(); - hub.captureMessage(options.name); - } -} - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - integrations: [new CustomIntegration()], -}); diff --git a/scenarios/browser/basic-custom-integration/package.json b/scenarios/browser/basic-custom-integration/package.json deleted file mode 100644 index 0d65cdf1fd85..000000000000 --- a/scenarios/browser/basic-custom-integration/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-custom-integration", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-custom-transport/index.js b/scenarios/browser/basic-custom-transport/index.js deleted file mode 100644 index 7e453b13259d..000000000000 --- a/scenarios/browser/basic-custom-transport/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import { init, Transports } from "@sentry/browser"; - -class CustomTransport extends Transports.BaseTransport { - constructor(options) { - super(options); - } - - sendEvent(event) { - console.log("Sending Event"); - return super.sendEvent(event); - } - - sendSession(session) { - console.log("Sending Session"); - return super.sendSession(session); - } -} - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - transport: CustomTransport -}); diff --git a/scenarios/browser/basic-custom-transport/package.json b/scenarios/browser/basic-custom-transport/package.json deleted file mode 100644 index 55293071b717..000000000000 --- a/scenarios/browser/basic-custom-transport/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-custom-transport", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-no-client-reports/index.js b/scenarios/browser/basic-no-client-reports/index.js deleted file mode 100644 index 5c52e71e2518..000000000000 --- a/scenarios/browser/basic-no-client-reports/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - sendClientReports: false, -}); diff --git a/scenarios/browser/basic-no-client-reports/package.json b/scenarios/browser/basic-no-client-reports/package.json deleted file mode 100644 index a43e8f57ee5e..000000000000 --- a/scenarios/browser/basic-no-client-reports/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-no-client-reports", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-no-default-integrations/index.js b/scenarios/browser/basic-no-default-integrations/index.js deleted file mode 100644 index fa0d50153682..000000000000 --- a/scenarios/browser/basic-no-default-integrations/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - defaultIntegrations: false, -}); diff --git a/scenarios/browser/basic-no-default-integrations/package.json b/scenarios/browser/basic-no-default-integrations/package.json deleted file mode 100644 index cbbf97445002..000000000000 --- a/scenarios/browser/basic-no-default-integrations/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-no-default-integrations", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-no-dsn/index.js b/scenarios/browser/basic-no-dsn/index.js deleted file mode 100644 index b1e65a541bc6..000000000000 --- a/scenarios/browser/basic-no-dsn/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import { init } from "@sentry/browser"; - -init(); diff --git a/scenarios/browser/basic-no-dsn/package.json b/scenarios/browser/basic-no-dsn/package.json deleted file mode 100644 index 0d6d42459880..000000000000 --- a/scenarios/browser/basic-no-dsn/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-no-dsn", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-no-sessions/index.js b/scenarios/browser/basic-no-sessions/index.js deleted file mode 100644 index 6152ed8f4332..000000000000 --- a/scenarios/browser/basic-no-sessions/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - release: "my-app@1.2.3", - autoSessionTracking: false, -}); diff --git a/scenarios/browser/basic-no-sessions/package.json b/scenarios/browser/basic-no-sessions/package.json deleted file mode 100644 index 0aa83cd2012b..000000000000 --- a/scenarios/browser/basic-no-sessions/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-no-sessions", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-with-debug/index.js b/scenarios/browser/basic-with-debug/index.js deleted file mode 100644 index feb43c4afbee..000000000000 --- a/scenarios/browser/basic-with-debug/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - debug: true, -}); diff --git a/scenarios/browser/basic-with-debug/package.json b/scenarios/browser/basic-with-debug/package.json deleted file mode 100644 index 11adf6b8d51e..000000000000 --- a/scenarios/browser/basic-with-debug/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-with-debug", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-with-sessions/index.js b/scenarios/browser/basic-with-sessions/index.js deleted file mode 100644 index 9a346cf1be3a..000000000000 --- a/scenarios/browser/basic-with-sessions/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - release: "my-app@1.2.3", -}); diff --git a/scenarios/browser/basic-with-sessions/package.json b/scenarios/browser/basic-with-sessions/package.json deleted file mode 100644 index d8012e78fb3e..000000000000 --- a/scenarios/browser/basic-with-sessions/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-with-sessions", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic-with-tunnel/index.js b/scenarios/browser/basic-with-tunnel/index.js deleted file mode 100644 index 2716574cc3d1..000000000000 --- a/scenarios/browser/basic-with-tunnel/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - tunnel: "/errors", -}); diff --git a/scenarios/browser/basic-with-tunnel/package.json b/scenarios/browser/basic-with-tunnel/package.json deleted file mode 100644 index 9d35d8e664f6..000000000000 --- a/scenarios/browser/basic-with-tunnel/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic-with-tunnel", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/basic/index.js b/scenarios/browser/basic/index.js deleted file mode 100644 index 4a17f885a9ed..000000000000 --- a/scenarios/browser/basic/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { init } from "@sentry/browser"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", -}); diff --git a/scenarios/browser/basic/package.json b/scenarios/browser/basic/package.json deleted file mode 100644 index da52f2cfdf84..000000000000 --- a/scenarios/browser/basic/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "basic", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/nextjs-client/index.js b/scenarios/browser/nextjs-client/index.js deleted file mode 100644 index 2e1d4645c8dc..000000000000 --- a/scenarios/browser/nextjs-client/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { init } from "@sentry/nextjs/esm/index.client"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", -}); diff --git a/scenarios/browser/nextjs-client/package.json b/scenarios/browser/nextjs-client/package.json deleted file mode 100644 index 638d816e2e70..000000000000 --- a/scenarios/browser/nextjs-client/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "nextjs-client", - "private": true, - "version": "0.0.0", - "dependencies": { - "next": "12" - } -} diff --git a/scenarios/browser/package.json b/scenarios/browser/package.json deleted file mode 100644 index 305641c25f9e..000000000000 --- a/scenarios/browser/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "scenarios-browser", - "main": "webpack.js", - "private": true, - "version": "0.0.0", - "devDependencies": { - "html-webpack-plugin": "^5.5.0", - "webpack": "^5.76.0", - "webpack-bundle-analyzer": "^4.5.0", - "inquirer": "^8.2.0" - } -} diff --git a/scenarios/browser/perf-auto/index.js b/scenarios/browser/perf-auto/index.js deleted file mode 100644 index ae46d8d7fb26..000000000000 --- a/scenarios/browser/perf-auto/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import { init } from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, -}); diff --git a/scenarios/browser/perf-auto/package.json b/scenarios/browser/perf-auto/package.json deleted file mode 100644 index 83d2c54e9e99..000000000000 --- a/scenarios/browser/perf-auto/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "perf-auto", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/perf-manual/index.js b/scenarios/browser/perf-manual/index.js deleted file mode 100644 index ce0ecfe73746..000000000000 --- a/scenarios/browser/perf-manual/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import { init, startTransaction } from "@sentry/browser"; -import "@sentry/tracing"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", - tracesSampleRate: 1.0, -}); - -const transaction = startTransaction({ op: "task", name: "Important Stuff" }); - -setTimeout(() => { - transaction.finish(); -}, 1000); diff --git a/scenarios/browser/perf-manual/package.json b/scenarios/browser/perf-manual/package.json deleted file mode 100644 index e8e94f0dd61d..000000000000 --- a/scenarios/browser/perf-manual/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "perf-manual", - "private": true, - "version": "0.0.0" -} diff --git a/scenarios/browser/react/index.js b/scenarios/browser/react/index.js deleted file mode 100644 index 199a160d26a6..000000000000 --- a/scenarios/browser/react/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom" -import { init } from "@sentry/react"; - -init({ - dsn: "https://00000000000000000000000000000000@o000000.ingest.sentry.io/0000000", -}); - -class Hello extends React.Component { - render() { - return React.createElement('div', null, `Hello ${this.props.toWhat}`); - } -} - -ReactDOM.render( - React.createElement(Hello, { toWhat: 'World' }, null), - // eslint-disable-next-line no-undef - document.getElementById('root') -); diff --git a/scenarios/browser/react/package.json b/scenarios/browser/react/package.json deleted file mode 100644 index 068e2fd2e168..000000000000 --- a/scenarios/browser/react/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "react", - "private": true, - "version": "0.0.0", - "dependencies": { - "react": "17", - "react-dom": "17" - } -} diff --git a/scenarios/browser/webpack.js b/scenarios/browser/webpack.js deleted file mode 100644 index 9bbb24c48a10..000000000000 --- a/scenarios/browser/webpack.js +++ /dev/null @@ -1,82 +0,0 @@ -const path = require('path'); -const { promises } = require('fs'); - -const inquirer = require('inquirer'); -const webpack = require('webpack'); -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; -const HtmlWebpackPlugin = require('html-webpack-plugin'); - -async function init() { - const scenarios = await getScenariosFromDirectories(); - - const answers = await inquirer.prompt([ - { - type: 'rawlist', - name: 'scenario', - message: 'Which scenario you want to run?', - choices: scenarios, - pageSize: scenarios.length, - loop: false, - }, - ]); - - console.log(`Bundling scenario: ${answers.scenario}`); - - await runWebpack(answers.scenario); -} - -async function runWebpack(scenario) { - const alias = await generateAlias(); - - webpack( - { - mode: 'production', - entry: path.resolve(__dirname, scenario), - output: { - filename: 'main.js', - path: path.resolve(__dirname, 'dist', scenario), - }, - plugins: [new BundleAnalyzerPlugin({ analyzerMode: 'static' }), new HtmlWebpackPlugin()], - resolve: { - alias, - }, - }, - (err, stats) => { - if (err || stats.hasErrors()) { - console.log(err); - } - console.log('DONE', stats); - }, - ); -} - -const PACKAGE_PATH = '../../packages'; - -/** - * Generate webpack aliases based on packages in monorepo - * Example of an alias: '@sentry/serverless': 'path/to/sentry-javascript/packages/serverless', - */ -async function generateAlias() { - const dirents = await promises.readdir(PACKAGE_PATH); - - return Object.fromEntries( - await Promise.all( - dirents.map(async d => { - const packageJSON = JSON.parse(await promises.readFile(path.resolve(PACKAGE_PATH, d, 'package.json'))); - return [packageJSON['name'], path.resolve(PACKAGE_PATH, d)]; - }), - ), - ); -} - -/** - * Generates an array of available scenarios - */ -async function getScenariosFromDirectories() { - const exclude = ['node_modules', 'dist', '~', 'package.json', 'yarn.lock', 'webpack.js']; - - const dirents = await promises.readdir(__dirname, { withFileTypes: true }); - return dirents.map(dirent => dirent.name).filter(mape => !exclude.includes(mape)); -} - -init(); diff --git a/scenarios/browser/yarn.lock b/scenarios/browser/yarn.lock deleted file mode 100644 index 05a2d184cab2..000000000000 --- a/scenarios/browser/yarn.lock +++ /dev/null @@ -1,1123 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.14" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" - integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@polka/url@^1.0.0-next.20": - version "1.0.0-next.21" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" - integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== - -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "7.28.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68" - integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/html-minifier-terser@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.0.0.tgz#563c1c6c132cd204e71512f9c0b394ff90d3fae7" - integrity sha512-NZwaaynfs1oIoLAV1vg18e7QMVDvw+6SQrdJc8w3BwUaoroVSf6EBj/Sk4PBWGxsq0dzhA2drbsuMC1/6C6KgQ== - -"@types/json-schema@*", "@types/json-schema@^7.0.8": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/node@*": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== - -acorn-walk@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.1: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -ajv-keywords@^3.5.2: - version "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.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -browserslist@^4.14.5: - version "4.17.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d" - integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw== - dependencies: - caniuse-lite "^1.0.30001274" - electron-to-chromium "^1.3.886" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -caniuse-lite@^1.0.30001274: - version "1.0.30001278" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz#51cafc858df77d966b17f59b5839250b24417fff" - integrity sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg== - -chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -clean-css@^5.1.5: - version "5.2.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.2.tgz#d3a7c6ee2511011e051719838bdcf8314dc4548d" - integrity sha512-/eR8ru5zyxKzpBLv9YZvMXgTSSQn7AdkMItMYynsFgGwTveCRVam9IUPFloE85B4vAIj05IuKmmEoV7/AQjT0w== - dependencies: - source-map "~0.6.0" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.5.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-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^8.1.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -css-select@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" - integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== - dependencies: - boolbase "^1.0.0" - css-what "^5.0.0" - domhandler "^4.2.0" - domutils "^2.6.0" - nth-check "^2.0.0" - -css-what@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" - integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-serializer@^1.0.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" - integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" - integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== - -domhandler@^4.0.0, domhandler@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" - integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== - dependencies: - domelementtype "^2.2.0" - -domutils@^2.5.2, domutils@^2.6.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -duplexer@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -electron-to-chromium@^1.3.886: - version "1.3.891" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.891.tgz#51d7224e64157656276f152a0b3361708fde1bf9" - integrity sha512-3cpwR82QkIS01CN/dup/4Yr3BiOiRLlZlcAFn/5FbNCunMO9ojqDgEP9JEo1QNLflu3pEnPWve50gHOEKc7r6w== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.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== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -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== - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -graceful-fs@^4.1.2, graceful-fs@^4.2.4, 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== - -gzip-size@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" - integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== - dependencies: - duplexer "^0.1.2" - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -html-minifier-terser@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.0.2.tgz#14059ad64b69bf9f8b8a33f25b53411d8321e75d" - integrity sha512-AgYO3UGhMYQx2S/FBJT3EM0ZYcKmH6m9XL9c1v77BeK/tYJxGPxT1/AtsdUi4FcP8kZGmqqnItCcjFPcX9hk6A== - dependencies: - camel-case "^4.1.2" - clean-css "^5.1.5" - commander "^8.1.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.7.2" - -html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - -htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - -iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inquirer@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" - integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.2.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -jest-worker@^27.0.6: - version "27.3.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.3.1.tgz#0def7feae5b8042be38479799aeb7b5facac24b2" - integrity sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - -lodash@^4.17.20, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -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== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== - -mime-types@^2.1.27: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== - dependencies: - mime-db "1.50.0" - -mime@^2.3.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== - -nth-check@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" - integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== - dependencies: - boolbase "^1.0.0" - -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readable-stream@^3.4.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== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - -renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -rxjs@^7.2.0: - version "7.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" - integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== - dependencies: - tslib "^2.1.0" - -safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -signal-exit@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== - -sirv@^1.0.7: - version "1.0.18" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.18.tgz#105fab52fb656ce8a2bebbf36b11052005952899" - integrity sha512-f2AOPogZmXgJ9Ma2M22ZEhc1dNtRIzcEkiflMFeVTRq+OViOZMvH1IPMVOwrKaxpSaHioBJiDR0SluRqGa7atA== - dependencies: - "@polka/url" "^1.0.0-next.20" - mime "^2.3.1" - totalist "^1.0.0" - -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== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.1.3: - version "5.2.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.5.tgz#ce65b9880a0c36872555c4874f45bbdb02ee32c9" - integrity sha512-3luOVHku5l0QBeYS8r4CdHYWEGMmIj3H1U64jgkdZzECcSOJAyJ9TjuqcQZvw1Y+4AOBN9SeYJPJmFn2cM4/2g== - dependencies: - jest-worker "^27.0.6" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - terser "^5.7.2" - -terser@^5.7.2: - version "5.14.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" - integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== - -tslib@^2.0.3, tslib@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= - -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -webpack-bundle-analyzer@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5" - integrity sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ== - dependencies: - acorn "^8.0.4" - acorn-walk "^8.0.0" - chalk "^4.1.0" - commander "^7.2.0" - gzip-size "^6.0.0" - lodash "^4.17.20" - opener "^1.5.2" - sirv "^1.0.7" - ws "^7.3.1" - -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - -webpack@^5.76.0: - version "5.76.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" - integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -ws@^7.3.1: - version "7.5.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" - integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== From 7249cf9defc5ca081c1e91a5dbc7bfa1b1871ee2 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Mon, 27 Nov 2023 21:42:36 +0000 Subject: [PATCH 04/10] fix(remix): Check the error data before spreading. (#9664) --- packages/remix/src/client/errors.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/remix/src/client/errors.tsx b/packages/remix/src/client/errors.tsx index a6afefbc0ef7..c2214bd283df 100644 --- a/packages/remix/src/client/errors.tsx +++ b/packages/remix/src/client/errors.tsx @@ -23,13 +23,14 @@ export function captureRemixErrorBoundaryError(error: unknown): string | undefin const eventData = isRemixErrorResponse ? { function: 'ErrorResponse', - ...error.data, + ...getErrorData(error), } : { function: 'ReactError', }; const actualError = isRemixErrorResponse ? getExceptionToCapture(error) : error; + eventId = captureException(actualError, { mechanism: { type: 'instrument', @@ -42,10 +43,21 @@ export function captureRemixErrorBoundaryError(error: unknown): string | undefin return eventId; } +function getErrorData(error: ErrorResponse): object { + if (isString(error.data)) { + return { + error: error.data, + }; + } + + return error.data; +} + function getExceptionToCapture(error: ErrorResponse): string | ErrorResponse { if (isString(error.data)) { return error.data; } + if (error.statusText) { return error.statusText; } From 85a494ac794f6f5c35ff0c5196fa4beddb3026ef Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 28 Nov 2023 09:00:06 +0100 Subject: [PATCH 05/10] fix(astro): Configure sourcemap assets directory for Vercel adapter (#9665) This PR adds support for uploading sourcemaps when using the `@astrojs/vercel/*` adapters. It seems that the adapter updates the config.outdir value too late for our previous detection logic to correctly detect the .vercel output directory. Furthermore, the adapter for some reason first saves server files to /dist only to copy it later to /.vercel/functions. This copy command seems to happen too late for when our sourcemaps plugin runs. For these two reasons, we try to detect the used adapter (love that this is much simpler in Astro than Sveltekit) and adjust the assets glob to search for files in both, `dist` and `.vercel`. --- packages/astro/src/integration/index.ts | 10 +++++++ packages/astro/test/integration/index.test.ts | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index 5f5629697e3e..e844e383aaec 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -100,6 +100,16 @@ function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined { } function getSourcemapsAssetsGlob(config: AstroConfig): string { + // The vercel adapter puts the output into its .vercel directory + // However, the way this adapter is written, the config.outDir value is update too late for + // us to reliably detect it. Also, server files are first temporarily written to /dist and then + // only copied over to /.vercel. This seems to happen too late though. + // So we glob on both of these directories. + // Another case of "it ain't pretty but it works":( + if (config.adapter && config.adapter.name?.startsWith('@astrojs/vercel')) { + return '{.vercel,dist}/**/*'; + } + // paths are stored as "file://" URLs const outDirPathname = config.outDir && path.resolve(config.outDir.pathname); const rootDirName = path.resolve((config.root && config.root.pathname) || process.cwd()); diff --git a/packages/astro/test/integration/index.test.ts b/packages/astro/test/integration/index.test.ts index 51132971321d..fcf606c40e0b 100644 --- a/packages/astro/test/integration/index.test.ts +++ b/packages/astro/test/integration/index.test.ts @@ -83,6 +83,33 @@ describe('sentryAstro integration', () => { }); }); + it('sets the correct assets glob for vercel if the Vercel adapter is used', async () => { + const integration = sentryAstro({ + sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false }, + }); + // @ts-expect-error - the hook exists and we only need to pass what we actually use + await integration.hooks['astro:config:setup']({ + updateConfig, + injectScript, + config: { + // @ts-expect-error - we only need to pass what we actually use + adapter: { name: '@astrojs/vercel/serverless' }, + }, + }); + + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); + expect(sentryVitePluginSpy).toHaveBeenCalledWith({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: false, + debug: false, + sourcemaps: { + assets: ['{.vercel,dist}/**/*'], + }, + }); + }); + it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => { const integration = sentryAstro({ sourceMapsUploadOptions: { enabled: false }, From 3a96b23bc5ce74d8234695b95f6bb7fb49cd90a0 Mon Sep 17 00:00:00 2001 From: Quisido Date: Tue, 28 Nov 2023 00:40:17 -0800 Subject: [PATCH 06/10] feat: Support `exactOptionalPropertyTypes` on `ErrorBoundary` (#9098) --- packages/react/src/errorboundary.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react/src/errorboundary.tsx b/packages/react/src/errorboundary.tsx index dacc30b5d85a..66a026c7fe6d 100644 --- a/packages/react/src/errorboundary.tsx +++ b/packages/react/src/errorboundary.tsx @@ -23,12 +23,12 @@ export type FallbackRender = (errorData: { export type ErrorBoundaryProps = { children?: React.ReactNode | (() => React.ReactNode); /** If a Sentry report dialog should be rendered on error */ - showDialog?: boolean; + showDialog?: boolean | undefined; /** * Options to be passed into the Sentry report dialog. * No-op if {@link showDialog} is false. */ - dialogOptions?: ReportDialogOptions; + dialogOptions?: ReportDialogOptions | undefined; /** * A fallback component that gets rendered when the error boundary encounters an error. * @@ -37,17 +37,17 @@ export type ErrorBoundaryProps = { * the error, the component stack, and an function that resets the error boundary on error. * */ - fallback?: React.ReactElement | FallbackRender; + fallback?: React.ReactElement | FallbackRender | undefined; /** Called when the error boundary encounters an error */ - onError?(error: Error, componentStack: string, eventId: string): void; + onError?: ((error: Error, componentStack: string, eventId: string) => void) | undefined; /** Called on componentDidMount() */ - onMount?(): void; + onMount?: (() => void) | undefined; /** Called if resetError() is called from the fallback render props function */ - onReset?(error: Error | null, componentStack: string | null, eventId: string | null): void; + onReset?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined; /** Called on componentWillUnmount() */ - onUnmount?(error: Error | null, componentStack: string | null, eventId: string | null): void; + onUnmount?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined; /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */ - beforeCapture?(scope: Scope, error: Error | null, componentStack: string | null): void; + beforeCapture?: ((scope: Scope, error: Error | null, componentStack: string | null) => void) | undefined; }; type ErrorBoundaryState = From f2e57ad07073805e557a32c7d5819a858051e6be Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 28 Nov 2023 10:53:45 +0100 Subject: [PATCH 07/10] chore(astro): Allow Astro 4.0 in peer dependencies (#9683) Astro 4.0.0 beta is out so let's adjust our peer deps! I opted for an open max version for now. THere's a risk of this being problematic with future major versions but I'd argue we'd get support requests either way. The important part IMO is the lower bound. --- packages/astro/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index 7de67f5e4e02..3797589ef805 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -40,7 +40,7 @@ "access": "public" }, "peerDependencies": { - "astro": "3.x" + "astro": ">=3.x" }, "dependencies": { "@sentry/browser": "7.82.0", From 98d49885df5253dd4a3c6112a838c0ba0f1fe0aa Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 28 Nov 2023 11:02:01 +0100 Subject: [PATCH 08/10] fix: Don't depend on browser types in `types` (#9682) This is a hotfix for https://github.com/getsentry/sentry-javascript/issues/9679. We leaked Browser/React types into the generic `@sentry/types` package which should not have any runtime specific types. --- packages/replay/src/coreHandlers/handleDom.ts | 4 ++-- packages/replay/src/coreHandlers/util/domUtils.ts | 3 +-- packages/types/src/instrument.ts | 6 ++++-- packages/utils/src/instrument/dom.ts | 2 ++ packages/utils/src/instrument/history.ts | 2 ++ packages/utils/src/instrument/index.ts | 2 ++ packages/utils/src/instrument/xhr.ts | 2 ++ 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/replay/src/coreHandlers/handleDom.ts b/packages/replay/src/coreHandlers/handleDom.ts index 53a92575b027..a5c20810481b 100644 --- a/packages/replay/src/coreHandlers/handleDom.ts +++ b/packages/replay/src/coreHandlers/handleDom.ts @@ -41,7 +41,7 @@ export const handleDomListener: (replay: ReplayContainer) => (handlerData: Handl handleClick( replay.clickDetector, result as Breadcrumb & { timestamp: number; data: { nodeId: number } }, - getClickTargetNode(handlerData.event) as HTMLElement, + getClickTargetNode(handlerData.event as Event) as HTMLElement, ); } @@ -97,7 +97,7 @@ function getDomTarget(handlerData: HandlerDataDom): { target: Node | null; messa // Accessing event.target can throw (see getsentry/raven-js#838, #768) try { - target = isClick ? getClickTargetNode(handlerData.event) : getTargetNode(handlerData.event); + target = isClick ? getClickTargetNode(handlerData.event as Event) : getTargetNode(handlerData.event as Event); message = htmlTreeAsString(target, { maxStringLength: 200 }) || ''; } catch (e) { message = ''; diff --git a/packages/replay/src/coreHandlers/util/domUtils.ts b/packages/replay/src/coreHandlers/util/domUtils.ts index 83f34dc19f31..889ccd0c6052 100644 --- a/packages/replay/src/coreHandlers/util/domUtils.ts +++ b/packages/replay/src/coreHandlers/util/domUtils.ts @@ -1,5 +1,4 @@ import type { INode } from '@sentry-internal/rrweb-snapshot'; -import type { HandlerDataDom } from '@sentry/types'; const INTERACTIVE_SELECTOR = 'button,a'; @@ -15,7 +14,7 @@ export function getClosestInteractive(element: Element): Element { * This is useful because if you click on the image in , * The target will be the image, not the button, which we don't want here */ -export function getClickTargetNode(event: HandlerDataDom['event'] | MouseEvent | Node): Node | INode | null { +export function getClickTargetNode(event: Event | MouseEvent | Node): Node | INode | null { const target = getTargetNode(event); if (!target || !(target instanceof Element)) { diff --git a/packages/types/src/instrument.ts b/packages/types/src/instrument.ts index 16ec5a3b75b7..5c42c8cebf27 100644 --- a/packages/types/src/instrument.ts +++ b/packages/types/src/instrument.ts @@ -63,7 +63,8 @@ export interface HandlerDataFetch { } export interface HandlerDataDom { - event: Event | { target: EventTarget }; + // TODO: Replace `object` here with a vendored type for browser Events. We can't depend on the `DOM` or `react` TS types package here. + event: object | { target: object }; name: string; global?: boolean; } @@ -82,7 +83,8 @@ export interface HandlerDataError { column?: number; error?: Error; line?: number; - msg: string | Event; + // TODO: Replace `object` here with a vendored type for browser Events. We can't depend on the `DOM` or `react` TS types package here. + msg: string | object; url?: string; } diff --git a/packages/utils/src/instrument/dom.ts b/packages/utils/src/instrument/dom.ts index 71f64e43ebc5..aab64c8c149b 100644 --- a/packages/utils/src/instrument/dom.ts +++ b/packages/utils/src/instrument/dom.ts @@ -1,3 +1,5 @@ +// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages. + /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/ban-types */ import type { HandlerDataDom } from '@sentry/types'; diff --git a/packages/utils/src/instrument/history.ts b/packages/utils/src/instrument/history.ts index b13eabf99e3b..dc144c0e5818 100644 --- a/packages/utils/src/instrument/history.ts +++ b/packages/utils/src/instrument/history.ts @@ -1,3 +1,5 @@ +// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages. + /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/ban-types */ import type { HandlerDataHistory } from '@sentry/types'; diff --git a/packages/utils/src/instrument/index.ts b/packages/utils/src/instrument/index.ts index e74f6788f6e2..2e2255496dd2 100644 --- a/packages/utils/src/instrument/index.ts +++ b/packages/utils/src/instrument/index.ts @@ -1,3 +1,5 @@ +// TODO(v8): Consider moving this file (or at least parts of it) into the browser package. The registered handlers are mostly non-generic and we risk leaking runtime specific code into generic packages. + import { DEBUG_BUILD } from '../debug-build'; import type { InstrumentHandlerCallback as _InstrumentHandlerCallback, diff --git a/packages/utils/src/instrument/xhr.ts b/packages/utils/src/instrument/xhr.ts index d0245dcdd2ee..eb3ec8e158d5 100644 --- a/packages/utils/src/instrument/xhr.ts +++ b/packages/utils/src/instrument/xhr.ts @@ -1,3 +1,5 @@ +// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages. + /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/ban-types */ import type { HandlerDataXhr, SentryWrappedXMLHttpRequest, WrappedFunction } from '@sentry/types'; From 16e50374cc3c0aafad9ba326cb2c8e06a8151b50 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 28 Nov 2023 11:05:47 +0100 Subject: [PATCH 09/10] feat(astro): Add `assets` option to source maps upload options (#9668) Adds the `assets` option to the Astro integration source maps upload options. It behaves just like the `assets` option of the Vite plugin, taking a (array of) glob(s) and overriding the default values. This came up in #9591 and I think it makes sense to give users with more advanced/custom setups the ability to override our defaults. --- packages/astro/src/integration/index.ts | 6 ++-- packages/astro/src/integration/types.ts | 12 +++++++ packages/astro/test/integration/index.test.ts | 32 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index e844e383aaec..213fae64ed7a 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -42,7 +42,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN, telemetry: uploadOptions.telemetry ?? true, sourcemaps: { - assets: [getSourcemapsAssetsGlob(config)], + assets: uploadOptions.assets ?? [getSourcemapsAssetsGlob(config)], }, debug: options.debug ?? false, }), @@ -106,13 +106,13 @@ function getSourcemapsAssetsGlob(config: AstroConfig): string { // only copied over to /.vercel. This seems to happen too late though. // So we glob on both of these directories. // Another case of "it ain't pretty but it works":( - if (config.adapter && config.adapter.name?.startsWith('@astrojs/vercel')) { + if (config.adapter?.name?.startsWith('@astrojs/vercel')) { return '{.vercel,dist}/**/*'; } // paths are stored as "file://" URLs const outDirPathname = config.outDir && path.resolve(config.outDir.pathname); - const rootDirName = path.resolve((config.root && config.root.pathname) || process.cwd()); + const rootDirName = path.resolve(config.root?.pathname || process.cwd()); if (outDirPathname) { const relativePath = path.relative(rootDirName, outDirPathname); diff --git a/packages/astro/src/integration/types.ts b/packages/astro/src/integration/types.ts index 7d27402c5a45..8c069a2516a7 100644 --- a/packages/astro/src/integration/types.ts +++ b/packages/astro/src/integration/types.ts @@ -68,6 +68,18 @@ type SourceMapsOptions = { * @default true */ telemetry?: boolean; + + /** + * A glob or an array of globs that specify the build artifacts and source maps that will uploaded to Sentry. + * + * If this option is not specified, sensible defaults based on your `outDir`, `rootDir` and `adapter` + * config will be used. Use this option to override these defaults, for instance if you have a + * customized build setup that diverges from Astro's defaults. + * + * The globbing patterns must follow the implementation of the `glob` package. + * @see https://www.npmjs.com/package/glob#glob-primer + */ + assets?: string | Array; }; }; diff --git a/packages/astro/test/integration/index.test.ts b/packages/astro/test/integration/index.test.ts index fcf606c40e0b..7dba9a0ef347 100644 --- a/packages/astro/test/integration/index.test.ts +++ b/packages/astro/test/integration/index.test.ts @@ -110,6 +110,38 @@ describe('sentryAstro integration', () => { }); }); + it('prefers user-specified assets-globs over the default values', async () => { + const integration = sentryAstro({ + sourceMapsUploadOptions: { + enabled: true, + org: 'my-org', + project: 'my-project', + assets: ['dist/server/**/*, dist/client/**/*'], + }, + }); + // @ts-expect-error - the hook exists and we only need to pass what we actually use + await integration.hooks['astro:config:setup']({ + updateConfig, + injectScript, + // @ts-expect-error - only passing in partial config + config: { + outDir: new URL('file://path/to/project/build'), + }, + }); + + expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1); + expect(sentryVitePluginSpy).toHaveBeenCalledWith({ + authToken: 'my-token', + org: 'my-org', + project: 'my-project', + telemetry: true, + debug: false, + sourcemaps: { + assets: ['dist/server/**/*, dist/client/**/*'], + }, + }); + }); + it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => { const integration = sentryAstro({ sourceMapsUploadOptions: { enabled: false }, From ab318e5368c70e9481bca6ee98a2fb4a7a8bf488 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 28 Nov 2023 11:09:50 +0100 Subject: [PATCH 10/10] meta: Update Changelog for 7.83.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a29d239945b..03dadf042f89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 7.83.0 + +- chore(astro): Allow Astro 4.0 in peer dependencies (#9683) +- feat(astro): Add `assets` option to source maps upload options (#9668) +- feat(react): Support `exactOptionalPropertyTypes` on `ErrorBoundary` (#9098) +- fix: Don't depend on browser types in `types` (#9682) +- fix(astro): Configure sourcemap assets directory for Vercel adapter (#9665) +- fix(remix): Check the error data before spreading. (#9664) + ## 7.82.0 - feat(astro): Automatically add Sentry middleware in Astro integration (#9532)