node-mojo
Version:
Qwasi Mojo nodejs client
421 lines (352 loc) • 17 kB
JavaScript
// Copyright (c) 2015-2016, Qwasi Inc (http://www.qwasi.com/)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Qwasi nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL QWASI BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.SOFTWARE
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _util = require('util');
var _util2 = _interopRequireDefault(_util);
var _events = require('events');
var _events2 = _interopRequireDefault(_events);
var _request = require('request');
var _request2 = _interopRequireDefault(_request);
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _jwtDecode = require('jwt-decode');
var _jwtDecode2 = _interopRequireDefault(_jwtDecode);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _log = require('./log');
var _log2 = _interopRequireDefault(_log);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// Client provides a base crud client for the node-mojo library
var Client = function (_EventEmitter) {
_inherits(Client, _EventEmitter);
function Client(options) {
_classCallCheck(this, Client);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Client).call(this));
options = options || {};
_this.url = options.url;
_this.version = options.version || 'v1';
_this.client_id = options.client_id;
_this.client_secret = options.client_secret;
_this.token = options.token;
return _this;
}
// login returns a user token, using the client_id and client_secret
// if the api client does not have permission to authenticate users the
// call will fail.
_createClass(Client, [{
key: 'login',
value: function login(creds, options, callback) {
var _this2 = this;
var login_url = _util2.default.format('%s/%s', this.url, 'session');
if (_lodash2.default.isFunction(creds)) {
callback = creds;
creds = undefined;
}
if (_lodash2.default.isFunction(options)) {
callback = options;
options = undefined;
}
creds = creds || {};
options = options || {};
_lodash2.default.defaults(creds, {
client_id: this.client_id,
client_secret: this.client_secret
});
if (creds.username && creds.password) {
options.grant_type = options.grant_type || 'password';
}
_lodash2.default.defaults(options, {
grant_type: 'client_credentials'
});
return new _bluebird2.default(function (resolve, reject) {
_request2.default.post({
url: login_url,
auth: {
username: creds.client_id,
password: creds.client_secret
},
form: {
grant_type: options.grant_type,
username: creds.username || undefined,
password: creds.password || undefined
},
json: true
}, function (err, response, body) {
if (err) {
(0, _log2.default)('Client %s authenticatication failed: %s.', creds.username || creds.client_id, err);
return reject(err);
}
if (response.statusCode >= 400) {
var error = body.error_description || body.error;
(0, _log2.default)('Client %s authenticatication failed: %s.', creds.username || creds.client_id, error);
return reject(new Error(error));
}
_this2.token = body.access_token;
(0, _log2.default)('Client %s authenticated successfully.', creds.username || creds.client_id);
resolve(body);
});
}).nodeify(callback);
}
// logout deletes the token and invalidates the session associated with
// that token.
}, {
key: 'logout',
value: function logout(token, callback) {
var logout_url = _util2.default.format('%s/%s/%s', this.url, 'session', token);
return new _bluebird2.default(function (resolve, reject) {
var owner = null;
try {
var session = (0, _jwtDecode2.default)(token);
owner = session.owner.name;
} catch (e) {
(0, _log2.default)('Failed to decode session token: %s.', e);
return reject(e);
}
_request2.default.del({
url: logout_url,
json: true
}, function (err, response, body) {
if (err) {
(0, _log2.default)('Client %s session delete failed: %s.', owner, err);
return reject(err);
}
if (response.statusCode >= 400) {
var error = body.error_description || body.error;
(0, _log2.default)('Client %s session delete failed: %s.', owner, error);
return reject(new Error(error));
}
(0, _log2.default)('Client %s session deleted.', owner);
resolve(body);
});
}).nodeify(callback);
}
// create creates a new document for the given model
}, {
key: 'create',
value: function create(model, doc, callback) {
var _this3 = this;
var create_url = _util2.default.format('%s/%s/%s', this.url, this.version, model);
return new _bluebird2.default(function (resolve, reject) {
_request2.default.post({
url: create_url,
auth: {
bearer: _this3.token
},
json: true,
body: doc
}, function (err, response, body) {
if (err) {
(0, _log2.default)('create %s failed: %s.', model, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err = body.error_description || body.error;
(0, _log2.default)('create %s failed: %s.', model, _err);
return reject(_err);
}
(0, _log2.default)('create %s successful, id=%s.', model, body.id);
resolve(body);
});
}).nodeify(callback);
}
}, {
key: 'read',
value: function read(model, id, options, callback) {
var _this4 = this;
var read_url = _util2.default.format('%s/%s/%s/%s', this.url, this.version, model, id);
if (_lodash2.default.isFunction(options)) {
callback = options;
options = undefined;
}
return new _bluebird2.default(function (resolve, reject) {
_request2.default.get({
url: read_url,
auth: {
bearer: _this4.token
},
json: true,
qs: options
}, function (err, response, body) {
if (err) {
(0, _log2.default)('read %s:%s failed: %s.', model, id, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err2 = body.error_description || body.error;
(0, _log2.default)('read %s:%s failed: %s.', model, id, _err2);
return reject(_err2);
}
(0, _log2.default)('read %s:%s successful.', model, id);
resolve(body);
});
}).nodeify(callback);
}
}, {
key: 'update',
value: function update(model, id, doc, callback) {
var _this5 = this;
var update_url = _util2.default.format('%s/%s/%s/%s', this.url, this.version, model, id);
return new _bluebird2.default(function (resolve, reject) {
_request2.default.put({
url: update_url,
auth: {
bearer: _this5.token
},
json: true,
body: doc
}, function (err, response, body) {
if (err) {
(0, _log2.default)('update %s:%s failed: %s.', model, id, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err3 = body.error_description || body.error;
(0, _log2.default)('update %s:%s failed: %s.', model, id, _err3);
return reject(_err3);
}
(0, _log2.default)('update %s:%s successful.', model, id);
resolve(body);
});
}).nodeify(callback);
}
}, {
key: 'del',
value: function del(model, id, callback) {
var _this6 = this;
var del_url = _util2.default.format('%s/%s/%s/%s', this.url, this.version, model, id);
return new _bluebird2.default(function (resolve, reject) {
_request2.default.put({
url: del_url,
auth: {
bearer: _this6.token
},
json: true
}, function (err, response, body) {
if (err) {
(0, _log2.default)('delete %s:%s failed: %s.', model, id, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err4 = body.error_description || body.error;
(0, _log2.default)('delete %s:%s failed: %s.', model, id, _err4);
return reject(_err4);
}
(0, _log2.default)('delete %s:%s successful.', model, id);
resolve(body);
});
}).nodeify(callback);
}
}, {
key: 'search',
value: function search(model, options, callback) {
var _this7 = this;
var search_url = _util2.default.format('%s/%s/%s', this.url, this.version, model);
if (_lodash2.default.isFunction(options)) {
callback = options;
options = undefined;
}
options = options || {};
return new _bluebird2.default(function (resolve, reject) {
_request2.default.get({
url: search_url,
auth: {
bearer: _this7.token
},
json: true,
qs: options
}, function (err, response, body) {
if (err) {
(0, _log2.default)('search %s:%s failed: %s.', model, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err5 = body.error_description || body.error;
(0, _log2.default)('search %s failed: %s.', model, _err5);
return reject(_err5);
}
(0, _log2.default)('search %s successful.', model);
resolve(body);
});
}).nodeify(callback);
}
}, {
key: 'count',
value: function count(model, options, callback) {
var _this8 = this;
var count_url = _util2.default.format('%s/%s/%s/count', this.url, this.version, model);
if (_lodash2.default.isFunction(options)) {
callback = options;
options = undefined;
}
options = options || {};
return new _bluebird2.default(function (resolve, reject) {
_request2.default.get({
url: count_url,
auth: {
bearer: _this8.token
},
json: true,
qs: options
}, function (err, response, body) {
if (err) {
(0, _log2.default)('count %s:%s failed: %s.', model, err);
return reject(err);
}
if (response.statusCode >= 400) {
var _err6 = body.error_description || body.error;
(0, _log2.default)('count %s failed: %s.', model, _err6);
return reject(_err6);
}
(0, _log2.default)('count %s successful.', model);
resolve(body);
});
}).nodeify(callback);
}
// bearer returns a new copy of the client using the specified bearer token
}, {
key: 'bearer',
value: function bearer(token) {
var client = new Client(this);
client.token = token || client.token;
return client;
}
// member returns the member api service
}, {
key: 'members',
get: function get() {
var Members = require('./members');
return new Members.default(this);
}
}]);
return Client;
}(_events2.default);
exports.default = Client;