diff --git a/src/echo.ts b/src/echo.ts index c39149fa..30819c15 100644 --- a/src/echo.ts +++ b/src/echo.ts @@ -14,6 +14,7 @@ import { SocketIoPrivateChannel, } from './channel'; import { Connector, PusherConnector, SocketIoConnector, NullConnector } from './connector'; +import { isConstructor } from './util'; /** * This class is the primary API for interacting with broadcasting. @@ -60,8 +61,8 @@ export default class Echo { this.connector = new SocketIoConnector(this.options); } else if (this.options.broadcaster == 'null') { this.connector = new NullConnector(this.options); - } else if (typeof this.options.broadcaster == 'function') { - this.connector = this.options.broadcaster(this.options as EchoOptions<'function'>); + } else if (typeof this.options.broadcaster == 'function' && isConstructor(this.options.broadcaster)) { + this.connector = new this.options.broadcaster(this.options as EchoOptions<'function'>); } else { throw new Error( `Broadcaster ${typeof this.options.broadcaster} ${this.options.broadcaster} is not supported.` @@ -261,11 +262,13 @@ type Broadcaster = { }; }; +type Constructor = new (...args: any[]) => T; + type EchoOptions = { /** * The broadcast connector. */ - broadcaster: T extends 'function' ? (options: EchoOptions) => any : T; + broadcaster: T extends 'function' ? Constructor> : T; [key: string]: any; }; diff --git a/src/util/index.ts b/src/util/index.ts index dd12291d..cf233c22 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1 +1,11 @@ +function isConstructor(obj: any): obj is new (...args: any[]) => any { + try { + new obj(); + } catch (err) { + if (err.message.includes('is not a constructor')) return false; + } + return true; +} + +export { isConstructor }; export * from './event-formatter'; diff --git a/tests/echo.test.ts b/tests/echo.test.ts index 910d7533..bf12a061 100644 --- a/tests/echo.test.ts +++ b/tests/echo.test.ts @@ -1,4 +1,5 @@ import Echo from '../src/echo'; +import { NullConnector } from '../src/connector'; describe('Echo', () => { test('it will not throw error for supported driver', () => { @@ -15,7 +16,10 @@ describe('Echo', () => { ); expect(() => new Echo({ broadcaster: 'null' })).not.toThrowError('Broadcaster string null is not supported.'); + expect(() => new Echo({ broadcaster: NullConnector })).not.toThrowError(); + // eslint-disable-next-line + // @ts-ignore // eslint-disable-next-line @typescript-eslint/no-empty-function expect(() => new Echo({ broadcaster: () => {} })).not.toThrowError('Broadcaster function is not supported.'); });