<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: helix_web_services_client.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: helix_web_services_client.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>// The Client object is how people should access the Helix Web Services server // via AJAX calls (that uses jQuery). // // The API here is promise-oriented, which makes it slightly different to work // with than the Ruby or Qt SDKs. // Initialize jQuery that can be tested on node.js or run in a browser. var $ = require('jquery'); // When executing tests, this needs to be used to initialize jquery, which... // is wonderfully automated. //if (typeof(process) == 'undefined') { // $ = require('jquery'); //} else { // $ = require('jquery')(require("jsdom").jsdom().parentWindow); // // var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // // $.support.cors = true; // $.ajaxSettings.xhr = function () { // return new XMLHttpRequest(); // }; //} //if (typeof(btoa) == 'undefined') { // btoa = require('btoa'); //} var assign = require('object-assign'); require('./polyfill'); // Construct a new HelixWebServicesClient interface /** * Create the main client object used to communicate via remote calls. * * @param {Object} options Set various properties on this object. * @constructor */ function HelixWebServicesClient(options) { options = options || {}; /** * The base URL, e.g. `http://example.com` of the web server. * * @type {string} */ this.url = options.url; /** * The Perforce user name. * * @type {string} */ this.user = options.user; /** * If accessing an HWS instance behind a proxy, it's probably available * underneath a subdirectory * * @type {string} */ this.prefix = options.prefix || ""; /** * Set a security token if you know it. This is used for authenticated * methods. * * @type {string} */ this.session_token = options.session_token; this._expiredCallbacks = []; } // Use our main constructor as a namespace for exporting models. HelixWebServicesClient.Models = require('./models'); //------------------------------------------------------------------------- // Local (private) Methods //------------------------------------------------------------------------- // Private method that will call jQuery.ajax and return it's promise. // // Options: // - client // - method // - url // - ... and others, passed to jQuery.ajax directly function authAjax(options) { var ajaxOpts = { beforeSend: function (xhr) { var auth = btoa(options.client.user + ":" + options.client.session_token); xhr.setRequestHeader("Authorization", "Basic " + auth); } }; // Other options are just included into ajaxOpts copy = assign({}, options); delete copy.client; assign(ajaxOpts, copy); var ajax = $.ajax(ajaxOpts); // We check for session expiration failures and trigger a sepcial handler on // our client. var deferred = $.Deferred(); ajax.done(deferred.resolve); ajax.fail(function(jqXHR, textStatus, error) { if (jqXHR.status == 403) { options.client._expiredCallbacks.forEach(function(cb) { cb.call(); }); } else { deferred.reject(jqXHR, textStatus, error); } }); return deferred.promise(); } // Will alter the path, encoding each subpath component along the route, // and encode it to become a path parameter. function normalizePath(path) { if (!path) { return ''; } if (path.startsWith('//')) { path = path.substring(2); } parts = path.split('/'); return parts.map(function(p) { return encodeURIComponent(p); }).join('/'); } assign(HelixWebServicesClient.prototype, { //------------------------------------------------------------------------- // Callbacks //------------------------------------------------------------------------- /** * When your session expires on any particular call, this callback will get * triggered. * * @param {function} callback A function() {} that gets called back if the * session is no longer valid. */ addSessionExpiredHandler: function(callback) { this._expiredCallbacks.push(callback); }, //------------------------------------------------------------------------- // Asynchronous Methods //------------------------------------------------------------------------- /** * Creates a new session token by logging into the server. * * @param {String} [user] Optional attribute. If you specify it, we'll cache it as the * `user` property. * @param {String} password Required Perforce password for the user. * @returns {Promise.<String>|Promise.<jqXHR, String, error>} On success, * you'll receive the security token, which will be cached on this client * object as the `session_token` property. * @memberOf! HelixWebServicesClient# */ logIn: function (user, password) { if (!password) { password = user; user = this.user; } // TODO we very likely want to configure ajax for common error handling var ajax = $.post( this.urlTo('/auth/v1/sessions'), {user: this.user, password: password} ); // We wrap the promise in order to cache the session before done() is // invoked. var deferred = $.Deferred(); var self = this; ajax.done(function (data, textStatus, jqXHR) { self.session_token = data; deferred.resolve(self.session_token); }); ajax.fail(function (jqXHR, textStatus, error) { deferred.reject(jqXHR, textStatus, error); }); return deferred.promise(); }, /** * Destroys the session (on the server) * * @returns {Promise|Promise<jqXHR, textStatus, error>} * @memberOf! HelixWebServicesClient# */ logOut: function () { var ajax = authAjax({ client: this, method: 'DELETE', url: this.urlTo('/auth/v1/sessions/' + this.session_token) }); var deferred = $.Deferred(); ajax.done(function () { deferred.resolve(); }); ajax.fail(deferred.reject); return deferred.promise(); }, /** * List files at the particular directory level. * * @param {String} path The directory to list. Should be an absolute depot * path, e.g., `//depot/dirA`. When empty, this lists * depots in the system. * * @returns {Promise.<Array.<PathItem>>|Promise.<jqXHR, String, error>} * Promises resolve to a list of PathItem models or the error data. Each * PathItem is either all depot paths (if `path` is empty) or the child * Directory or Files of `path`. * * @memberOf! HelixWebServicesClient# */ listFiles: function (path) { var subPath = normalizePath(path); var ajax = authAjax({ client: this, method: 'GET', url: this.urlTo('/perforce/v1/files/' + subPath), dataType: 'json' }); var deferred = $.Deferred(); ajax.done(function (items) { var arr = HelixWebServicesClient.Models.PathItem.fromArray(items); deferred.resolve(arr); }); ajax.fail(deferred.reject); return deferred.promise(); }, /** * Create a new Helix Sync project. * * @param {Object|Project} project * @returns {Promise.<Project>|Promise.<jqXHR, String, error>} Will return * the 'updated' project structure, which likely has several default * configuration values set. * @memberOf! HelixWebServicesClient# */ createSyncProject: function (project) { var ajax = authAjax({ client: this, method: 'POST', url: this.urlTo('/sync/v1/projects'), data: JSON.stringify(project), contentType: 'application/json', dataType: 'json', processData: false }); var deferred = $.Deferred(); ajax.done(function (updated) { deferred.resolve(updated); }); ajax.fail(deferred.reject); return deferred.promise(); }, /** * List the Helix Sync projects the current user is a member of. * * @returns {*|Promise.<Array.<Project>>|Promise.<jqXHR, textStatus, error>} * @memberOf! HelixWebServicesClient# */ listMySyncProjects: function () { return this.syncProjects({members: this.user}); }, /** * List all Helix Sync projects on the server. * * @returns {*|Promise.<Array.<Project>>|Promise.<jqXHR, textStatus, error>} * @memberOf! HelixWebServicesClient# */ listAllSyncProjects: function () { return this.syncProjects(); }, // TODO this should resolve to an array of our project models instead of an array-like Object /** * Fetch a listing of Helix Sync projects from the server. * * @param {Object} [options] Set 'listType' * @returns {Promise.<Array<Project>>|Promise<jqXHR, textStatus, error>} * @memberOf! HelixWebServicesClient# */ syncProjects: function (options) { var ajaxOptions = { client: this, method: 'GET', url: this.urlTo('/sync/v1/projects'), dataType: 'json' }; if (options) ajaxOptions['data'] = options; var ajax = authAjax(ajaxOptions); var deferred = $.Deferred(); ajax.done(function (projects) { deferred.resolve(projects); }); ajax.fail(deferred.reject); return deferred.promise(); }, //------------------------------------------------------------------------- // Helper Methods //------------------------------------------------------------------------- // These methods shouldn't return Promise interfaces. urlTo: function (path) { var url = this.url || ""; if (this.prefix) { url += this.prefix; } url += path; return url; } }); module.exports = HelixWebServicesClient; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="HelixWebServicesClient.html">HelixWebServicesClient</a></li><li><a href="models.Depot.html">Depot</a></li><li><a href="models.Dir.html">Dir</a></li><li><a href="models.File.html">File</a></li></ul><h3>Mixins</h3><ul><li><a href="Node.html">Node</a></li></ul><h3>Global</h3><ul><li><a href="global.html#addSessionExpiredHandler">addSessionExpiredHandler</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0-dev</a> on Wed Jun 24 2015 12:48:35 GMT-0700 (PDT) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 15688 | Doug Scheirer |
Populate -o //guest/perforce_software/helix-web-services/... //guest/doug_scheirer/helix-web-services/.... |
||
//guest/perforce_software/helix-web-services/main/build/doc/helix_web_services_client_js/helix_web_services_client.js.html | |||||
#4 | 14151 | tjuricek |
Add depot tree control and selection to the create projects page. Styling and error checking is kept to a minimum for the time being. Our goal is just internal workflow and feedback. |
||
#3 | 14108 | tjuricek |
Added models for handling Perforce server depot listing and traversal. This is not complete, however, the models are a start to making it easy to generate a tree control. (Most tree controls in the wild assume you know the tree structure from the start, which is not true in our case.) The tricky bit is making it easy to build the tree out given that you're visiting only one directory at a time. |
||
#2 | 14105 | tjuricek |
add 'listMy' and 'listAll' sync project variations to the JS API. Also, set up the project list to switch between the two project types. Also, setup each item in the project list to not be a grouped list item, but a custom view component. Not particularly useful, but it just displays a description now. |
||
#1 | 14002 | tjuricek | Some preliminary API documentation for the JavaScript SDK. |