diff --git a/reste.js b/reste.js index 0250064..6cff3b1 100644 --- a/reste.js +++ b/reste.js @@ -1,5 +1,4 @@ var main = function() { - var reste = this; // setup vars @@ -9,20 +8,19 @@ var main = function() { // generic log handler in DEV mode function log(message) { if (config.debug && message) { - console.log('::RESTE::' + message); + console.log("::RESTE::" + message); } } // generic log handler in DEV mode function warn(message) { if (config.debug && message) { - console.warn('::RESTE::' + message); + console.warn("::RESTE::" + message); } } // sets up the config, headers, adds methods reste.config = function(args) { - config = args; reste.setRequestHeaders(config.requestHeaders); @@ -32,14 +30,12 @@ var main = function() { }); if (config.models) { - initModels(); config.models.forEach(function(model) { reste.addModel(model); }); } - }; reste.setUrl = function(url) { @@ -53,7 +49,6 @@ var main = function() { // makes an http request to a URL, as a POST / GET / currently, // passing params and callback function makeHttpRequest(args, onLoad, onError) { - function isJSON(str) { try { JSON.parse(str); @@ -72,10 +67,10 @@ var main = function() { } // debug the url - if (args.url.indexOf('http') >= 0) { + if (args.url.indexOf("http") >= 0) { log(args.url); } else { - log((config.url ? config.url + args.url : args.url)); + log(config.url ? config.url + args.url : args.url); } if (args.params) { @@ -86,8 +81,7 @@ var main = function() { var http = Ti.Network.createHTTPClient(); reste.clearCookies = function() { - if (http) - http.clearCookies(config.url); + if (http) http.clearCookies(config.url); }; var formEncode = false; @@ -95,48 +89,86 @@ var main = function() { //set some defaults http.setTimeout(config.timeout || 10000); - if (_.has(config, 'validatesSecureCertificate')) { - http.setValidatesSecureCertificate(config.validatesSecureCertificate); + if (_.has(config, "validatesSecureCertificate")) { + http.setValidatesSecureCertificate( + config.validatesSecureCertificate + ); } // open the url and check if we're overrding with // a local http based url - if (args.url.indexOf('http') >= 0) { + if (args.url.indexOf("http") >= 0) { http.open(args.method, args.url); } else { - http.open(args.method, (config.url ? config.url + args.url : args.url)); + http.open( + args.method, + config.url ? config.url + args.url : args.url + ); } // load up any global request headers requestHeaders.forEach(function(header) { - if (header.name === 'Content-Type' && header.value === 'application/x-www-form-urlencoded') { + if ( + header.name === "Content-Type" && + header.value === "application/x-www-form-urlencoded" + ) { formEncode = true; } - http.setRequestHeader(header.name, typeof header.value === 'function' ? header.value() : header.value); - - log('Setting global header - ' + header.name + ': ' + ( typeof header.value === 'function' ? header.value() : header.value)); + http.setRequestHeader( + header.name, + typeof header.value === "function" + ? header.value() + : header.value + ); + + log( + "Setting global header - " + + header.name + + ": " + + (typeof header.value === "function" + ? header.value() + : header.value) + ); }); // non-global headers if (args.headers) { // load up any request headers for (var header in args.headers) { - if (header === 'Content-Type' && args.headers[header] === 'application/x-www-form-urlencoded') { + if ( + header === "Content-Type" && + args.headers[header] === "application/x-www-form-urlencoded" + ) { formEncode = true; - } else if (header === 'Content-Type' && args.headers[header] === 'application/json') { + } else if ( + header === "Content-Type" && + args.headers[header] === "application/json" + ) { formEncode = false; } - http.setRequestHeader(header, typeof args.headers[header] === 'function' ? args.headers[header]() : args.headers[header]); - - log('Setting local header - ' + header + ': ' + ( typeof args.headers[header] === 'function' ? args.headers[header]() : args.headers[header])); + http.setRequestHeader( + header, + typeof args.headers[header] === "function" + ? args.headers[header]() + : args.headers[header] + ); + + log( + "Setting local header - " + + header + + ": " + + (typeof args.headers[header] === "function" + ? args.headers[header]() + : args.headers[header]) + ); } } // security manager (Pro / Enterprise) - if (_.has(config, 'securityManager')) { + if (_.has(config, "securityManager")) { http.setSecurityManager(config.securityManager); } @@ -150,15 +182,14 @@ var main = function() { } else if (onLoad) { onLoad(response); } - }; http.onerror = function(e) { e.url = args.url; function retry() { - log('Retrying...'); - return makeHttpRequest(args, onLoad, onError); + log("Retrying..."); + return makeHttpRequest(args, onLoad, onError); } var error; @@ -166,10 +197,12 @@ var main = function() { if (config.errorsAsObjects) { error = e; error.content = parseJSON(http.responseText); - warn('Errors will be returned as objects.'); + warn("Errors will be returned as objects."); } else { error = parseJSON(http.responseText); - warn('Future versions of RESTe will return errors as objects. Use config.errorsAsObjects = true to support this now and update your apps!'); + warn( + "Future versions of RESTe will return errors as objects. Use config.errorsAsObjects = true to support this now and update your apps!" + ); } // if local error, handle it @@ -183,7 +216,7 @@ var main = function() { onLoad(error, retry); } else { // and if reste's not specified, error! - throw 'RESTe :: No error handler / callback for: ' + args.url; + throw "RESTe :: No error handler / callback for: " + args.url; } }; @@ -191,7 +224,10 @@ var main = function() { // go log(args.params); - if (args.params && (args.method === 'POST' || args.method === 'PUT')) { + if ( + args.params && + (args.method === "POST" || args.method === "PUT") + ) { if (formEncode) { http.send(args.params); } else { @@ -202,27 +238,23 @@ var main = function() { } } - args.params = args.params || {}; var beforePost = args.beforePost || config.beforePost; var beforeSend = args.beforeSend || config.beforeSend; - if (args.method === 'POST' && typeof beforePost === 'function') { - + if (args.method === "POST" && typeof beforePost === "function") { // initialise empty params in case it's undefined beforePost(args.params, function(e) { args.params = e; send(); }); - - } else if ( typeof beforeSend === 'function') { + } else if (typeof beforeSend === "function") { beforeSend(args.params, function(e) { args.params = e; send(); }); - } else { send(); } @@ -234,8 +266,8 @@ var main = function() { requestHeaders = []; for (var header in headers) { requestHeaders.push({ - name : header, - value : headers[header] + name: header, + value: headers[header] }); } }; @@ -253,8 +285,8 @@ var main = function() { if (!changed) { // add it requestHeaders.push({ - name : Object.keys(header)[0], - value : header[Object.keys(header)[0]] + name: Object.keys(header)[0], + value: header[Object.keys(header)[0]] }); } }; @@ -268,45 +300,45 @@ var main = function() { // add a new method reste.addMethod = function(args) { - log(args.requestHeaders); reste[args.name] = function(params, onLoad, onError) { - var body, - method = 'GET', + method = "GET", url, deferred; - if (args.post) - method = 'POST'; - if (args.get) - method = 'GET'; - if (args.put) - method = 'PUT'; - if (args.delete) - method = 'DELETE'; + if (args.post) method = "POST"; + if (args.get) method = "GET"; + if (args.put) method = "PUT"; + if (args.delete) method = "DELETE"; url = args[method.toLowerCase()] || args.get; - if (config.Q && !onLoad && typeof (params) != 'function') { + if (config.Q && !onLoad && typeof params != "function") { deferred = config.Q.defer(); onLoad = deferred.resolve; onError = deferred.reject; } - if (!onLoad && typeof (params) === 'function') { + if (!onLoad && typeof params === "function") { onLoad = params; } else { for (var param in params) { - if (param === 'body') { + if (param === "body") { body = params[param]; } else { - while (url.indexOf('<' + param + '>') >= 0) { - if ( typeof params[param] === 'object') { - url = url.replace('<' + param + '>', JSON.stringify(params[param])); + while (url.indexOf("<" + param + ">") >= 0) { + if (typeof params[param] === "object") { + url = url.replace( + "<" + param + ">", + JSON.stringify(params[param]) + ); } else { - url = url.replace('<' + param + '>', params[param]); + url = url.replace( + "<" + param + ">", + params[param] + ); } } } @@ -333,51 +365,64 @@ var main = function() { if (args.expects) { // look for explicityly required parameters args.expects.forEach(function(expectedParam) { - if ((method === 'POST' && params.body) ? !params.body[expectedParam] : !params[expectedParam]) { - throw 'RESTe :: missing parameter ' + expectedParam + ' for method ' + args.name; + if ( + method === "POST" && params.body + ? !params.body[expectedParam] + : !params[expectedParam] + ) { + throw "RESTe :: missing parameter " + + expectedParam + + " for method " + + args.name; } }); - return makeHttpRequest({ - url : url, - method : method, - params : body, - headers : args.requestHeaders || args.headers, - beforePost : args.beforePost, - beforeSend : args.beforeSend - }, onLoad, onError); - + return makeHttpRequest( + { + url: url, + method: method, + params: body, + headers: args.requestHeaders || args.headers, + beforePost: args.beforePost, + beforeSend: args.beforeSend + }, + onLoad, + onError + ); } else { - var m, missing = [], re = /(\<\w*\>)/g; //work out which parameters are required if (config.autoValidateParams) { - - while (( m = re.exec(url)) !== null) { + while ((m = re.exec(url)) !== null) { if (m.index === re.lastIndex) { re.lastIndex++; } missing.push(m[0]); } - } if (missing.length > 0) { - throw 'RESTe :: missing parameter/s ' + missing + ' for method ' + args.name; + throw "RESTe :: missing parameter/s " + + missing + + " for method " + + args.name; } else { - - return makeHttpRequest({ - url : url, - method : method, - params : body, - headers : args.requestHeaders || args.headers, - beforePost : args.beforePost, - beforeSend : args.beforeSend - }, onLoad, onError); + return makeHttpRequest( + { + url: url, + method: method, + params: body, + headers: args.requestHeaders || args.headers, + beforePost: args.beforePost, + beforeSend: args.beforeSend + }, + onLoad, + onError + ); } } @@ -395,7 +440,11 @@ var main = function() { // if we have a config based transfor for th emodel // then attach this to the model, or create a default - if (reste.modelConfig && reste.modelConfig[name] && reste.modelConfig[name].transform) { + if ( + reste.modelConfig && + reste.modelConfig[name] && + reste.modelConfig[name].transform + ) { model.transform = function(model, transform) { if (transform) { this.__transform = transform(this); @@ -420,25 +469,23 @@ var main = function() { }; reste.createCollection = function(name, content) { - if (!Alloy.Collections[name]) { Alloy.Collections[name] = new Backbone.Collection(); } - if ( content instanceof Array) { + if (content instanceof Array) { // on-the-fly collection, so populate from array Alloy.Collections[name].reset(content); // and override fetch to trigger a change event Alloy.Collections[name].fetch = function() { - Alloy.Collections[name].trigger('change'); + Alloy.Collections[name].trigger("change"); }; } else { - throw 'No Array specified for createCollection'; + throw "No Array specified for createCollection"; } }; function initModels() { - // add a new model definition reste.addModel = function(args) { reste.modelConfig = reste.modelConfig || {}; @@ -447,9 +494,9 @@ var main = function() { reste.modelConfig[args.name] = args; var model = Backbone.Model.extend({ - _type : args.name, - _method : args.name, - transform : function(model, transform) { + _type: args.name, + _method: args.name, + transform: function(model, transform) { if (transform) { this.__transform = transform(this); } else if (args.transform) { @@ -463,7 +510,9 @@ var main = function() { if (args.collections) { args.collections.forEach(function(collection) { - Alloy.Collections[collection.name] = Alloy.Collections[collection.name] || new Backbone.Collection(); + Alloy.Collections[collection.name] = + Alloy.Collections[collection.name] || + new Backbone.Collection(); Alloy.Collections[collection.name]._type = args.name; Alloy.Collections[collection.name]._name = collection.name; Alloy.Collections[collection.name].model = model; @@ -473,62 +522,69 @@ var main = function() { // Intercept sync to handle collections / models Backbone.sync = function(method, model, options) { - log('Backbone.sync: ' + method + ' ' + model._type); + log("Backbone.sync: " + method + " " + model._type); var modelConfig = reste.modelConfig[model._type]; - var body, - onError; + var body, onError; // if this is a collection, get the data and complete - if ( model instanceof Backbone.Collection && modelConfig && modelConfig.collections) { + if ( + model instanceof Backbone.Collection && + modelConfig && + modelConfig.collections + ) { var collectionConfig = _.where(modelConfig.collections, { - name: model._name + name: model._name })[0]; var methodCall = reste[collectionConfig.read]; - methodCall(options, function(response) { - - if ((response != null) && (response != undefined)) { - - // check if we have a return property - if (response[collectionConfig.content]) { - - response[collectionConfig.content].forEach(function(item) { - item.id = item[modelConfig.id]; - }); - - if (options.success) options.success(response[collectionConfig.content]); - - Alloy.Collections[collectionConfig.name].trigger('sync'); - - } else { - - // otherwise just return an array with the response - response.forEach(function(item) { - item.id = item[modelConfig.id]; - }); + methodCall( + options, + function(response) { + if (response != null && response != undefined) { + // check if we have a return property + if (response[collectionConfig.content]) { + response[collectionConfig.content].forEach( + function(item) { + item.id = item[modelConfig.id]; + } + ); + + if (options.success) + options.success( + response[collectionConfig.content] + ); + + Alloy.Collections[ + collectionConfig.name + ].trigger("sync"); + } else { + // otherwise just return an array with the response + response.forEach(function(item) { + item.id = item[modelConfig.id]; + }); - if (options.success) options.success(response); + if (options.success) options.success(response); - Alloy.Collections[collectionConfig.name].trigger('sync'); + Alloy.Collections[ + collectionConfig.name + ].trigger("sync"); + } + } + }, + function(response) { + if (options.error) { + options.error(response); } - } - }, function(response) { - - if (options.error) { - options.error(response); } - - }); - - } else if ( model instanceof Backbone.Model) { - - if (model.get('id') && method === 'create') { - method = 'update'; + ); + } else if (model instanceof Backbone.Model) { + if (model.get("id") && method === "create") { + method = "update"; } - if (method === 'update') { + if (method === "update") { params = {}; // if we're specifying attributes to changes @@ -541,7 +597,7 @@ var main = function() { } // update! - params[modelConfig.id] = model.get('id'); + params[modelConfig.id] = model.get("id"); params.body = params.body || model.toJSON(); @@ -554,64 +610,70 @@ var main = function() { params.body = modelConfig.beforeUpdate(params.body); } - options.error ? onError = function(e) { - options.error(e); - } : onError = null; - - reste[modelConfig.update](params, function(e) { - // calls error handler if we have it defined and 201 returned - if (e.code > 200) { - onError(e); - } else { - // otherwise pass to success - options.success(e); - } - }, onError); + options.error + ? (onError = function(e) { + options.error(e); + }) + : (onError = null); + + reste[modelConfig.update]( + params, + function(e) { + // calls error handler if we have it defined and 201 returned + if (e.code > 200) { + onError(e); + } else { + // otherwise pass to success + options.success(e); + } + }, + onError + ); } - if (method === 'read') { - + if (method === "read") { if (modelConfig.read) { - if (model[modelConfig.id]) { options[modelConfig.id] = model[modelConfig.id]; - } else if (model.get('id')) { - options[modelConfig.id] = model.get('id'); + } else if (model.get("id")) { + options[modelConfig.id] = model.get("id"); } - options.error ? onError = function(e) { - options.error(e); - } : onError = null; - - reste[modelConfig.read](options, function(e) { - - if (modelConfig.content) { - - var result = e[modelConfig.content]; - - if (result.length === 1) { - //result is an array with value as first entry - options.success(result[0]); - } - else { - //result is not an array - options.success(result); - } - } else { - // calls error handler if we have it defined and 201+ returned - if (e.code > 200) { - onError(e); + options.error + ? (onError = function(e) { + options.error(e); + }) + : (onError = null); + + reste[modelConfig.read]( + options, + function(e) { + if (modelConfig.content) { + var result = e[modelConfig.content]; + + if (result.length === 1) { + //result is an array with value as first entry + options.success(result[0]); + } else { + //result is not an array + options.success(result); + } } else { - // otherwise pass to success - options.success(e); + // calls error handler if we have it defined and 201+ returned + if (e.code > 200) { + onError(e); + } else { + // otherwise pass to success + options.success(e); + } } - } - }, onError); + }, + onError + ); } } - if (method === 'create') { - + if (method === "create") { body = model.toJSON(); // remove any ids from the body @@ -623,31 +685,36 @@ var main = function() { body = modelConfig.beforeDelete(body); } - options.error ? onError = function(e) { - options.error(e); - } : onError = null; - - reste[modelConfig.create]({ - body : body - }, function(e) { - // calls error handler if we have it defined and 201+ returned - - if (e.code > 200) { - onError(e); - } else { - // otherwise pass to success - e.id = e[modelConfig.id]; - model.set('id', e[modelConfig.id]); - options.success(e); - } - }, onError); + options.error + ? (onError = function(e) { + options.error(e); + }) + : (onError = null); + + reste[modelConfig.create]( + { + body: body + }, + function(e) { + // calls error handler if we have it defined and 201+ returned + + if (e.code > 200) { + onError(e); + } else { + // otherwise pass to success + e.id = e[modelConfig.id]; + model.set("id", e[modelConfig.id]); + options.success(e); + } + }, + onError + ); } - if (method === 'delete') { - + if (method === "delete") { body = {}; - body[modelConfig.id] = model.get('id'); + body[modelConfig.id] = model.get("id"); body.body = model.toJSON(); // change to change the attributes before sending @@ -655,19 +722,25 @@ var main = function() { body.body = modelConfig.beforeCreate(body.body); } - options.error ? onError = function(e) { - options.error(e); - } : onError = null; - - reste[modelConfig.delete](body, function(e) { - // calls error handler if we have it defined and 201+ returned - if (e.code > 200) { - onError(e); - } else { - // otherwise pass to success - options.success(e); - } - }, onError); + options.error + ? (onError = function(e) { + options.error(e); + }) + : (onError = null); + + reste[modelConfig.delete]( + body, + function(e) { + // calls error handler if we have it defined and 201+ returned + if (e.code > 200) { + onError(e); + } else { + // otherwise pass to success + options.success(e); + } + }, + onError + ); } } };