diff --git a/.craft.yml b/.craft.yml index 99efaf3d095e..f795d317b05e 100644 --- a/.craft.yml +++ b/.craft.yml @@ -132,9 +132,6 @@ targets: includeNames: /^sentry-internal-eslint-config-sdk-\d.*\.tgz$/ ## 8. Deprecated packages we still release (but no packages depend on them anymore) - - name: npm - id: '@sentry/hub' - includeNames: /^sentry-hub-\d.*\.tgz$/ - name: npm id: '@sentry/tracing' includeNames: /^sentry-tracing-\d.*\.tgz$/ diff --git a/dev-packages/browser-integration-tests/utils/generatePlugin.ts b/dev-packages/browser-integration-tests/utils/generatePlugin.ts index cf2816ab0033..fe583e271ca3 100644 --- a/dev-packages/browser-integration-tests/utils/generatePlugin.ts +++ b/dev-packages/browser-integration-tests/utils/generatePlugin.ts @@ -115,7 +115,7 @@ export const LOADER_CONFIGS: Record; * When using compiled versions of the tracing and browser packages, their aliases look for example like * '@sentry/browser': 'path/to/sentry-javascript/packages/browser/esm/index.js' * and all other monorepo packages' aliases look for example like - * '@sentry/hub': 'path/to/sentry-javascript/packages/hub' + * '@sentry/react': 'path/to/sentry-javascript/packages/react' * * When using bundled versions of the tracing and browser packages, all aliases look for example like * '@sentry/browser': false diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts index 46c0608d641d..3ec4677b17bc 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts @@ -3,8 +3,6 @@ import * as _SentryBrowser from '@sentry/browser'; // biome-ignore lint/nursery/noUnusedImports: import * as _SentryCore from '@sentry/core'; // biome-ignore lint/nursery/noUnusedImports: -import * as _SentryHub from '@sentry/hub'; -// biome-ignore lint/nursery/noUnusedImports: import * as _SentryIntegrations from '@sentry/integrations'; // biome-ignore lint/nursery/noUnusedImports: import * as _SentryNode from '@sentry/node'; diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json index dd4a2b22544d..919d2fb99e84 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json @@ -15,7 +15,6 @@ "dependencies": { "@sentry/browser": "latest || *", "@sentry/core": "latest || *", - "@sentry/hub": "latest || *", "@sentry/integrations": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry-node": "latest || *", diff --git a/dev-packages/e2e-tests/verdaccio-config/config.yaml b/dev-packages/e2e-tests/verdaccio-config/config.yaml index 2ed138f1cdcc..143596b74849 100644 --- a/dev-packages/e2e-tests/verdaccio-config/config.yaml +++ b/dev-packages/e2e-tests/verdaccio-config/config.yaml @@ -86,12 +86,6 @@ packages: unpublish: $all # proxy: npmjs # Don't proxy for E2E tests! - '@sentry/hub': - access: $all - publish: $all - unpublish: $all - # proxy: npmjs # Don't proxy for E2E tests! - '@sentry/integrations': access: $all publish: $all diff --git a/dev-packages/rollup-utils/plugins/bundlePlugins.mjs b/dev-packages/rollup-utils/plugins/bundlePlugins.mjs index e2a96c9697de..1df1e2ac917d 100644 --- a/dev-packages/rollup-utils/plugins/bundlePlugins.mjs +++ b/dev-packages/rollup-utils/plugins/bundlePlugins.mjs @@ -157,7 +157,6 @@ export function makeTSPlugin(jsVersion) { paths: { '@sentry/browser': ['../browser/src'], '@sentry/core': ['../core/src'], - '@sentry/hub': ['../hub/src'], '@sentry/types': ['../types/src'], '@sentry/utils': ['../utils/src'], '@sentry-internal/integration-shims': ['../integration-shims/src'], diff --git a/package.json b/package.json index 9ecacd34c252..74fbfe2a650f 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "packages/eslint-plugin-sdk", "packages/feedback", "packages/gatsby", - "packages/hub", "packages/integrations", "packages/integration-shims", "packages/nextjs", diff --git a/packages/core/test/lib/exports.test.ts b/packages/core/test/lib/exports.test.ts deleted file mode 100644 index cb4c9fbdd16d..000000000000 --- a/packages/core/test/lib/exports.test.ts +++ /dev/null @@ -1,335 +0,0 @@ -import { GLOBAL_OBJ } from '@sentry/utils'; -import { - Hub, - Scope, - captureSession, - endSession, - getCurrentScope, - getIsolationScope, - makeMain, - setContext, - setExtra, - setExtras, - setTag, - setTags, - setUser, - startSession, - withIsolationScope, - withScope, -} from '../../src'; -import { isInitialized } from '../../src/exports'; -import { TestClient, getDefaultTestClientOptions } from '../mocks/client'; - -function getTestClient(): TestClient { - return new TestClient( - getDefaultTestClientOptions({ - dsn: 'https://username@domain/123', - }), - ); -} - -describe('withScope', () => { - beforeEach(() => { - const client = getTestClient(); - const hub = new Hub(client); - // eslint-disable-next-line deprecation/deprecation - makeMain(hub); - }); - - it('works without a return value', () => { - const scope1 = getCurrentScope(); - expect(scope1).toBeInstanceOf(Scope); - - scope1.setTag('foo', 'bar'); - - const res = withScope(scope => { - expect(scope).toBeInstanceOf(Scope); - expect(scope).not.toBe(scope1); - expect(scope['_tags']).toEqual({ foo: 'bar' }); - - expect(getCurrentScope()).toBe(scope); - }); - - expect(getCurrentScope()).toBe(scope1); - expect(res).toBe(undefined); - }); - - it('works with a return value', () => { - const res = withScope(() => { - return 'foo'; - }); - - expect(res).toBe('foo'); - }); - - it('works with an async function return value', async () => { - const res = withScope(async () => { - return 'foo'; - }); - - expect(res).toBeInstanceOf(Promise); - expect(await res).toBe('foo'); - }); - - it('correctly sets & resets the current scope', () => { - const scope1 = getCurrentScope(); - - withScope(scope2 => { - expect(scope2).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope2); - }); - - withScope(scope3 => { - expect(scope3).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope3); - }); - - expect(getCurrentScope()).toBe(scope1); - }); - - it('correctly sets & resets the current scope with async functions', async () => { - const scope1 = getCurrentScope(); - - await withScope(async scope2 => { - expect(scope2).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope2); - - await new Promise(resolve => setTimeout(resolve, 10)); - - expect(getCurrentScope()).toBe(scope2); - }); - - await withScope(async scope3 => { - expect(scope3).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope3); - - await new Promise(resolve => setTimeout(resolve, 10)); - - expect(getCurrentScope()).toBe(scope3); - }); - - expect(getCurrentScope()).toBe(scope1); - }); - - it('correctly sets & resets the current scope when an error happens', () => { - const scope1 = getCurrentScope(); - - const error = new Error('foo'); - - expect(() => - withScope(scope2 => { - expect(scope2).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope2); - - throw error; - }), - ).toThrow(error); - - expect(getCurrentScope()).toBe(scope1); - }); - - it('correctly sets & resets the current scope with async functions & errors', async () => { - const scope1 = getCurrentScope(); - - const error = new Error('foo'); - - await expect( - withScope(async scope2 => { - expect(scope2).not.toBe(scope1); - expect(getCurrentScope()).toBe(scope2); - - throw error; - }), - ).rejects.toBe(error); - - expect(getCurrentScope()).toBe(scope1); - }); - - it('allows to pass a custom scope', () => { - const scope1 = getCurrentScope(); - scope1.setExtra('x1', 'x1'); - - const customScope = new Scope(); - customScope.setExtra('x2', 'x2'); - - withScope(customScope, scope2 => { - expect(scope2).not.toBe(scope1); - expect(scope2).toBe(customScope); - expect(getCurrentScope()).toBe(scope2); - expect(scope2['_extra']).toEqual({ x2: 'x2' }); - }); - - withScope(customScope, scope3 => { - expect(scope3).not.toBe(scope1); - expect(scope3).toBe(customScope); - expect(getCurrentScope()).toBe(scope3); - expect(scope3['_extra']).toEqual({ x2: 'x2' }); - }); - - expect(getCurrentScope()).toBe(scope1); - }); -}); - -describe('session APIs', () => { - beforeEach(() => { - const client = getTestClient(); - const hub = new Hub(client); - // eslint-disable-next-line deprecation/deprecation - makeMain(hub); - }); - - describe('startSession', () => { - it('starts a session', () => { - const session = startSession(); - - expect(session).toMatchObject({ - status: 'ok', - errors: 0, - init: true, - environment: 'production', - ignoreDuration: false, - sid: expect.any(String), - did: undefined, - timestamp: expect.any(Number), - started: expect.any(Number), - duration: expect.any(Number), - toJSON: expect.any(Function), - }); - }); - - it('ends a previously active session and removes it from the scope', () => { - const session1 = startSession(); - - expect(session1.status).toBe('ok'); - expect(getIsolationScope().getSession()).toBe(session1); - - const session2 = startSession(); - - expect(session2.status).toBe('ok'); - expect(session1.status).toBe('exited'); - expect(getIsolationScope().getSession()).toBe(session2); - }); - }); - - describe('endSession', () => { - it('ends a session and removes it from the scope', () => { - const session = startSession(); - - expect(session.status).toBe('ok'); - expect(getIsolationScope().getSession()).toBe(session); - - endSession(); - - expect(session.status).toBe('exited'); - expect(getIsolationScope().getSession()).toBe(undefined); - }); - }); - - describe('captureSession', () => { - it('captures a session without ending it by default', () => { - const session = startSession({ release: '1.0.0' }); - - expect(session.status).toBe('ok'); - expect(session.init).toBe(true); - expect(getIsolationScope().getSession()).toBe(session); - - captureSession(); - - // this flag indicates the session was sent via BaseClient - expect(session.init).toBe(false); - - // session is still active and on the scope - expect(session.status).toBe('ok'); - expect(getIsolationScope().getSession()).toBe(session); - }); - - it('captures a session and ends it if end is `true`', () => { - const session = startSession({ release: '1.0.0' }); - - expect(session.status).toBe('ok'); - expect(session.init).toBe(true); - expect(getIsolationScope().getSession()).toBe(session); - - captureSession(true); - - // this flag indicates the session was sent via BaseClient - expect(session.init).toBe(false); - - // session is still active and on the scope - expect(session.status).toBe('exited'); - expect(getIsolationScope().getSession()).toBe(undefined); - }); - }); - - describe('setUser', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setUser({ id: 'foo' }); - expect(isolationScope.getScopeData().user.id).toBe('foo'); - }); - }); - }); - - describe('setTags', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setTags({ wee: true, woo: false }); - expect(isolationScope.getScopeData().tags['wee']).toBe(true); - expect(isolationScope.getScopeData().tags['woo']).toBe(false); - }); - }); - }); - - describe('setTag', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setTag('foo', true); - expect(isolationScope.getScopeData().tags['foo']).toBe(true); - }); - }); - }); - - describe('setExtras', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setExtras({ wee: { foo: 'bar' }, woo: { foo: 'bar' } }); - expect(isolationScope.getScopeData().extra?.wee).toEqual({ foo: 'bar' }); - expect(isolationScope.getScopeData().extra?.woo).toEqual({ foo: 'bar' }); - }); - }); - }); - - describe('setExtra', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setExtra('foo', { bar: 'baz' }); - expect(isolationScope.getScopeData().extra?.foo).toEqual({ bar: 'baz' }); - }); - }); - }); - - describe('setContext', () => { - it('should write to the isolation scope', () => { - withIsolationScope(isolationScope => { - setContext('foo', { bar: 'baz' }); - expect(isolationScope.getScopeData().contexts?.foo?.bar).toBe('baz'); - }); - }); - }); -}); - -describe('isInitialized', () => { - it('returns false if no client is setup', () => { - GLOBAL_OBJ.__SENTRY__.hub = undefined; - expect(isInitialized()).toBe(false); - }); - - it('returns true if client is setup', () => { - const client = getTestClient(); - const hub = new Hub(client); - // eslint-disable-next-line deprecation/deprecation - makeMain(hub); - - expect(isInitialized()).toBe(true); - }); -}); diff --git a/packages/hub/test/global.test.ts b/packages/core/test/lib/global.test.ts similarity index 87% rename from packages/hub/test/global.test.ts rename to packages/core/test/lib/global.test.ts index 23bc51193a29..7e6bdf58ac9e 100644 --- a/packages/hub/test/global.test.ts +++ b/packages/core/test/lib/global.test.ts @@ -2,7 +2,7 @@ import { GLOBAL_OBJ } from '@sentry/utils'; -import { Hub, getCurrentHub, getHubFromCarrier } from '../src'; +import { Hub, getCurrentHub, getHubFromCarrier } from '../../src/hub'; describe('global', () => { test('getGlobalHub', () => { @@ -28,7 +28,7 @@ describe('global', () => { const newestHub = new Hub(undefined, undefined, undefined, 999999); GLOBAL_OBJ.__SENTRY__.hub = newestHub; const fn = jest.fn().mockImplementation(function (...args: []) { - // @ts-expect-error typescript complains that this can be `any` + // @ts-expect-error 'this' implicitly has type 'any' because it does not have a type annotation expect(this).toBe(newestHub); expect(args).toEqual([1, 2, 3]); }); diff --git a/packages/hub/test/session.test.ts b/packages/core/test/lib/session.test.ts similarity index 98% rename from packages/hub/test/session.test.ts rename to packages/core/test/lib/session.test.ts index fd8a1a58c359..fcded43eb740 100644 --- a/packages/hub/test/session.test.ts +++ b/packages/core/test/lib/session.test.ts @@ -3,7 +3,7 @@ import type { SessionContext } from '@sentry/types'; import { timestampInSeconds } from '@sentry/utils'; -import { closeSession, makeSession, updateSession } from '../src'; +import { closeSession, makeSession, updateSession } from '../../src/session'; describe('Session', () => { it('initializes with the proper defaults', () => { diff --git a/packages/hub/test/sessionflusher.test.ts b/packages/core/test/lib/sessionflusher.test.ts similarity index 98% rename from packages/hub/test/sessionflusher.test.ts rename to packages/core/test/lib/sessionflusher.test.ts index 0079e56087b4..f2c019839bcd 100644 --- a/packages/hub/test/sessionflusher.test.ts +++ b/packages/core/test/lib/sessionflusher.test.ts @@ -2,7 +2,7 @@ import type { Client } from '@sentry/types'; -import { SessionFlusher } from '../src'; +import { SessionFlusher } from '../../src/sessionflusher'; describe('Session Flusher', () => { let sendSession: jest.Mock; diff --git a/packages/hub/.eslintrc.js b/packages/hub/.eslintrc.js deleted file mode 100644 index 5a2cc7f1ec08..000000000000 --- a/packages/hub/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.js'], -}; diff --git a/packages/hub/LICENSE b/packages/hub/LICENSE deleted file mode 100644 index 535ef0561e1b..000000000000 --- a/packages/hub/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/hub/README.md b/packages/hub/README.md deleted file mode 100644 index 24e11a114d67..000000000000 --- a/packages/hub/README.md +++ /dev/null @@ -1,20 +0,0 @@ -

- - Sentry - -

- -# Sentry JavaScript SDK Hub - -[![npm version](https://img.shields.io/npm/v/@sentry/hub.svg)](https://www.npmjs.com/package/@sentry/hub) -[![npm dm](https://img.shields.io/npm/dm/@sentry/hub.svg)](https://www.npmjs.com/package/@sentry/hub) -[![npm dt](https://img.shields.io/npm/dt/@sentry/hub.svg)](https://www.npmjs.com/package/@sentry/hub) - -## Links - -- [Official SDK Docs](https://docs.sentry.io/quickstart/) -- [TypeDoc](http://getsentry.github.io/sentry-javascript/) - -## General - -This package provides the `Hub` and `Scope` for all JavaScript related SDKs. diff --git a/packages/hub/jest.config.js b/packages/hub/jest.config.js deleted file mode 100644 index 24f49ab59a4c..000000000000 --- a/packages/hub/jest.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../jest/jest.config.js'); diff --git a/packages/hub/package.json b/packages/hub/package.json deleted file mode 100644 index 1d51f3adb0be..000000000000 --- a/packages/hub/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@sentry/hub", - "version": "7.100.0", - "description": "Sentry hub which handles global state managment.", - "repository": "git://github.com/getsentry/sentry-javascript.git", - "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/hub", - "author": "Sentry", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "files": [ - "cjs", - "esm", - "types", - "types-ts3.8" - ], - "main": "build/cjs/index.js", - "module": "build/esm/index.js", - "types": "build/types/index.d.ts", - "typesVersions": { - "<4.9": { - "build/types/index.d.ts": [ - "build/types-ts3.8/index.d.ts" - ] - } - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@sentry/core": "7.100.0", - "@sentry/types": "7.100.0", - "@sentry/utils": "7.100.0" - }, - "scripts": { - "build": "run-p build:transpile build:types", - "build:dev": "yarn build", - "build:transpile": "rollup -c rollup.npm.config.mjs", - "build:types": "run-s build:types:core build:types:downlevel", - "build:types:core": "tsc -p tsconfig.types.json", - "build:types:downlevel": "yarn downlevel-dts build/types build/types-ts3.8 --to ts3.8", - "build:watch": "run-p build:transpile:watch build:types:watch", - "build:dev:watch": "yarn build:watch", - "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch", - "build:types:watch": "tsc -p tsconfig.types.json --watch", - "build:tarball": "ts-node ../../scripts/prepack.ts && npm pack ./build", - "circularDepCheck": "madge --circular src/index.ts", - "clean": "rimraf build coverage sentry-hub-*.tgz", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", - "test": "jest", - "test:watch": "jest --watch", - "yalc:publish": "ts-node ../../scripts/prepack.ts && yalc publish build --push --sig" - }, - "volta": { - "extends": "../../package.json" - }, - "sideEffects": false -} diff --git a/packages/hub/rollup.npm.config.mjs b/packages/hub/rollup.npm.config.mjs deleted file mode 100644 index 84a06f2fb64a..000000000000 --- a/packages/hub/rollup.npm.config.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; - -export default makeNPMConfigVariants(makeBaseNPMConfig()); diff --git a/packages/hub/src/index.ts b/packages/hub/src/index.ts deleted file mode 100644 index f865df997d29..000000000000 --- a/packages/hub/src/index.ts +++ /dev/null @@ -1,159 +0,0 @@ -export type { Carrier, Layer } from '@sentry/core'; - -import { - Hub as HubCore, - Scope as ScopeCore, - SessionFlusher as SessionFlusherCore, - addBreadcrumb as addBreadcrumbCore, - addGlobalEventProcessor as addGlobalEventProcessorCore, - captureEvent as captureEventCore, - captureException as captureExceptionCore, - captureMessage as captureMessageCore, - closeSession as closeSessionCore, - configureScope as configureScopeCore, - getCurrentHub as getCurrentHubCore, - getHubFromCarrier as getHubFromCarrierCore, - getMainCarrier as getMainCarrierCore, - makeMain as makeMainCore, - makeSession as makeSessionCore, - setContext as setContextCore, - setExtra as setExtraCore, - setExtras as setExtrasCore, - setHubOnCarrier as setHubOnCarrierCore, - setTag as setTagCore, - setTags as setTagsCore, - setUser as setUserCore, - startTransaction as startTransactionCore, - updateSession as updateSessionCore, - withScope as withScopeCore, -} from '@sentry/core'; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8 - */ -export class Hub extends HubCore {} - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8 - */ -export class Scope extends ScopeCore {} - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -// eslint-disable-next-line deprecation/deprecation -export const getCurrentHub = getCurrentHubCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ - -export const addGlobalEventProcessor = addGlobalEventProcessorCore; // eslint-disable-line deprecation/deprecation - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const getHubFromCarrier = getHubFromCarrierCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const getMainCarrier = getMainCarrierCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -// eslint-disable-next-line deprecation/deprecation -export const makeMain = makeMainCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setHubOnCarrier = setHubOnCarrierCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const SessionFlusher = SessionFlusherCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const closeSession = closeSessionCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const makeSession = makeSessionCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const updateSession = updateSessionCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const addBreadcrumb = addBreadcrumbCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const captureException = captureExceptionCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const captureEvent = captureEventCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const captureMessage = captureMessageCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -// eslint-disable-next-line deprecation/deprecation -export const configureScope = configureScopeCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -// eslint-disable-next-line deprecation/deprecation -export const startTransaction = startTransactionCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setContext = setContextCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setExtra = setExtraCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setExtras = setExtrasCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setTag = setTagCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setTags = setTagsCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const setUser = setUserCore; - -/** - * @deprecated This export has moved to @sentry/core. The @sentry/hub package will be removed in v8. - */ -export const withScope = withScopeCore; diff --git a/packages/hub/test/exports.test.ts b/packages/hub/test/exports.test.ts deleted file mode 100644 index 0b48e38a9c49..000000000000 --- a/packages/hub/test/exports.test.ts +++ /dev/null @@ -1,313 +0,0 @@ -/* eslint-disable deprecation/deprecation */ - -import type { Scope } from '../src'; -import { - captureEvent, - captureException, - captureMessage, - configureScope, - getCurrentHub, - getHubFromCarrier, - setContext, - setExtra, - setExtras, - setTag, - setTags, - setUser, - withScope, -} from '../src'; - -export class TestClient { - public static instance?: TestClient; - - public constructor(public options: Record) { - TestClient.instance = this; - } - - public mySecretPublicMethod(str: string): string { - return `secret: ${str}`; - } -} - -export class TestClient2 {} - -export function init(options: Record): void { - getCurrentHub().bindClient(new TestClient(options) as any); -} - -// eslint-disable-next-line no-var -declare var global: any; - -describe('Top Level API', () => { - beforeEach(() => { - global.__SENTRY__ = { - hub: undefined, - }; - }); - - describe('Capture', () => { - test('Return an event_id', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - const eventId = captureException(e); - expect(eventId).toBeTruthy(); - }); - }); - - test('Exception', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - captureException(e); - expect(client.captureException.mock.calls[0][0]).toBe(e); - }); - }); - - test('Exception with explicit scope', () => { - const client: any = { - captureException: jest.fn(async () => Promise.resolve()), - }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = new Error('test exception'); - const captureContext = { extra: { foo: 'wat' } }; - captureException(e, captureContext); - expect(client.captureException.mock.calls[0][0]).toBe(e); - expect(client.captureException.mock.calls[0][1].captureContext).toEqual(captureContext); - }); - }); - - test('Message', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - captureMessage(message); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - }); - }); - - test('Message with explicit scope', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - const captureContext = { extra: { foo: 'wat' } }; - captureMessage(message, captureContext); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - // Skip the level if explicit content is provided - expect(client.captureMessage.mock.calls[0][1]).toBe(undefined); - expect(client.captureMessage.mock.calls[0][2].captureContext).toBe(captureContext); - }); - }); - - // NOTE: We left custom level as 2nd argument to not break the API. Should be removed and unified in v6. - // TODO: Before we release v8, check if this is still a thing - test('Message with custom level', () => { - const client: any = { captureMessage: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const message = 'yo'; - const level = 'warning'; - captureMessage(message, level); - expect(client.captureMessage.mock.calls[0][0]).toBe(message); - expect(client.captureMessage.mock.calls[0][1]).toBe('warning'); - }); - }); - - test('Event', () => { - const client: any = { captureEvent: jest.fn(async () => Promise.resolve()) }; - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - const e = { message: 'test' }; - captureEvent(e); - expect(client.captureEvent.mock.calls[0][0]).toBe(e); - }); - }); - }); - - describe('configureScope', () => { - test('User Context', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - getCurrentHub().popScope(); - }); - - test('Extra Context', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setExtra('id', '1234'); - }); - expect(global.__SENTRY__.hub._stack[1].scope._extra).toEqual({ - id: '1234', - }); - getCurrentHub().popScope(); - }); - - test('Tags Context', () => { - init({}); - configureScope((scope: Scope) => { - scope.setTag('id', '1234'); - }); - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ - id: '1234', - }); - }); - - test('Fingerprint', () => { - const client: any = new TestClient({}); - getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - configureScope((scope: Scope) => { - scope.setFingerprint(['abcd']); - }); - expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['abcd']); - }); - - test('Level', () => { - const client: any = new TestClient({}); - const scope = getCurrentHub().pushScope(); - getCurrentHub().bindClient(client); - scope.setLevel('warning'); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); - }); - }); - - test('Clear Scope', () => { - const client: any = new TestClient({}); - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(client); - expect(global.__SENTRY__.hub._stack.length).toBe(2); - configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - configureScope((scope: Scope) => { - scope.clear(); - }); - expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({}); - }); - }); - - test('returns undefined before binding a client', () => { - expect(getCurrentHub().getClient()).toBeUndefined(); - }); - - test('returns the bound client', () => { - init({}); - expect(getCurrentHub().getClient()).toBe(TestClient.instance); - }); - - test('does not throw an error when pushing different clients', () => { - init({}); - expect(() => { - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(new TestClient2() as any); - }); - }).not.toThrow(); - }); - - test('does not throw an error when pushing same clients', () => { - init({}); - expect(() => { - getCurrentHub().withScope(() => { - getCurrentHub().bindClient(new TestClient({}) as any); - }); - }).not.toThrow(); - }); - - test('custom carrier', () => { - const iAmSomeGlobalVarTheUserHasToManage = { - state: {}, - }; - const hub = getHubFromCarrier(iAmSomeGlobalVarTheUserHasToManage.state); - hub.pushScope(); - hub.bindClient(new TestClient({}) as any); - hub.configureScope((scope: Scope) => { - scope.setUser({ id: '1234' }); - }); - expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1].scope._user).toEqual({ - id: '1234', - }); - hub.popScope(); - expect((iAmSomeGlobalVarTheUserHasToManage.state as any).__SENTRY__.hub._stack[1]).toBeUndefined(); - }); - - test('withScope', () => { - withScope(scope => { - scope.setLevel('warning'); - scope.setFingerprint(['1']); - withScope(scope2 => { - scope2.setLevel('info'); - scope2.setFingerprint(['2']); - withScope(scope3 => { - scope3.clear(); - expect(global.__SENTRY__.hub._stack[1].scope._level).toEqual('warning'); - expect(global.__SENTRY__.hub._stack[1].scope._fingerprint).toEqual(['1']); - expect(global.__SENTRY__.hub._stack[2].scope._level).toEqual('info'); - expect(global.__SENTRY__.hub._stack[2].scope._fingerprint).toEqual(['2']); - expect(global.__SENTRY__.hub._stack[3].scope._level).toBeUndefined(); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(3); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(2); - }); - expect(global.__SENTRY__.hub._stack).toHaveLength(1); - }); - - test('setExtras', () => { - init({}); - setExtras({ a: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ a: 'b' }); - }); - - test('setTags', () => { - init({}); - setTags({ a: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' }); - }); - - test('setExtra', () => { - init({}); - setExtra('a', 'b'); - // biome-ignore format: Follow-up for prettier - expect(global.__SENTRY__.hub._stack[0].scope._extra).toEqual({ 'a': 'b' }); - }); - - test('setTag', () => { - init({}); - setTag('a', 'b'); - // biome-ignore format: Follow-up for prettier - expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ 'a': 'b' }); - }); - - test('setUser', () => { - init({}); - setUser({ id: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._user).toEqual({ id: 'b' }); - }); - - test('setContext', () => { - init({}); - setContext('test', { id: 'b' }); - expect(global.__SENTRY__.hub._stack[0].scope._contexts).toEqual({ test: { id: 'b' } }); - }); -}); diff --git a/packages/hub/test/hub.test.ts b/packages/hub/test/hub.test.ts deleted file mode 100644 index 08ec6a22130a..000000000000 --- a/packages/hub/test/hub.test.ts +++ /dev/null @@ -1,556 +0,0 @@ -/* eslint-disable @typescript-eslint/unbound-method */ -/* eslint-disable deprecation/deprecation */ - -import type { Client, Event, EventType } from '@sentry/types'; - -import { getCurrentScope, makeMain } from '@sentry/core'; -import { Hub, Scope, getCurrentHub } from '../src'; - -const clientFn: any = jest.fn(); - -function makeClient() { - return { - getOptions: jest.fn(), - captureEvent: jest.fn(), - captureException: jest.fn(), - close: jest.fn(), - flush: jest.fn(), - getDsn: jest.fn(), - getIntegration: jest.fn(), - setupIntegrations: jest.fn(), - captureMessage: jest.fn(), - captureSession: jest.fn(), - } as unknown as Client; -} - -/** - * Return an array containing the arguments passed to the given mocked or spied-upon function. - * - * By default, the args passed to the first call of the function are returned, but it is also possible to retrieve the - * nth call by passing `callIndex`. If the function wasn't called, an error message is returned instead. - */ -function getPassedArgs(mock: (...args: any[]) => any, callIndex: number = 0): any[] { - const asMock = mock as jest.MockedFunction<(...args: any[]) => any>; - return asMock.mock.calls[callIndex] || ["Error: Function wasn't called."]; -} - -describe('Hub', () => { - afterEach(() => { - jest.restoreAllMocks(); - jest.useRealTimers(); - }); - - test('call bindClient with provided client when constructing new instance', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - expect(hub.getClient()).toBe(testClient); - }); - - test('push process into stack', () => { - const hub = new Hub(); - expect(hub.getStack()).toHaveLength(1); - }); - - test('pass in filled layer', () => { - const hub = new Hub(clientFn); - expect(hub.getStack()).toHaveLength(1); - }); - - test('isOlderThan', () => { - const hub = new Hub(); - expect(hub.isOlderThan(0)).toBeFalsy(); - }); - - describe('pushScope', () => { - test('simple', () => { - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - const hub = new Hub(undefined, localScope); - hub.pushScope(); - expect(hub.getStack()).toHaveLength(2); - expect(hub.getStack()[1].scope).not.toBe(localScope); - expect((hub.getStack()[1].scope as Scope as any)._extra).toEqual({ a: 'b' }); - }); - - test('inherit client', () => { - const testClient: any = { bla: 'a' }; - const hub = new Hub(testClient); - hub.pushScope(); - expect(hub.getStack()).toHaveLength(2); - expect(hub.getStack()[1].client).toBe(testClient); - }); - - describe('bindClient', () => { - test('should override current client', () => { - const testClient = makeClient(); - const nextClient = makeClient(); - const hub = new Hub(testClient); - hub.bindClient(nextClient); - expect(hub.getStack()).toHaveLength(1); - expect(hub.getStack()[0].client).toBe(nextClient); - }); - - test('should bind client to the top-most layer', () => { - const testClient: any = { bla: 'a' }; - const nextClient: any = { foo: 'bar' }; - const hub = new Hub(testClient); - hub.pushScope(); - hub.bindClient(nextClient); - expect(hub.getStack()).toHaveLength(2); - expect(hub.getStack()[0].client).toBe(testClient); - expect(hub.getStack()[1].client).toBe(nextClient); - }); - - test('should call setupIntegration method of passed client', () => { - const testClient = makeClient(); - const nextClient = makeClient(); - const hub = new Hub(testClient); - hub.bindClient(nextClient); - expect(testClient.setupIntegrations).toHaveBeenCalled(); - expect(nextClient.setupIntegrations).toHaveBeenCalled(); - }); - }); - - test('inherit processors', async () => { - expect.assertions(1); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - const hub = new Hub({ a: 'b' } as any, localScope); - - localScope.addEventProcessor(async (processedEvent: Event) => { - processedEvent.dist = '1'; - return processedEvent; - }); - - hub.pushScope(); - const pushedScope = hub.getStackTop().scope; - - return pushedScope!.applyToEvent(event).then(final => { - expect(final!.dist).toEqual('1'); - }); - }); - }); - - test('popScope', () => { - const hub = new Hub(); - hub.pushScope(); - expect(hub.getStack()).toHaveLength(2); - hub.popScope(); - expect(hub.getStack()).toHaveLength(1); - }); - - describe('withScope', () => { - let hub: Hub; - - beforeEach(() => { - hub = new Hub(); - }); - - test('simple', () => { - hub.withScope(() => { - expect(hub.getStack()).toHaveLength(2); - }); - expect(hub.getStack()).toHaveLength(1); - }); - - test('bindClient', () => { - const testClient: any = { bla: 'a' }; - hub.withScope(() => { - hub.bindClient(testClient); - expect(hub.getStack()).toHaveLength(2); - expect(hub.getStack()[1].client).toBe(testClient); - }); - expect(hub.getStack()).toHaveLength(1); - }); - - test('should bubble up exceptions', () => { - const error = new Error('test'); - expect(() => { - hub.withScope(() => { - throw error; - }); - }).toThrow(error); - }); - }); - - test('getCurrentClient', () => { - const testClient: any = { bla: 'a' }; - const hub = new Hub(testClient); - expect(hub.getClient()).toBe(testClient); - }); - - test('getStack', () => { - const client: any = { a: 'b' }; - const hub = new Hub(client); - expect(hub.getStack()[0].client).toBe(client); - }); - - test('getStackTop', () => { - const testClient: any = { bla: 'a' }; - const hub = new Hub(); - hub.pushScope(); - hub.pushScope(); - hub.bindClient(testClient); - expect(hub.getStackTop().client).toEqual({ bla: 'a' }); - }); - - describe('configureScope', () => { - test('should have an access to provide scope', () => { - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - const hub = new Hub({} as any, localScope); - const cb = jest.fn(); - hub.configureScope(cb); - expect(cb).toHaveBeenCalledWith(localScope); - }); - - test('should not invoke without client and scope', () => { - const hub = new Hub(); - const cb = jest.fn(); - hub.configureScope(cb); - expect(cb).not.toHaveBeenCalled(); - }); - }); - - describe('captureException', () => { - test('simple', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureException('a'); - const args = getPassedArgs(testClient.captureException); - - expect(args[0]).toBe('a'); - }); - - test('should set event_id in hint', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureException('a'); - const args = getPassedArgs(testClient.captureException); - - expect(args[1].event_id).toBeTruthy(); - }); - - test('should keep event_id from hint', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - const id = Math.random().toString(); - - hub.captureException('a', { event_id: id }); - const args = getPassedArgs(testClient.captureException); - - expect(args[1].event_id).toBe(id); - }); - - test('should generate hint if not provided in the call', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - const ex = new Error('foo'); - - hub.captureException(ex); - const args = getPassedArgs(testClient.captureException); - - expect(args[1].originalException).toBe(ex); - expect(args[1].syntheticException).toBeInstanceOf(Error); - expect(args[1].syntheticException.message).toBe('Sentry syntheticException'); - }); - }); - - describe('captureMessage', () => { - test('simple', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureMessage('a'); - const args = getPassedArgs(testClient.captureMessage); - - expect(args[0]).toBe('a'); - }); - - test('should set event_id in hint', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureMessage('a'); - const args = getPassedArgs(testClient.captureMessage); - - expect(args[2].event_id).toBeTruthy(); - }); - - test('should keep event_id from hint', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - const id = Math.random().toString(); - - hub.captureMessage('a', undefined, { event_id: id }); - const args = getPassedArgs(testClient.captureMessage); - - expect(args[2].event_id).toBe(id); - }); - - test('should generate hint if not provided in the call', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureMessage('foo'); - const args = getPassedArgs(testClient.captureMessage); - - expect(args[2].originalException).toBe('foo'); - expect(args[2].syntheticException).toBeInstanceOf(Error); - expect(args[2].syntheticException.message).toBe('foo'); - }); - }); - - describe('captureEvent', () => { - test('simple', () => { - const event: Event = { - extra: { b: 3 }, - }; - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureEvent(event); - const args = getPassedArgs(testClient.captureEvent); - - expect(args[0]).toBe(event); - }); - - test('should set event_id in hint', () => { - const event: Event = { - extra: { b: 3 }, - }; - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureEvent(event); - const args = getPassedArgs(testClient.captureEvent); - - expect(args[1].event_id).toBeTruthy(); - }); - - test('should keep event_id from hint', () => { - const event: Event = { - extra: { b: 3 }, - }; - const testClient = makeClient(); - const hub = new Hub(testClient); - const id = Math.random().toString(); - - hub.captureEvent(event, { event_id: id }); - const args = getPassedArgs(testClient.captureEvent); - - expect(args[1].event_id).toBe(id); - }); - - test('sets lastEventId', () => { - const event: Event = { - extra: { b: 3 }, - }; - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureEvent(event); - const args = getPassedArgs(testClient.captureEvent); - - expect(args[1].event_id).toEqual(hub.lastEventId()); - }); - - const eventTypesToIgnoreLastEventId: EventType[] = ['transaction', 'replay_event']; - it.each(eventTypesToIgnoreLastEventId)('eventType %s does not set lastEventId', eventType => { - const event: Event = { - extra: { b: 3 }, - type: eventType, - }; - const testClient = makeClient(); - const hub = new Hub(testClient); - - hub.captureEvent(event); - const args = getPassedArgs(testClient.captureEvent); - - expect(args[1].event_id).not.toEqual(hub.lastEventId()); - }); - }); - - test('lastEventId should be the same as last created', () => { - const event: Event = { - extra: { b: 3 }, - }; - const hub = new Hub(); - const eventId = hub.captureEvent(event); - expect(eventId).toBe(hub.lastEventId()); - }); - - describe('run', () => { - test('simple', () => { - const currentHub = getCurrentHub(); - const myScope = new Scope(); - const myClient: any = { a: 'b' }; - myScope.setExtra('a', 'b'); - const myHub = new Hub(myClient, myScope); - myHub.run(hub => { - expect(hub.getScope()).toBe(myScope); - expect(hub.getClient()).toBe(myClient); - expect(hub).toBe(getCurrentHub()); - }); - expect(currentHub).toBe(getCurrentHub()); - }); - - test('should bubble up exceptions', () => { - const hub = new Hub(); - const error = new Error('test'); - expect(() => { - hub.run(() => { - throw error; - }); - }).toThrow(error); - }); - }); - - describe('breadcrumbs', () => { - test('withScope', () => { - expect.assertions(6); - const hub = new Hub(clientFn); - hub.addBreadcrumb({ message: 'My Breadcrumb' }); - hub.withScope(scope => { - scope.addBreadcrumb({ message: 'scope breadcrumb' }); - const event: Event = {}; - void scope - .applyToEvent(event) - .then((appliedEvent: Event | null) => { - expect(appliedEvent).toBeTruthy(); - expect(appliedEvent!.breadcrumbs).toHaveLength(2); - expect(appliedEvent!.breadcrumbs![0].message).toEqual('My Breadcrumb'); - expect(appliedEvent!.breadcrumbs![0]).toHaveProperty('timestamp'); - expect(appliedEvent!.breadcrumbs![1].message).toEqual('scope breadcrumb'); - expect(appliedEvent!.breadcrumbs![1]).toHaveProperty('timestamp'); - }) - .then(null, e => { - // eslint-disable-next-line no-console - console.error(e); - }); - }); - }); - }); - - describe('shouldSendDefaultPii()', () => { - test('return false if sendDefaultPii is not set', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - expect(hub.shouldSendDefaultPii()).toBe(false); - }); - - test('return true if sendDefaultPii is set in the client options', () => { - const testClient = makeClient(); - testClient.getOptions = () => { - return { - sendDefaultPii: true, - } as unknown as any; - }; - const hub = new Hub(testClient); - expect(hub.shouldSendDefaultPii()).toBe(true); - }); - }); - - describe('session APIs', () => { - beforeEach(() => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - }); - - describe('startSession', () => { - it('starts a session', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - const session = hub.startSession(); - - expect(session).toMatchObject({ - status: 'ok', - errors: 0, - init: true, - environment: 'production', - ignoreDuration: false, - sid: expect.any(String), - did: undefined, - timestamp: expect.any(Number), - started: expect.any(Number), - duration: expect.any(Number), - toJSON: expect.any(Function), - }); - }); - - it('ends a previously active session and removes it from the scope', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - - const session1 = hub.startSession(); - - expect(session1.status).toBe('ok'); - expect(getCurrentScope().getSession()).toBe(session1); - - const session2 = hub.startSession(); - - expect(session2.status).toBe('ok'); - expect(session1.status).toBe('exited'); - expect(getCurrentHub().getScope().getSession()).toBe(session2); - }); - }); - - describe('endSession', () => { - it('ends a session and removes it from the scope', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - - const session = hub.startSession(); - - expect(session.status).toBe('ok'); - expect(getCurrentScope().getSession()).toBe(session); - - hub.endSession(); - - expect(session.status).toBe('exited'); - expect(getCurrentHub().getScope().getSession()).toBe(undefined); - }); - }); - - describe('captureSession', () => { - it('captures a session without ending it by default', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - - const session = hub.startSession(); - - expect(session.status).toBe('ok'); - expect(getCurrentScope().getSession()).toBe(session); - - hub.captureSession(); - - expect(testClient.captureSession).toHaveBeenCalledWith(expect.objectContaining({ status: 'ok' })); - }); - - it('captures a session and ends it if end is `true`', () => { - const testClient = makeClient(); - const hub = new Hub(testClient); - makeMain(hub); - - const session = hub.startSession(); - - expect(session.status).toBe('ok'); - expect(hub.getScope().getSession()).toBe(session); - - hub.captureSession(true); - - expect(testClient.captureSession).toHaveBeenCalledWith(expect.objectContaining({ status: 'exited' })); - }); - }); - }); -}); diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts deleted file mode 100644 index 08f4a73abcb2..000000000000 --- a/packages/hub/test/scope.test.ts +++ /dev/null @@ -1,783 +0,0 @@ -/* eslint-disable deprecation/deprecation */ - -import type { Event, EventHint, RequestSessionStatus } from '@sentry/types'; -import { GLOBAL_OBJ } from '@sentry/utils'; - -import { Scope, addGlobalEventProcessor } from '../src'; - -describe('Scope', () => { - afterEach(() => { - jest.resetAllMocks(); - jest.useRealTimers(); - GLOBAL_OBJ.__SENTRY__ = GLOBAL_OBJ.__SENTRY__ || {}; - GLOBAL_OBJ.__SENTRY__.globalEventProcessors = undefined; - }); - - describe('init', () => { - test('it creates a propagation context', () => { - const scope = new Scope(); - - // @ts-expect-error asserting on private properties - expect(scope._propagationContext).toEqual({ - traceId: expect.any(String), - spanId: expect.any(String), - sampled: undefined, - dsc: undefined, - parentSpanId: undefined, - }); - }); - }); - - describe('attributes modification', () => { - test('setFingerprint', () => { - const scope = new Scope(); - scope.setFingerprint(['abcd']); - expect((scope as any)._fingerprint).toEqual(['abcd']); - }); - - test('setExtra', () => { - const scope = new Scope(); - scope.setExtra('a', 1); - expect((scope as any)._extra).toEqual({ a: 1 }); - }); - - test('setExtras', () => { - const scope = new Scope(); - scope.setExtras({ a: 1 }); - expect((scope as any)._extra).toEqual({ a: 1 }); - }); - - test('setExtras with undefined overrides the value', () => { - const scope = new Scope(); - scope.setExtra('a', 1); - scope.setExtras({ a: undefined }); - expect((scope as any)._extra).toEqual({ a: undefined }); - }); - - test('setTag', () => { - const scope = new Scope(); - scope.setTag('a', 'b'); - expect((scope as any)._tags).toEqual({ a: 'b' }); - }); - - test('setTags', () => { - const scope = new Scope(); - scope.setTags({ a: 'b' }); - expect((scope as any)._tags).toEqual({ a: 'b' }); - }); - - test('setUser', () => { - const scope = new Scope(); - scope.setUser({ id: '1' }); - expect((scope as any)._user).toEqual({ id: '1' }); - }); - - test('setUser with null unsets the user', () => { - const scope = new Scope(); - scope.setUser({ id: '1' }); - scope.setUser(null); - expect((scope as any)._user).toEqual({}); - }); - - test('addBreadcrumb', () => { - const scope = new Scope(); - scope.addBreadcrumb({ message: 'test' }); - expect((scope as any)._breadcrumbs[0]).toHaveProperty('message', 'test'); - }); - - test('addBreadcrumb can be limited to hold up to N breadcrumbs', () => { - const scope = new Scope(); - for (let i = 0; i < 10; i++) { - scope.addBreadcrumb({ message: 'test' }, 5); - } - expect((scope as any)._breadcrumbs).toHaveLength(5); - }); - - test('addBreadcrumb can go over DEFAULT_MAX_BREADCRUMBS value', () => { - const scope = new Scope(); - for (let i = 0; i < 120; i++) { - scope.addBreadcrumb({ message: 'test' }, 111); - } - expect((scope as any)._breadcrumbs).toHaveLength(111); - }); - - test('setLevel', () => { - const scope = new Scope(); - scope.setLevel('fatal'); - expect((scope as any)._level).toEqual('fatal'); - }); - - test('setTransactionName', () => { - const scope = new Scope(); - scope.setTransactionName('/abc'); - expect((scope as any)._transactionName).toEqual('/abc'); - }); - - test('setTransactionName with no value unsets it', () => { - const scope = new Scope(); - scope.setTransactionName('/abc'); - scope.setTransactionName(); - expect((scope as any)._transactionName).toBeUndefined(); - }); - - test('setContext', () => { - const scope = new Scope(); - scope.setContext('os', { id: '1' }); - expect((scope as any)._contexts.os).toEqual({ id: '1' }); - }); - - test('setContext with null unsets it', () => { - const scope = new Scope(); - scope.setContext('os', { id: '1' }); - scope.setContext('os', null); - expect((scope as any)._user).toEqual({}); - }); - - test('setSpan', () => { - const scope = new Scope(); - const span = { fake: 'span' } as any; - scope.setSpan(span); - expect((scope as any)._span).toEqual(span); - }); - - test('setSpan with no value unsets it', () => { - const scope = new Scope(); - scope.setSpan({ fake: 'span' } as any); - scope.setSpan(); - expect((scope as any)._span).toEqual(undefined); - }); - - test('setProcessingMetadata', () => { - const scope = new Scope(); - scope.setSDKProcessingMetadata({ dogs: 'are great!' }); - expect((scope as any)._sdkProcessingMetadata.dogs).toEqual('are great!'); - }); - - test('set and get propagation context', () => { - const scope = new Scope(); - const oldPropagationContext = scope.getPropagationContext(); - scope.setPropagationContext({ - traceId: '86f39e84263a4de99c326acab3bfe3bd', - spanId: '6e0c63257de34c92', - sampled: true, - }); - expect(scope.getPropagationContext()).not.toEqual(oldPropagationContext); - expect(scope.getPropagationContext()).toEqual({ - traceId: '86f39e84263a4de99c326acab3bfe3bd', - spanId: '6e0c63257de34c92', - sampled: true, - }); - }); - - test('chaining', () => { - const scope = new Scope(); - scope.setLevel('fatal').setUser({ id: '1' }); - expect((scope as any)._level).toEqual('fatal'); - expect((scope as any)._user).toEqual({ id: '1' }); - }); - }); - - describe('clone', () => { - test('basic inheritance', () => { - const parentScope = new Scope(); - parentScope.setExtra('a', 1); - const scope = Scope.clone(parentScope); - expect((parentScope as any)._extra).toEqual((scope as any)._extra); - }); - - test('_requestSession clone', () => { - const parentScope = new Scope(); - parentScope.setRequestSession({ status: 'errored' }); - const scope = Scope.clone(parentScope); - expect(parentScope.getRequestSession()).toEqual(scope.getRequestSession()); - }); - - test('parent changed inheritance', () => { - const parentScope = new Scope(); - const scope = Scope.clone(parentScope); - parentScope.setExtra('a', 2); - expect((scope as any)._extra).toEqual({}); - expect((parentScope as any)._extra).toEqual({ a: 2 }); - }); - - test('child override inheritance', () => { - const parentScope = new Scope(); - parentScope.setExtra('a', 1); - - const scope = Scope.clone(parentScope); - scope.setExtra('a', 2); - expect((parentScope as any)._extra).toEqual({ a: 1 }); - expect((scope as any)._extra).toEqual({ a: 2 }); - }); - - test('child override should set the value of parent _requestSession', () => { - // Test that ensures if the status value of `status` of `_requestSession` is changed in a child scope - // that it should also change in parent scope because we are copying the reference to the object - const parentScope = new Scope(); - parentScope.setRequestSession({ status: 'errored' }); - - const scope = Scope.clone(parentScope); - const requestSession = scope.getRequestSession(); - if (requestSession) { - requestSession.status = 'ok'; - } - - expect(parentScope.getRequestSession()).toEqual({ status: 'ok' }); - expect(scope.getRequestSession()).toEqual({ status: 'ok' }); - }); - - test('should clone propagation context', () => { - const parentScope = new Scope(); - const scope = Scope.clone(parentScope); - - // @ts-expect-error accessing private property for test - expect(scope._propagationContext).toEqual(parentScope._propagationContext); - }); - }); - - describe('applyToEvent', () => { - test('basic usage', async () => { - const scope = new Scope(); - scope.setExtra('a', 2); - scope.setTag('a', 'b'); - scope.setUser({ id: '1' }); - scope.setFingerprint(['abcd']); - scope.setLevel('warning'); - scope.setTransactionName('/abc'); - scope.addBreadcrumb({ message: 'test' }); - scope.setContext('os', { id: '1' }); - scope.setSDKProcessingMetadata({ dogs: 'are great!' }); - - const event: Event = {}; - const processedEvent = await scope.applyToEvent(event); - - expect(processedEvent!.extra).toEqual({ a: 2 }); - expect(processedEvent!.tags).toEqual({ a: 'b' }); - expect(processedEvent!.user).toEqual({ id: '1' }); - expect(processedEvent!.fingerprint).toEqual(['abcd']); - expect(processedEvent!.level).toEqual('warning'); - expect(processedEvent!.transaction).toEqual('/abc'); - expect(processedEvent!.breadcrumbs![0]).toHaveProperty('message', 'test'); - expect(processedEvent!.contexts).toEqual({ os: { id: '1' } }); - expect(processedEvent!.sdkProcessingMetadata).toEqual({ - dogs: 'are great!', - }); - }); - - test('merge with existing event data', async () => { - expect.assertions(8); - const scope = new Scope(); - scope.setExtra('a', 2); - scope.setTag('a', 'b'); - scope.setUser({ id: '1' }); - scope.setFingerprint(['abcd']); - scope.addBreadcrumb({ message: 'test' }); - scope.setContext('server', { id: '2' }); - const event: Event = { - breadcrumbs: [{ message: 'test1' }], - contexts: { os: { id: '1' } }, - extra: { b: 3 }, - fingerprint: ['efgh'], - tags: { b: 'c' }, - user: { id: '3' }, - }; - return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.extra).toEqual({ a: 2, b: 3 }); - expect(processedEvent!.tags).toEqual({ a: 'b', b: 'c' }); - expect(processedEvent!.user).toEqual({ id: '3' }); - expect(processedEvent!.fingerprint).toEqual(['efgh', 'abcd']); - expect(processedEvent!.breadcrumbs).toHaveLength(2); - expect(processedEvent!.breadcrumbs![0]).toHaveProperty('message', 'test1'); - expect(processedEvent!.breadcrumbs![1]).toHaveProperty('message', 'test'); - expect(processedEvent!.contexts).toEqual({ - os: { id: '1' }, - server: { id: '2' }, - }); - }); - }); - - test('should make sure that fingerprint is always array', async () => { - const scope = new Scope(); - const event: Event = {}; - - // @ts-expect-error we want to be able to assign string value - event.fingerprint = 'foo'; - await scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.fingerprint).toEqual(['foo']); - }); - - // @ts-expect-error we want to be able to assign string value - event.fingerprint = 'bar'; - await scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.fingerprint).toEqual(['bar']); - }); - }); - - test('should merge fingerprint from event and scope', async () => { - const scope = new Scope(); - scope.setFingerprint(['foo']); - const event: Event = { - fingerprint: ['bar'], - }; - - await scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.fingerprint).toEqual(['bar', 'foo']); - }); - }); - - test('should remove default empty fingerprint array if theres no data available', async () => { - const scope = new Scope(); - const event: Event = {}; - await scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.fingerprint).toEqual(undefined); - }); - }); - - test('scope level should have priority over event level', async () => { - expect.assertions(1); - const scope = new Scope(); - scope.setLevel('warning'); - const event: Event = {}; - event.level = 'fatal'; - return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.level).toEqual('warning'); - }); - }); - - test('scope transaction should have priority over event transaction', async () => { - expect.assertions(1); - const scope = new Scope(); - scope.setTransactionName('/abc'); - const event: Event = {}; - event.transaction = '/cdf'; - return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.transaction).toEqual('/abc'); - }); - }); - - test('adds trace context', async () => { - const scope = new Scope(); - const span = { - fake: 'span', - spanContext: () => ({}), - toJSON: () => ({ origin: 'manual' }), - } as any; - scope.setSpan(span); - const event: Event = {}; - const processedEvent = await scope.applyToEvent(event); - expect(processedEvent!.contexts!.trace as any).toEqual({ origin: 'manual' }); - }); - - test('existing trace context in event should take precedence', async () => { - expect.assertions(1); - const scope = new Scope(); - const span = { - fake: 'span', - spanContext: () => ({}), - toJSON: () => ({ a: 'b' }), - } as any; - scope.setSpan(span); - const event: Event = { - contexts: { - trace: { a: 'c' } as any, - }, - }; - return scope.applyToEvent(event).then(processedEvent => { - expect((processedEvent!.contexts!.trace as any).a).toEqual('c'); - }); - }); - - test('adds `transaction` tag when transaction on scope', async () => { - expect.assertions(1); - const scope = new Scope(); - const transaction = { - fake: 'span', - spanContext: () => ({}), - toJSON: () => ({ a: 'b', description: 'fake transaction' }), - getDynamicSamplingContext: () => ({}), - } as any; - transaction.transaction = transaction; // because this is a transaction, its `transaction` pointer points to itself - scope.setSpan(transaction); - const event: Event = {}; - return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.tags!.transaction).toEqual('fake transaction'); - }); - }); - - test('adds `transaction` tag when span on scope', async () => { - expect.assertions(1); - const scope = new Scope(); - const transaction = { - spanContext: () => ({}), - toJSON: () => ({ description: 'fake transaction' }), - getDynamicSamplingContext: () => ({}), - }; - const span = { - fake: 'span', - spanContext: () => ({}), - toJSON: () => ({ a: 'b' }), - transaction, - } as any; - scope.setSpan(span); - const event: Event = {}; - return scope.applyToEvent(event).then(processedEvent => { - expect(processedEvent!.tags!.transaction).toEqual('fake transaction'); - }); - }); - }); - - test('clear', () => { - const scope = new Scope(); - // @ts-expect-error accessing private property - const oldPropagationContext = scope._propagationContext; - scope.setExtra('a', 2); - scope.setTag('a', 'b'); - scope.setUser({ id: '1' }); - scope.setFingerprint(['abcd']); - scope.addBreadcrumb({ message: 'test' }); - scope.setRequestSession({ status: 'ok' }); - expect((scope as any)._extra).toEqual({ a: 2 }); - scope.clear(); - expect((scope as any)._extra).toEqual({}); - expect((scope as any)._requestSession).toEqual(undefined); - // @ts-expect-error accessing private property - expect(scope._propagationContext).toEqual({ - traceId: expect.any(String), - spanId: expect.any(String), - sampled: undefined, - }); - // @ts-expect-error accessing private property - expect(scope._propagationContext).not.toEqual(oldPropagationContext); - }); - - test('clearBreadcrumbs', () => { - const scope = new Scope(); - scope.addBreadcrumb({ message: 'test' }); - expect((scope as any)._breadcrumbs).toHaveLength(1); - scope.clearBreadcrumbs(); - expect((scope as any)._breadcrumbs).toHaveLength(0); - }); - - describe('update', () => { - let scope: Scope; - - beforeEach(() => { - scope = new Scope(); - scope.setTags({ foo: '1', bar: '2' }); - scope.setExtras({ foo: '1', bar: '2' }); - scope.setContext('foo', { id: '1' }); - scope.setContext('bar', { id: '2' }); - scope.setUser({ id: '1337' }); - scope.setLevel('info'); - scope.setFingerprint(['foo']); - scope.setRequestSession({ status: 'ok' }); - }); - - test('given no data, returns the original scope', () => { - const updatedScope = scope.update(); - expect(updatedScope).toEqual(scope); - }); - - test('given neither function, Scope or plain object, returns original scope', () => { - // @ts-expect-error we want to be able to update scope with string - const updatedScope = scope.update('wat'); - expect(updatedScope).toEqual(scope); - }); - - test('given callback function, pass it the scope and returns original or modified scope', () => { - const cb = jest - .fn() - .mockImplementationOnce(v => v) - .mockImplementationOnce(v => { - v.setTag('foo', 'bar'); - return v; - }); - - let updatedScope = scope.update(cb); - expect(cb).toHaveBeenNthCalledWith(1, scope); - expect(updatedScope).toEqual(scope); - - updatedScope = scope.update(cb); - expect(cb).toHaveBeenNthCalledWith(2, scope); - expect(updatedScope).toEqual(scope); - }); - - test('given callback function, when it doesnt return instanceof Scope, ignore it and return original scope', () => { - const cb = jest.fn().mockImplementationOnce(_v => 'wat'); - const updatedScope = scope.update(cb); - expect(cb).toHaveBeenCalledWith(scope); - expect(updatedScope).toEqual(scope); - }); - - test('given another instance of Scope, it should merge two together, with the passed scope having priority', () => { - const localScope = new Scope(); - localScope.setTags({ bar: '3', baz: '4' }); - localScope.setExtras({ bar: '3', baz: '4' }); - localScope.setContext('bar', { id: '3' }); - localScope.setContext('baz', { id: '4' }); - localScope.setUser({ id: '42' }); - localScope.setLevel('warning'); - localScope.setFingerprint(['bar']); - (localScope as any)._requestSession = { status: 'ok' }; - - const updatedScope = scope.update(localScope) as any; - - expect(updatedScope._tags).toEqual({ - bar: '3', - baz: '4', - foo: '1', - }); - expect(updatedScope._extra).toEqual({ - bar: '3', - baz: '4', - foo: '1', - }); - expect(updatedScope._contexts).toEqual({ - bar: { id: '3' }, - baz: { id: '4' }, - foo: { id: '1' }, - }); - expect(updatedScope._user).toEqual({ id: '42' }); - expect(updatedScope._level).toEqual('warning'); - expect(updatedScope._fingerprint).toEqual(['bar']); - expect(updatedScope._requestSession.status).toEqual('ok'); - // @ts-expect-error accessing private property for test - expect(updatedScope._propagationContext).toEqual(localScope._propagationContext); - }); - - test('given an empty instance of Scope, it should preserve all the original scope data', () => { - const updatedScope = scope.update(new Scope()) as any; - - expect(updatedScope._tags).toEqual({ - bar: '2', - foo: '1', - }); - expect(updatedScope._extra).toEqual({ - bar: '2', - foo: '1', - }); - expect(updatedScope._contexts).toEqual({ - bar: { id: '2' }, - foo: { id: '1' }, - }); - expect(updatedScope._user).toEqual({ id: '1337' }); - expect(updatedScope._level).toEqual('info'); - expect(updatedScope._fingerprint).toEqual(['foo']); - expect(updatedScope._requestSession.status).toEqual('ok'); - }); - - test('given a plain object, it should merge two together, with the passed object having priority', () => { - const localAttributes = { - contexts: { bar: { id: '3' }, baz: { id: '4' } }, - extra: { bar: '3', baz: '4' }, - fingerprint: ['bar'], - level: 'warning' as const, - tags: { bar: '3', baz: '4' }, - user: { id: '42' }, - requestSession: { status: 'errored' as RequestSessionStatus }, - propagationContext: { - traceId: '8949daf83f4a4a70bee4c1eb9ab242ed', - spanId: 'a024ad8fea82680e', - sampled: true, - }, - }; - - const updatedScope = scope.update(localAttributes) as any; - - expect(updatedScope._tags).toEqual({ - bar: '3', - baz: '4', - foo: '1', - }); - expect(updatedScope._extra).toEqual({ - bar: '3', - baz: '4', - foo: '1', - }); - expect(updatedScope._contexts).toEqual({ - bar: { id: '3' }, - baz: { id: '4' }, - foo: { id: '1' }, - }); - expect(updatedScope._user).toEqual({ id: '42' }); - expect(updatedScope._level).toEqual('warning'); - expect(updatedScope._fingerprint).toEqual(['bar']); - expect(updatedScope._requestSession).toEqual({ status: 'errored' }); - expect(updatedScope._propagationContext).toEqual({ - traceId: '8949daf83f4a4a70bee4c1eb9ab242ed', - spanId: 'a024ad8fea82680e', - sampled: true, - }); - }); - }); - - describe('addEventProcessor', () => { - test('should allow for basic event manipulation', async () => { - expect.assertions(3); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - localScope.addEventProcessor((processedEvent: Event) => { - expect(processedEvent.extra).toEqual({ a: 'b', b: 3 }); - return processedEvent; - }); - localScope.addEventProcessor((processedEvent: Event) => { - processedEvent.dist = '1'; - return processedEvent; - }); - localScope.addEventProcessor((processedEvent: Event) => { - expect(processedEvent.dist).toEqual('1'); - return processedEvent; - }); - - return localScope.applyToEvent(event).then(final => { - expect(final!.dist).toEqual('1'); - }); - }); - - test('should work alongside global event processors', async () => { - expect.assertions(3); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - - // eslint-disable-next-line deprecation/deprecation - addGlobalEventProcessor((processedEvent: Event) => { - processedEvent.dist = '1'; - return processedEvent; - }); - - localScope.addEventProcessor((processedEvent: Event) => { - expect(processedEvent.extra).toEqual({ a: 'b', b: 3 }); - return processedEvent; - }); - - localScope.addEventProcessor((processedEvent: Event) => { - expect(processedEvent.dist).toEqual('1'); - return processedEvent; - }); - - return localScope.applyToEvent(event).then(final => { - expect(final!.dist).toEqual('1'); - }); - }); - - test('should allow for async callbacks', async () => { - jest.useFakeTimers(); - expect.assertions(6); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - const callCounter = jest.fn(); - localScope.addEventProcessor((processedEvent: Event) => { - callCounter(1); - expect(processedEvent.extra).toEqual({ a: 'b', b: 3 }); - return processedEvent; - }); - localScope.addEventProcessor( - async (processedEvent: Event) => - new Promise(resolve => { - callCounter(2); - setTimeout(() => { - callCounter(3); - processedEvent.dist = '1'; - resolve(processedEvent); - }, 1); - jest.runAllTimers(); - }), - ); - localScope.addEventProcessor((processedEvent: Event) => { - callCounter(4); - return processedEvent; - }); - - return localScope.applyToEvent(event).then(processedEvent => { - expect(callCounter.mock.calls[0][0]).toBe(1); - expect(callCounter.mock.calls[1][0]).toBe(2); - expect(callCounter.mock.calls[2][0]).toBe(3); - expect(callCounter.mock.calls[3][0]).toBe(4); - expect(processedEvent!.dist).toEqual('1'); - }); - }); - - test('should correctly handle async rejections', async () => { - jest.useFakeTimers(); - expect.assertions(2); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - const callCounter = jest.fn(); - localScope.addEventProcessor((processedEvent: Event) => { - callCounter(1); - expect(processedEvent.extra).toEqual({ a: 'b', b: 3 }); - return processedEvent; - }); - localScope.addEventProcessor( - async (_processedEvent: Event) => - new Promise((_, reject) => { - setTimeout(() => { - reject('bla'); - }, 1); - jest.runAllTimers(); - }), - ); - localScope.addEventProcessor((processedEvent: Event) => { - callCounter(4); - return processedEvent; - }); - - return localScope.applyToEvent(event).then(null, reason => { - expect(reason).toEqual('bla'); - }); - }); - - test('should drop an event when any of processors return null', async () => { - expect.assertions(1); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - localScope.addEventProcessor(async (_: Event) => null); - return localScope.applyToEvent(event).then(processedEvent => { - expect(processedEvent).toBeNull(); - }); - }); - - test('should have an access to the EventHint', async () => { - expect.assertions(3); - const event: Event = { - extra: { b: 3 }, - }; - const localScope = new Scope(); - localScope.setExtra('a', 'b'); - localScope.addEventProcessor(async (internalEvent: Event, hint?: EventHint) => { - expect(hint).toBeTruthy(); - expect(hint!.syntheticException).toBeTruthy(); - return internalEvent; - }); - return localScope.applyToEvent(event, { syntheticException: new Error('what') }).then(processedEvent => { - expect(processedEvent).toEqual(event); - }); - }); - - test('should notify all the listeners about the changes', () => { - jest.useFakeTimers(); - const scope = new Scope(); - const listener = jest.fn(); - scope.addScopeListener(listener); - scope.setExtra('a', 2); - jest.runAllTimers(); - expect(listener).toHaveBeenCalled(); - expect(listener.mock.calls[0][0]._extra).toEqual({ a: 2 }); - }); - }); -}); diff --git a/packages/hub/tsconfig.json b/packages/hub/tsconfig.json deleted file mode 100644 index bf45a09f2d71..000000000000 --- a/packages/hub/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - - "include": ["src/**/*"], - - "compilerOptions": { - // package-specific options - } -} diff --git a/packages/hub/tsconfig.test.json b/packages/hub/tsconfig.test.json deleted file mode 100644 index af7e36ec0eda..000000000000 --- a/packages/hub/tsconfig.test.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "include": ["test/**/*"], - - "compilerOptions": { - // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["jest"] - - // other package-specific, test-specific options - } -} diff --git a/packages/hub/tsconfig.types.json b/packages/hub/tsconfig.types.json deleted file mode 100644 index 65455f66bd75..000000000000 --- a/packages/hub/tsconfig.types.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "outDir": "build/types" - } -} diff --git a/packages/serverless/scripts/buildLambdaLayer.ts b/packages/serverless/scripts/buildLambdaLayer.ts index 9b6912898386..a462a33c6804 100644 --- a/packages/serverless/scripts/buildLambdaLayer.ts +++ b/packages/serverless/scripts/buildLambdaLayer.ts @@ -18,7 +18,7 @@ async function buildLambdaLayer(): Promise { // Create the main SDK bundle // TODO: Check if we can get rid of this, after the lerna 6/nx update?? await ensureBundleBuildPrereqs({ - dependencies: ['@sentry/utils', '@sentry/hub', '@sentry/core', '@sentry/node'], + dependencies: ['@sentry/utils', '@sentry/core', '@sentry/node'], }); run('yarn rollup --config rollup.aws.config.mjs'); diff --git a/packages/tracing/README.md b/packages/tracing/README.md index 462f2da52ff8..09bf79eb2e89 100644 --- a/packages/tracing/README.md +++ b/packages/tracing/README.md @@ -19,7 +19,7 @@ ## General -This package contains extensions to the `@sentry/hub` to enable Sentry AM related functionality. It also provides integrations for Browser and Node that provide a good experience out of the box. +This package contains extensions to the Sentry SDKs to enable Sentry AM related functionality. It also provides integrations for Browser and Node that provide a good experience out of the box. ## Migrating from @sentry/apm to @sentry/tracing diff --git a/packages/tracing/test/testutils.ts b/packages/tracing/test/testutils.ts index 484e3bf3cc35..5ce79099d38f 100644 --- a/packages/tracing/test/testutils.ts +++ b/packages/tracing/test/testutils.ts @@ -6,9 +6,8 @@ import { JSDOM } from 'jsdom'; /** * Injects DOM properties into node global object. * - * Useful for running tests where some of the tested code applies to @sentry/node and some applies to @sentry/browser - * (e.g. tests in @sentry/tracing or @sentry/hub). Note that not all properties from the browser `window` object are - * available. + * Useful for running tests where some of the tested code is isomorphic (apply to both node and browser). + * Note that not all properties from the browser `window` object are available. * * @param properties The names of the properties to add */ diff --git a/scripts/ensure-bundle-deps.ts b/scripts/ensure-bundle-deps.ts index 4e61a6ecf993..189614bbb044 100644 --- a/scripts/ensure-bundle-deps.ts +++ b/scripts/ensure-bundle-deps.ts @@ -147,12 +147,13 @@ function run(cmd: string, options?: childProcess.ExecSyncOptions): string { // TODO: Not ideal that we're hard-coding this, and it's easy to get when we're in a package directory, but would take // more work to get from the repo level. Fortunately this list is unlikely to change very often, and we're the only ones // we'll break if it gets out of date. -const dependencies = ['@sentry/utils', '@sentry/hub', '@sentry/core']; +const dependencies = ['@sentry/utils', '@sentry/core']; if (['sentry-javascript', 'tracing', 'wasm'].includes(path.basename(process.cwd()))) { dependencies.push('@sentry/browser'); } +// eslint-disable-next-line @typescript-eslint/no-floating-promises void ensureBundleBuildPrereqs({ dependencies, });