Skip to content

Commit ed7652c

Browse files
committed
WIP: add convertIntegrationFnToClass util
1 parent d53b30c commit ed7652c

File tree

2 files changed

+84
-7
lines changed

2 files changed

+84
-7
lines changed

packages/core/src/integration.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import type { Client, Event, EventHint, Integration, IntegrationFn, IntegrationFnResult, Options } from '@sentry/types';
1+
import type {
2+
Client,
3+
Event,
4+
EventHint,
5+
Integration,
6+
IntegrationClass,
7+
IntegrationFn,
8+
IntegrationFnResult,
9+
Options,
10+
} from '@sentry/types';
211
import { arrayify, logger } from '@sentry/utils';
312

413
import { DEBUG_BUILD } from './debug-build';
@@ -160,22 +169,44 @@ function findIndex<T>(arr: T[], callback: (item: T) => boolean): number {
160169
* Generate a full integration function from a simple function.
161170
* This will ensure to add the given name both to the function definition, as well as to the integration return value.
162171
*/
163-
export function makeIntegrationFn<
164-
Fn extends (...rest: any[]) => Partial<IntegrationFnResult>,
165-
>(name: string, fn: Fn): ((...rest: Parameters<Fn>) => ReturnType<Fn> & { name: string }) & { id: string } {
172+
export function makeIntegrationFn<Fn extends (...rest: any[]) => Partial<IntegrationFnResult>>(
173+
name: string,
174+
fn: Fn,
175+
): ((...rest: Parameters<Fn>) => ReturnType<Fn> & { name: string }) & { id: string } {
166176
const patchedFn = addIdToIntegrationFnResult(name, fn);
167177

168-
169178
return Object.assign(patchedFn, { id: name });
170179
}
171180

181+
/**
182+
* Convert a new integration function to the legacy class syntax.
183+
* In v8, we can remove this and instead export the integration functions directly.
184+
*/
185+
export function convertIntegrationFnToClass<Fn extends IntegrationFn<(...rest: any[]) => IntegrationFnResult>>(
186+
fn: Fn,
187+
): IntegrationClass<Integration> {
188+
return Object.assign(
189+
function ConvertedIntegration(...rest: any[]) {
190+
const res = {
191+
// eslint-disable-next-line @typescript-eslint/no-empty-function
192+
setupOnce: () => {},
193+
...fn(...rest),
194+
name: fn.id,
195+
};
196+
197+
return res;
198+
},
199+
{ id: fn.id },
200+
) as unknown as IntegrationClass<Integration>;
201+
}
202+
172203
function addIdToIntegrationFnResult<Fn extends (...rest: any[]) => Partial<IntegrationFnResult>>(
173204
name: string,
174205
fn: Fn,
175206
): (...rest: Parameters<Fn>) => ReturnType<Fn> & { name: string } {
176-
const patchedFn = ((...rest: Parameters<Fn>): ReturnType<Fn> & { name: string } => {
207+
const patchedFn = (...rest: Parameters<Fn>): ReturnType<Fn> & { name: string } => {
177208
return { ...fn(...rest), name } as ReturnType<Fn> & { name: string };
178-
});
209+
};
179210

180211
return patchedFn;
181212
}

packages/core/test/lib/integration.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { logger } from '@sentry/utils';
44
import { Hub, makeMain } from '../../src/hub';
55
import {
66
addIntegration,
7+
convertIntegrationFnToClass,
78
getIntegrationsToSetup,
89
installedIntegrations,
910
makeIntegrationFn,
@@ -719,3 +720,48 @@ describe('makeIntegrationFn', () => {
719720
makeIntegrationFn('testName', () => ({ other: 'aha' }));
720721
});
721722
});
723+
724+
describe('convertIntegrationFnToClass', () => {
725+
it('works with a minimal integration', () => {
726+
const integrationFn = makeIntegrationFn('testName', () => ({}));
727+
728+
const IntegrationClass = convertIntegrationFnToClass(integrationFn);
729+
730+
expect(IntegrationClass.id).toBe('testName');
731+
732+
const integration = new IntegrationClass();
733+
expect(integration).toEqual({
734+
name: 'testName',
735+
setupOnce: expect.any(Function),
736+
});
737+
});
738+
739+
it('works with integration hooks', () => {
740+
const setup = jest.fn();
741+
const setupOnce = jest.fn();
742+
const processEvent = jest.fn();
743+
const preprocessEvent = jest.fn();
744+
745+
const integrationFn = makeIntegrationFn('testName', () => {
746+
return {
747+
setup,
748+
setupOnce,
749+
processEvent,
750+
preprocessEvent,
751+
};
752+
});
753+
754+
const IntegrationClass = convertIntegrationFnToClass(integrationFn);
755+
756+
expect(IntegrationClass.id).toBe('testName');
757+
758+
const integration = new IntegrationClass();
759+
expect(integration).toEqual({
760+
name: 'testName',
761+
setupOnce,
762+
setup,
763+
processEvent,
764+
preprocessEvent,
765+
});
766+
});
767+
});

0 commit comments

Comments
 (0)