UNPKG

caliveapicreator

Version:

A rapid development node sdk for API's for CA Live API Creator REST API services.

419 lines (382 loc) 12.2 kB
module.exports = (function () { var SDK, Q, http, https, _, querystring; Q = require('q'); http = require('http'); https = require('https'); URL = require('url'); _ = require('underscore'); querystring = require('querystring'); SDK = { debug: true, /** * The base project url. This attribute is initialized during a SDK.connect(url, ...) method */ url: null, /** * The plain Auth Token (apikey). * This attribute is initialized during a SDK.connect(url, ...) method, * either from having been passed directly, or after a username/password request has succeeded. */ apiKey: null, /** * The username passed to SDK.connect(url, username, password) */ username: null, /** * The password passed to SDK.connect(url, username, password) */ password: null, /** * The url object resulting from URL.parse(url). * After SDK.connect() succeeds, additional parameters are added (ex: SDK.params.headers) */ params: null, //produced by _.pick(URL.parse(url), 'host', 'path', 'port') /** * The promise set by SDK.connect(), used internally to verify an API key exists * before making requests */ connection: null, /** * A placeholder or the node packages http and https. * If the project is accessible through https, req is updated during SDK.connect() */ req: http, /** * Default request headers set for SDK.endpoint() methods [get(), post(), put(), del()] */ headers: {'X-liveapicreatorLogic-ResponseFormat':'json', 'Content-Type':'application/json'}, /** * Default filters supplementing an SDK.endpoint().get(filters) request */ filters: {}, /** * The endpoint for a user to authenticate */ authEndpoint: '/@authentication', /** * Convenience function testing a string for ":" */ isUrlWithPort: function (host) { if (!host) { return host; } return host.match('\:'); }, /** * Convenience function for retrieving the first element of a url that include a port */ stripUrlPort: function (host) { return host.split(':')[0]; }, /** * Removes the first and last "/" */ stripWrappingSlashes: function (str) { return str.replace(/^\/|\/$/g, ''); }, /** * The default method of connecting to an API. Returns an instance of this library * and initializes a promise used to make requests on API endpoints. * * @param string url the API url base * @param string key an API key, typically found in Logic Designer's Security section. When connecting * with a username/password, this second argument is a username * @param string password an optional argument when using liveapicreatorlogic.connect() with a user/password combination */ connect: function (url, key, password) { var deferred, options, headers, liveapicreator; liveapicreator = _.extend({}, SDK); liveapicreator.url = this.stripWrappingSlashes(url); liveapicreator.params = _.pick(URL.parse(url), 'host', 'path', 'port'); liveapicreator.params.headers = {}; if (url.match('https')) { liveapicreator.req = https; } //passed a url with a defined port if (liveapicreator.isUrlWithPort(liveapicreator.params.host)) { liveapicreator.params.host = liveapicreator.stripUrlPort(liveapicreator.params.host); } deferred = Q.defer(); liveapicreator.connection = deferred.promise; //Is this a username/password combo if (password) { options = liveapicreator.setOptions({method: 'POST'}); options.path += liveapicreator.authEndpoint; var req = liveapicreator.req.request(options, function (res) { if (res.statusCode == 503) { deferred.reject(res.statusCode); } res.setEncoding('utf8'); res.on('data', function (data) { data = JSON.parse(data); liveapicreator.apiKey = data.apikey; liveapicreator.params.headers.Authorization = 'CALiveAPICreator ' + data.apikey + ':1'; deferred.resolve(); }); }); req.end(JSON.stringify({username: key, password: password})); req.on('error', function(e) { deferred.reject('Authentication failed, please confirm the username and/or password'); }); } else { //liveapicreatorlogic.connect() was directly passed an API key liveapicreator.apiKey = key; liveapicreator.params.headers.Authorization = 'CALiveAPICreator ' + key + ':1'; deferred.resolve(); } return liveapicreator; }, log: function (output) { if (this.debug) { console.log(output); } }, /** * Internal method used to merge default liveapicreatorlogic.params options with those passed in via params */ setOptions: function (params, override) { if (!override) { override = {}; } return _.extend(params, this.params, override); }, /** * Internal method for merging liveapicreatorlogic.headers attributes with those passed in via headers. * * @param object options a collection of URL.parse(url) attributes, which may or may not contain options.headers * @param object headers a collection of header attributes to be appended to the request */ setHeaders: function (options, headers) { if (!headers) { headers = {}; } if (options.headers) { var headers = options.headers; headers = _.extend(headers, this.headers, headers); } return options; }, /** * Internal method for merging liveapicreatorlogic.filters attributes with those passed in via filters */ setFilters: function (filters) { filters = _.extend({}, this.filters, filters); return filters; }, /** * A convenience function for setting the default pagesize filter. Overriden by filters passed to endpoint objects. */ setPageSize: function (num) { this.filters.pagesize = num; }, /** * A method for stringifying a filters collection */ formatFilters: function (filters) { if (typeof filters == "string") { return filters.replace(" ", "%20"); } else if (filters) { filters = querystring.stringify(filters); } else { filters = this.setFilters({}); filters = querystring.stringify(filters); } return filters; }, /** * The default method used to make requests to specific endpoints. * liveapicreatorlogic.endpoint() returns an endpoint object with the following methods: * liveapicreatorlogic.endpoint().get(filters, headers) - returning a promise of a GET request * liveapicreatorlogic.endpoint().post(data, filters, headers) - returning a promise of a POST request * liveapicreatorlogic.endpoint().put(data, filters, headers) - returning a promise of a PUT request * liveapicreatorlogic.endpoint().del(data, filters, headers) - returning a promise of a DELETE request */ endpoint: function (endpoint, options) { var url, urlParams, prefix; urlParams = {}; url = ''; prefix = ''; if (endpoint.substr(0) != '/') { url = URL.parse(endpoint); //is this possibly a full url? if (url && url.path && url.host) { urlParams = _.pick(URL.parse(url), 'host', 'path', 'port'); endpoint = ''; if (this.isUrlWithPort(urlParams.host)) { urlParams.host = this.stripUrlPort(urlParams.host); } } else { prefix = '/'; endpoint = prefix + this.stripWrappingSlashes(endpoint); } } var liveapicreator = this; return { get: function (filters, headers) { var deferred; deferred = Q.defer(); filters = liveapicreator.formatFilters(filters); liveapicreator.connection.then(function () { var options; options = liveapicreator.setOptions({method: 'GET'}, urlParams); options = liveapicreator.setHeaders(options, headers); options.path += endpoint; if (filters) { options.path += '?' + filters; } options.path = options.path.replace(/\%27/g, "'"); var req = liveapicreator.req.request(options, function (res) { var data = ''; res.setEncoding('utf8'); res.on('data', function (chunk) { if (chunk) { data += chunk; } }); res.on('end', function (info) { data = JSON.parse(data); if (res.statusCode > 299) { //response codes 300+ indicate an error deferred.reject(data); } else { //status ok deferred.resolve(data); } }); }); req.end(); req.on('error', function(e) { deferred.reject(e); }); }); return deferred.promise; }, put: function (body, filters, headers) { var deferred; deferred = Q.defer(); filters = liveapicreator.formatFilters(filters); liveapicreator.connection.then(function () { var options; options = liveapicreator.setOptions({method: 'PUT'}, urlParams); options = liveapicreator.setHeaders(options, headers); options.path += endpoint; if (filters) { options.path += '?' + filters; } options.path = options.path.replace(/\%27/g, "'"); var req = liveapicreator.req.request(options, function (res) { var data = ''; res.setEncoding('utf8'); res.on('data', function (chunk) { if (chunk) { data += chunk; } }); res.on('end', function (info) { data = JSON.parse(data); if (res.statusCode > 299) { //response codes 300+ indicate an error deferred.reject(data); } else { //status ok deferred.resolve(data); } }); }); req.end(JSON.stringify(body)); req.on('error', function(e) { deferred.reject(e); }); }); return deferred.promise; }, post: function (body, filters, headers) { var deferred; deferred = Q.defer(); filters = liveapicreator.formatFilters(filters); liveapicreator.connection.then(function () { var options; options = liveapicreator.setOptions({method: 'POST'}, urlParams); options = liveapicreator.setHeaders(options, headers); options.path += endpoint; if (filters) { options.path += '?' + filters; } options.path = options.path.replace(/\%27/g, "'"); var req = liveapicreator.req.request(options, function (res) { var data = ''; res.setEncoding('utf8'); res.on('data', function (chunk) { if (chunk) { data += chunk; } }); res.on('end', function (info) { data = JSON.parse(data); if (res.statusCode > 299) { //response codes 300+ indicate an error deferred.reject(data); } else { //status ok deferred.resolve(data); } }); }); req.end(JSON.stringify(body)); req.on('error', function(e) { deferred.reject(e); }); }); return deferred.promise; }, del: function (body, filters, headers) { var deferred; deferred = Q.defer(); if (!filters) {filters = {};} filters.checksum = body['@metadata'].checksum; filters = liveapicreator.formatFilters(filters); liveapicreator.connection.then(function () { var options; options = liveapicreator.setOptions({method: 'DELETE'}, urlParams); options = liveapicreator.setHeaders(options, headers); options.path += endpoint; if (filters) { options.path += '?' + filters; } options.path = options.path.replace(/\%27/g, "'"); var req = liveapicreator.req.request(options, function (res) { var data = ''; res.setEncoding('utf8'); res.on('data', function (chunk) { if (chunk) { data += chunk; } }); res.on('end', function (info) { data = JSON.parse(data); if (res.statusCode > 299) { //response codes 300+ indicate an error deferred.reject(data); } else { //status ok deferred.resolve(data); } }); }); //req.end(JSON.stringify(body)); req.end(); req.on('error', function(e) { deferred.reject(e); }); }); return deferred.promise; }, }; return deferred.promise; }, }; return SDK; })();