import { FgCredentialAPI } from './apis/credential-api'; import { FgFunctionsAPI } from './apis/functions-api'; import { FgIdentityAPI } from './apis/identity-api'; import { FgLeaderboardAPI } from './apis/leaderboard-api'; import { FgLoggerAPI } from './apis/logger-api'; import { FgStorageAPI } from './apis/storage-api'; import { FgStorageFilesAPI } from './apis/storage-files-api'; import { FgStorageKdbAPI } from './apis/storage-kdb-api'; import { FgStoreAPI } from './apis/store-api'; import { FetchRequestDriver, AxiosRequestDriver } from './drivers'; import { EnvironmentType } from './enum/environment.type'; import { StringActionDelegate } from './enum/string-action-delegate'; import { ICredentialObject } from './interfaces/credential-object.interface'; import { IEncryptionDriver } from './interfaces/encryption-driver.interface'; import { IRequestDriver } from './interfaces/request-driver.interface'; import { IStorageConnectionCredentials } from './interfaces/storage-connection-credentials.interface'; import { BaseAPIConstructorOpts } from './logic/base/base-api-constructor-opts'; import { FgStorageConnectedAPIConstructorParameters } from './logic/storage/fg-storage-connected-api-constructor-params'; import { CredentialSessionManager } from './managers/credential-session-manager'; import { EncryptionManager } from './managers/encryption-manager'; import { IdentitySessionManager } from './managers/identity-session.manager'; import { AsyncUtils } from './utils/async-utils'; // eslint-disable-next-line no-var declare var window: any; export class Nexus { /** * @type {Nexus} */ static instance: Nexus; private _requestDriver: IRequestDriver; private _encryptionDriver: IEncryptionDriver; private _environment: EnvironmentType; private _timeout: number; private _credentialsMgr: CredentialSessionManager; private _credentials: ICredentialObject; private _keys: any; private _baseUrl: string; constructor(opts) { Nexus.instance = this; const { // Alt 1: KS login key = null, secret = null, // Alt 2: KS-Token login keySecretToken = null, // Alt 2 Plus: Already logged-in token credentialSessionToken = null, // --- requestDriver = null, encryptionDriver = null, baseUrl = null, environment = 'production', timeout = 30, keys = {}, } = opts; if (!requestDriver || requestDriver === 'fetch') { this._requestDriver = new FetchRequestDriver(); } else if (requestDriver === 'axios') { this._requestDriver = new AxiosRequestDriver(opts.axios || window.axios); } else { this._requestDriver = requestDriver; } this._encryptionDriver = encryptionDriver || new EncryptionManager(); if ((!key || !secret) && !keySecretToken) { throw new Error('Key and secret are required.'); } if (!['production', 'development', 'rapidapi'].includes(environment)) { throw new Error('Environment must be one of: production, development, rapidapi.'); } this._environment = environment; this._timeout = timeout; this._credentialsMgr = new CredentialSessionManager(undefined, this._encryptionDriver); if (keySecretToken) { this._credentialsMgr.saveCredentialToken(keySecretToken); } else { this._credentialsMgr.saveCredential({ key, secret }); } const credentialLoaded = this._credentialsMgr.loadCredential(); const credentialTokenForLogin = credentialLoaded?.token; this._credentials = { // Key-secret condensed in a token credential: credentialTokenForLogin || null, // Token used if was logged in previously to not login again token: credentialSessionToken || null, }; this._keys = keys; this._baseUrl = baseUrl; } get isProduction() { return this._environment === 'production' || this._environment === 'rapidapi'; } get credentialTokenForLogin(): string | null { return this._credentials?.credential; } get credentialToken(): string | null { return this._credentials?.token; } async login() { if (this._credentials.token) { // Already logged in return; } const credentialAPI = this._createInstance(FgCredentialAPI, { onLogin: newToken => { this._credentials.token = newToken; } }); await credentialAPI.isWorking(); let timeout = this._timeout; while (!this._credentials.token) { await AsyncUtils.wait(1000); if (timeout-- === 0) { throw new Error('Timeout reached.'); } } } logout() { /*if (this.credentialAPI != null) { // TODO Logout }*/ } getKdb(dbCredentials: IStorageConnectionCredentials) { return new FgStorageKdbAPI(this._createKdbAPIConstructorParams(dbCredentials)); } getFiles(dbCredentials: IStorageConnectionCredentials) { return new FgStorageFilesAPI(this._createKdbAPIConstructorParams(dbCredentials)); } /** * Logger API. * @returns {FgLoggerAPI} */ getLogger() { return this._createInstance(FgLoggerAPI) as FgLoggerAPI; } /** * Identity API. * @returns {FgIdentityAPI} */ getIdentity() { return this._createInstance(FgIdentityAPI, null, { token: this._credentials.credential }) as FgIdentityAPI; } /** * Store API. * @returns {FgStoreAPI} */ getStore() { return this._createInstance(FgStoreAPI, null, { token: this._credentials.credential }) as FgStoreAPI; } /** * Functions API. * @returns {FgFunctionsAPI} */ getFunctions() { return this._createInstance(FgFunctionsAPI) as FgFunctionsAPI; } /** * Store API. * @returns {FgStorageAPI} */ getStorage() { return this._createInstance(FgStorageAPI) as FgStorageAPI; } /** * Leaderboard API. * @returns {FgLeaderboardAPI} */ getLeaderboard() { return this._createInstance(FgLeaderboardAPI) as FgLeaderboardAPI; } getIdentitySessionManager() { return new IdentitySessionManager(this); } private _createKdbAPIConstructorParams(dbCredentials: IStorageConnectionCredentials, onLogin?: StringActionDelegate) { const opts = new BaseAPIConstructorOpts(); Object.assign(opts, { environment: this._environment, isProduction: this.isProduction, keys: this._keys, onLogin: onLogin, }); const ctor = new FgStorageConnectedAPIConstructorParameters(dbCredentials, this._requestDriver, this._encryptionDriver, this._baseUrl, opts, this._credentials); return ctor; } private _createInstance(ApiClass, settings: any = {}, extraArgs?: any) { const opts = { isProduction: this.isProduction, environment: this._environment, keys: this._keys }; const finalSettings = Object.assign({}, opts, settings); const args = { encryptionDriver: this._encryptionDriver, requestDriver: this._requestDriver, baseUrl: this._baseUrl, opts: finalSettings, credentialObject: this._credentials }; if (extraArgs) { Object.assign(args, extraArgs); } return new ApiClass(args); } } /** * @deprecated Use 'Nexus' instead of 'FgAPI'. */ export const FgAPI = Nexus;