From 82f0ec344154c4679a84ceffd49c550b7fd0a084 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Fri, 23 Sep 2016 19:00:53 +0200 Subject: [PATCH 1/8] Added support for POST, PUT, DELETE request methods --- lib/http-requests.js | 280 ++++++++++++++++++++++++++++++++++++++++++- lib/softlayer.js | 71 ++++++++++- 2 files changed, 348 insertions(+), 3 deletions(-) diff --git a/lib/http-requests.js b/lib/http-requests.js index 6c0356e..5c1691e 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -18,6 +18,7 @@ function _isNumberSet(value) { * @param mask object mask * @param offset pagination offset * @param limit pagination result limit + * @param headers custom headers for the request * @param callback */ exports.get = function(credentials, pathElements, mask, filter, offset, limit, headers, callback) { @@ -101,4 +102,281 @@ exports.get = function(credentials, pathElements, mask, filter, offset, limit, h }); req.end(); -}; \ No newline at end of file +}; + +/** + * Sends a PUT request to the given softlayer rest endpoint. + * @param credentials object containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param mask object mask + * @param offset pagination offset + * @param limit pagination result limit + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.put = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + + //build path + pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; + var path = _basePath + pathElements.join('/'); + + //Basic authentication + var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); + + var body = JSON.stringify({ + parameters: [ + parameters + ] + }); + + + headers = headers || { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }; + + + + + headers['Content-Length'] = body.length + headers['Authorization'] = auth; + + var request_options = { + host: _baseUrl, + path: path, + port: 443, + method: 'PUT', + rejectUnauthorized: false, + headers: headers + }; + + // Set up the request + var req = https.request(request_options, function(res) { + res.setEncoding('utf8'); + + var data = ''; + res.on('data', function(chunk) { + data += chunk; + }); + + res.on('end', function() { + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + var error; + if (data) { + error = JSON.parse(data); + error.statusCode = res.statusCode; + } else { + error = { + statusCode: res.statusCode + }; + } + callback(error, {}); + } else { + if (headers['Content-Type'] === 'application/json') { + callback(null, JSON.parse(data)); + } else { + callback(null, data); + } + } + }); + }); + + req.on('error', function(error) { + callback(error, {}); + }); + + req.write(body); + req.end(); +}; + +/** + * Sends a GET request to the given softlayer rest endpoint. + * @param credentials object containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param mask object mask + * @param offset pagination offset + * @param limit pagination result limit + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.post = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + + //build path + pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; + var path = _basePath + pathElements.join('/'); + + //Basic authentication + var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); + + var body = ''; + if (parameters.constructor === Array) { + body = JSON.stringify({ + parameters: parameters + }); + } else { + body = JSON.stringify({ + parameters: [ + parameters + ] + }); + } + + headers = headers || { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }; + + + + + headers['Content-Length'] = body.length + headers['Authorization'] = auth; + + var request_options = { + host: _baseUrl, + path: path, + port: 443, + method: 'POST', + rejectUnauthorized: false, + headers: headers + }; + + // Set up the request + var req = https.request(request_options, function(res) { + res.setEncoding('utf8'); + + var data = ''; + res.on('data', function(chunk) { + data += chunk; + }); + + res.on('end', function() { + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + var error; + if (data) { + error = JSON.parse(data); + error.statusCode = res.statusCode; + } else { + error = { + statusCode: res.statusCode + }; + } + callback(error, {}); + } else { + if (headers['Content-Type'] === 'application/json') { + callback(null, JSON.parse(data)); + } else { + callback(null, data); + } + } + }); + }); + + req.on('error', function(error) { + callback(error, {}); + }); + + req.write(body); + req.end(); +}; + + +/** + * Sends a GET request to the given softlayer rest endpoint. + * @param credentials object containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param mask object mask + * @param offset pagination offset + * @param limit pagination result limit + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.delete = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { + + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + + + //build path + pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; + var path = _basePath + pathElements.join('/'); + + //Basic authentication + var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); + + var body = JSON.stringify({ + parameters: [ + parameters + ] + }); + + + headers = headers || { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }; + + + + + headers['Content-Length'] = body.length + headers['Authorization'] = auth; + + var request_options = { + host: _baseUrl, + path: path, + port: 443, + method: 'DELETE', + rejectUnauthorized: false, + headers: headers + }; + + // Set up the request + var req = https.request(request_options, function(res) { + res.setEncoding('utf8'); + + var data = ''; + res.on('data', function(chunk) { + data += chunk; + }); + + res.on('end', function() { + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + var error; + if (data) { + error = JSON.parse(data); + error.statusCode = res.statusCode; + } else { + error = { + statusCode: res.statusCode + }; + } + callback(error, {}); + } else { + if (headers['Content-Type'] === 'application/json') { + callback(null, JSON.parse(data)); + } else { + callback(null, data); + } + } + }); + }); + + req.on('error', function(error) { + callback(error, {}); + }); + + req.write(body); + req.end(); +}; diff --git a/lib/softlayer.js b/lib/softlayer.js index 55a2da9..d193837 100644 --- a/lib/softlayer.js +++ b/lib/softlayer.js @@ -96,7 +96,7 @@ SoftLayer.prototype.mask = function (mask) { * Adds the given object filter to the prepared service request. * You can pass a json object to this method * @params filter json object to add to the path - * @retirn {SoftLayer} + * @return {SoftLayer} */ SoftLayer.prototype.filter = function (filter) { if (!this.service) this.service = _getDefaults(); @@ -106,6 +106,19 @@ SoftLayer.prototype.filter = function (filter) { return this; } +/** + * Adds the given parameters to the prepared service request. + * @params parameters Object to be passed to the request body. + * @return {SoftLayer} + */ + +SoftLayer.prototype.parameters = function(parameters) { + if (!this.service) this.service = _getDefaults(); + this.service.parameters = parameters; + return this; +} + + /** * Adds offset and limit to the prepared service request. * @param offset @@ -160,5 +173,59 @@ SoftLayer.prototype.get = function (callback) { }).nodeify(callback); }; +/** + * PUT the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.put = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.put(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + +/** + * POST the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.post = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.post(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + +/** + * DELETE the prepared service request. + * @param callback optional node style callback + * @returns {bluebird} a bluebird promise + */ +SoftLayer.prototype.delete = function (callback) { + var _this = this; + return new Promise(function (resolve, reject) { + HttpRequests.delete(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + _this.reset(); + if (error) { + return reject(error); + } + return resolve(result); + }); + }).nodeify(callback); +}; + -services(SoftLayer); \ No newline at end of file +services(SoftLayer); From 39b189f0d1999f8df4e25cd8890a7ea96f242899 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Fri, 23 Sep 2016 20:33:04 +0200 Subject: [PATCH 2/8] updated tests for filter object --- package.json | 2 +- test/http-request-test.js | 30 ++++++++++++++++++------------ test/softlayer-test.js | 10 ++++++++-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 75226a6..9167776 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Softlayer API Wrapper for node", "main": "./lib/softlayer.js", "scripts": { - "test": "gulp test" + "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec" }, "repository": { "type": "git", diff --git a/test/http-request-test.js b/test/http-request-test.js index 3a57ebf..9667042 100644 --- a/test/http-request-test.js +++ b/test/http-request-test.js @@ -5,8 +5,14 @@ var fs = require('fs'); var path = require('path'); var expect = require('chai').expect; var HttpRequests = require('../lib/http-requests'); +var credentials = { }; + +try { + credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); +} catch (e) { + //no credentials +} -var credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); describe('HttpRequests', function () { @@ -22,14 +28,14 @@ describe('HttpRequests', function () { describe('get()', function() { it('should fail because of missing credentials', function(done) { - HttpRequests.get(undefined, null, null,null,null, null, function(err) { + HttpRequests.get(undefined, null, null, null, null, null, null, function(err) { expect(err).to.be.ok; done(); }); }); it('should fail because of missing path', function(done) { - HttpRequests.get({apiUser: 'user', apiKey: 'key'}, null, null,null,null, null, function(err) { + HttpRequests.get({apiUser: 'user', apiKey: 'key'}, null, null,null,null, null, null, function(err) { expect(err).to.be.ok; done(); }); @@ -37,7 +43,7 @@ describe('HttpRequests', function () { it('should fail with status 401 because of incorrect user credentials', function(done) { var path=['Account']; - HttpRequests.get({apiUser: 'user', apiKey: 'key'}, path, null,null,null, null, function(err) { + HttpRequests.get({apiUser: 'user', apiKey: 'key'}, path, null, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(401); @@ -47,7 +53,7 @@ describe('HttpRequests', function () { }); it('should fail with status 404 because of invalid path', function(done) { var path=['ThisIsInvalid']; - HttpRequests.get(credentials, path, null,null,null, null, function(err) { + HttpRequests.get(credentials, path, null, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(404); done(); @@ -57,7 +63,7 @@ describe('HttpRequests', function () { it('should fail with status 500 because of invalid mask', function(done) { var path=['Account']; var mask=['(/;'] - HttpRequests.get(credentials, path, mask, null,null, null, function(err) { + HttpRequests.get(credentials, path, mask, null, null, null, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(500); @@ -67,7 +73,7 @@ describe('HttpRequests', function () { it('should fail with status 500 because of using pagination with invalid limit', function(done) { var path=['Account', 'Invoices']; - HttpRequests.get(credentials, path, null, 0, 0, null, function(err) { + HttpRequests.get(credentials, path, null, null, 0, 0, null, function(err) { expect(err).to.be.ok; expect(err.statusCode).to.equal(500); @@ -78,7 +84,7 @@ describe('HttpRequests', function () { it('should successfully return a Softlayer object', function(done) { var path=['Account']; - HttpRequests.get(credentials, path, null, null, null, null, function(err, res) { + HttpRequests.get(credentials, path, null, null, null, null, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; @@ -94,7 +100,7 @@ describe('HttpRequests', function () { 'Accept': 'application/xml', 'Content-Type': 'application/xml' }; - HttpRequests.get(credentials, path, null, null, null, headers, function(err, res) { + HttpRequests.get(credentials, path, null, null, null, null, headers, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; @@ -107,7 +113,7 @@ describe('HttpRequests', function () { var path=['Account']; var mask=['city']; - HttpRequests.get(credentials, path, mask, null, null, null, function(err, res) { + HttpRequests.get(credentials, path, mask, null, null, null, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.city).to.be.ok; //we masked with city, so it should be part of the result @@ -121,7 +127,7 @@ describe('HttpRequests', function () { var path=['Account', ['Invoices']]; var mask=['id']; - HttpRequests.get(credentials, path, mask, 0, 2, null, function(err, res) { + HttpRequests.get(credentials, path, mask, null, 0, 2, null, function(err, res) { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.length).to.equal(2); @@ -131,4 +137,4 @@ describe('HttpRequests', function () { }); -}); \ No newline at end of file +}); diff --git a/test/softlayer-test.js b/test/softlayer-test.js index cbdf17e..5262721 100644 --- a/test/softlayer-test.js +++ b/test/softlayer-test.js @@ -5,7 +5,13 @@ var fs = require('fs'); var path = require('path'); var expect = require('chai').expect; var SoftLayer = require('../lib/softlayer'); -var credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); +var credentials = { }; + +try { + credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); +} catch (e) { + //no credentials +} describe('SoftLayer API', function () { @@ -238,4 +244,4 @@ describe('SoftLayer API', function () { }); }); -}); \ No newline at end of file +}); From bd0c1411108358a9760393b2f3c6f5f66dde5877 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Fri, 23 Sep 2016 21:50:16 +0200 Subject: [PATCH 3/8] fixed issues in tests --- lib/http-requests.js | 9 ++++++++- package.json | 9 +++------ test/softlayer-test.js | 39 +++++++++++++++++++-------------------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/lib/http-requests.js b/lib/http-requests.js index 5c1691e..abf5832 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -79,7 +79,14 @@ exports.get = function(credentials, pathElements, mask, filter, offset, limit, h if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { var error; if (data) { - error = JSON.parse(data); + if (headers['Content-Type'] === 'application/json') { + error = JSON.parse(data); + } else { + error = { + data: data + } + } + error.statusCode = res.statusCode; } else { error = { diff --git a/package.json b/package.json index 9167776..bc862f8 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Softlayer API Wrapper for node", "main": "./lib/softlayer.js", "scripts": { - "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec" + "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec || exit 0" }, "repository": { "type": "git", @@ -24,10 +24,7 @@ "bluebird": "^2.9.13" }, "devDependencies": { - "chai": "^2.1.1", - "gulp": "^3.8.11", - "gulp-jshint": "^1.9.2", - "gulp-mocha": "^2.0.0", - "mocha": "^2.2.1" + "chai": "^3.5.0", + "mocha": "^3.0.2" } } diff --git a/test/softlayer-test.js b/test/softlayer-test.js index 5262721..d72da5c 100644 --- a/test/softlayer-test.js +++ b/test/softlayer-test.js @@ -2,6 +2,7 @@ * Created by michael.wibmer on 11.03.2015. */ var fs = require('fs'); +var Promise = require('bluebird'); var path = require('path'); var expect = require('chai').expect; var SoftLayer = require('../lib/softlayer'); @@ -177,23 +178,20 @@ describe('SoftLayer API', function () { it('should successfully return a masked Softlayer object, and reset the internal service object', function(done) { - var result = null, error = null; - var client = new SoftLayer() .path('Account') .mask(['id']) .auth(credentials.apiUser, credentials.apiKey) .get() .then(function(res) { - result = res; - }, function(err) { - error = err; + expect(res).to.be.ok; + expect(res.id).to.equal(credentials.accountId); + expect(client.service).to.not.be.ok; + }) + .catch(function(err) { + expect(err).to.equal(null); }) .finally(function() { - expect(error).to.equal(null); - expect(result).to.be.ok; - expect(result.id).to.equal(credentials.accountId); - expect(client.service).to.not.be.ok; done(); }); }); @@ -209,8 +207,11 @@ describe('SoftLayer API', function () { expect(err).to.equal(null); expect(res).to.be.ok; expect(res.id).to.equal(credentials.accountId); + + }) + .finally(function() { done(); - }); + }) }); }); @@ -218,8 +219,6 @@ describe('SoftLayer API', function () { it('should successfully return a Softlayer object as xml', function (done) { - var result = null, error = null; - var client = new SoftLayer() .path('Account') .mask(['id']) @@ -230,17 +229,17 @@ describe('SoftLayer API', function () { }) .get() .then(function (res) { - result = res; - }, function (err) { - error = err; + expect(res).to.be.ok; + expect(res).to.contains('?xml'); + expect(client.service).to.not.be.ok; + }) + .catch(function (err) { + expect(err).to.equal(null); }) .finally(function () { - expect(error).to.equal(null); - expect(result).to.be.ok; - expect(result).to.contains('?xml'); - expect(client.service).to.not.be.ok; - done(); + done() }); + }); }); From 2ef9916ab542788c27629b36f5da93b3fc3f28ca Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Fri, 23 Sep 2016 23:35:16 +0200 Subject: [PATCH 4/8] refactored http-requests, added eslint --- .eslintignore | 2 + .eslintrc | 20 ++ .jshintrc | 40 ---- README.md | 23 ++- gulpfile.js | 22 --- lib/http-requests.js | 390 +++++++++----------------------------- lib/services.js | 2 +- lib/softlayer.js | 18 +- package.json | 10 +- test/http-request-test.js | 2 - 10 files changed, 136 insertions(+), 393 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc delete mode 100644 .jshintrc delete mode 100644 gulpfile.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..77712c4 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +**/node_modules +**/test diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..f976464 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,20 @@ +{ + "extends": "formidable/configurations/es5", + "env": { + "node": true + }, + rules: { + "max-len": [0, 120, 4], + "quotes": ["error", "single"], + "indent": [0, "tab"], + "space-before-function-paren": 0, + strict: 0, + curly: 0, + "max-params": 0, + "valid-jsdoc": 0, + "max-statements": 0, + "consistent-return": 0, + "no-magic-numbers": 0, + "consistent-this": ["error", "_this"] + } +} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 3678478..0000000 --- a/.jshintrc +++ /dev/null @@ -1,40 +0,0 @@ -{ - "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. - "browser": true, // Standard browser globals e.g. `window`, `document`. - "esnext": true, // Allow ES.next specific features such as `const` and `let`. - "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.). - "camelcase": false, // Permit only camelcase for `var` and `object indexes`. - "curly": false, // Require {} for every new block or scope. - "eqeqeq": true, // Require triple equals i.e. `===`. - "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef": true, // Prohibit variable use before definition. - "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`. - "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. - "quotmark": "single", // Define quotes to string values. - "regexp": true, // Prohibit `.` and `[^...]` in regular expressions. - "undef": true, // Require all non-global variables be declared before they are used. - "unused": false, // Warn unused variables. - "strict": true, // Require `use strict` pragma in every file. - "trailing": true, // Prohibit trailing whitespaces. - "smarttabs": false, // Suppresses warnings about mixed tabs and spaces - "globals": { // Globals variables. - "Promise" : true - }, - "predef": [ // Extra globals. - "define", - "require", - "exports", - "module", - "describe", - "before", - "beforeEach", - "after", - "afterEach", - "it", - "inject", - "expect" - ], - "indent": 4, // Specify indentation spacing - "devel": true, // Allow development statements e.g. `console.log();`. - "noempty": true // Prohibit use of empty blocks. -} \ No newline at end of file diff --git a/README.md b/README.md index 0064719..56e774d 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ This method sets the credentials ```javascript client.auth(apiUser, apiKey); ``` - ##### mask() Using this method you can add an object mask to the request. You can pass an array of mask elements, or simply string arguments to the method. ```javascript @@ -73,8 +72,8 @@ client.headers({ 'Content-Type': 'application/json' }); ``` -##### get() -With get() the request is submitted. This method returns a Promise. If you prefer node callbacks, you can pass a callback to the method. +##### get(), put(), post(), delete() +Calling one of these methods, the request is submitted. This method returns a Promise. If you prefer node callbacks, you can pass a callback to the method. ```javascript //Using Promises: client.get() @@ -85,11 +84,9 @@ client.get() }); //Using node callback: client.get(function(err,res) { - + }); ``` -##### post(), put(), delete() -These methods are not yet implemented. ##### Chaining it all together ```javascript var SoftLayer = require('softlayer-node'); @@ -107,19 +104,21 @@ client ``` ## Tests -To run the tests open a command line and tpye +To run the tests open a command line and type ``` -npm test +npm run test ``` -or +## eslint +To run eslint open a command line and type ``` -gulp test +npm run eslint ``` -You will need to have gulp and mocha installed to run the tests. **Important:** The tests make real http requests (only GET) to an account, which has to be configured in a file called credentials.json in the test folder. + +You will need to have gulp and mocha installed to run the tests. **Important:** The tests make real http requests (currently only GET) to a SoftLayer account, which has to be configured in a file called credentials.json in the test folder. This file must have the following content: ``` json { - "accountId": "[account id]", + "accountId": "[accountId]", "apiUser": "[api user]", "apiKey": "[api key]" } diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index ca03b06..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Created by michael.wibmer on 04.02.2015. - */ -var gulp = require('gulp'); -var jshint = require('gulp-jshint'); -var mocha = require('gulp-mocha'); - -gulp.task('test', function () { - return gulp.src('./test/**-test.js', {read: false}) - .pipe(mocha({reporter: 'spec'})); -}); - -gulp.task('lint', function() { - return gulp.src('./lib/*.js') - .pipe(jshint()) - .pipe(jshint.reporter('default')); -}); - -// Watch Files For Changes -gulp.task('dev', ['lint'], function() { - gulp.watch(['lib/*.js', 'test/*.js'], ['test']); -}); \ No newline at end of file diff --git a/lib/http-requests.js b/lib/http-requests.js index abf5832..56b2af5 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -1,36 +1,21 @@ 'use strict'; -var https = require('https'); +var request = require('request'); // Private constants -var _baseUrl = 'api.softlayer.com'; -var _basePath = '/rest/v3/'; +var _baseUrl = 'https://api.softlayer.com/rest/v3/'; var _servicePrefix = 'SoftLayer_'; // Private methods -function _isNumberSet(value) { - return value!==undefined && value!==null; -} - -/** - * Sends a GET request to the given softlayer rest endpoint. - * @param credentials object containing apiUser and apiKey - * @param pathElements an array of path elements to construct the REST url - * @param mask object mask - * @param offset pagination offset - * @param limit pagination result limit - * @param headers custom headers for the request - * @param callback - */ -exports.get = function(credentials, pathElements, mask, filter, offset, limit, headers, callback) { - - if (!credentials) return callback(new Error('No credentials provided.'), {}); - if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); - +var _isNumberSet = function(value) { + return value !== undefined && value !== null; +}; +var _buildPath = function(pathElements, mask, filter, offset, limit) { //build path - pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; - var path = _basePath + pathElements.join('/'); - + if (pathElements[0].indexOf(_servicePrefix < 0)) { + pathElements[0] = _servicePrefix + pathElements[0]; + } + var path = _baseUrl + pathElements.join('/'); //add object mask if available if (mask && mask.length > 0) { @@ -44,10 +29,13 @@ exports.get = function(credentials, pathElements, mask, filter, offset, limit, h //add pagination if available if (_isNumberSet(offset) && _isNumberSet(limit)) { - if (limit === 0) return callback({statusCode: 500, error: 'Limit must not be zero.'}, {}); - path += (path.indexOf('?') > -1 ? '&' : '?'); + path += path.indexOf('?') > -1 ? '&' : '?'; path += 'resultLimit=' + offset + ',' + limit; } + return path; +}; + +var _buildHeaders = function(credentials, headers) { //Basic authentication var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); @@ -55,335 +43,127 @@ exports.get = function(credentials, pathElements, mask, filter, offset, limit, h 'Content-Type': 'application/json', 'Accept': 'application/json' }; - headers['Authorization'] = auth; - - var request_options = { - host: _baseUrl, - path: path, - port: 443, - method: 'GET', - rejectUnauthorized: false, - headers: headers - }; - - // Set up the request - var req = https.request(request_options, function(res) { - res.setEncoding('utf8'); - - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); - - res.on('end', function() { - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - var error; - if (data) { - if (headers['Content-Type'] === 'application/json') { - error = JSON.parse(data); - } else { - error = { - data: data - } - } + headers.Authorization = auth; + return headers; +}; +var _handleResponse = function(callback) { + return function(error, res, body) { + if (!error && res.statusCode === 200) { + if (res['Content-Type'] === 'application/json') { + return callback(null, JSON.parse(body)); + } else { + return callback(null, body); + } + } + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + if (body) { + if (res['Content-Type'] === 'application/json') { + error = JSON.parse(body); error.statusCode = res.statusCode; - } else { - error = { - statusCode: res.statusCode - }; } - callback(error, {}); } else { - if (headers['Content-Type'] === 'application/json') { - callback(null, JSON.parse(data)); - } else { - callback(null, data); - } + error = error || {}; + error.statusCode = res.statusCode; } - }); - }); - - req.on('error', function(error) { - callback(error, {}); - }); - - req.end(); + return callback(error, {}); + } + return callback(error, {}); + }; }; /** - * Sends a PUT request to the given softlayer rest endpoint. + * Sends a GET request to the given softlayer rest endpoint. * @param credentials object containing apiUser and apiKey * @param pathElements an array of path elements to construct the REST url * @param mask object mask * @param offset pagination offset * @param limit pagination result limit * @param headers custom headers for the request - * @param parameters parameters for the the request body - * @param callback + * @param callback callback funtion + * @return undefined */ -exports.put = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { +exports.get = function(credentials, pathElements, mask, filter, offset, limit, headers, callback) { if (!credentials) return callback(new Error('No credentials provided.'), {}); if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); + if (limit === 0) return callback({ statusCode: 500, error: 'Limit must not be zero.' }, { }); - - //build path - pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; - var path = _basePath + pathElements.join('/'); - - //Basic authentication - var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); - - var body = JSON.stringify({ - parameters: [ - parameters - ] - }); - - - headers = headers || { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; - - - - - headers['Content-Length'] = body.length - headers['Authorization'] = auth; - - var request_options = { - host: _baseUrl, - path: path, - port: 443, - method: 'PUT', - rejectUnauthorized: false, - headers: headers + var requestOptions = { + url: _buildPath(pathElements, mask, filter, offset, limit), + headers: _buildHeaders(credentials, headers) }; - - // Set up the request - var req = https.request(request_options, function(res) { - res.setEncoding('utf8'); - - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); - - res.on('end', function() { - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - var error; - if (data) { - error = JSON.parse(data); - error.statusCode = res.statusCode; - } else { - error = { - statusCode: res.statusCode - }; - } - callback(error, {}); - } else { - if (headers['Content-Type'] === 'application/json') { - callback(null, JSON.parse(data)); - } else { - callback(null, data); - } - } - }); - }); - - req.on('error', function(error) { - callback(error, {}); - }); - - req.write(body); - req.end(); + request.get(requestOptions, _handleResponse(callback)); }; /** - * Sends a GET request to the given softlayer rest endpoint. - * @param credentials object containing apiUser and apiKey + * Sends a PUT request to the given softlayer rest endpoint. + * @param {Object} credentials containing apiUser and apiKey * @param pathElements an array of path elements to construct the REST url - * @param mask object mask - * @param offset pagination offset - * @param limit pagination result limit * @param headers custom headers for the request * @param parameters parameters for the the request body * @param callback */ -exports.post = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { +exports.put = function(credentials, pathElements, headers, parameters, callback) { if (!credentials) return callback(new Error('No credentials provided.'), {}); if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); - - //build path - pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; - var path = _basePath + pathElements.join('/'); - - //Basic authentication - var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); - - var body = ''; - if (parameters.constructor === Array) { - body = JSON.stringify({ - parameters: parameters - }); - } else { - body = JSON.stringify({ - parameters: [ - parameters - ] - }); - } - - headers = headers || { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; - - - - - headers['Content-Length'] = body.length - headers['Authorization'] = auth; - - var request_options = { - host: _baseUrl, - path: path, - port: 443, - method: 'POST', - rejectUnauthorized: false, - headers: headers + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } }; - // Set up the request - var req = https.request(request_options, function(res) { - res.setEncoding('utf8'); + request.put(requestOptions, _handleResponse(callback)); +}; - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); +/** + * Sends a POST request to the given softlayer rest endpoint. + * @param {Object} credentials containing apiUser and apiKey + * @param pathElements an array of path elements to construct the REST url + * @param headers custom headers for the request + * @param parameters parameters for the the request body + * @param callback + */ +exports.post = function(credentials, pathElements, headers, parameters, callback) { - res.on('end', function() { - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - var error; - if (data) { - error = JSON.parse(data); - error.statusCode = res.statusCode; - } else { - error = { - statusCode: res.statusCode - }; - } - callback(error, {}); - } else { - if (headers['Content-Type'] === 'application/json') { - callback(null, JSON.parse(data)); - } else { - callback(null, data); - } - } - }); - }); + if (!credentials) return callback(new Error('No credentials provided.'), {}); + if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); - req.on('error', function(error) { - callback(error, {}); - }); + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } + }; - req.write(body); - req.end(); + request.post(requestOptions, _handleResponse(callback)); }; /** - * Sends a GET request to the given softlayer rest endpoint. + * Sends a DELETE request to the given softlayer rest endpoint. * @param credentials object containing apiUser and apiKey * @param pathElements an array of path elements to construct the REST url - * @param mask object mask - * @param offset pagination offset - * @param limit pagination result limit * @param headers custom headers for the request * @param parameters parameters for the the request body * @param callback */ -exports.delete = function(credentials, pathElements, mask, offset, limit, headers, parameters, callback) { +exports.delete = function(credentials, pathElements, headers, parameters, callback) { if (!credentials) return callback(new Error('No credentials provided.'), {}); if (!pathElements || pathElements.length < 1) return callback(new Error('No path provided.'), {}); - - //build path - pathElements[0] = pathElements[0].indexOf(_servicePrefix < 0) ? (_servicePrefix + pathElements[0]) : pathElements[0]; - var path = _basePath + pathElements.join('/'); - - //Basic authentication - var auth = 'Basic ' + new Buffer(credentials.apiUser + ':' + credentials.apiKey).toString('base64'); - - var body = JSON.stringify({ - parameters: [ - parameters - ] - }); - - - headers = headers || { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }; - - - - - headers['Content-Length'] = body.length - headers['Authorization'] = auth; - - var request_options = { - host: _baseUrl, - path: path, - port: 443, - method: 'DELETE', - rejectUnauthorized: false, - headers: headers + var requestOptions = { + url: _buildPath(pathElements), + headers: _buildHeaders(credentials, headers), + json: { + parameters: parameters.constructor === Array ? parameters : [parameters] + } }; - - // Set up the request - var req = https.request(request_options, function(res) { - res.setEncoding('utf8'); - - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); - - res.on('end', function() { - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - var error; - if (data) { - error = JSON.parse(data); - error.statusCode = res.statusCode; - } else { - error = { - statusCode: res.statusCode - }; - } - callback(error, {}); - } else { - if (headers['Content-Type'] === 'application/json') { - callback(null, JSON.parse(data)); - } else { - callback(null, data); - } - } - }); - }); - - req.on('error', function(error) { - callback(error, {}); - }); - - req.write(body); - req.end(); + request.delete(requestOptions, _handleResponse(callback)); }; diff --git a/lib/services.js b/lib/services.js index 8880cd6..883f5c8 100644 --- a/lib/services.js +++ b/lib/services.js @@ -849,4 +849,4 @@ module.exports = function(SoftLayer) { SoftLayer.prototype.virtualStorageRepository = function () { return this.path('Virtual_Storage_Repository'); }; -}; \ No newline at end of file +}; diff --git a/lib/softlayer.js b/lib/softlayer.js index d193837..957b96f 100644 --- a/lib/softlayer.js +++ b/lib/softlayer.js @@ -31,7 +31,7 @@ var SoftLayer = function SoftLayer(apiUser, apiKey) { module.exports = SoftLayer; //private methods -function _getDefaults() { +var _getDefaults = function() { return { pathElements: [], mask: [], @@ -42,7 +42,7 @@ function _getDefaults() { 'Content-Type': 'application/json' } }; -} +}; /** * Appends the arguments of this function to the path of the prepared service request. @@ -100,11 +100,11 @@ SoftLayer.prototype.mask = function (mask) { */ SoftLayer.prototype.filter = function (filter) { if (!this.service) this.service = _getDefaults(); - if(filter) { + if (filter) { this.service.filter = filter; } return this; -} +}; /** * Adds the given parameters to the prepared service request. @@ -116,7 +116,7 @@ SoftLayer.prototype.parameters = function(parameters) { if (!this.service) this.service = _getDefaults(); this.service.parameters = parameters; return this; -} +}; /** @@ -163,7 +163,7 @@ SoftLayer.prototype.auth = function (apiUser, apiKey) { SoftLayer.prototype.get = function (callback) { var _this = this; return new Promise(function (resolve, reject) { - HttpRequests.get(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.filter, _this.service.offset, _this.service.limit,_this.service.headers, function (error, result) { + HttpRequests.get(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.filter, _this.service.offset, _this.service.limit, _this.service.headers, function (error, result) { _this.reset(); if (error) { return reject(error); @@ -181,7 +181,7 @@ SoftLayer.prototype.get = function (callback) { SoftLayer.prototype.put = function (callback) { var _this = this; return new Promise(function (resolve, reject) { - HttpRequests.put(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + HttpRequests.put(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { _this.reset(); if (error) { return reject(error); @@ -199,7 +199,7 @@ SoftLayer.prototype.put = function (callback) { SoftLayer.prototype.post = function (callback) { var _this = this; return new Promise(function (resolve, reject) { - HttpRequests.post(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + HttpRequests.post(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { _this.reset(); if (error) { return reject(error); @@ -217,7 +217,7 @@ SoftLayer.prototype.post = function (callback) { SoftLayer.prototype.delete = function (callback) { var _this = this; return new Promise(function (resolve, reject) { - HttpRequests.delete(_this.credentials, _this.service.pathElements, _this.service.mask, _this.service.offset, _this.service.limit,_this.service.headers,_this.service.parameters, function (error, result) { + HttpRequests.delete(_this.credentials, _this.service.pathElements, _this.service.headers, _this.service.parameters, function (error, result) { _this.reset(); if (error) { return reject(error); diff --git a/package.json b/package.json index bc862f8..7e78208 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Softlayer API Wrapper for node", "main": "./lib/softlayer.js", "scripts": { - "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec || exit 0" + "test": "./node_modules/.bin/mocha ./test/**/*-test.js --reporter spec || exit 0", + "eslint": "./node_modules/.bin/eslint . || exit 0" }, "repository": { "type": "git", @@ -21,10 +22,15 @@ }, "homepage": "https://github.com/pmpkin/softlayer-node", "dependencies": { - "bluebird": "^2.9.13" + "bluebird": "^2.9.13", + "request": "^2.75.0" }, "devDependencies": { "chai": "^3.5.0", + "eslint": "^3.5.0", + "eslint-config-formidable": "^1.0.1", + "eslint-plugin-filenames": "^1.1.0", + "eslint-plugin-import": "^1.16.0", "mocha": "^3.0.2" } } diff --git a/test/http-request-test.js b/test/http-request-test.js index 9667042..4295fae 100644 --- a/test/http-request-test.js +++ b/test/http-request-test.js @@ -13,8 +13,6 @@ try { //no credentials } - - describe('HttpRequests', function () { //set higher default timeout due to networking From fa8281b0cde06456d9e2c414448641715fdd3aa9 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Mon, 26 Sep 2016 10:32:23 +0200 Subject: [PATCH 5/8] updated tests, added travis.yml --- .travis.yml | 28 ++++++++++++++++++++++++++ lib/http-requests.js | 41 ++++++++++++++++++++++++--------------- test/http-request-test.js | 17 ++++++---------- test/softlayer-test.js | 11 +---------- test/test-utils.js | 20 +++++++++++++++++++ wercker.yml | 5 ----- 6 files changed, 80 insertions(+), 42 deletions(-) create mode 100644 .travis.yml create mode 100644 test/test-utils.js delete mode 100644 wercker.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d7251b9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +language: node_js + +node_js: + - "6" + +notifications: + slack: pmpkin:QReL3WOed24nwQcVtqvlQyYW + +before_install: +- | + if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/' + then + echo "Only docs were updated, stopping build process." + exit + fi + npm install npm@3.x -g + phantomjs --version +script: +- | + if [ "$TEST_TYPE" = test ]; then + npm test + else + npm run $TEST_TYPE + fi +env: + matrix: + - TEST_TYPE=eslint + - TEST_TYPE=test diff --git a/lib/http-requests.js b/lib/http-requests.js index 56b2af5..e582639 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -19,12 +19,14 @@ var _buildPath = function(pathElements, mask, filter, offset, limit) { //add object mask if available if (mask && mask.length > 0) { - path += '?objectMask=' + mask.join(';'); + path += (path.indexOf('?') > -1 ? '&' : '?'); + path += 'objectMask=' + mask.join(';'); } //add object filter if available if (filter) { - path += '&objectFilter=' + JSON.stringify(filter); + path += (path.indexOf('?') > -1 ? '&' : '?'); + path += 'objectFilter=' + JSON.stringify(filter); } //add pagination if available @@ -48,27 +50,34 @@ var _buildHeaders = function(credentials, headers) { }; var _handleResponse = function(callback) { - return function(error, res, body) { - if (!error && res.statusCode === 200) { - if (res['Content-Type'] === 'application/json') { + return function(err, res, body) { + if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { + + if (body && res.headers['content-type'] === 'application/json') { + var error = JSON.parse(body); + error.statusCode = res.statusCode; + return callback(error, {}); + } + if (err) { + err.statusCode = res.statusCode; + } else { + err = { + statusCode: res.statusCode + } + } + return callback(err, {}); + } else { + if (res.headers['content-type'] === 'application/json') { return callback(null, JSON.parse(body)); } else { return callback(null, body); } } - if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) { - if (body) { - if (res['Content-Type'] === 'application/json') { - error = JSON.parse(body); - error.statusCode = res.statusCode; - } - } else { - error = error || {}; - error.statusCode = res.statusCode; - } + + if (error) { return callback(error, {}); } - return callback(error, {}); + return callback({ statusCode: 500, message: 'Internal server error (API)'}, {}); }; }; diff --git a/test/http-request-test.js b/test/http-request-test.js index 4295fae..666f5e8 100644 --- a/test/http-request-test.js +++ b/test/http-request-test.js @@ -1,17 +1,9 @@ /** * Created by michael.wibmer on 11.03.2015. */ -var fs = require('fs'); -var path = require('path'); var expect = require('chai').expect; var HttpRequests = require('../lib/http-requests'); -var credentials = { }; - -try { - credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); -} catch (e) { - //no credentials -} +var credentials = require('./test-utils').loadCredentials(); describe('HttpRequests', function () { @@ -24,6 +16,7 @@ describe('HttpRequests', function () { }); describe('get()', function() { + it('should fail because of missing credentials', function(done) { HttpRequests.get(undefined, null, null, null, null, null, null, function(err) { @@ -38,6 +31,7 @@ describe('HttpRequests', function () { done(); }); }); + it('should fail with status 401 because of incorrect user credentials', function(done) { var path=['Account']; @@ -49,6 +43,8 @@ describe('HttpRequests', function () { }); }); + + it('should fail with status 404 because of invalid path', function(done) { var path=['ThisIsInvalid']; HttpRequests.get(credentials, path, null, null, null, null, null, function(err) { @@ -68,6 +64,7 @@ describe('HttpRequests', function () { done(); }); }); + it('should fail with status 500 because of using pagination with invalid limit', function(done) { var path=['Account', 'Invoices']; @@ -83,7 +80,6 @@ describe('HttpRequests', function () { var path=['Account']; HttpRequests.get(credentials, path, null, null, null, null, null, function(err, res) { - expect(err).to.equal(null); expect(res).to.be.ok; expect(res.id).to.equal(credentials.accountId); @@ -132,7 +128,6 @@ describe('HttpRequests', function () { done(); }); }); - }); }); diff --git a/test/softlayer-test.js b/test/softlayer-test.js index d72da5c..4300bcd 100644 --- a/test/softlayer-test.js +++ b/test/softlayer-test.js @@ -1,19 +1,10 @@ /** * Created by michael.wibmer on 11.03.2015. */ -var fs = require('fs'); var Promise = require('bluebird'); -var path = require('path'); var expect = require('chai').expect; var SoftLayer = require('../lib/softlayer'); -var credentials = { }; - -try { - credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); -} catch (e) { - //no credentials -} - +var credentials = require('./test-utils').loadCredentials(); describe('SoftLayer API', function () { //set higher default timeout due to networking diff --git a/test/test-utils.js b/test/test-utils.js new file mode 100644 index 0000000..a49a59e --- /dev/null +++ b/test/test-utils.js @@ -0,0 +1,20 @@ +var fs = require('fs'); +var path = require('path'); + +exports.loadCredentials = function() { + var credentials = null; + try { + credentials = JSON.parse(fs.readFileSync(path.normalize(__dirname + '/credentials.json', 'utf8'))); + } catch (e) { + //no credentials + } + + if (!credentials && process.env.SOFTLAYER_API_ACCOUNT && process.env.SOFTLAYER_API_USER && process.env.SOFTLAYER_API_KEY) { + credentials = { + accountId: process.env.SOFTLAYER_API_ACCOUNT, + apiUser: process.env.SOFTLAYER_API_USER, + apiKey: process.env.SOFTLAYER_API_USER + } + } + return credentials || {}; +} diff --git a/wercker.yml b/wercker.yml deleted file mode 100644 index 8245549..0000000 --- a/wercker.yml +++ /dev/null @@ -1,5 +0,0 @@ -box: wercker/nodejs@1.4.0 -build: - steps: - - npm-install - - npm-test \ No newline at end of file From 6433efad161fdf0bb5076d1979a2a8116c7164f7 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Mon, 26 Sep 2016 10:43:57 +0200 Subject: [PATCH 6/8] updated travis build, added badges to readme --- .travis.yml | 9 --------- README.md | 2 ++ package.json | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7251b9..35af9c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,15 +6,6 @@ node_js: notifications: slack: pmpkin:QReL3WOed24nwQcVtqvlQyYW -before_install: -- | - if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/' - then - echo "Only docs were updated, stopping build process." - exit - fi - npm install npm@3.x -g - phantomjs --version script: - | if [ "$TEST_TYPE" = test ]; then diff --git a/README.md b/README.md index 56e774d..130f562 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # softlayer-node [Softlayer API](http://sldn.softlayer.com/reference/softlayerapi) wrapper for node. The module provides a simple fluent interface to construct API calls. +[![Build Status](https://travis-ci.org/pmpkin/softlayer-node.svg)](https://travis-ci.org/pmpkin/softlayer-node) +[![npm version](https://badge.fury.io/js/softlayer-node.svg)](https://badge.fury.io/js/softlayer-node) ## Installation The most simple way is to install the npm package: diff --git a/package.json b/package.json index 7e78208..58cbfcd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "softlayer-node", - "version": "0.1.0", + "version": "0.2.0", "description": "Softlayer API Wrapper for node", "main": "./lib/softlayer.js", "scripts": { From 2fef91d5e2d4a75c501e73bc1862dca03d5de5b4 Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Mon, 26 Sep 2016 10:53:30 +0200 Subject: [PATCH 7/8] fixed eslint errors --- lib/http-requests.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/http-requests.js b/lib/http-requests.js index e582639..ef2f6f0 100644 --- a/lib/http-requests.js +++ b/lib/http-requests.js @@ -19,13 +19,13 @@ var _buildPath = function(pathElements, mask, filter, offset, limit) { //add object mask if available if (mask && mask.length > 0) { - path += (path.indexOf('?') > -1 ? '&' : '?'); + path += path.indexOf('?') > -1 ? '&' : '?'; path += 'objectMask=' + mask.join(';'); } //add object filter if available if (filter) { - path += (path.indexOf('?') > -1 ? '&' : '?'); + path += path.indexOf('?') > -1 ? '&' : '?'; path += 'objectFilter=' + JSON.stringify(filter); } @@ -63,21 +63,18 @@ var _handleResponse = function(callback) { } else { err = { statusCode: res.statusCode - } + }; } return callback(err, {}); - } else { - if (res.headers['content-type'] === 'application/json') { - return callback(null, JSON.parse(body)); - } else { - return callback(null, body); - } + } else if (err) { + return callback(err, {}); } - if (error) { - return callback(error, {}); + if (res.headers['content-type'] === 'application/json') { + return callback(null, JSON.parse(body)); } - return callback({ statusCode: 500, message: 'Internal server error (API)'}, {}); + + return callback(null, body); }; }; From c91644e12642714c1a8db105a5f4b615b400876d Mon Sep 17 00:00:00 2001 From: Michael Wibmer Date: Mon, 26 Sep 2016 10:55:55 +0200 Subject: [PATCH 8/8] updated badges in readme [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 130f562..53fc371 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # softlayer-node [Softlayer API](http://sldn.softlayer.com/reference/softlayerapi) wrapper for node. The module provides a simple fluent interface to construct API calls. + [![Build Status](https://travis-ci.org/pmpkin/softlayer-node.svg)](https://travis-ci.org/pmpkin/softlayer-node) [![npm version](https://badge.fury.io/js/softlayer-node.svg)](https://badge.fury.io/js/softlayer-node)