diff --git a/README.md b/README.md index 2b018a2..951f200 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,15 @@ yarn add @incognia/api Require the package: CommonJS modules: + ```js const { IncogniaApi } = require('@incognia/api') ``` Or ES modules: + ```js -import { IncogniaApi } from "@incognia/api"; +import { IncogniaApi } from '@incognia/api' ``` Instantiate with your clientId and clientSecret: @@ -41,6 +43,18 @@ const incogniaApi = new IncogniaApi({ }) ``` +Additionally, the Incognia API instance can be stored in a global instance as follows. This implementation makes +sure that a single Incognia API client is created and used. + +```js +IncogniaApi.setSingletonInstance( + new IncogniaApi({ clientId: 'clientId', clientSecret: 'clientSecret' }) +) + +// Retrieves the stored instance +const incogniaApi = IncogniaApi.getSingletonInstance() +``` + ## API methods ### Registering a Mobile Signup @@ -77,7 +91,7 @@ This method registers a new web signup for the given session token, returning a ```js try { const signup = await incogniaApi.registerWebSignup({ - sessionToken: 'session_token', + sessionToken: 'session_token' }) } catch (error) { console.log(error.message) @@ -108,14 +122,13 @@ This method registers a new web login for the given session token and account, r try { const login = await incogniaApi.registerWebLogin({ sessionToken: 'session_token', - accountId: 'account_id', + accountId: 'account_id' }) } catch (error) { console.log(error.message) } ``` - ### Registering a Payment This method registers a new payment for the given installation and account, returning a transaction assessment, containing the risk assessment and supporting evidence. diff --git a/src/incogniaApi.ts b/src/incogniaApi.ts index ce992dd..039c90d 100644 --- a/src/incogniaApi.ts +++ b/src/incogniaApi.ts @@ -56,6 +56,37 @@ export const apiEndpoints: ApiEndpoints = { } export class IncogniaApi { + /* + ** Singleton support + */ + + private static instance?: IncogniaApi + + public static setSingletonInstance(instance: IncogniaApi): void { + if (!IncogniaApi.instance) { + if (!instance) { + throw new IncogniaError( + 'No instance provided to set as singleton instance' + ) + } + IncogniaApi.instance = instance + } + } + + public static getSingletonInstance(): IncogniaApi { + if (!IncogniaApi.instance) { + throw new IncogniaError('No singleton instance set') + } + return IncogniaApi.instance + } + + public static resetSingletonInstance(): void { + IncogniaApi.instance = undefined + } + + /* + ** Implementation + */ readonly clientId: string readonly clientSecret: string incogniaToken: IncogniaToken | null diff --git a/test/incogniaApi.test.ts b/test/incogniaApi.test.ts index 968b85a..0f6a48c 100644 --- a/test/incogniaApi.test.ts +++ b/test/incogniaApi.test.ts @@ -24,7 +24,7 @@ const credentials = { clientSecret: 'clientSecret' } -describe('API', () => { +describe('IncogniaApi', () => { beforeEach(() => { nock.cleanAll() incogniaApi = new IncogniaApi(credentials) @@ -236,7 +236,7 @@ describe('API', () => { ) const expectedData = { - event: FeedbackEvent.AccountTakeover, + event: FeedbackEvent.AccountTakeover } const expectedParams = { @@ -265,8 +265,8 @@ describe('API', () => { paymentId: 'payment_id', signupId: 'signup_id', timestamp: 123, - occurredAt: new Date("Jul 19 2024 01:02:03 UTC"), - expiresAt: new Date("Jul 30 2024 01:02:03 UTC"), + occurredAt: new Date('Jul 19 2024 01:02:03 UTC'), + expiresAt: new Date('Jul 30 2024 01:02:03 UTC') }, { dryRun: true @@ -402,4 +402,35 @@ describe('API', () => { expect(initIncognia).toThrowError(IncogniaError) }) }) + + describe('Singleton support', () => { + beforeEach(() => IncogniaApi.resetSingletonInstance()) + + it('sets and gets the singleton instance', () => { + IncogniaApi.setSingletonInstance(incogniaApi) + + const newClient = new IncogniaApi(credentials) + IncogniaApi.setSingletonInstance(newClient) + + expect(IncogniaApi.getSingletonInstance()).toEqual(incogniaApi) + }) + + it('throws an error when no singleton instance is set', () => { + const getSingletonInstance = () => { + IncogniaApi.getSingletonInstance() + } + expect(getSingletonInstance).toThrow('No singleton instance set') + expect(getSingletonInstance).toThrowError(IncogniaError) + }) + + it('throws an error when no instance is provided', () => { + const setSingletonInstance = () => { + IncogniaApi.setSingletonInstance(null as any) + } + expect(setSingletonInstance).toThrow( + 'No instance provided to set as singleton instance' + ) + expect(setSingletonInstance).toThrowError(IncogniaError) + }) + }) })