UNPKG

@cargochain/sdk-js

Version:

The CargoChain platform allows application developers to build supply chain solutions that enable the secure distribution of cargo information among trusted partners.

154 lines (134 loc) 4.73 kB
const Fetcher = require('./Fetcher'); const ReferenceDataClient = require('./ReferenceDataClient'); const ProfileClient = require('./ProfileClient'); const singleton = Symbol(); const singletonEnforcer = Symbol(); /** * This singleton class represents the CargoChain JS client. In order to call the CargoChain API, * you have to use the instance of this class by specifying the URL of the CargoChain API. */ class CargoChainClient { constructor(enforcer) { if (enforcer !== singletonEnforcer) { throw new Error('Cannot construct singleton'); } this._apiServerUrl = null; this._accessToken = null; this._profileClient = null; this._referenceDataClient = null; this._onAccessTokenExpired = null; } /** * Gets the instance of this class. * @returns {CargoChainClient} The instance. * @example * var client = CargoChainClient.instance; */ static get instance() { if (!this[singleton]) { this[singleton] = new CargoChainClient(singletonEnforcer); } return this[singleton]; } /** * Sets the CargoChain API url. * @param {string} apiServerUrl - A string that represents the CargoChain API url. */ setUrl(apiServerUrl) { if (apiServerUrl) this._apiServerUrl = apiServerUrl.endsWith('/') ? apiServerUrl.substring(0, apiServerUrl.length - 1) : apiServerUrl; else this._apiServerUrl = null; } /** * Gets the CargoChain API url. */ getUrl() { return this._apiServerUrl; } /** * Sets the access token used by the client. * @param {string} value - The access token. */ setAccessToken(value) { this._accessToken = value; } /** * Gets the access token. */ getAccessToken() { return this._accessToken; } /** * Occurs when the Access Token has expired or is invalid. * This event allows to generate and specify a new access token. * @param {function} callback */ setOnAccessTokenExpiredHandler(callback) { this._onAccessTokenExpired = callback; } /** * Gets the ProfileClient. * @returns {ProfileClient} An instance of the ProfileClient. */ get profile() { if (!this._profileClient) { this._profileClient = new ProfileClient(this); } return this._profileClient; } /** * Gets the ReferenceDataClient. * @returns {ReferenceDataClient} An instance of the ReferenceDataClient. */ get referenceData() { if (!this._referenceDataClient) { this._referenceDataClient = new ReferenceDataClient(this); } return this._referenceDataClient; } _getFetcher() { return Fetcher; } _get(url, data) { return this._sendRequestWithRetry(() => this._getFetcher().get(this._apiServerUrl + url, data, this.getAccessToken())); } _getPagedResponse(url, page, data) { var params = Object.assign({}, data, page); return this._sendRequestWithRetry( () => this._getFetcher().get(this._apiServerUrl + url, params, this.getAccessToken()), res => { return { data: res.data.data, page: res.data.page, isSuccess: res.isSuccess, message: res.message, statusCode: res.statusCode }; }); } _post(url, data) { return this._sendRequestWithRetry(() => this._getFetcher().post(this._apiServerUrl + url, data, this.getAccessToken())); } _sendRequestWithRetry(request, formatter) { if (!(formatter && {}.toString.call(formatter) === '[object Function]')) { formatter = x => x; } return new Promise((resolve) => { request().then((res) => { if (!res.isSuccess && res.statusCode === 401) { // Retry with new access token if (this._onAccessTokenExpired && {}.toString.call(this._onAccessTokenExpired) === '[object Function]') { this._onAccessTokenExpired(); request().then((res2) => { resolve(formatter(res2)); }); } } else { resolve(formatter(res)); } }); }); } } module.exports = CargoChainClient;