You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/02/11 17:20:54 UTC
[08/50] [abbrv] lots of updates
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/Entity.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Entity.js b/sdks/html5-javascript/lib/modules/Entity.js
new file mode 100644
index 0000000..e84e400
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/Entity.js
@@ -0,0 +1,684 @@
+/*
+ * A class to Model a Usergrid Entity.
+ * Set the type and uuid of entity in the 'data' json object
+ *
+ * @constructor
+ * @param {object} options {client:client, data:{'type':'collection_type', uuid:'uuid', 'key':'value'}}
+ */
+Usergrid.Entity = function(options) {
+ if (options) {
+ this._data = options.data || {};
+ this._client = options.client || {};
+ }
+};
+
+/*
+ * method to determine whether or not the passed variable is a Usergrid Entity
+ *
+ * @method isEntity
+ * @public
+ * @params {any} obj - any variable
+ * @return {boolean} Returns true or false
+ */
+Usergrid.Entity.isEntity = function(obj){
+ return (obj && obj instanceof Usergrid.Entity);
+}
+
+/*
+ * method to determine whether or not the passed variable is a Usergrid Entity
+ * That has been saved.
+ *
+ * @method isPersistedEntity
+ * @public
+ * @params {any} obj - any variable
+ * @return {boolean} Returns true or false
+ */
+Usergrid.Entity.isPersistedEntity = function(obj){
+ return (isEntity(obj) && isUUID(obj.get('uuid')));
+}
+
+/*
+ * returns a serialized version of the entity object
+ *
+ * Note: use the client.restoreEntity() function to restore
+ *
+ * @method serialize
+ * @return {string} data
+ */
+Usergrid.Entity.prototype.serialize = function () {
+ return JSON.stringify(this._data);
+};
+
+/*
+ * gets a specific field or the entire data object. If null or no argument
+ * passed, will return all data, else, will return a specific field
+ *
+ * @method get
+ * @param {string} field
+ * @return {string} || {object} data
+ */
+Usergrid.Entity.prototype.get = function (key) {
+ var value;
+ if(arguments.length===0){
+ value=this._data;
+ }else if(arguments.length>1){
+ key=[].slice.call(arguments).reduce(function(p,c,i,a){
+ if(c instanceof Array){
+ p= p.concat(c);
+ }else{
+ p.push(c);
+ }
+ return p;
+ },[]);
+ }
+ if(key instanceof Array){
+ var self=this;
+ value=key.map(function(k){return self.get(k)});
+ }else if("undefined" !== typeof key){
+ value=this._data[key];
+ }
+ return value;
+};
+/*
+ * adds a specific key value pair or object to the Entity's data
+ * is additive - will not overwrite existing values unless they
+ * are explicitly specified
+ *
+ * @method set
+ * @param {string} key || {object}
+ * @param {string} value
+ * @return none
+ */
+Usergrid.Entity.prototype.set = function (key, value) {
+ if (typeof key === 'object') {
+ for(var field in key) {
+ this._data[field] = key[field];
+ }
+ } else if (typeof key === 'string') {
+ if (value === null) {
+ delete this._data[key];
+ } else {
+ this._data[key] = value;
+ }
+ } else {
+ this._data = {};
+ }
+};
+
+Usergrid.Entity.prototype.getEndpoint = function () {
+ var type = this.get('type'), name, endpoint;
+ var nameProperties=['uuid', 'name'];
+ if (type === undefined) {
+ throw new UsergridError('cannot fetch entity, no entity type specified', 'no_type_specified');
+ }else if(type==="users"){
+ nameProperties.unshift('username');
+ }
+
+ var names= this.get(nameProperties).filter(function(x){return "undefined"!==typeof x});
+ if (names.length===0) {
+ throw new UsergridError("Cannot infer an UUID or type from the entity", 'no_name_specified');
+ }else{
+ name=names.shift();
+ }
+ return [type, name].join('/');
+};
+/*
+ * Saves the entity back to the database
+ *
+ * @method save
+ * @public
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ */
+Usergrid.Entity.prototype.save = function (callback) {
+ var self = this,
+ type = this.get('type'),
+ method = 'POST',
+ entityId=this.get("uuid"),
+ data = {},
+ entityData = this.get(),
+ /*password = this.get('password'),
+ oldpassword = this.get('oldpassword'),
+ newpassword = this.get('newpassword'),*/
+ SYSTEM_PROPERTIES=['metadata','created','modified','oldpassword','newpassword','type','activated','uuid'],
+ options={
+ method:method,
+ endpoint:type
+ };
+ console.log("SAVE DATA #1", entityId, entityData);
+
+ //update the entity
+ if (entityId) {
+ options.method = 'PUT';
+ options.endpoint += '/' + entityId;
+ }
+
+ //remove system-specific properties
+ Object.keys(entityData)
+ .filter(function(key){return (SYSTEM_PROPERTIES.indexOf(key)===-1)})
+ .forEach(function(key){
+ data[key]= entityData[key];
+ });
+ console.log("SAVE DATA #2", data);
+ options.body=data;
+ //save the entity first
+ this._client.request(options, function (err, response) {
+ console.log("SAVE DATA #3", response);
+ var entity=response.getEntity();
+ if(entity){
+ self.set(entity);
+ }
+ doCallback(callback,[err, self]);
+
+ /*
+ TODO move user logic to its own entity
+ */
+
+ /*
+
+ //clear out pw info if present
+ self.set('password', null);
+ self.set('oldpassword', null);
+ self.set('newpassword', null);
+ if (err && self._client.logging) {
+ console.log('could not save entity');
+ if (typeof(callback) === 'function') {
+ return callback(err, retdata, self);
+ }
+ } else {
+ if (retdata.entities) {
+ if (retdata.entities.length) {
+ var entity = retdata.entities[0];
+ self.set(entity);
+ var path = retdata.path;
+ //for connections, API returns type
+ while (path.substring(0, 1) === "/") {
+ path = path.substring(1);
+ }
+ self.set('type', path);
+ }
+ }
+ //if this is a user, update the password if it has been specified;
+ var needPasswordChange = ((self.get('type') === 'user' || self.get('type') === 'users') && oldpassword && newpassword);
+ if (needPasswordChange) {
+ //Note: we have a ticket in to change PUT calls to /users to accept the password change
+ // once that is done, we will remove this call and merge it all into one
+ var pwdata = {};
+ pwdata.oldpassword = oldpassword;
+ pwdata.newpassword = newpassword;
+ var options = {
+ method:'PUT',
+ endpoint:type+'/password',
+ body:pwdata
+ }
+ self._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('could not update user');
+ }
+ //remove old and new password fields so they don't end up as part of the entity object
+ self.set('oldpassword', null);
+ self.set('newpassword', null);
+ if (typeof(callback) === 'function') {
+ callback(err, data, self);
+ }
+ });
+ } else if (typeof(callback) === 'function') {
+ callback(err, retdata, self);
+ }
+ }*/
+ });
+};
+
+/*
+ * refreshes the entity by making a GET call back to the database
+ *
+ * @method fetch
+ * @public
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ */
+Usergrid.Entity.prototype.fetch = function (callback) {
+ var endpoint, self = this;
+
+ //Check for an entity type, then if a uuid is available, use that, otherwise, use the name
+ //try {
+ endpoint=this.getEndpoint();
+ /*} catch (e) {
+ if (self._client.logging) {
+ console.log(e);
+ }
+ return callback(true, {
+ error: e
+ }, self);
+ }*/
+ var options = {
+ method: 'GET',
+ endpoint: endpoint
+ };
+ this._client.request(options, function (err, response) {
+ var entity=response.getEntity();
+ if(entity){
+ self.set(entity);
+ }
+ console.log("AFTER FETCH", self.get(), entity, response);
+ doCallback(callback,[err, entity, self]);
+ });
+};
+
+/*
+ * deletes the entity from the database - will only delete
+ * if the object has a valid uuid
+ *
+ * @method destroy
+ * @public
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ *
+ */
+Usergrid.Entity.prototype.destroy = function (callback) {
+ var self = this;
+ var endpoint = this.getEndpoint();
+
+ var options = {
+ method:'DELETE',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (!err) {
+ self.set(null);
+ }
+ if (typeof(callback) === 'function') {
+ doCallback(callback,[err, data]);
+ }
+ });
+};
+
+/*
+ * connects one entity to another
+ *
+ * @method connect
+ * @public
+ * @param {string} connection
+ * @param {object} entity
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ *
+ */
+Usergrid.Entity.prototype.connect = function (connection, entity, callback) {
+
+ var self = this;
+
+ var error;
+ //connectee info
+ var connecteeType = entity.get('type');
+ var connectee = this.getEntityId(entity);
+ if (!connectee) {
+ if (typeof(callback) === 'function') {
+ error = 'Error trying to delete object - no uuid specified.';
+ if (self._client.logging) {
+ console.log(error);
+ }
+ callback(true, error);
+ }
+ return;
+ }
+
+ //connector info
+ var connectorType = this.get('type');
+ var connector = this.getEntityId(this);
+ if (!connector) {
+ if (typeof(callback) === 'function') {
+ error = 'Error in connect - no uuid specified.';
+ if (self._client.logging) {
+ console.log(error);
+ }
+ callback(true, error);
+ }
+ return;
+ }
+
+ var endpoint = connectorType + '/' + connector + '/' + connection + '/' + connecteeType + '/' + connectee;
+ var options = {
+ method:'POST',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('entity could not be connected');
+ }
+ if (typeof(callback) === 'function') {
+ callback(err, data);
+ }
+ });
+};
+
+/*
+ * returns a unique identifier for an entity
+ *
+ * @method connect
+ * @public
+ * @param {object} entity
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ *
+ */
+Usergrid.Entity.prototype.getEntityId = function (entity) {
+ var id = false;
+ if (isUUID(entity.get('uuid'))) {
+ id = entity.get('uuid');
+ } else {
+ if (this.get("type") === 'users') {
+ id = entity.get('username');
+ } else if (entity.get('name')) {
+ id = entity.get('name');
+ }
+ }
+ return id;
+};
+
+/*
+ * gets an entities connections
+ *
+ * @method getConnections
+ * @public
+ * @param {string} connection
+ * @param {object} entity
+ * @param {function} callback
+ * @return {callback} callback(err, data, connections)
+ *
+ */
+Usergrid.Entity.prototype.getConnections = function (connection, callback) {
+
+ var self = this;
+
+ //connector info
+ var connectorType = this.get('type');
+ var connector = this.getEntityId(this);
+ if (!connector) {
+ if (typeof(callback) === 'function') {
+ var error = 'Error in getConnections - no uuid specified.';
+ if (self._client.logging) {
+ console.log(error);
+ }
+ callback(true, error);
+ }
+ return;
+ }
+
+ var endpoint = connectorType + '/' + connector + '/' + connection + '/';
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('entity could not be connected');
+ }
+
+ self[connection] = {};
+
+ var length = data.entities.length;
+ for (var i = 0; i < length; i++) {
+ if (data.entities[i].type === 'user'){
+ self[connection][data.entities[i].username] = data.entities[i];
+ } else {
+ self[connection][data.entities[i].name] = data.entities[i]
+ }
+ }
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+Usergrid.Entity.prototype.getGroups = function (callback) {
+
+ var self = this;
+
+ var endpoint = 'users' + '/' + this.get('uuid') + '/groups' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('entity could not be connected');
+ }
+
+ self.groups = data.entities;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+Usergrid.Entity.prototype.getActivities = function (callback) {
+
+ var self = this;
+
+ var endpoint = this.get('type') + '/' + this.get('uuid') + '/activities' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('entity could not be connected');
+ }
+
+ for (var entity in data.entities) {
+ data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
+ }
+
+ self.activities = data.entities;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+Usergrid.Entity.prototype.getFollowing = function (callback) {
+
+ var self = this;
+
+ var endpoint = 'users' + '/' + this.get('uuid') + '/following' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('could not get user following');
+ }
+
+ for (var entity in data.entities) {
+ data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
+ var image = self._client.getDisplayImage(data.entities[entity].email, data.entities[entity].picture);
+ data.entities[entity]._portal_image_icon = image;
+ }
+
+ self.following = data.entities;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+
+Usergrid.Entity.prototype.getFollowers = function (callback) {
+
+ var self = this;
+
+ var endpoint = 'users' + '/' + this.get('uuid') + '/followers' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('could not get user followers');
+ }
+
+ for (var entity in data.entities) {
+ data.entities[entity].createdDate = (new Date(data.entities[entity].created)).toUTCString();
+ var image = self._client.getDisplayImage(data.entities[entity].email, data.entities[entity].picture);
+ data.entities[entity]._portal_image_icon = image;
+ }
+
+ self.followers = data.entities;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+Usergrid.Entity.prototype.getRoles = function (callback) {
+
+ var self = this;
+
+ var endpoint = this.get('type') + '/' + this.get('uuid') + '/roles' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('could not get user roles');
+ }
+
+ self.roles = data.entities;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+Usergrid.Entity.prototype.getPermissions = function (callback) {
+
+ var self = this;
+
+ var endpoint = this.get('type') + '/' + this.get('uuid') + '/permissions' ;
+ var options = {
+ method:'GET',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('could not get user permissions');
+ }
+
+ var permissions = [];
+ if (data.data) {
+ var perms = data.data;
+ var count = 0;
+
+ for (var i in perms) {
+ count++;
+ var perm = perms[i];
+ var parts = perm.split(':');
+ var ops_part = "";
+ var path_part = parts[0];
+
+ if (parts.length > 1) {
+ ops_part = parts[0];
+ path_part = parts[1];
+ }
+
+ ops_part.replace("*", "get,post,put,delete")
+ var ops = ops_part.split(',');
+ var ops_object = {}
+ ops_object.get = 'no';
+ ops_object.post = 'no';
+ ops_object.put = 'no';
+ ops_object.delete = 'no';
+ for (var j in ops) {
+ ops_object[ops[j]] = 'yes';
+ }
+
+ permissions.push({
+ operations: ops_object,
+ path: path_part,
+ perm: perm
+ });
+ }
+ }
+
+ self.permissions = permissions;
+
+ if (typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+
+};
+
+/*
+ * disconnects one entity from another
+ *
+ * @method disconnect
+ * @public
+ * @param {string} connection
+ * @param {object} entity
+ * @param {function} callback
+ * @return {callback} callback(err, data)
+ *
+ */
+Usergrid.Entity.prototype.disconnect = function (connection, entity, callback) {
+
+ var self = this;
+
+ var error;
+ //connectee info
+ var connecteeType = entity.get('type');
+ var connectee = this.getEntityId(entity);
+ if (!connectee) {
+ if (typeof(callback) === 'function') {
+ error = 'Error trying to delete object - no uuid specified.';
+ if (self._client.logging) {
+ console.log(error);
+ }
+ callback(true, error);
+ }
+ return;
+ }
+
+ //connector info
+ var connectorType = this.get('type');
+ var connector = this.getEntityId(this);
+ if (!connector) {
+ if (typeof(callback) === 'function') {
+ error = 'Error in connect - no uuid specified.';
+ if (self._client.logging) {
+ console.log(error);
+ }
+ callback(true, error);
+ }
+ return;
+ }
+
+ var endpoint = connectorType + '/' + connector + '/' + connection + '/' + connecteeType + '/' + connectee;
+ var options = {
+ method:'DELETE',
+ endpoint:endpoint
+ };
+ this._client.request(options, function (err, data) {
+ if (err && self._client.logging) {
+ console.log('entity could not be disconnected');
+ }
+ if (typeof(callback) === 'function') {
+ callback(err, data);
+ }
+ });
+};
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/Error.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Error.js b/sdks/html5-javascript/lib/modules/Error.js
new file mode 100644
index 0000000..e2b44b8
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/Error.js
@@ -0,0 +1,125 @@
+//noinspection ThisExpressionReferencesGlobalObjectJS
+
+/**
+ * Created by ryan bridges on 2014-02-05.
+ */
+(function (global) {
+ //noinspection JSUnusedAssignment
+ var name = 'UsergridError',
+ short,
+ _name = global[name],
+ _short = (short && short !== undefined) ? global[short] : undefined;
+
+ /*
+ * Instantiates a new UsergridError
+ *
+ * @method UsergridError
+ * @public
+ * @params {<string>} message
+ * @params {<string>} id - the error code, id, or name
+ * @params {<int>} timestamp
+ * @params {<int>} duration
+ * @params {<string>} exception - the Java exception from Usergrid
+ * @return Returns - a new UsergridError object
+ *
+ * Example:
+ *
+ * UsergridError(message);
+ */
+
+ function UsergridError(message, name, timestamp, duration, exception){
+ this.message=message;
+ this.name=name;
+ this.timestamp=timestamp||Date.now();
+ this.duration=duration||0;
+ this.exception=exception;
+ }
+ UsergridError.prototype=new Error();
+ UsergridError.prototype.constructor = UsergridError;
+ /*
+ * Creates a UsergridError from the JSON response returned from the backend
+ *
+ * @method fromResponse
+ * @public
+ * @params {object} response - the deserialized HTTP response from the Usergrid API
+ * @return Returns a new UsergridError object.
+ *
+ * Example:
+ * {
+ * "error":"organization_application_not_found",
+ * "timestamp":1391618508079,
+ * "duration":0,
+ * "exception":"org.usergrid.rest.exceptions.OrganizationApplicationNotFoundException",
+ * "error_description":"Could not find application for yourorgname/sandboxxxxx from URI: yourorgname/sandboxxxxx"
+ * }
+ */
+ UsergridError.fromResponse=function(response){
+ if(response && "undefined"!==typeof response){
+ return new UsergridError(response.error_description, response.error, response.timestamp, response.duration, response.exception);
+ }else{
+ return new UsergridError();
+ }
+ };
+ UsergridError.createSubClass=function(name){
+ if(name in global && global[name])return global[name]
+ global[name]=function(){};
+ global[name].name=name;
+ global[name].prototype=new UsergridError();
+ return global[name];
+ };
+
+ function UsergridHTTPResponseError(message, name, timestamp, duration, exception){
+ this.message=message;
+ this.name=name;
+ this.timestamp=timestamp||Date.now();
+ this.duration=duration||0;
+ this.exception=exception;
+ }
+ UsergridHTTPResponseError.prototype=new UsergridError();
+ function UsergridInvalidHTTPMethodError(message, name, timestamp, duration, exception){
+ this.message=message;
+ this.name=name;
+ this.timestamp=timestamp||Date.now();
+ this.duration=duration||0;
+ this.exception=exception;
+ }
+ UsergridInvalidHTTPMethodError.prototype=new UsergridError();
+ function UsergridInvalidURIError(message, name, timestamp, duration, exception){
+ this.message=message;
+ this.name=name;
+ this.timestamp=timestamp||Date.now();
+ this.duration=duration||0;
+ this.exception=exception;
+ }
+ UsergridInvalidURIError.prototype=new UsergridError();
+ function UsergridKeystoreDatabaseUpgradeNeededError(message, name, timestamp, duration, exception){
+ this.message=message;
+ this.name=name;
+ this.timestamp=timestamp||Date.now();
+ this.duration=duration||0;
+ this.exception=exception;
+ }
+ UsergridKeystoreDatabaseUpgradeNeededError.prototype=new UsergridError();
+
+ global['UsergridHTTPResponseError'] = UsergridHTTPResponseError;
+ global['UsergridInvalidHTTPMethodError'] = UsergridInvalidHTTPMethodError;
+ global['UsergridInvalidURIError'] = UsergridInvalidURIError;
+ global['UsergridKeystoreDatabaseUpgradeNeededError'] = UsergridKeystoreDatabaseUpgradeNeededError;
+
+ global[name] = UsergridError;
+ if (short !== undefined) {
+ //noinspection JSUnusedAssignment
+ global[short] = UsergridError;
+ }
+ global[name].noConflict = function () {
+ if (_name) {
+ global[name] = _name;
+ }
+ if (short !== undefined) {
+ global[short] = _short;
+ }
+ return UsergridError;
+ };
+ return global[name];
+}(this));
+
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/Folder.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Folder.js b/sdks/html5-javascript/lib/modules/Folder.js
new file mode 100644
index 0000000..11d7521
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/Folder.js
@@ -0,0 +1,167 @@
+/*
+ * A class to model a Usergrid folder.
+ *
+ * @constructor
+ * @param {object} options {name:"MyPhotos", path:"/user/uploads", owner:"00000000-0000-0000-0000-000000000000" }
+ * @returns {callback} callback(err, folder)
+ */
+Usergrid.Folder = function(options, callback) {
+ var self = this,
+ messages = [];
+ console.log("FOLDER OPTIONS", options);
+ self._client = options.client;
+ self._data = options.data || {};
+ self._data.type = "folders";
+ var missingData = ["name", "owner", "path"].some(function(required) { return !(required in self._data)});
+ if(missingData){
+ return doCallback(callback, [true, new Usergrid.Error("Invalid asset data: 'name', 'owner', and 'path' are required properties.")], self);
+ }
+ self.save(function(err, data) {
+ if (err) {
+ doCallback(callback, [true, new Usergrid.Error(data)], self);
+ } else {
+ if (data.entities.length){
+ self.set(data.entities[0]);
+ }
+ doCallback(callback, [false, self], self);
+ }
+ });
+};
+/*
+ * Inherit from Usergrid.Entity.
+ */
+Usergrid.Folder.prototype = new Usergrid.Entity();
+
+
+/*
+ * fetch the folder and associated assets
+ *
+ * @method fetch
+ * @public
+ * @param {function} callback(err, self)
+ * @returns {callback} callback(err, self)
+ */
+Usergrid.Folder.prototype.fetch = function(callback) {
+ var self = this;
+ Usergrid.Entity.prototype.fetch.call(self, function(err, data) {
+ console.log("self", self.get());
+ console.log("data", data);
+ if (!err) {
+ self.getAssets(function(err, data) {
+ if (err) {
+ doCallback(callback, [true, new Usergrid.Error(data)], self);
+ } else {
+ doCallback(callback, [null, self], self);
+ }
+ });
+ } else {
+ doCallback(callback, [true, new Usergrid.Error(data)], self)
+ }
+ })
+};
+/*
+ * Add an asset to the folder.
+ *
+ * @method addAsset
+ * @public
+ * @param {object} options {asset:(uuid || Usergrid.Asset || {name:"photo.jpg", path:"/user/uploads", "content-type":"image/jpeg", owner:"F01DE600-0000-0000-0000-000000000000" }) }
+ * @returns {callback} callback(err, folder)
+ */
+Usergrid.Folder.prototype.addAsset = function(options, callback) {
+ var self = this;
+ if (('asset' in options)) {
+ var asset = null;
+ switch (typeof options.asset) {
+ case 'object':
+ asset = options.asset;
+ if (!(asset instanceof Usergrid.Entity)) {
+ asset = new Usergrid.Asset(asset);
+ }
+ break;
+ case 'string':
+ if (isUUID(options.asset)) {
+ asset = new Usergrid.Asset({
+ client: self._client,
+ data: {
+ uuid: options.asset,
+ type: "assets"
+ }
+ });
+ }
+ break;
+ }
+ if (asset && asset instanceof Usergrid.Entity) {
+ asset.fetch(function(err, data) {
+ if (err) {
+ doCallback(callback, [err, new Usergrid.Error(data)], self)
+ } else {
+ var endpoint = ["folders", self.get("uuid"), "assets", asset.get("uuid")].join('/');
+ var options = {
+ method: 'POST',
+ endpoint: endpoint
+ };
+ self._client.request(options, callback);
+ }
+ })
+ }
+ } else {
+ //nothing to add
+ doCallback(callback, [true, {
+ error_description: "No asset specified"
+ }], self)
+ }
+};
+
+/*
+ * Remove an asset from the folder.
+ *
+ * @method removeAsset
+ * @public
+ * @param {object} options {asset:(uuid || Usergrid.Asset || {name:"photo.jpg", path:"/user/uploads", "content-type":"image/jpeg", owner:"F01DE600-0000-0000-0000-000000000000" }) }
+ * @returns {callback} callback(err, folder)
+ */
+Usergrid.Folder.prototype.removeAsset = function(options, callback) {
+ var self = this;
+ if (('asset' in options)) {
+ var asset = null;
+ switch (typeof options.asset) {
+ case 'object':
+ asset = options.asset;
+ break;
+ case 'string':
+ if (isUUID(options.asset)) {
+ asset = new Usergrid.Asset({
+ client: self._client,
+ data: {
+ uuid: options.asset,
+ type: "assets"
+ }
+ });
+ }
+ break;
+ }
+ if (asset && asset !== null) {
+ var endpoint = ["folders", self.get("uuid"), "assets", asset.get("uuid")].join('/');
+ self._client.request({
+ method: 'DELETE',
+ endpoint: endpoint
+ }, callback);
+ }
+ } else {
+ //nothing to add
+ doCallback(callback, [true, {
+ error_description: "No asset specified"
+ }], self)
+ }
+};
+
+/*
+ * List the assets in the folder.
+ *
+ * @method getAssets
+ * @public
+ * @returns {callback} callback(err, assets)
+ */
+Usergrid.Folder.prototype.getAssets = function(callback) {
+ return this.getConnections("assets", callback);
+};
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/Group.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/Group.js b/sdks/html5-javascript/lib/modules/Group.js
new file mode 100644
index 0000000..2a853be
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/Group.js
@@ -0,0 +1,233 @@
+/*
+ * A class to model a Usergrid group.
+ * Set the path in the options object.
+ *
+ * @constructor
+ * @param {object} options {client:client, data: {'key': 'value'}, path:'path'}
+ */
+Usergrid.Group = function(options, callback) {
+ this._path = options.path;
+ this._list = [];
+ this._client = options.client;
+ this._data = options.data || {};
+ this._data.type = "groups";
+};
+
+/*
+ * Inherit from Usergrid.Entity.
+ * Note: This only accounts for data on the group object itself.
+ * You need to use add and remove to manipulate group membership.
+ */
+Usergrid.Group.prototype = new Usergrid.Entity();
+
+/*
+ * Fetches current group data, and members.
+ *
+ * @method fetch
+ * @public
+ * @param {function} callback
+ * @returns {function} callback(err, data)
+ */
+Usergrid.Group.prototype.fetch = function(callback) {
+ var self = this;
+ var groupEndpoint = 'groups/'+this._path;
+ var memberEndpoint = 'groups/'+this._path+'/users';
+
+ var groupOptions = {
+ method:'GET',
+ endpoint:groupEndpoint
+ }
+
+ var memberOptions = {
+ method:'GET',
+ endpoint:memberEndpoint
+ }
+
+ this._client.request(groupOptions, function(err, data){
+ if(err) {
+ if(self._client.logging) {
+ console.log('error getting group');
+ }
+ if(typeof(callback) === 'function') {
+ callback(err, data);
+ }
+ } else {
+ if(data.entities) {
+ var groupData = data.entities[0];
+ self._data = groupData || {};
+ self._client.request(memberOptions, function(err, data) {
+ if(err && self._client.logging) {
+ console.log('error getting group users');
+ } else {
+ if(data.entities) {
+ var count = data.entities.length;
+ self._list = [];
+ for (var i = 0; i < count; i++) {
+ var uuid = data.entities[i].uuid;
+ if(uuid) {
+ var entityData = data.entities[i] || {};
+ var entityOptions = {
+ type: entityData.type,
+ client: self._client,
+ uuid:uuid,
+ data:entityData
+ };
+ var entity = new Usergrid.Entity(entityOptions);
+ self._list.push(entity);
+ }
+
+ }
+ }
+ }
+ if(typeof(callback) === 'function') {
+ callback(err, data, self._list);
+ }
+ });
+ }
+ }
+ });
+};
+
+/*
+ * Retrieves the members of a group.
+ *
+ * @method members
+ * @public
+ * @param {function} callback
+ * @return {function} callback(err, data);
+ */
+Usergrid.Group.prototype.members = function(callback) {
+ if(typeof(callback) === 'function') {
+ callback(null, this._list);
+ }
+};
+
+/*
+ * Adds a user to the group, and refreshes the group object.
+ *
+ * Options object: {user: user_entity}
+ *
+ * @method add
+ * @public
+ * @params {object} options
+ * @param {function} callback
+ * @return {function} callback(err, data)
+ */
+Usergrid.Group.prototype.add = function(options, callback) {
+ var self = this;
+ var options = {
+ method:"POST",
+ endpoint:"groups/"+this._path+"/users/"+options.user.get('username')
+ }
+
+ this._client.request(options, function(error, data){
+ if(error) {
+ if(typeof(callback) === 'function') {
+ callback(error, data, data.entities);
+ }
+ } else {
+ self.fetch(callback);
+ }
+ });
+}
+
+/*
+ * Removes a user from a group, and refreshes the group object.
+ *
+ * Options object: {user: user_entity}
+ *
+ * @method remove
+ * @public
+ * @params {object} options
+ * @param {function} callback
+ * @return {function} callback(err, data)
+ */
+Usergrid.Group.prototype.remove = function(options, callback) {
+ var self = this;
+
+ var options = {
+ method:"DELETE",
+ endpoint:"groups/"+this._path+"/users/"+options.user.get('username')
+ }
+
+ this._client.request(options, function(error, data){
+ if(error) {
+ if(typeof(callback) === 'function') {
+ callback(error, data);
+ }
+ } else {
+ self.fetch(callback);
+ }
+ });
+}
+
+/*
+ * Gets feed for a group.
+ *
+ * @public
+ * @method feed
+ * @param {function} callback
+ * @returns {callback} callback(err, data, activities)
+ */
+Usergrid.Group.prototype.feed = function(callback) {
+ var self = this;
+
+ var endpoint = "groups/"+this._path+"/feed";
+
+ var options = {
+ method:"GET",
+ endpoint:endpoint
+ }
+
+ this._client.request(options, function(err, data){
+ if (err && self.logging) {
+ console.log('error trying to log user in');
+ }
+ if(typeof(callback) === 'function') {
+ callback(err, data, data.entities);
+ }
+ });
+}
+
+/*
+ * Creates activity and posts to group feed.
+ *
+ * options object: {user: user_entity, content: "activity content"}
+ *
+ * @public
+ * @method createGroupActivity
+ * @params {object} options
+ * @param {function} callback
+ * @returns {callback} callback(err, entity)
+ */
+Usergrid.Group.prototype.createGroupActivity = function(options, callback){
+ var user = options.user;
+ options = {
+ client: this._client,
+ data: {
+ actor: {
+ "displayName": user.get("username"),
+ "uuid": user.get("uuid"),
+ "username": user.get("username"),
+ "email": user.get("email"),
+ "picture": user.get("picture"),
+ "image": {
+ "duration": 0,
+ "height": 80,
+ "url": user.get("picture"),
+ "width": 80
+ },
+ },
+ "verb": "post",
+ "content": options.content,
+ "type": 'groups/' + this._path + '/activities'
+ }
+ }
+
+ var entity = new Usergrid.Entity(options);
+ entity.save(function(err, data) {
+ if (typeof(callback) === 'function') {
+ callback(err, entity);
+ }
+ });
+};
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/Ajax.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Ajax.js b/sdks/html5-javascript/lib/modules/util/Ajax.js
new file mode 100644
index 0000000..e8228ea
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/Ajax.js
@@ -0,0 +1,74 @@
+//Ajax
+(function() {
+ var name = 'Ajax', global = this, overwrittenName = global[name], exports;
+
+ Function.prototype.partial = function() {
+ var fn = this,b = [].slice.call(arguments);
+ return fn.bind(undefined, b);
+ }
+
+ exports = (function() {
+ function Ajax() {
+ this.logger=new global.Logger(name);
+ var self=this;
+ function encode(data) {
+ var result = "";
+ if (typeof data === "string") {
+ result = data;
+ } else {
+ var e = encodeURIComponent;
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ result += '&' + e(i) + '=' + e(data[i]);
+ }
+ }
+ }
+ return result;
+ }
+ var request = function(m, u, d) {
+ var p = new Promise(), timeout;
+ self.logger.time(m + ' ' + u);
+ self.logger.timeEnd(m + ' ' + u);
+ (function(xhr) {
+ xhr.onreadystatechange = function() {
+ this.readyState ^ 4 || (self.logger.timeEnd(m + ' ' + u), clearTimeout(timeout), p.done(null, this));
+ };
+ xhr.onerror=function(response){
+ clearTimeout(timeout);
+ p.done(response, null);
+ }
+ xhr.oncomplete=function(response){
+ clearTimeout(timeout);
+ self.info("%s request to %s returned %s", m, u, this.status );
+ }
+ xhr.open(m, u);
+ if (d) {
+ xhr.setRequestHeader("Content-Type", "application/json");
+ xhr.setRequestHeader("Accept", "application/json");
+ }
+ timeout = setTimeout(function() {
+ xhr.abort();
+ p.done("API Call timed out.", null)
+ }, 30000);
+ //TODO stick that timeout in a config variable
+ xhr.send(encode(d));
+ }(new XMLHttpRequest()));
+ return p;
+ };
+ this.request=request;
+ this.get = request.partial('GET');
+ this.post = request.partial('POST');
+ this.put = request.partial('PUT');
+ this.delete = request.partial('DELETE');
+ }
+ return new Ajax();
+ }());
+ global[name] = exports;
+ global[name].noConflict = function() {
+ if(overwrittenName){
+ global[name] = overwrittenName;
+ }
+ return exports;
+ };
+ return global[name];
+}());
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/Event.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Event.js b/sdks/html5-javascript/lib/modules/util/Event.js
new file mode 100644
index 0000000..146d03e
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/Event.js
@@ -0,0 +1,33 @@
+var UsergridEventable = function(){
+ throw Error("'UsergridEventable' is not intended to be invoked directly")
+}
+UsergridEventable.prototype = {
+ bind : function(event, fn){
+ this._events = this._events || {};
+ this._events[event] = this._events[event] || [];
+ this._events[event].push(fn);
+ },
+ unbind : function(event, fn){
+ this._events = this._events || {};
+ if( event in this._events === false ) return;
+ this._events[event].splice(this._events[event].indexOf(fn), 1);
+ },
+ trigger : function(event /* , args... */){
+ this._events = this._events || {};
+ if( event in this._events === false ) return;
+ for(var i = 0; i < this._events[event].length; i++){
+ this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1))
+ }
+ }
+};
+UsergridEventable.mixin = function(destObject){
+ var props = ['bind', 'unbind', 'trigger'];
+ for(var i = 0; i < props.length; i ++){
+ if(props[i] in destObject.prototype){
+ console.warn("overwriting '"+props[i]+"' on '"+destObject.name+"'.");
+ console.warn("the previous version can be found at '_"+props[i]+"' on '"+destObject.name+"'.");
+ destObject.prototype['_'+props[i]]=destObject.prototype[props[i]];
+ }
+ destObject.prototype[props[i]] = UsergridEventable.prototype[props[i]];
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/KeyStore.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/KeyStore.js b/sdks/html5-javascript/lib/modules/util/KeyStore.js
new file mode 100644
index 0000000..6a3ec1c
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/KeyStore.js
@@ -0,0 +1,199 @@
+//KeyStore
+var KeyStore = (function(global) {
+ global.indexedDB = global.indexedDB || global.mozIndexedDB || global.webkitIndexedDB || global.msIndexedDB;
+ // (Mozilla has never prefixed these objects, so we don't need global.mozIDB*)
+ global.IDBTransaction = global.IDBTransaction || global.webkitIDBTransaction || global.msIDBTransaction;
+ global.IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange || global.msIDBKeyRange;
+
+ var store="data",
+ keyPath="key",
+ database="test_keystore",
+ version= 8,
+ logger=new Logger('KeyStore');
+ var db, objectStore;
+ function createObjectStore(db, name, keyPath){
+ var p = new Promise(), objectStore;
+ try {
+ objectStore = event.currentTarget.transaction.objectStore(store);
+ //console.log(objectStore);
+ if (!objectStore) throw "not found";
+ } catch (e) {
+ logger.warn("creating new objectStore",e);
+ objectStore = db.createObjectStore(name, {
+ keyPath: keyPath
+ });
+ } finally {
+ objectStore.transaction.oncomplete = function(event) {
+ // console.info("created ObjectStore: '%s'", store);
+ p.done(null, objectStore);
+ };
+ }
+ return p;
+ }
+ function createObjectStoreIndex(objectStore, keyPath){
+ var p = new Promise(), index;
+ try {
+ index = objectStore.index(keyPath);
+ if (!index) throw "not found";
+ } catch (e) {
+ objectStore.createIndex(keyPath, keyPath, {
+ unique: true
+ });
+ } finally {
+ // objectStore.transaction.oncomplete = function(event) {
+ // console.info("created ObjectStore index: '%s'", keyPath);
+ p.done(null, db);
+ // };
+ }
+ return p;
+ }
+ function openDatabase(){
+ var p = new Promise();
+ var request = indexedDB.open(database, version);
+ request.onerror = function(event) {
+ console.error("internal keystore error: " + event.target.errorCode);
+ p.done(event.target, null);
+ };
+ request.onupgradeneeded = function(event) {
+ console.warn("upgrading internal keystore");
+ Promise.chain([
+ function(err, db){return createObjectStore(event.target.result, store, keyPath)},
+ function(err, objectStore){return createObjectStoreIndex(objectStore, keyPath)}
+ ])
+ };
+ request.onsuccess = function(event) {
+ //console.info("successfully opened database %s", event.target.result);
+ p.done(null, event.target.result);
+ };
+ return p;
+ }
+
+ function get(key) {
+ var p=new Promise();
+ openDatabase().then(function(err, db){
+ var item = db.transaction(store, "readwrite").objectStore(store).index(keyPath).get(key);
+ item.onsuccess = function(event) {
+ // console.log(event.target.result);
+ p.done(null, event.target.result);//request.result
+ };
+ item.onerror = function(event) {
+ p.done(event.target.error, null);
+ };
+ })
+ return p;
+ }
+ function save(key, value) {
+ var p=new Promise();
+ openDatabase().then(function(err, db){
+ var _store=db.transaction(store, "readwrite").objectStore(store);
+ var item = _store.index(keyPath).get(key);
+ item.onsuccess = function(event) {
+ //update
+ _store.put({key:key,value:value}).onsuccess=function(){
+ console.log("put");
+ p.done(null, event.target.result);//request.result
+ }
+ };
+ item.onerror = function(event) {
+ _store.post({key:key,value:value}).onsuccess=function(){
+ console.log("post");
+ p.done(event.target.error, null);//request.result
+ }
+ //p.done(event.target.error, event.target.result);
+ };
+ })
+ return p;
+ }
+ function remove(key) {
+ var p=new Promise();
+ openDatabase().then(function(err, db){
+ var item = db.transaction(store, "readwrite").objectStore(store).delete(key);
+ item.onsuccess = function(event) {
+ p.done(null, event.target.result);//request.result
+ };
+ item.onerror = function(event) {
+ p.done(event.target.error, event.target.result);
+ };
+ });
+ return p;
+ }
+ function post(key, value) {
+ var p=new Promise();
+ openDatabase().then(function(err, db){
+ var item = db.transaction(store, "readwrite").objectStore(store).add({key:key, value:value});
+ item.onsuccess = function(event) {
+ p.done(null, event.target.result);//request.result
+ };
+ item.onerror = function(event) {
+ p.done(event.target.error, event.target.result);
+ };
+ })
+ return p;
+ }
+ function put(key, value) {
+ var p=new Promise();
+ var item = db.transaction(store, "readwrite").objectStore(store).put(key, value);
+ item.onsuccess = function(event) {
+ p.done(null, event.target.result);//request.result
+ };
+ item.onerror = function(event) {
+ p.done(event.target.error, event.target.result);
+ };
+ return p;
+ }
+ /*
+ *
+ * {databases:[{
+ * name:'name'
+ * version:1,
+ * 'stores':[
+ * {
+ * name:'name',
+ * options:{}
+ * }
+ * ]
+ *
+ * }]
+ *
+ */
+ function KeyStoreFactory(options){
+ this.data=options;
+ var self=this;
+ self.data.databases.forEach(function(database){
+ console.log(database);
+ //make DB request;
+ });
+ }
+ KeyStoreFactory.prototype=new UsergridEvent();
+ KeyStoreFactory.prototype.openDatabase=function(database){
+ var self=this, p=new Promise();
+ var request = indexedDB.open(database, version);
+ request.onerror = function(event) {
+ console.error("internal keystore error: " + event.target.errorCode);
+ p.done(event.target, null);
+ };
+ request.onupgradeneeded = function(event) {
+ console.warn("upgrading internal keystore");
+ throw new UsergridKeystoreDatabaseUpgradeNeededError("internal keystore requires upgrade");
+ /*Promise.chain([
+ function(err, db){return createObjectStore(event.target.result, store, keyPath)},
+ function(err, objectStore){return createObjectStoreIndex(objectStore, keyPath)}
+ ])*/
+ };
+ request.onsuccess = function(event) {
+ //console.info("successfully opened database %s", event.target.result);
+ p.done(null, event.target.result);
+ };
+ return p;
+ }
+ global['KeyStoreFactory']=KeyStoreFactory;
+ global['KeyStore']={
+ openDatabase:openDatabase,
+ get:get,
+ put:put,
+ post:post,
+ save:save,
+ remove:remove
+ };
+ return global['KeyStore'];
+}(this));
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/Logger.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Logger.js b/sdks/html5-javascript/lib/modules/util/Logger.js
new file mode 100644
index 0000000..f81a0e8
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/Logger.js
@@ -0,0 +1,68 @@
+//Logger
+(function() {
+ var name = 'Logger', global = this, overwrittenName = global[name], exports;
+ /* logging */
+ function Logger(name) {
+ this.logEnabled = true;
+ this.init(name, true);
+ }
+ Logger.METHODS=[
+ "log", "error", "warn", "info", "debug", "assert", "clear", "count",
+ "dir", "dirxml", "exception", "group", "groupCollapsed", "groupEnd",
+ "profile", "profileEnd", "table", "time", "timeEnd", "trace"
+ ];
+ Logger.prototype.init=function(name, logEnabled){
+ this.name=name||"UNKNOWN";
+ this.logEnabled=logEnabled||true;
+ var addMethod=function(method){this[method]=this.createLogMethod(method)}.bind(this);
+ Logger.METHODS.forEach(addMethod)
+ }
+ Logger.prototype.createLogMethod=function(method){
+ return Logger.prototype.log.bind(this, method);
+ }
+ Logger.prototype.prefix=function(method, args){
+ var prepend='['+method.toUpperCase()+']['+name+"]:\t";
+ if(['log', 'error', 'warn', 'info'].indexOf(method)!==-1){
+ if("string"===typeof args[0]){
+ args[0]=prepend+args[0];
+ }else{
+ args.unshift(prepend);
+ }
+ }
+ return args;
+ }
+ Logger.prototype.log=function(){
+ var args=[].slice.call(arguments);
+ method=args.shift();
+ if(Logger.METHODS.indexOf(method)===-1){
+ method="log";
+ }
+ if(!(this.logEnabled && console && console[method]))return;
+ args=this.prefix(method, args);
+ console[method].apply(console, args);
+ }
+ Logger.prototype.setLogEnabled=function(logEnabled){
+ this.logEnabled=logEnabled||true;
+ }
+
+ Logger.mixin = function(destObject){
+ destObject.__logger=new Logger(destObject.name||"UNKNOWN");
+ var addMethod=function(method){
+ if(method in destObject.prototype){
+ console.warn("overwriting '"+method+"' on '"+destObject.name+"'.");
+ console.warn("the previous version can be found at '_"+method+"' on '"+destObject.name+"'.");
+ destObject.prototype['_'+method]=destObject.prototype[method];
+ }
+ destObject.prototype[method]=destObject.__logger.createLogMethod(method);
+ };
+ Logger.METHODS.forEach(addMethod)
+ }
+ global[name] = Logger;
+ global[name].noConflict = function() {
+ if(overwrittenName){
+ global[name] = overwrittenName;
+ }
+ return Logger;
+ };
+ return global[name];
+}());
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/Promise.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Promise.js b/sdks/html5-javascript/lib/modules/util/Promise.js
new file mode 100644
index 0000000..e2d97a6
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/Promise.js
@@ -0,0 +1,83 @@
+//Promise
+(function(global) {
+ var name = 'Promise', overwrittenName = global[name], exports;
+
+ function Promise() {
+ this.complete = false;
+ this.error = null;
+ this.result = null;
+ this.callbacks = [];
+ }
+ Promise.prototype.create = function() {
+ return new Promise()
+ };
+ Promise.prototype.then = function(callback, context) {
+ var f = function() {
+ return callback.apply(context, arguments)
+ };
+ if (this.complete) {
+ f(this.error, this.result);
+ } else {
+ this.callbacks.push(f);
+ }
+ };
+ Promise.prototype.done = function(error, result) {
+ this.complete = true;
+ this.error = error;
+ this.result = result;
+ if(this.callbacks){
+ for (var i = 0; i < this.callbacks.length; i++) this.callbacks[i](error, result);
+ this.callbacks.length = 0;
+ }
+ };
+ Promise.join = function(promises) {
+ var p = new Promise(),
+ total = promises.length,
+ completed = 0,
+ errors = [],
+ results = [];
+
+ function notifier(i) {
+ return function(error, result) {
+ completed += 1;
+ errors[i] = error;
+ results[i] = result;
+ if (completed === total) {
+ p.done(errors, results);
+ }
+ };
+ }
+ for (var i = 0; i < total; i++) {
+ promises[i]().then(notifier(i));
+ }
+ return p;
+ };
+ Promise.chain = function(promises, error, result) {
+ var p = new Promise();
+ if (promises===null||promises.length === 0) {
+ p.done(error, result);
+ } else {
+ promises[0](error, result).then(function(res, err) {
+ promises.splice(0, 1);
+ //self.logger.info(promises.length)
+ if(promises){
+ Promise.chain(promises, res, err).then(function(r, e) {
+ p.done(r, e);
+ });
+ }else{
+ p.done(res, err);
+ }
+ });
+ }
+ return p;
+ };
+
+ global[name] = Promise;
+ global[name].noConflict = function() {
+ if(overwrittenName){
+ global[name] = overwrittenName;
+ }
+ return Promise;
+ };
+ return global[name];
+}(this));
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/lib/modules/util/Storable.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/lib/modules/util/Storable.js b/sdks/html5-javascript/lib/modules/util/Storable.js
new file mode 100644
index 0000000..5c4da2e
--- /dev/null
+++ b/sdks/html5-javascript/lib/modules/util/Storable.js
@@ -0,0 +1,88 @@
+function UsergridStorable(storage, keyPrefix){
+ //throw Error("'UsergridStorable' is not intended to be invoked directly")
+}
+UsergridStorable.prototype.setStorage = function(storage) {
+ if(!(storage instanceof Storage)){
+ console.warn("parameter passed to 'setStorage' is not a browser Storage interface. using sessionStorage");
+ storage=sessionStorage;
+ }
+ return this._storage=storage;
+};
+UsergridStorable.prototype.getStorage = function() {
+ if(!(this._storage instanceof Storage)){
+ console.warn("parameter passed to 'setStorage' is not a browser Storage interface. using sessionStorage");
+ this._storage=sessionStorage;
+ }
+ return this._storage;
+};
+UsergridStorable.prototype.getStorageKey = function(key) {
+ if(!this._keyPrefix)this._keyPrefix='usergrid_js_sdk_';
+ return this._keyPrefix+key;
+};
+UsergridStorable.prototype.get=function(key){
+ var value;
+ if(arguments.length>1){
+ key=[].slice.call(arguments).reduce(function(p,c,i,a){
+ if(c instanceof Array){
+ p= p.concat(c);
+ }else{
+ p.push(c);
+ }
+ return p;
+ },[]);
+ }
+ if(this._storage instanceof Storage){
+ if(key instanceof Array){
+ var self=this;
+ value=key.map(function(k){return self.get(k)});
+ }else if("undefined" !== typeof key){
+ this[key]=JSON.parse(this.getStorage().getItem(this.getStorageKey(key)));
+ value=this[key];
+ }
+ }
+ return value;
+}
+UsergridStorable.prototype.set=function(key, value){
+ if(this._storage instanceof Storage){
+ if(value){
+ this[key]=JSON.stringify(value);
+ this.getStorage().setItem(this.getStorageKey(key),this[key]);
+ }else{
+ delete this[key];
+ this.getStorage().removeItem(this.getStorageKey(key));
+ }
+ }
+}
+/*
+ * A public method to store the OAuth token for later use - uses localstorage if available
+ *
+ * @method setToken
+ * @public
+ * @params {string} token
+ * @return none
+ */
+UsergridStorable.prototype.setToken = function (token) {
+ return this.set('token', token);
+};
+
+/*
+ * A public method to get the OAuth token
+ *
+ * @method getToken
+ * @public
+ * @return {string} token
+ */
+UsergridStorable.prototype.getToken = function () {
+ return this.get('token');
+};
+UsergridStorable.mixin = function(destObject){
+ var props = ['getStorage', 'setStorage', 'getStorageKey', 'get', 'set', 'getToken', 'setToken'];
+ for(var i = 0; i < props.length; i ++){
+ if(props[i] in destObject.prototype){
+ console.warn("overwriting '"+props[i]+"' on '"+destObject.name+"'.");
+ console.warn("the previous version can be found at '_"+props[i]+"' on '"+destObject.name+"'.");
+ destObject.prototype['_'+props[i]]=destObject.prototype[props[i]];
+ }
+ destObject.prototype[props[i]] = UsergridStorable.prototype[props[i]];
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/9dfc5628/sdks/html5-javascript/tests/mocha/test.js
----------------------------------------------------------------------
diff --git a/sdks/html5-javascript/tests/mocha/test.js b/sdks/html5-javascript/tests/mocha/test.js
index b07463c..ec132a8 100644
--- a/sdks/html5-javascript/tests/mocha/test.js
+++ b/sdks/html5-javascript/tests/mocha/test.js
@@ -115,7 +115,7 @@ describe('Usergrid', function() {
usergridTestHarness(err, data, done, [
function(err, data) {
- assert(data.entities.length >= 0);
+ assert(!data.entities);
console.log(JSON.stringify(data))
}
]);
@@ -129,7 +129,7 @@ describe('Usergrid', function() {
usergridTestHarness(err, data, done, [
function(err, data) {
- assert(data.entities.length === 0)
+ assert(!data.entities)
}
]);
});
@@ -152,10 +152,10 @@ describe('Usergrid', function() {
type: 'dogs',
name: 'Rocky'
}
-
- client.createEntity(options, function(err, data) {
+ client.createEntity(options, function(err, entity) {
assert(!err, "dog not created");
- dog = data;
+ dog = entity;
+ console.log("AFTER CREATE", dog.get());
done();
});
});
@@ -165,6 +165,7 @@ describe('Usergrid', function() {
done();
return;
}
+ console.log("BEFORE FETCH", dog.get());
//once the dog is created, you can set single properties:
dog.fetch(function(err) {
assert(!err, "dog not fetched");
@@ -187,7 +188,7 @@ describe('Usergrid', function() {
}
//set is additive, so previously set properties are not overwritten
dog.set(data);
-
+ console.log("BEFORE SAVE", dog.get());
//finally, call save on the object to save it back to the database
dog.save(function(err) {
assert(!err, "dog not saved");