diff --git a/src/eap.ts b/src/eap.ts index c20528eb..e1e349ac 100644 --- a/src/eap.ts +++ b/src/eap.ts @@ -1,12 +1,17 @@ import {SlotId, FetchResponse} from './fetch'; import {NullableJsonObject} from './sdk/json'; +import {Plug} from './plug'; export interface EapFeatures { - fetch

(slotId: I): Promise>; + fetch

(this: Plug, slotId: I): Promise>; +} + +interface EapHooks extends EapFeatures{ + initialize(this: Plug): void; } declare global { interface Window { - croctEap?: Partial; + croctEap?: Partial; } } diff --git a/src/plug.ts b/src/plug.ts index 2d7a6be3..4e3d0d96 100644 --- a/src/plug.ts +++ b/src/plug.ts @@ -230,6 +230,12 @@ export class GlobalPlug implements Plug { ); } + const initializeEap = window.croctEap?.initialize; + + if (typeof initializeEap === 'function') { + initializeEap.call(this); + } + Promise.all(pending).then(() => { this.initialize(); @@ -314,7 +320,7 @@ export class GlobalPlug implements Plug { * This API is unstable and subject to change in future releases. */ public fetch

(slotId: I): Promise> { - return this.eap('fetch')(slotId); + return this.eap('fetch').call(this, slotId); } public async unplug(): Promise { @@ -366,7 +372,7 @@ export class GlobalPlug implements Plug { private eap(feature: T): EapFeatures[T] { const logger = this.sdk.getLogger(); const eap = window.croctEap; - const method = typeof eap === 'object' ? eap[feature] : undefined; + const method: EapFeatures[T] | undefined = typeof eap === 'object' ? eap[feature] : undefined; if (typeof method !== 'function') { throw new Error( @@ -378,6 +384,6 @@ export class GlobalPlug implements Plug { logger.warn(`The ${feature} API is still unstable and subject to change in future releases.`); - return method.bind(eap); + return method; } } diff --git a/test/plug.test.ts b/test/plug.test.ts index 0baab59f..e6be3687 100644 --- a/test/plug.test.ts +++ b/test/plug.test.ts @@ -4,6 +4,7 @@ import {Plugin, PluginFactory} from '../src/plugin'; import {GlobalPlug} from '../src/plug'; import {CDN_URL} from '../src/constants'; import {Token} from '../src/sdk/token'; +import {Plug} from '../build'; jest.mock('../src/constants', () => { return { @@ -119,6 +120,18 @@ describe('The Croct plug', () => { expect(initialize).toBeCalledWith(config); }); + test('should call the EAP initialization hook', () => { + window.croctEap = { + initialize: jest.fn().mockImplementation(function initialize(this: Plug) { + expect(this).toBe(croct); + }), + }; + + croct.plug({appId: APP_ID}); + + expect(window.croctEap.initialize).toBeCalled(); + }); + test('should log failures initializing plugins', () => { croct.extend('foo', () => { throw new Error('Failure'); @@ -856,7 +869,11 @@ describe('The Croct plug', () => { const response = Promise.resolve({payload: {title: 'Hello'}}); window.croctEap = { - fetch: jest.fn().mockReturnValue(response), + fetch: jest.fn().mockImplementation(function fetch(this: Plug) { + expect(this).toBe(croct); + + return response; + }), }; const actualResponse = croct.fetch('foo');