Core.js

/**
 * Created by pavel.mash on 10.09.2016.
 */

var EventEmitter = require('./events');
var UBNotifierWSProtocol = require('./UBNotifierWSProtocol');
var UBConnection = require('./UBConnection');
var ClientRepository = require('./ClientRepository');
var _ = require('./libs/lodash/lodash');
/*
 * TODO - describe
 * Fired for a {@link Core} instance just after got an application config from server.
 * This is a good place to inject a localization for your application, since on this stage
 * we know a user {@link Core.preferredLocale}.
 *
 * Params: {@link Core} instance
 * @event gotApplicationConfig
 */

/**
 * @classdesc
 * Initialize all necessary data structures for a communication with the UnityBase server
 *
 * Example:
 *
     var $core = new Core({
        host: window.location.origin,
        path: window.location.pathname,
        onCredentialRequired: function(conn, isRepeat){
            if (isRepeat){
                throw new UB.UBAbortError('invalid')
            } else {
                return Q.resolve({authSchema: 'UB', login: 'admin', password: 'admin'})
            }
        },
        onAuthorizationFail:  function(reason){
            alert(reason);
        }
    });

     $core.initialize().then(function($core){
        $core.connection.get('stat').done(function(statResp){
            document.getElementById('ubstat').innerText = JSON.stringify(statResp.data, null, '\t');
        });

        UB.Repository('ubm_navshortcut').attrs(['ID', 'code', 'caption']).selectAsArray().done(function(data){
            var tmpl = _.template(document.getElementById('repo-template').innerHTML);
            var result = tmpl(data.resultData);
            // document.getElementById('ubnav').innerText = JSON.stringify(data.resultData);
            document.getElementById('ubnav').innerHTML = result;
        });
    });

 * @param cfg
 * @param {string} cfg.host Server host
 * @param {string} [cfg.path] API path - the same as in Server config `httpServer.path`
 * @param cfg.onCredentialRequired Callback for requesting a user creadentials. See {@link UBConnection} constructor `requestAuthParams` parameter description
 * @param [cfg.onAuthorizationFail] Callback for authorization failure. See {@link authorizationFail} event.
 * @param [cfg.onNeedChangePassword] Callback for a password exparition. See {@link passwordExpired} event
 * @param [cfg.onGotApplicationConfig]
 * @param [cfg.onGotApplicationDomain]
 * @constructor
 * @mixes EventEmitter
 */
function Core(cfg){
    var config = this.config = _.clone(cfg);

    EventEmitter.call(this);
    _.assign(this, EventEmitter.prototype);
    /**
     * Connection to the server
     * @type {UBConnection}
     */
    this.connection = new UBConnection({
        host: config.host,
        appName: config.path || '/',
        requestAuthParams: config.onCredentialRequired
    });
    if (config.onAuthorizationFail){
        this.connection.on('authorizationFail', this.config.onAuthorizationFail);
    }
    if (config.onNeedChangePassword) {
        this.connection.on('passwordExpired', config.onNeedChangePassword);
    }

    /**
     * WebSocket `ubNotifier` protocol instance
     * @type {UBNotifierWSProtocol}
     */
    this.ubNotifier = null;

    /**
     * Application settings transferred form a server
     * @type {{}}
     */
    this.appConfig = {};

    /**
     * The preferred (used in previous user session if any or a default for application) locale
     * @type {string}
     */
    this.preferredLocale = 'en';

    /**
     * The application domain
     * @type {UBDomain}
     */
    this.domain = null;
}

/**
 * Initialize a Core. Return a promise, resolved to {Core} instance
 * @return {Promise}
 */
Core.prototype.initialize = function(){
    var me = this;
    return this.connection.getAppInfo().then(function(appInfo) {
        // apply a default app settings to the gerAppInfo result
        me.appConfig = _.defaults(_.clone(appInfo), {
            applicationName: 'UnityBase',
            loginWindowTopLogoURL: '',
            loginWindowBottomLogoURL: '',
            themeName: 'UBGrayTheme',
            userDbVersion: null,
            defaultLang: 'en',
            supportedLanguages: ['en'],
        });
        // create ubNotifier after retrieve appInfo (we need to know supported WS protocols)
        me.ubNotifier = new UBNotifierWSProtocol(me.connection);
        // try to determinate default user language
        var preferredLocale = localStorage.getItem(me.connection.appName + 'preferredLocale');
        if (!preferredLocale) {
            preferredLocale = me.appConfig.defaultLang;
        }
        // is language supported by application?
        if (me.appConfig.supportedLanguages.indexOf(preferredLocale) === -1) {
            preferredLocale = me.appConfig.defaultLang;
        }
        me.preferredLocale = preferredLocale;
        if (me.config.onGotApplicationConfig){
            return me.config.onGotApplicationConfig(me)
        } else {
            return true;
        }
    }).then(function(){
        return me.connection.initEncriptionIfNeed();
    }).then(function(){
        return me.connection.initCache(me.appConfig.userDbVersion);
    }).then(function(){
        return me.connection.authorize();
    }).then(function(){
        // here we authorized and know a user-related data
        var myLocale = me.connection.userData('lang');
        localStorage.setItem(me.connection.appName + 'preferredLocale', myLocale);
        me.preferredLocale = myLocale;
        return me.connection.getDomainInfo(me.config.onGotApplicationDomain);
    }).then(function(domain) {
        me.domain = domain;
        //dirty hack
        /**
         * Construct new ClientRepository object using Core.connection as connection parameter value.
         *
         * Warning - method added after UBCore.initialize() is resolved.
         *
         * @memberof UB
         * @method Repository
         * @param {String} entityName
         * @return {ClientRepository}
         */
        window.UB.Repository = function(entityName){
            return new ClientRepository(me.connection, entityName);
        };
        return me;
    });
};

module.exports = Core;