Home Reference Source Repository

src/core/devkit.js


import OlapicRestClient from '../tools/rest';
import OlapicUtils from '../tools/utils';
import OlapicCustomersHandler from './entities/customer/customer.handler';
import OlapicWidgetsHandler from './entities/widget/widget.handler';

/**
 * The symbol key to store the singleton on the static object.
 * @type {symbol}
 * @ignore
 */
const singleton = Symbol();
/**
 * The private key to ensure the singleton constructor can only be called from inside this module.
 * @type {symbol}
 * @ignore
 */
const singletonPrivateKey = Symbol();

/**
 * The main singleton for the DevKit project. It handles the first connection to to the API and
 * stores the customer information.
 * To have access to this object, you should always call `.getInstance()`. If you try to
 * instantiate it with the `new` keyword it will throw an error.
 *
 * @example
 * let instance = OlapicDevKit.getInstance();
 */
class OlapicDevKit {
    /**
     * Gets the singleton instance, and optionally sets a new API key.
     * @example
     * let instance = OlapicDevKit.getInstance();
     *
     * @param  {string} [APIKey=null] - The Olapic customer API key.
     * @return {OlapicDevKit} The singleton instance of OlapicDevKit.
     */
    static getInstance(APIKey = null) {
        if (!this[singleton]) {
            this[singleton] = new OlapicDevKit(singletonPrivateKey);
        }

        if (APIKey) {
            this[singleton].APIKey = APIKey;
        }

        return this[singleton];
    }
    /**
     * OlapicDevKit class constructor.
     * @param  {symbol} [singletonKey] - The private key to ensure it can be only call from here.
     * @private
     * @ignore
     */
    constructor(singletonKey) {
        if (singletonKey !== singletonPrivateKey) {
            throw new Error('OlapicDevKit is a singleton, use .getInstance() instead');
        }
        /**
         * The Olapic API entry point.
         * @type {string}
         */
        this.APIUrl = '//photorankapi-a.akamaihd.net';
        /**
         * A flag to know if the instance is connected and has the customer information.
         * @type {boolean}
         */
        this.connected = false;
        /**
         * The rest client that makes the requests to the API.
         * @see {OlapicRestClient}
         * @type {OlapicRestClient}
         */
        this.rest = new OlapicRestClient();
        /**
         * The connected customer information.
         * @see {OlapicCustomerEntity}
         * @type {OlapicCustomerEntity}
         */
        this.customer = null;
        /**
         * The Olapic customer API key.
         * @type {?string}
         * @ignore
         */
        this._APIKey = null;
        /**
         * The API version.
         * @type {string}
         * @ignore
         */
        this._APIVersion = 'v2.2';
        /**
         * The Olapic API endpoints that DevKit may require.
         * @type {Object}
         */
        this._knownEndpoints = {
            categoryByID: '/category/{ID}',
            widgetByHash: '/widgets/{hash}',
            widgetSettingsByID: '/widgets/settings/{ID}',
            customerByID: '/customers/{ID}',
            mediaByID: '/media/{ID}',
            streamByID: '/streams/{ID}',
            userByID: '/users/{ID}',
            instagramUserForCustomer: '/customers/{ID}/instagram_users/{username}',
        };

        this._setRestClientBaseQuery();
    }
    /**
     * This method is called by the setters of APIKey and APIVersion and rewrites the rest
     * client base query string for every request.
     * @private
     * @ignore
     */
    _setRestClientBaseQuery() {
        this.rest.setRequestBaseQuery({
            // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
            auth_token: this._APIKey,
            wrap_responses: 1,
            // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
            version: this._APIVersion,
        });
    }
    /**
     * Connects DevKit to the API and returns the customer entity.
     * @example
     * .connect(widgetID).then((response) => {
     *     let {customer, widget} = response;
     * });
     *
     * @see {OlapicCustomerEntity}
     * @see {OlapicWidgetEntity}
     * @param  {string} [widgetInstance=null] - A widget instance ID so the connection will also
     *                                          retrieve a widget entity.
     * @return {Promise<Object, Error>} If the widget instance is specified, it will return an
     *                                  Object with the keys customer and widget, otherwise, it
     *                                  will return a customer entity.
     */
    connect(widgetInstance = '') {
        return new Promise(((resolve, reject) => {
            if (this.connected && this.customer) {
                resolve(this.customer);
            } else {
                let url = this.APIUrl;
                if (widgetInstance) {
                    url += '/widgets/' + widgetInstance;
                }

                this.rest.get(url).then((response) => {
                    this.connected = true;
                    this.customer = OlapicCustomersHandler.entityFromJSON(response);
                    if (widgetInstance) {
                        resolve({
                            customer: this.customer,
                            widget: OlapicWidgetsHandler.entityFromJSON(response),
                        });
                    } else {
                        resolve(this.customer);
                    }
                }).catch(reject);
            }
        }).bind(this));
    }
    /**
     * Disconnect DevKit from the current customer.
     */
    disconnect() {
        this.connected = false;
        this.customer = null;
    }
    /**
     * Get one of the endpoints for the Olapic API.
     * @example
     * // Returns .../category/12
     * .getEndpoint('categoryByID', { ID: 12 });
     * // Returns .../widgets/abc
     * .getEndpoint('widgetByHash', { hash: 'abc' });
     * // Returns .../widgets/settings/12
     * .getEndpoint('widgetSettingsByID', { ID: 12 });
     * // Returns .../customers/12
     * .getEndpoint('customerByID', { ID: 12 });
     * // Returns .../media/12
     * .getEndpoint('mediaByID', { ID: 12 });
     * // Returns .../streams/12
     * .getEndpoint('streamByID', { ID: 12 });
     * // Returns .../users/12
     * .getEndpoint('userByID', { ID: 12 });
     * // Returns .../customers/12/instagram_users/olapic
     * .getEndpoint('instagramUserForCustomer', { ID: 12, username: 'olapic'});
     *
     * @param  {string} endpoint        - The endpoint name.
     * @param  {Object} [parameters={}] - A list of required parameters for the endpoint.
     * @return {string} The generated API endpoint.
     */
    getEndpoint(endpoint, parameters = {}) {
        let url = this._knownEndpoints[endpoint];
        if (url) {
            url = this.APIUrl + url;
            url = OlapicUtils.assignToString(url, parameters);
        }

        return url ? url : null;
    }
    /**
     * Set the Olapic customer API key.
     * @type string
     */
    set APIKey(value) {
        this._APIKey = value;
        this._setRestClientBaseQuery();
    }
    /**
     * Get the Olapic customer API key.
     * @type string
     */
    get APIKey() {
        return this._APIKey;
    }
    /**
     * Set the Olapic API version to use.
     * @type string
     */
    set APIVersion(value) {
        this._APIVersion = value;
        this._setRestClientBaseQuery();
    }
    /**
     * Get the Olapic API version.
     * @type string
     */
    get APIVersion() {
        return this._APIVersion;
    }

}
/**
 * @type {OlapicDevKit}
 * @module OlapicDevKit
 */
export default OlapicDevKit;