Skip to content

Commit 5498a78

Browse files
authored
feat(core): Add client.getIntegrationByName() (#10130)
And also deprecate both `getIntegration()` as well as `getIntegrationById()` which is only on the baseclient, but not on the client type, anyhow :grimace:. Usage: ```ts const replay = getClient().getIntegrationByName('Replay'); ``` Or, if you want to have an easier time with types: ```ts const replay = getClient().getIntegrationByName<Replay>('Replay'); ``` ## Why do we need this In v8, integrations will not be classes anymore, so you cannot pass a class definition anymore to `getIntegration()`. We also decided to remove the static `id` field, so you cannot find an integration via that way anymore. `getIntegrationById()` was always just on the baseclient, so not properly types anyhow. It is also an inconsistent/weird naming because we will not have an `id` anymore for integrations at all.
1 parent dd72e4d commit 5498a78

File tree

25 files changed

+86
-54
lines changed

25 files changed

+86
-54
lines changed

MIGRATION.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ but in v8 you will not be able to rely on this always existing anymore - any int
1919
This should not affect most people, but in the case that you are manually calling `integration.setupOnce()` right now,
2020
make sure to guard it's existence properly.
2121

22+
## Deprecate `getIntegration()` and `getIntegrationById()`
23+
24+
This deprecates `getIntegration()` on both the hub & the client, as well as `getIntegrationById()` on the baseclient.
25+
Instead, use `getIntegrationByName()`. You can optionally pass an integration generic to make it easier to work with
26+
typescript:
27+
28+
```ts
29+
const replay = getClient().getIntegrationByName<Replay>('Replay');
30+
```
31+
2232
## Deprecate `Hub`
2333

2434
The `Hub` has been a very important part of the Sentry SDK API up until now. Hubs were the SDK's "unit of concurrency"

dev-packages/browser-integration-tests/loader-suites/loader/onLoad/customBrowserTracing/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ sentryTest('should handle custom added BrowserTracing integration', async ({ get
2727
expect(eventData.transaction_info?.source).toEqual('url');
2828

2929
const tracePropagationTargets = await page.evaluate(() => {
30-
const browserTracing = (window as any).Sentry.getClient().getIntegrationById('BrowserTracing');
30+
const browserTracing = (window as any).Sentry.getClient().getIntegrationByName('BrowserTracing');
3131
return browserTracing.options.tracePropagationTargets;
3232
});
3333

dev-packages/browser-integration-tests/loader-suites/loader/onLoad/customIntegrations/test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ sentryTest('should handle custom added integrations & default integrations', asy
2424
});
2525

2626
const hasCustomIntegration = await page.evaluate(() => {
27-
return !!(window as any).Sentry.getClient().getIntegrationById('CustomIntegration');
27+
return !!(window as any).Sentry.getClient().getIntegrationByName('CustomIntegration');
2828
});
2929

3030
const hasReplay = await page.evaluate(() => {
31-
return !!(window as any).Sentry.getClient().getIntegrationById('Replay');
31+
return !!(window as any).Sentry.getClient().getIntegrationByName('Replay');
3232
});
3333
const hasBrowserTracing = await page.evaluate(() => {
34-
return !!(window as any).Sentry.getClient().getIntegrationById('BrowserTracing');
34+
return !!(window as any).Sentry.getClient().getIntegrationByName('BrowserTracing');
3535
});
3636

3737
expect(hasCustomIntegration).toEqual(true);

dev-packages/browser-integration-tests/loader-suites/loader/onLoad/customIntegrationsFunction/test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ sentryTest(
2121
});
2222

2323
const hasCustomIntegration = await page.evaluate(() => {
24-
return !!(window as any).Sentry.getClient().getIntegrationById('CustomIntegration');
24+
return !!(window as any).Sentry.getClient().getIntegrationByName('CustomIntegration');
2525
});
2626

2727
const hasReplay = await page.evaluate(() => {
28-
return !!(window as any).Sentry.getClient().getIntegrationById('Replay');
28+
return !!(window as any).Sentry.getClient().getIntegrationByName('Replay');
2929
});
3030
const hasBrowserTracing = await page.evaluate(() => {
31-
return !!(window as any).Sentry.getClient().getIntegrationById('BrowserTracing');
31+
return !!(window as any).Sentry.getClient().getIntegrationByName('BrowserTracing');
3232
});
3333

3434
expect(hasCustomIntegration).toEqual(true);

dev-packages/browser-integration-tests/loader-suites/loader/onLoad/customReplay/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ sentryTest('should handle custom added Replay integration', async ({ getLocalTes
2727
expect(eventData.segment_id).toBe(0);
2828

2929
const useCompression = await page.evaluate(() => {
30-
const replay = (window as any).Sentry.getClient().getIntegrationById('Replay');
30+
const replay = (window as any).Sentry.getClient().getIntegrationByName('Replay');
3131
return replay._replay.getOptions().useCompression;
3232
});
3333

packages/astro/test/client/sdk.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe('Sentry client SDK', () => {
6161
});
6262

6363
const integrationsToInit = browserInit.mock.calls[0][0]?.integrations;
64-
const browserTracing = getClient<BrowserClient>()?.getIntegrationById('BrowserTracing');
64+
const browserTracing = getClient<BrowserClient>()?.getIntegrationByName('BrowserTracing');
6565

6666
expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' }));
6767
expect(browserTracing).toBeDefined();
@@ -77,7 +77,7 @@ describe('Sentry client SDK', () => {
7777
});
7878

7979
const integrationsToInit = browserInit.mock.calls[0][0]?.integrations;
80-
const browserTracing = getClient<BrowserClient>()?.getIntegrationById('BrowserTracing');
80+
const browserTracing = getClient<BrowserClient>()?.getIntegrationByName('BrowserTracing');
8181

8282
expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' }));
8383
expect(browserTracing).toBeUndefined();
@@ -92,7 +92,7 @@ describe('Sentry client SDK', () => {
9292
});
9393

9494
const integrationsToInit = browserInit.mock.calls[0][0]?.integrations;
95-
const browserTracing = getClient<BrowserClient>()?.getIntegrationById('BrowserTracing');
95+
const browserTracing = getClient<BrowserClient>()?.getIntegrationByName('BrowserTracing');
9696

9797
expect(integrationsToInit).not.toContainEqual(expect.objectContaining({ name: 'BrowserTracing' }));
9898
expect(browserTracing).toBeUndefined();
@@ -109,7 +109,7 @@ describe('Sentry client SDK', () => {
109109

110110
const integrationsToInit = browserInit.mock.calls[0][0]?.integrations;
111111

112-
const browserTracing = getClient<BrowserClient>()?.getIntegrationById('BrowserTracing') as BrowserTracing;
112+
const browserTracing = getClient<BrowserClient>()?.getIntegrationByName('BrowserTracing') as BrowserTracing;
113113
const options = browserTracing.options;
114114

115115
expect(integrationsToInit).toContainEqual(expect.objectContaining({ name: 'BrowserTracing' }));

packages/core/src/baseclient.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,24 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
334334
* Gets an installed integration by its `id`.
335335
*
336336
* @returns The installed integration or `undefined` if no integration with that `id` was installed.
337+
* @deprecated Use `getIntegrationByName()` instead.
337338
*/
338339
public getIntegrationById(integrationId: string): Integration | undefined {
339-
return this._integrations[integrationId];
340+
return this.getIntegrationByName(integrationId);
340341
}
341342

342343
/**
343-
* @inheritDoc
344+
* Gets an installed integration by its name.
345+
*
346+
* @returns The installed integration or `undefined` if no integration with that `name` was installed.
347+
*/
348+
public getIntegrationByName<T extends Integration = Integration>(integrationName: string): T | undefined {
349+
return this._integrations[integrationName] as T | undefined;
350+
}
351+
352+
/**
353+
* Returns the client's instance of the given integration class, it any.
354+
* @deprecated Use `getIntegrationByName()` instead.
344355
*/
345356
public getIntegration<T extends Integration>(integration: IntegrationClass<T>): T | null {
346357
try {

packages/core/src/hub.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,13 +472,14 @@ export class Hub implements HubInterface {
472472

473473
/**
474474
* @inheritDoc
475-
* @deprecated Use `Sentry.getClient().getIntegration()` instead.
475+
* @deprecated Use `Sentry.getClient().getIntegrationByName()` instead.
476476
*/
477477
public getIntegration<T extends Integration>(integration: IntegrationClass<T>): T | null {
478478
// eslint-disable-next-line deprecation/deprecation
479479
const client = this.getClient();
480480
if (!client) return null;
481481
try {
482+
// eslint-disable-next-line deprecation/deprecation
482483
return client.getIntegration(integration);
483484
} catch (_oO) {
484485
DEBUG_BUILD && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);

packages/core/test/lib/base.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,7 @@ describe('BaseClient', () => {
14961496
client.setupIntegrations();
14971497

14981498
expect(Object.keys((client as any)._integrations).length).toEqual(1);
1499-
expect(client.getIntegration(TestIntegration)).toBeTruthy();
1499+
expect(client.getIntegrationByName(TestIntegration.id)).toBeTruthy();
15001500
});
15011501

15021502
test('sets up each integration on `init` call', () => {
@@ -1507,7 +1507,7 @@ describe('BaseClient', () => {
15071507
client.init();
15081508

15091509
expect(Object.keys((client as any)._integrations).length).toEqual(1);
1510-
expect(client.getIntegration(TestIntegration)).toBeTruthy();
1510+
expect(client.getIntegrationByName(TestIntegration.id)).toBeTruthy();
15111511
});
15121512

15131513
test('skips installation for `setupIntegrations()` if DSN is not provided', () => {
@@ -1519,7 +1519,7 @@ describe('BaseClient', () => {
15191519
client.setupIntegrations();
15201520

15211521
expect(Object.keys((client as any)._integrations).length).toEqual(0);
1522-
expect(client.getIntegration(TestIntegration)).toBeFalsy();
1522+
expect(client.getIntegrationByName(TestIntegration.id)).toBeFalsy();
15231523
});
15241524

15251525
test('skips installation for `init()` if DSN is not provided', () => {
@@ -1530,7 +1530,7 @@ describe('BaseClient', () => {
15301530
client.init();
15311531

15321532
expect(Object.keys((client as any)._integrations).length).toEqual(0);
1533-
expect(client.getIntegration(TestIntegration)).toBeFalsy();
1533+
expect(client.getIntegrationByName(TestIntegration.id)).toBeFalsy();
15341534
});
15351535

15361536
test('skips installation for `setupIntegrations()` if `enabled` is set to `false`', () => {
@@ -1546,7 +1546,7 @@ describe('BaseClient', () => {
15461546
client.setupIntegrations();
15471547

15481548
expect(Object.keys((client as any)._integrations).length).toEqual(0);
1549-
expect(client.getIntegration(TestIntegration)).toBeFalsy();
1549+
expect(client.getIntegrationByName(TestIntegration.id)).toBeFalsy();
15501550
});
15511551

15521552
test('skips installation for `init()` if `enabled` is set to `false`', () => {
@@ -1561,7 +1561,7 @@ describe('BaseClient', () => {
15611561
client.init();
15621562

15631563
expect(Object.keys((client as any)._integrations).length).toEqual(0);
1564-
expect(client.getIntegration(TestIntegration)).toBeFalsy();
1564+
expect(client.getIntegrationByName(TestIntegration.id)).toBeFalsy();
15651565
});
15661566

15671567
test('skips installation if integrations are already installed', () => {
@@ -1577,7 +1577,7 @@ describe('BaseClient', () => {
15771577
client.setupIntegrations();
15781578

15791579
expect(Object.keys((client as any)._integrations).length).toEqual(1);
1580-
expect(client.getIntegration(TestIntegration)).toBeTruthy();
1580+
expect(client.getIntegrationByName(TestIntegration.id)).toBeTruthy();
15811581
expect(setupIntegrationsHelper).toHaveBeenCalledTimes(1);
15821582

15831583
// ...but it shouldn't try to install a second time
@@ -1597,7 +1597,7 @@ describe('BaseClient', () => {
15971597
client.init();
15981598

15991599
expect(Object.keys((client as any)._integrations).length).toEqual(1);
1600-
expect(client.getIntegration(TestIntegration)).toBeTruthy();
1600+
expect(client.getIntegrationByName(TestIntegration.id)).toBeTruthy();
16011601
expect(setupIntegrationsHelper).toHaveBeenCalledTimes(1);
16021602

16031603
client.init();

packages/core/test/mocks/integration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class TestIntegration implements Integration {
99

1010
public setupOnce(): void {
1111
const eventProcessor: EventProcessor = (event: Event) => {
12-
if (!getClient()?.getIntegration(TestIntegration)) {
12+
if (!getClient()?.getIntegrationByName?.('TestIntegration')) {
1313
return event;
1414
}
1515

0 commit comments

Comments
 (0)