/**
* @copyright Copyright (c) 2015, All Rights Reserved.
* @licence MIT
* @author Eric Peterson
*
* @file Handy extension to native Web Data Connector objects.
*/
// jscs:disable disallowMultipleVarDecl,safeContextKeyword
exports = module.exports = Connector;
// Scoping insanity.
var _tableau,
_this;
/**
* A native Tableau web data connector object, decorated with several utility
* methods that prevent the need to reach out to the global tableau object.
*
* @class
*/
function Connector(tableau) {
_tableau = tableau;
_this = this;
// Turns out this doesn't do much anyway and isn't really necessary...
// tableau.makeConnector();
// Create a space where we can store data getter promises.
this.semaphore = {};
}
/**
* Registers a promise with the connector for a particular table's data. This
* promise can be read from and chained via the waitForData method.
*
* @param {string} tableId - The ID of the table for which the given promise is
* being registered.
*
* @param {Promise} promise - The promise returned by the data retrieval callback
* associated with this table.
*
* @returns {Promise}
* @see wdcw~dataRetrieval
*/
Connector.prototype.registerDataRetrieval = function regRet(tableId, promise) {
_this.semaphore[tableId] = promise;
return promise;
};
/**
* Returns a promise that resolves when data collection for the given table
* completes. The promise will resolve with the full set of data returned for
* the given table.
*
* @param {string} tableId - The ID of the table whose data you are waiting for.
*
* @returns {Promise}
* @throws An error if no data retrieval promise has been registered for the
* given table.
*
* @see {@link Connector#registerDataRetrieval}
*
* @example
* connector.waitForData('independentTable')
* .then(function (independentTableData) {
* // Do things based on the independentTable's data here.
* });
*/
Connector.prototype.waitForData = function waitForData(tableId) {
if (!_this.semaphore.hasOwnProperty(tableId)) {
throw 'Could not find data gathering semaphore for table: ' + tableId;
}
return _this.semaphore[tableId];
};
/**
* Extension of the web data connector API that handles complex connection
* data getting for the implementor.
*
* @param {?string} key - An optional key to return an individual connection
* detail. If no key is provided, all connection details will be returned.
*
* @returns {Object|string}
* An object representing connection data. Keys are assumed to be form input
* names; values are assumed to be form input values. If a key was provided
* as, an individual connection detail will be returned as a string.
*
* @see connector.setConnectionData
*/
Connector.prototype.getConnectionData = function getConnectionData(key) {
var json = _tableau.connectionData ? JSON.parse(_tableau.connectionData) : {};
if (key) {
return json.hasOwnProperty(key) ? json[key] : '';
} else {
return json;
}
};
/**
* Extension of the web data connector API that handles complex connection
* data setting for the implementor.
*
* @param {Object} data - The data that's intended to be set for this
* connection. Keys are assumed to be form input names; values are assumed to
* be form input values.
*
* @returns {Object}
* Returns the data that was set.
*
* @see connector.getConnectionData
*/
Connector.prototype.setConnectionData = function setConnectionData(data) {
_tableau.connectionData = JSON.stringify(data);
return data;
};
/**
* Extension of the web data connector API that gets the connection username.
*
* @returns {string}
* The username associated with this connection.
*/
Connector.getUsername = function getUsername() {
return _tableau.username;
};
/**
* Extension of the web data connector API that sets the connection username.
*
* @param {string} username
* The username to be associated with this connection.
*
* @returns {string}
* The username now associated with this connection.
*/
Connector.prototype.setUsername = function setUsername(username) {
_tableau.username = username;
return _tableau.username;
};
/**
* Extension of the web data connector API that gets the connection password.
*
* @returns {string}
* The password associated with this connection.
*/
Connector.prototype.getPassword = function getPassword() {
return _tableau.password;
};
/**
* Extension of the web data connector API that sets the connection password.
*
* @param {string} password - The password or other sensitive connection
* information to be associated with this connection. The value is encrypted
* and stored by tableau.
*
* @returns {string}
* The password now associated with this connection.
*/
Connector.prototype.setPassword = function setPassword(password) {
_tableau.password = password;
return _tableau.password;
};
/**
* A generic error handler that can be used by implementors for simplicity.
*
* @param {Object} jqXHR
* @param {string} textStatus
* @param {string} errThrown
*/
Connector.prototype.ajaxErrorHandler = function (jqXHR, textStatus, errThrown) {
var message = 'There was a problem retrieving data: "' +
textStatus + '" with error thrown: "' +
errThrown + '"';
_tableau.abortWithError(message);
};
/**
* Generic error handler that can be passed to any Promise error handler.
*
* @param e
*/
Connector.prototype.promiseErrorHandler = function tableauErrorHandler(e) {
if (typeof e === 'string') {
_tableau.abortWithError(e);
} else {
_tableau.abortWithError(JSON.stringify(e));
}
};
/**
* Helper method used to determine whether or not authentication is being
* attempted for an ad-hoc query (Desktop) or in an automated context (Server).
* Useful when dealing with restrictive oauth providers.
*
* @returns {string}
* The authentication purpose. One of:
* - ephemeral: when the user is authenticating with Tableau Desktop.
* - enduring: when authentication is being performed on Server.
*/
Connector.prototype.getAuthPurpose = function getAuthPurpose() {
return _tableau.authPurpose;
};