diff --git a/.gitignore b/.gitignore index 73fc943c1152..3cc2319ea8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -57,5 +57,4 @@ packages/deno/build-test packages/deno/lib.deno.d.ts # gatsby -packages/gatsby/gatsby-browser.d.ts packages/gatsby/gatsby-node.d.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cbab31ee270..60fc8cfbb58f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,9 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott -## 8.0.0-alpha.6 +## 8.0.0-alpha.7 -This is the sixth alpha release of Sentry JavaScript SDK v8, which includes a variety of breaking changes. +This is the seventh alpha release of Sentry JavaScript SDK v8, which includes a variety of breaking changes. Read the [in-depth migration guide](./MIGRATION.md) to find out how to address any breaking changes in your code. @@ -16,6 +16,14 @@ Read the [in-depth migration guide](./MIGRATION.md) to find out how to address a We now use OpenTelemetry under the hood to power performance monitoring and tracing in the Next.js SDK. +- **feat(v8/gatsby): Update SDK initialization for gatsby (#11292)** + +In v8, you cannot initialize the SDK anymore via Gatsby plugin options. Instead, you have to configure the SDK in a +`sentry.config.js` file. + +We also removed the automatic initialization of `browserTracingIntegration`. You now have to add this integration +yourself. + ### Removal/Refactoring of deprecated functionality - feat(v8): Remove addGlobalEventProcessor (#11255) @@ -31,6 +39,7 @@ We now use OpenTelemetry under the hood to power performance monitoring and trac - ref(core): Remove `scope.setSpan()` and `scope.getSpan()` methods (#11051) - ref(profiling-node): Remove usage of getCurrentHub (#11275) - ref(v8): change integration.setupOnce signature (#11238) +- ref: remove node-experimental references (#11290) ### Other Changes @@ -49,6 +58,10 @@ We now use OpenTelemetry under the hood to power performance monitoring and trac - fix(node): Use `suppressTracing` to avoid capturing otel spans (#11288) - fix(opentelemetry): Do not stomp span status when `startSpan` callback throws (#11170) +## 8.0.0-alpha.6 + +This version did not publish correctly due to a configuration issue. + ## 8.0.0-alpha.5 This is the fifth alpha release of Sentry JavaScript SDK v8, which includes a variety of breaking changes. diff --git a/MIGRATION.md b/MIGRATION.md index 6a29b7122953..5a8f01c28875 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -39,7 +39,9 @@ New minimum supported browsers: For IE11 support please transpile your code to ES5 using babel or similar and add required polyfills. -**React**: We no longer support React 15 in version 8 of the React SDK. +**React**: The Next.js SDK now supports React 16+ + +**Next.js**: The Next.js SDK now supports Next.js 13.2.0+ ## 2. Package removal @@ -979,6 +981,118 @@ const config = { export default withSentryConfig(config); ``` +### Gatsby SDK + +#### Removal of Gatsby Initialization via plugin options + +In v8, we are removing the ability to initialize the Gatsby SDK via plugin options. Instead, you should create a +`sentry.config.js` file in the root of your project and initialize the SDK there. + +```js +// v7 - gatsby-config.js +module.exports = { + // ... + plugins: [ + { + resolve: '@sentry/gatsby', + options: { + dsn: process.env.SENTRY_DSN, + }, + }, + // ... + ], +}; +``` + +```js +// v8 - gatsby-config.js +module.exports = { + // ... + plugins: [ + { + resolve: '@sentry/gatsby', + }, + // ... + ], +}; + +// v8 - sentry.config.js +import * as Sentry from '@sentry/gatsby'; + +Sentry.init({ + dsn: '__PUBLIC_DSN__', +}); +``` + +We've also added `enableClientWebpackPlugin` which allows you to enable or disable the `@sentry/webpack-plugin` in the +client-side build. By default, it is enabled. + +```js +// v8 - gatsby-config.js +module.exports = { + // ... + plugins: [ + { + resolve: '@sentry/gatsby', + options: { + enableClientWebpackPlugin: false, + }, + }, + // ... + ], +}; +``` + +#### Automatic adding of `browserTracingIntegration` for Gatsby + +The Gatsby SDK no longer adds the `browserTracingIntegration` automatically. If you want to enable tracing in the +browser, you need to add it manually. Make sure to also configured a `tracePropagationTargets` value. + +```js +// v7 - gatsby-config.js +module.exports = { + // ... + plugins: [ + { + resolve: '@sentry/gatsby', + options: { + tracesSampleRate: 1.0, + }, + }, + // ... + ], +}; +``` + +```js +// v8 - gatsby-config.js +module.exports = { + // ... + plugins: [ + { + resolve: '@sentry/gatsby', + }, + // ... + ], +}; + +// v8 - sentry.config.js +import * as Sentry from '@sentry/gatsby'; + +Sentry.init({ + dsn: '__PUBLIC_DSN__', + integrations: [Sentry.browserTracingIntegration()], + + // Set tracesSampleRate to 1.0 to capture 100% + // of transactions for performance monitoring. + // We recommend adjusting this value in production + tracesSampleRate: 1.0, + + // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled + tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/], +}); +``` + ## 5. Behaviour Changes - [Updated behaviour of `tracePropagationTargets` in the browser](./MIGRATION.md#updated-behaviour-of-tracepropagationtargets-in-the-browser-http-tracing-headers--cors) diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/assert-build.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/assert-build.ts index b556662266f0..4412714740b0 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/assert-build.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/assert-build.ts @@ -31,8 +31,8 @@ const buildStderr = fs.readFileSync('.tmp_build_stderr', 'utf-8'); assert.match(buildStdout, /○ \/client-component/); assert.match(buildStdout, /● \/client-component\/parameter\/\[\.\.\.parameters\]/); assert.match(buildStdout, /● \/client-component\/parameter\/\[parameter\]/); -assert.match(buildStdout, /λ \/server-component/); -assert.match(buildStdout, /λ \/server-component\/parameter\/\[\.\.\.parameters\]/); -assert.match(buildStdout, /λ \/server-component\/parameter\/\[parameter\]/); +assert.match(buildStdout, /(λ|ƒ) \/server-component/); +assert.match(buildStdout, /(λ|ƒ) \/server-component\/parameter\/\[\.\.\.parameters\]/); +assert.match(buildStdout, /(λ|ƒ) \/server-component\/parameter\/\[parameter\]/); export {}; diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts index 7942b96b41b0..329ac33b7880 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/test/errors.client.test.ts @@ -6,15 +6,15 @@ test.describe('client-side errors', () => { test('captures error thrown on click', async ({ page }) => { await page.goto('/client-error'); - await expect(page.getByText('Client error')).toBeVisible(); - const errorEventPromise = waitForError('sveltekit-2', errorEvent => { return errorEvent?.exception?.values?.[0]?.value === 'Click Error'; }); - const clickPromise = page.getByText('Throw error').click(); + await page.getByText('Throw error').click(); + + await expect(errorEventPromise).resolves.toBeDefined(); - const [errorEvent, _] = await Promise.all([errorEventPromise, clickPromise]); + const errorEvent = await errorEventPromise; const errorEventFrames = errorEvent.exception?.values?.[0]?.stacktrace?.frames; diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.client.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.client.test.ts index 7cd1a545165b..ee366338391d 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit/test/errors.client.test.ts @@ -6,15 +6,15 @@ test.describe('client-side errors', () => { test('captures error thrown on click', async ({ page }) => { await page.goto('/client-error'); - await expect(page.getByText('Client error')).toBeVisible(); - const errorEventPromise = waitForError('sveltekit', errorEvent => { return errorEvent?.exception?.values?.[0]?.value === 'Click Error'; }); - const clickPromise = page.getByText('Throw error').click(); + await page.getByText('Throw error').click(); + + await expect(errorEventPromise).resolves.toBeDefined(); - const [errorEvent, _] = await Promise.all([errorEventPromise, clickPromise]); + const errorEvent = await errorEventPromise; const errorEventFrames = errorEvent.exception?.values?.[0]?.stacktrace?.frames; diff --git a/packages/bun/src/sdk.ts b/packages/bun/src/sdk.ts index 51099eb814b2..e9aabf5dae79 100644 --- a/packages/bun/src/sdk.ts +++ b/packages/bun/src/sdk.ts @@ -66,7 +66,7 @@ export function getDefaultIntegrations(_options: Options): Integration[] { * @example * ``` * - * const { addBreadcrumb } = require('@sentry/node-experimental'); + * const { addBreadcrumb } = require('@sentry/node'); * addBreadcrumb({ * message: 'My Breadcrumb', * // ... @@ -76,7 +76,7 @@ export function getDefaultIntegrations(_options: Options): Integration[] { * @example * ``` * - * const Sentry = require('@sentry/node-experimental'); + * const Sentry = require('@sentry/node'); * Sentry.captureMessage('Hello, world!'); * Sentry.captureException(new Error('Good bye')); * Sentry.captureEvent({ diff --git a/packages/gatsby/.eslintrc.js b/packages/gatsby/.eslintrc.js index e4856316be0e..ee0716e6ec2a 100644 --- a/packages/gatsby/.eslintrc.js +++ b/packages/gatsby/.eslintrc.js @@ -7,7 +7,7 @@ module.exports = { jsx: true, }, // ignore these because they're not covered by a `tsconfig`, which makes eslint throw an error - ignorePatterns: ['gatsby-browser.d.ts', 'gatsby-node.d.ts'], + ignorePatterns: ['gatsby-node.d.ts'], overrides: [ { files: ['scripts/**/*.ts'], @@ -15,16 +15,6 @@ module.exports = { project: ['../../tsconfig.dev.json'], }, }, - { - files: ['./gatsby-browser.js'], - env: { - browser: true, - node: false, - }, - parserOptions: { - sourceType: 'module', - }, - }, ], extends: ['../../.eslintrc.js'], }; diff --git a/packages/gatsby/README.md b/packages/gatsby/README.md index b87b99c365c1..5de12ed78410 100644 --- a/packages/gatsby/README.md +++ b/packages/gatsby/README.md @@ -6,7 +6,7 @@ # Official Sentry SDK for GatsbyJS -Register the package as a plugin in `gatsby-config.js`: +First register the package as a plugin in `gatsby-config.js`: ```javascript module.exports = { @@ -23,66 +23,32 @@ module.exports = { }; ``` -Options will be passed directly to `Sentry.init`. See all available options in -[our docs](https://docs.sentry.io/error-reporting/configuration/?platform=javascript). The `environment` value defaults -to `NODE_ENV` (or `'development'` if `NODE_ENV` is not set). - -## GitHub Actions - -The `release` value is inferred from `GITHUB_SHA`. - -## Netlify - -The `release` value is inferred from `COMMIT_REF`. - -## Vercel - -To automatically capture the `release` value on Vercel you will need to register appropriate -[system environment variable](https://vercel.com/docs/v2/build-step#system-environment-variables) (e.g. -`VERCEL_GITHUB_COMMIT_SHA`) in your project. - -## Sentry Performance - -To enable tracing, supply either `tracesSampleRate` or `tracesSampler` to the options. This will turn on the -`BrowserTracing` integration for automatic instrumentation of pageloads and navigations. +Then configure your `Sentry.init` call: ```javascript -module.exports = { - // ... - plugins: [ - { - resolve: '@sentry/gatsby', - options: { - dsn: process.env.SENTRY_DSN, // this is the default +import * as Sentry from '@sentry/gatsby'; - // A rate of 1 means all traces will be sent, so it's good for testing. - // In production, you'll likely want to either choose a lower rate or use `tracesSampler` instead (see below). - tracesSampleRate: 1, +Sentry.init({ + dsn: '__PUBLIC_DSN__', + integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()], - // Alternatively: - tracesSampler: samplingContext => { - // Examine provided context data (along with anything in the global namespace) to decide the sample rate - // for this transaction. - // Can return 0 to drop the transaction entirely. + // Set tracesSampleRate to 1.0 to capture 100% + // of transactions for performance monitoring. + // We recommend adjusting this value in production + tracesSampleRate: 1.0, - if ('...') { - return 0.5; // These are important - take a big sample - } else if ('...') { - return 0.01; // These are less important or happen much more frequently - only take 1% of them - } else if ('...') { - return 0; // These aren't something worth tracking - drop all transactions like this - } else { - return 0.1; // Default sample rate - } - }, - }, - }, - // ... - ], -}; + // Capture Replay for 10% of all sessions, + // plus for 100% of sessions with an error + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + + // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled + tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/], +}); ``` -If you want to supply options to the `BrowserTracing` integration, use the `browserTracingOptions` parameter. +The Gatsby SDK also automatically sets up sourcemaps uploading for you. To disable this functionality, set the +`enableClientWebpackPlugin` option to be `false`. ```javascript module.exports = { @@ -91,12 +57,7 @@ module.exports = { { resolve: '@sentry/gatsby', options: { - dsn: process.env.SENTRY_DSN, // this is the default - tracesSampleRate: 1, // or tracesSampler (see above) - browserTracingOptions: { - // disable creating spans for XHR requests - traceXHR: false, - }, + enableClientWebpackPlugin: false, }, }, // ... diff --git a/packages/gatsby/gatsby-browser.js b/packages/gatsby/gatsby-browser.js deleted file mode 100644 index 98621dbb43e9..000000000000 --- a/packages/gatsby/gatsby-browser.js +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable no-console */ -import { getClient, init } from '@sentry/gatsby'; - -export function onClientEntry(_, pluginParams) { - const isIntialized = isSentryInitialized(); - const areOptionsDefined = areSentryOptionsDefined(pluginParams); - - if (isIntialized) { - if (areOptionsDefined) { - console.warn( - 'Sentry Logger [Warn]: The SDK was initialized in the Sentry config file, but options were found in the Gatsby config. ' + - 'These have been ignored. Merge them to the Sentry config if you want to use them.\n' + - 'Learn more about the Gatsby SDK in https://docs.sentry.io/platforms/javascript/guides/gatsby/.', - ); - } - return; - } - - if (!areOptionsDefined) { - console.error( - 'Sentry Logger [Error]: No config for the Gatsby SDK was found.\n' + - 'Learn how to configure it in https://docs.sentry.io/platforms/javascript/guides/gatsby/.', - ); - return; - } - - init({ - // eslint-disable-next-line no-undef - dsn: __SENTRY_DSN__, - ...pluginParams, - }); -} - -function isSentryInitialized() { - return !!getClient(); -} - -function areSentryOptionsDefined(params) { - if (params == undefined) return false; - // Even if there aren't any options, there's a `plugins` property defined as an empty array - if (Object.keys(params).length == 1 && Array.isArray(params.plugins) && params.plugins.length == 0) { - return false; - } - return true; -} diff --git a/packages/gatsby/gatsby-node.js b/packages/gatsby/gatsby-node.js index 460e338de991..d60914a03061 100644 --- a/packages/gatsby/gatsby-node.js +++ b/packages/gatsby/gatsby-node.js @@ -1,48 +1,25 @@ const fs = require('fs'); -const SentryWebpackPlugin = require('@sentry/webpack-plugin'); +const { sentryWebpackPlugin } = require('@sentry/webpack-plugin'); -const sentryRelease = JSON.stringify( - // Always read first as Sentry takes this as precedence - process.env.SENTRY_RELEASE || - // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables - process.env.GITHUB_SHA || - // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata - process.env.COMMIT_REF || - // Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables - process.env.VERCEL_GIT_COMMIT_SHA || - // Zeit (now known as Vercel) - process.env.ZEIT_GITHUB_COMMIT_SHA || - process.env.ZEIT_GITLAB_COMMIT_SHA || - process.env.ZEIT_BITBUCKET_COMMIT_SHA || - undefined, -); - -const sentryDsn = JSON.stringify(process.env.SENTRY_DSN || ''); const SENTRY_USER_CONFIG = ['./sentry.config.js', './sentry.config.ts']; -exports.onCreateWebpackConfig = ({ plugins, getConfig, actions }) => { - actions.setWebpackConfig({ - plugins: [ - plugins.define({ - __SENTRY_RELEASE__: sentryRelease, - __SENTRY_DSN__: sentryDsn, - }), - ], - }); - - if (process.env.NODE_ENV === 'production') { +exports.onCreateWebpackConfig = ({ getConfig, actions }, options) => { + const enableClientWebpackPlugin = options.enableClientWebpackPlugin !== false; + if (process.env.NODE_ENV === 'production' && enableClientWebpackPlugin) { actions.setWebpackConfig({ plugins: [ - new SentryWebpackPlugin({ - // Only include files from the build output directory - include: 'public', - // Ignore files that aren't users' source code related - ignore: [ - 'polyfill-*', // related to polyfills - 'framework-*', // related to the frameworks (e.g. React) - 'webpack-runtime-*', // related to Webpack - ], + sentryWebpackPlugin({ + sourcemaps: { + // Only include files from the build output directory + assets: ['public'], + // Ignore files that aren't users' source code related + ignore: [ + 'polyfill-*', // related to polyfills + 'framework-*', // related to the frameworks (e.g. React) + 'webpack-runtime-*', // related to Webpack + ], + }, // Handle sentry-cli configuration errors when the user has not done it not to break // the build. errorHandler(err, invokeErr) { diff --git a/packages/gatsby/jest.config.js b/packages/gatsby/jest.config.js index 9a27709769d4..3770aa5b0db2 100644 --- a/packages/gatsby/jest.config.js +++ b/packages/gatsby/jest.config.js @@ -2,7 +2,6 @@ const baseConfig = require('../../jest/jest.config.js'); module.exports = { ...baseConfig, - setupFiles: ['/test/setEnvVars.ts'], testEnvironment: 'jsdom', transform: { '^.+\\.js$': 'ts-jest', diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index f17b00c8ec6f..13fff47e3b47 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -18,9 +18,7 @@ "esm", "types", "types-ts3.8", - "gatsby-browser.js", "gatsby-node.js", - "gatsby-browser.d.ts", "gatsby-node.d.ts" ], "main": "build/cjs/index.js", @@ -54,7 +52,7 @@ "@sentry/react": "8.0.0-alpha.5", "@sentry/types": "8.0.0-alpha.5", "@sentry/utils": "8.0.0-alpha.5", - "@sentry/webpack-plugin": "1.19.0" + "@sentry/webpack-plugin": "2.16.0" }, "peerDependencies": { "gatsby": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", diff --git a/packages/gatsby/scripts/prepack.ts b/packages/gatsby/scripts/prepack.ts index c103875f93d3..f6bf056fcfa3 100644 --- a/packages/gatsby/scripts/prepack.ts +++ b/packages/gatsby/scripts/prepack.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import * as path from 'path'; -const PACKAGE_ASSETS = ['gatsby-browser.js', 'gatsby-browser.d.ts', 'gatsby-node.js', 'gatsby-node.d.ts']; +const PACKAGE_ASSETS = ['gatsby-node.js', 'gatsby-node.d.ts']; export function prepack(buildDir: string): boolean { // copy package-specific assets to build dir diff --git a/packages/gatsby/scripts/pretest.ts b/packages/gatsby/scripts/pretest.ts index 834301f7c38a..bc64e0478b2f 100644 --- a/packages/gatsby/scripts/pretest.ts +++ b/packages/gatsby/scripts/pretest.ts @@ -2,7 +2,7 @@ import { execSync } from 'child_process'; import * as fs from 'fs'; function ensurePluginTypes(): void { - if (!fs.existsSync('gatsby-browser.d.ts') || !fs.existsSync('gatsby-node.d.ts')) { + if (!fs.existsSync('gatsby-node.d.ts')) { // eslint-disable-next-line no-console console.warn( '\nWARNING: Missing types for gatsby plugin files. Types will be created before running gatsby tests.', diff --git a/packages/gatsby/src/sdk.ts b/packages/gatsby/src/sdk.ts index d615daa8682a..48dfd5bb0b31 100644 --- a/packages/gatsby/src/sdk.ts +++ b/packages/gatsby/src/sdk.ts @@ -1,7 +1,6 @@ import { applySdkMetadata } from '@sentry/core'; import { init as reactInit } from '@sentry/react'; -import { getIntegrationsFromOptions } from './utils/integrations'; import type { GatsbyOptions } from './utils/types'; /** @@ -9,9 +8,7 @@ import type { GatsbyOptions } from './utils/types'; */ export function init(options: GatsbyOptions): void { applySdkMetadata(options, 'gatsby'); - const integrations = getIntegrationsFromOptions(options); reactInit({ ...options, - integrations, }); } diff --git a/packages/gatsby/src/utils/integrations.ts b/packages/gatsby/src/utils/integrations.ts deleted file mode 100644 index 7c61adee1d50..000000000000 --- a/packages/gatsby/src/utils/integrations.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { hasTracingEnabled } from '@sentry/core'; -import { browserTracingIntegration } from '@sentry/react'; -import type { Integration } from '@sentry/types'; - -import type { GatsbyOptions } from './types'; - -type UserFnIntegrations = (integrations: Integration[]) => Integration[]; -export type UserIntegrations = Integration[] | UserFnIntegrations; - -/** - * Returns the integrations to add to the SDK. - * If tracing is enabled, `BrowserTracing` is always present. - * - * @param options The options users have defined. - */ -export function getIntegrationsFromOptions(options: GatsbyOptions): UserIntegrations { - const isTracingEnabled = hasTracingEnabled(options); - if (options.integrations === undefined) { - return getIntegrationsFromArray([], isTracingEnabled); - } else if (Array.isArray(options.integrations)) { - return getIntegrationsFromArray(options.integrations, isTracingEnabled); - } else { - return getIntegrationsFromFunction(options.integrations, isTracingEnabled); - } -} - -/** - * Returns the integrations to add to the SDK, from the given integrations array. - * - * @param userIntegrations Array of user's integrations. - * @param isTracingEnabled Whether the user has enabled tracing. - */ -function getIntegrationsFromArray(userIntegrations: Integration[], isTracingEnabled: boolean): Integration[] { - if (isTracingEnabled && !userIntegrations.some(integration => integration.name === 'BrowserTracing')) { - userIntegrations.push(browserTracingIntegration()); - } - return userIntegrations; -} - -/** - * Returns the integrations to add to the SDK, from the given function. - * - * @param userIntegrations Function returning the user's integrations. - * @param isTracingEnabled Whether the user has enabled tracing. - */ -function getIntegrationsFromFunction( - userIntegrations: UserFnIntegrations, - isTracingEnabled: boolean, -): UserFnIntegrations { - const wrapper: UserFnIntegrations = (defaultIntegrations: Integration[]) => { - return getIntegrationsFromArray(userIntegrations(defaultIntegrations), isTracingEnabled); - }; - return wrapper; -} diff --git a/packages/gatsby/test/gatsby-browser.test.ts b/packages/gatsby/test/gatsby-browser.test.ts deleted file mode 100644 index 117de1cdd0ec..000000000000 --- a/packages/gatsby/test/gatsby-browser.test.ts +++ /dev/null @@ -1,157 +0,0 @@ -import type { Client } from '@sentry/types'; -import { onClientEntry } from '../gatsby-browser'; -import { browserTracingIntegration, getCurrentScope, getIsolationScope, setCurrentClient } from '../src/index'; - -(global as any).__SENTRY_RELEASE__ = '683f3a6ab819d47d23abfca9a914c81f0524d35b'; -(global as any).__SENTRY_DSN__ = 'https://examplePublicKey@o0.ingest.sentry.io/0'; - -let sentryInit = jest.fn(); -jest.mock('@sentry/gatsby', () => { - const original = jest.requireActual('@sentry/gatsby'); - return { - ...original, - init: (...args: any[]) => { - sentryInit(...args); - }, - }; -}); -global.console.warn = jest.fn(); -global.console.error = jest.fn(); - -let tracingAddExtensionMethods = jest.fn(); -jest.mock('@sentry/core', () => { - const original = jest.requireActual('@sentry/core'); - return { - ...original, - addTracingExtensions: (...args: any[]) => { - tracingAddExtensionMethods(...args); - }, - }; -}); - -describe('onClientEntry', () => { - beforeEach(() => { - sentryInit = jest.fn(); - tracingAddExtensionMethods = jest.fn(); - }); - - it.each([ - [{}, ['dsn']], - [{ key: 'value' }, ['dsn', 'key']], - ])('inits Sentry by default', (pluginParams, expectedKeys) => { - onClientEntry(undefined, pluginParams); - expect(sentryInit).toHaveBeenCalledTimes(1); - const calledWith = sentryInit.mock.calls[0][0]; - for (const key of expectedKeys) { - expect(calledWith[key]).toBeDefined(); - } - }); - - describe('inits Sentry once', () => { - beforeEach(() => { - getCurrentScope().clear(); - getIsolationScope().clear(); - getCurrentScope().setClient(undefined); - }); - - afterEach(() => { - (global.console.warn as jest.Mock).mockClear(); - (global.console.error as jest.Mock).mockClear(); - }); - - it('initialized in injected config, without pluginParams', () => { - const client = {} as Client; - setCurrentClient(client); - - onClientEntry(undefined, { plugins: [] }); - // eslint-disable-next-line no-console - expect(console.warn).not.toHaveBeenCalled(); - // eslint-disable-next-line no-console - expect(console.error).not.toHaveBeenCalled(); - expect(sentryInit).not.toHaveBeenCalled(); - }); - - it('initialized in injected config, with pluginParams', () => { - const client = {} as Client; - setCurrentClient(client); - - onClientEntry(undefined, { plugins: [], dsn: 'dsn', release: 'release' }); - // eslint-disable-next-line no-console - expect((console.warn as jest.Mock).mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "Sentry Logger [Warn]: The SDK was initialized in the Sentry config file, but options were found in the Gatsby config. These have been ignored. Merge them to the Sentry config if you want to use them. - Learn more about the Gatsby SDK in https://docs.sentry.io/platforms/javascript/guides/gatsby/.", - ] - `); - // eslint-disable-next-line no-console - expect(console.error).not.toHaveBeenCalled(); - expect(sentryInit).not.toHaveBeenCalled(); - }); - - it('not initialized in injected config, without pluginParams', () => { - onClientEntry(undefined, { plugins: [] }); - // eslint-disable-next-line no-console - expect(console.warn).not.toHaveBeenCalled(); - // eslint-disable-next-line no-console - expect((console.error as jest.Mock).mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "Sentry Logger [Error]: No config for the Gatsby SDK was found. - Learn how to configure it in https://docs.sentry.io/platforms/javascript/guides/gatsby/.", - ] - `); - }); - - it('not initialized in injected config, with pluginParams', () => { - onClientEntry(undefined, { plugins: [], dsn: 'dsn', release: 'release' }); - // eslint-disable-next-line no-console - expect(console.warn).not.toHaveBeenCalled(); - // eslint-disable-next-line no-console - expect(console.error).not.toHaveBeenCalled(); - expect(sentryInit).toHaveBeenCalledTimes(1); - expect(sentryInit.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "dsn": "dsn", - "plugins": Array [], - "release": "release", - } - `); - }); - }); - - it('sets a tracesSampleRate if defined as option', () => { - onClientEntry(undefined, { tracesSampleRate: 0.5 }); - expect(sentryInit).toHaveBeenLastCalledWith( - expect.objectContaining({ - tracesSampleRate: 0.5, - }), - ); - }); - - it('sets a tracesSampler if defined as option', () => { - const tracesSampler = jest.fn(); - onClientEntry(undefined, { tracesSampler }); - expect(sentryInit).toHaveBeenLastCalledWith( - expect.objectContaining({ - tracesSampler, - }), - ); - }); - - it('only defines a single `BrowserTracing` integration', () => { - const integrations = [browserTracingIntegration()]; - onClientEntry(undefined, { tracesSampleRate: 0.5, integrations }); - - expect(sentryInit).toHaveBeenLastCalledWith( - expect.objectContaining({ - integrations: [expect.objectContaining({ name: 'BrowserTracing' })], - }), - ); - }); - - // Run this last to check for any test side effects - it('does not run if plugin params are undefined', () => { - onClientEntry(undefined, undefined); - expect(sentryInit).toHaveBeenCalledTimes(0); - expect(tracingAddExtensionMethods).toHaveBeenCalledTimes(0); - }); -}); diff --git a/packages/gatsby/test/gatsby-node.test.ts b/packages/gatsby/test/gatsby-node.test.ts index 8880c133b90d..2e80ac03dcaa 100644 --- a/packages/gatsby/test/gatsby-node.test.ts +++ b/packages/gatsby/test/gatsby-node.test.ts @@ -1,28 +1,39 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { onCreateWebpackConfig } from '../gatsby-node'; describe('onCreateWebpackConfig', () => { - it('sets a webpack config', () => { - const plugins = { - define: jest.fn(), - }; + let originalNodeEnv: string | undefined; + beforeAll(() => { + originalNodeEnv = process.env.NODE_ENV; + process.env.NODE_ENV = 'production'; + }); + + afterAll(() => { + process.env.NODE_ENV = originalNodeEnv; + }); + + it('sets a webpack config', () => { const actions = { setWebpackConfig: jest.fn(), }; const getConfig = jest.fn(); - onCreateWebpackConfig({ plugins, actions, getConfig }); - - expect(plugins.define).toHaveBeenCalledTimes(1); - expect(plugins.define).toHaveBeenLastCalledWith({ - __SENTRY_DSN__: expect.any(String), - __SENTRY_RELEASE__: expect.any(String), - }); + onCreateWebpackConfig({ actions, getConfig }, {}); expect(actions.setWebpackConfig).toHaveBeenCalledTimes(1); expect(actions.setWebpackConfig).toHaveBeenLastCalledWith({ plugins: expect.any(Array) }); }); + + it('does not set a webpack config if enableClientWebpackPlugin is false', () => { + const actions = { + setWebpackConfig: jest.fn(), + }; + + const getConfig = jest.fn(); + + onCreateWebpackConfig({ actions, getConfig }, { enableClientWebpackPlugin: false }); + + expect(actions.setWebpackConfig).toHaveBeenCalledTimes(0); + }); }); diff --git a/packages/gatsby/test/integration.test.tsx b/packages/gatsby/test/integration.test.tsx deleted file mode 100644 index dbe10d9a3fbb..000000000000 --- a/packages/gatsby/test/integration.test.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { TextDecoder, TextEncoder } from 'util'; -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { render } from '@testing-library/react'; -import { useEffect } from 'react'; -// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX -import * as React from 'react'; - -import { onClientEntry } from '../gatsby-browser'; -import * as Sentry from '../src'; - -beforeAll(() => { - (global as any).__SENTRY_RELEASE__ = '683f3a6ab819d47d23abfca9a914c81f0524d35b'; - (global as any).__SENTRY_DSN__ = 'https://examplePublicKey@o0.ingest.sentry.io/0'; - (global as any).TextEncoder = TextEncoder; - (global as any).TextDecoder = TextDecoder; -}); - -describe('useEffect', () => { - it('captures error in use effect', () => { - let calls = 0; - - onClientEntry(undefined, { - beforeSend: (event: any) => { - expect(event).not.toBeUndefined(); - calls++; - - return null; - }, - }); - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function TestComponent() { - useEffect(() => { - const error = new Error('testing 123'); - Sentry.captureException(error); - }); - - return
Hello
; - } - - render(); - - expect(calls).toBe(1); - }); -}); diff --git a/packages/gatsby/test/sdk.test.ts b/packages/gatsby/test/sdk.test.ts index 7abdc82c6834..bbb77abf5af8 100644 --- a/packages/gatsby/test/sdk.test.ts +++ b/packages/gatsby/test/sdk.test.ts @@ -1,9 +1,6 @@ -import { SDK_VERSION, browserTracingIntegration, init } from '@sentry/react'; -import type { Integration } from '@sentry/types'; +import { SDK_VERSION, init } from '@sentry/react'; import { init as gatsbyInit } from '../src/sdk'; -import type { UserIntegrations } from '../src/utils/integrations'; -import type { GatsbyOptions } from '../src/utils/types'; jest.mock('@sentry/react', () => { const actual = jest.requireActual('@sentry/react'); @@ -47,58 +44,4 @@ describe('Initialize React SDK', () => { expect(callingObject.environment).toStrictEqual('custom env!'); }); }); - - test('Has browserTracingIntegration if tracing enabled', () => { - gatsbyInit({ tracesSampleRate: 1 }); - expect(reactInit).toHaveBeenCalledTimes(1); - const calledWith = reactInit.mock.calls[0][0]; - const integrationNames: string[] = calledWith.integrations.map((integration: Integration) => integration.name); - expect(integrationNames.some(name => name === 'BrowserTracing')).toBe(true); - }); -}); - -type TestArgs = [string, Integration[], GatsbyOptions, string[]]; - -describe('Integrations from options', () => { - afterEach(() => reactInit.mockClear()); - - test.each([ - ['tracing disabled, no integrations', [], {}, []], - ['tracing enabled, no integrations', [], { tracesSampleRate: 1 }, ['BrowserTracing']], - [ - 'tracing disabled, with browserTracingIntegration as an array', - [], - { integrations: [browserTracingIntegration()] }, - ['BrowserTracing'], - ], - [ - 'tracing disabled, with browserTracingIntegration as a function', - [], - { - integrations: () => [browserTracingIntegration()], - }, - ['BrowserTracing'], - ], - [ - 'tracing enabled, with browserTracingIntegration as an array', - [], - { tracesSampleRate: 1, integrations: [browserTracingIntegration()] }, - ['BrowserTracing'], - ], - [ - 'tracing enabled, with browserTracingIntegration as a function', - [], - { tracesSampleRate: 1, integrations: () => [browserTracingIntegration()] }, - ['BrowserTracing'], - ], - ] as TestArgs[])( - '%s', - (_testName, defaultIntegrations: Integration[], options: GatsbyOptions, expectedIntNames: string[]) => { - gatsbyInit(options); - const integrations: UserIntegrations = reactInit.mock.calls[0][0].integrations; - const arrIntegrations = Array.isArray(integrations) ? integrations : integrations(defaultIntegrations); - expect(arrIntegrations).toHaveLength(expectedIntNames.length); - arrIntegrations.map((integration, idx) => expect(integration.name).toStrictEqual(expectedIntNames[idx])); - }, - ); }); diff --git a/packages/gatsby/test/setEnvVars.ts b/packages/gatsby/test/setEnvVars.ts deleted file mode 100644 index bc9d45b9c84a..000000000000 --- a/packages/gatsby/test/setEnvVars.ts +++ /dev/null @@ -1,6 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access -process.env.SENTRY_RELEASE = '14abbb1678a2eb59d1a171ea33d630dd6c6eee70'; - -// This file needs to have an import or an export to count as a module, which is necessary when using -// the `isolatedModules` tsconfig option. -export const _ = ''; diff --git a/packages/gatsby/tsconfig.plugin.json b/packages/gatsby/tsconfig.plugin.json index 8a755642dd8b..88724d075f48 100644 --- a/packages/gatsby/tsconfig.plugin.json +++ b/packages/gatsby/tsconfig.plugin.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", - "include": ["gatsby-browser.js", "gatsby-node.js"], + "include": ["gatsby-node.js"], "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used diff --git a/packages/gatsby/tsconfig.test.json b/packages/gatsby/tsconfig.test.json index 0ac551ca12df..9d57a32062ed 100644 --- a/packages/gatsby/tsconfig.test.json +++ b/packages/gatsby/tsconfig.test.json @@ -9,7 +9,7 @@ // other package-specific, test-specific options - // Needed to parse ESM from gatsby-browser.js + // Needed to parse ESM from gatsby js files "allowJs": true } } diff --git a/packages/google-cloud-serverless/test/integrations/google-cloud-http.test.ts b/packages/google-cloud-serverless/test/integrations/google-cloud-http.test.ts index 5d90077df1fd..ca26d1069379 100644 --- a/packages/google-cloud-serverless/test/integrations/google-cloud-http.test.ts +++ b/packages/google-cloud-serverless/test/integrations/google-cloud-http.test.ts @@ -4,7 +4,7 @@ import { BigQuery } from '@google-cloud/bigquery'; import * as nock from 'nock'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; -import { NodeClient, createTransport, setCurrentClient } from '@sentry/node-experimental'; +import { NodeClient, createTransport, setCurrentClient } from '@sentry/node'; import { googleCloudHttpIntegration } from '../../src/integrations/google-cloud-http'; const mockSpanEnd = jest.fn(); diff --git a/packages/replay-internal/package.json b/packages/replay-internal/package.json index 8a94e8ecd35c..af55896a3198 100644 --- a/packages/replay-internal/package.json +++ b/packages/replay-internal/package.json @@ -32,6 +32,9 @@ "types-ts3.8" ], "sideEffects": false, + "publishConfig": { + "access": "public" + }, "scripts": { "build": "run-p build:transpile build:types build:bundle", "build:transpile": "rollup -c rollup.npm.config.mjs", diff --git a/yarn.lock b/yarn.lock index c3680ee0130b..a855ba24ac3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5731,18 +5731,6 @@ resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.30.2.tgz#1e84df37e9f0e5743b42435f92982cf7dae5e6d8" integrity sha512-gF9wSZxzXFgakkC+uKVLAAYlbYj13e1gTsNm3gm+ODfpV+rbHwvbKoLfNsbVCFVCEZxIV2rXEP5WmTr0kiMvWQ== -"@sentry/cli@^1.74.4": - version "1.77.1" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.77.1.tgz#ebcf884712ef6c3c75443f491ec16f6a22148aec" - integrity sha512-OtJ7U9LeuPUAY/xow9wwcjM9w42IJIpDtClTKI/RliE685vd/OJUIpiAvebHNthDYpQynvwb/0iuF4fonh+CKw== - dependencies: - https-proxy-agent "^5.0.0" - mkdirp "^0.5.5" - node-fetch "^2.6.7" - progress "^2.0.3" - proxy-from-env "^1.1.0" - which "^2.0.2" - "@sentry/cli@^2.22.3", "@sentry/cli@^2.30.2": version "2.30.2" resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.30.2.tgz#5f62ec56685808875577792dfdc7de1d047905a8" @@ -5770,13 +5758,6 @@ "@sentry/bundler-plugin-core" "2.14.2" unplugin "1.0.1" -"@sentry/webpack-plugin@1.19.0": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.19.0.tgz#2b134318f1552ba7f3e3f9c83c71a202095f7a44" - integrity sha512-qSpdgdGMtdzagGveSWgo2b+t8PdPUscuOjbOyWCsJme9jlTFnNk0rX7JEA55OUozikKHM/+vVh08USLBnPboZw== - dependencies: - "@sentry/cli" "^1.74.4" - "@sentry/webpack-plugin@2.16.0": version "2.16.0" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-2.16.0.tgz#4764577edb10c9575a8b4ce03135493f995f56b9"