Use standard code style.
This commit is contained in:
parent
c539dd5570
commit
6fa2e79c1c
@ -1,93 +0,0 @@
|
||||
{
|
||||
// Julien Fontanet JSHint configuration
|
||||
// https://gist.github.com/julien-f/8095615
|
||||
//
|
||||
// Changes from defaults:
|
||||
// - all enforcing options (except `++` & `--`) enabled
|
||||
// - single quotes
|
||||
// - indentation set to 2 instead of 4
|
||||
// - almost all relaxing options disabled
|
||||
// - environments are set to Node.js
|
||||
//
|
||||
// See http://jshint.com/docs/ for more details
|
||||
|
||||
"maxerr" : 50, // {int} Maximum error before stopping
|
||||
|
||||
// Enforcing
|
||||
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
|
||||
"camelcase" : true, // true: Identifiers must be in camelCase
|
||||
"curly" : true, // true: Require {} for every new block or scope
|
||||
"eqeqeq" : true, // true: Require triple equals (===) for comparison
|
||||
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
|
||||
"freeze" : true, // true: Prohibit overwriting prototypes of native objects (Array, Date, ...)
|
||||
"immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||
"indent" : 2, // {int} Number of spaces to use for indentation
|
||||
"latedef" : true, // true: Require variables/functions to be defined before being used
|
||||
"newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||
"noempty" : true, // true: Prohibit use of empty blocks
|
||||
"nonbsp" : true, // true: Prohibit use of non breakable spaces
|
||||
"nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment)
|
||||
"plusplus" : false, // true: Prohibit use of `++` & `--`
|
||||
"quotmark" : "single", // Quotation mark consistency:
|
||||
// false : do nothing (default)
|
||||
// true : ensure whatever is used is consistent
|
||||
// "single" : require single quotes
|
||||
// "double" : require double quotes
|
||||
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||
"unused" : true, // true: Require all defined variables be used
|
||||
"strict" : false, // true: Requires all functions run in ES5 Strict Mode
|
||||
"maxcomplexity" : 7, // {int} Max cyclomatic complexity per function
|
||||
"maxdepth" : 3, // {int} Max depth of nested blocks (within functions)
|
||||
"maxlen" : 80, // {int} Max number of characters per line
|
||||
"maxparams" : 4, // {int} Max number of formal params allowed per function
|
||||
"maxstatements" : 20, // {int} Max number statements per function
|
||||
|
||||
// Relaxing
|
||||
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
|
||||
"boss" : false, // true: Tolerate assignments where comparisons would be expected
|
||||
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
|
||||
"eqnull" : false, // true: Tolerate use of `== null`
|
||||
"esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`)
|
||||
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
|
||||
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
|
||||
"funcscope" : false, // true: Tolerate defining variables inside control statements
|
||||
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
|
||||
"iterator" : false, // true: Tolerate using the `__iterator__` property
|
||||
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
|
||||
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
|
||||
"laxcomma" : false, // true: Tolerate comma-first style coding
|
||||
"loopfunc" : false, // true: Tolerate functions being defined in loops
|
||||
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
|
||||
// (ex: `for each`, multiple try/catch, function expression…)
|
||||
"multistr" : false, // true: Tolerate multi-line strings
|
||||
"notypeof" : false, // true: Tolerate typeof comparison with unknown values.
|
||||
"proto" : false, // true: Tolerate using the `__proto__` property
|
||||
"scripturl" : false, // true: Tolerate script-targeted URLs
|
||||
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
|
||||
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
|
||||
"validthis" : false, // true: Tolerate using this in a non-constructor function
|
||||
"noyield" : false, // true: Tolerate generators without yields
|
||||
|
||||
// Environments
|
||||
"browser" : false, // Web Browser (window, document, etc)
|
||||
"browserify" : false, // Browserify (node.js code in the browser)
|
||||
"couch" : false, // CouchDB
|
||||
"devel" : false, // Development/debugging (alert, confirm, etc)
|
||||
"dojo" : false, // Dojo Toolkit
|
||||
"jquery" : false, // jQuery
|
||||
"mocha" : false, // mocha
|
||||
"mootools" : false, // MooTools
|
||||
"node" : true, // Node.js
|
||||
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
|
||||
"phantom" : false, // PhantomJS
|
||||
"prototypejs" : false, // Prototype and Scriptaculous
|
||||
"rhino" : false, // Rhino
|
||||
"worker" : false, // Web Workers
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
|
||||
// Custom Globals
|
||||
"globals" : {} // additional predefined global variables
|
||||
}
|
@ -1,132 +1,132 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var Bluebird = require('bluebird');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var inherits = require('util').inherits;
|
||||
var jsonRpc = require('json-rpc');
|
||||
var MethodNotFound = require('json-rpc/errors').MethodNotFound;
|
||||
var startsWith = require('lodash.startswith');
|
||||
var WebSocket = require('ws');
|
||||
var Bluebird = require('bluebird')
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
var inherits = require('util').inherits
|
||||
var jsonRpc = require('json-rpc')
|
||||
var MethodNotFound = require('json-rpc/errors').MethodNotFound
|
||||
var startsWith = require('lodash.startswith')
|
||||
var WebSocket = require('ws')
|
||||
|
||||
var ConnectionError = require('./connection-error');
|
||||
var fixUrl = require('./fix-url');
|
||||
var ConnectionError = require('./connection-error')
|
||||
var fixUrl = require('./fix-url')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function getCurrentUrl() {
|
||||
function getCurrentUrl () {
|
||||
/* global window: false */
|
||||
|
||||
if (typeof window === undefined) {
|
||||
throw new Error('cannot get current URL');
|
||||
throw new Error('cannot get current URL')
|
||||
}
|
||||
|
||||
return String(window.location);
|
||||
return String(window.location)
|
||||
}
|
||||
|
||||
function makeDeferred() {
|
||||
var resolve, reject;
|
||||
function makeDeferred () {
|
||||
var resolve, reject
|
||||
var promise = new Bluebird(function (resolve_, reject_) {
|
||||
resolve = resolve_;
|
||||
reject = reject_;
|
||||
});
|
||||
resolve = resolve_
|
||||
reject = reject_
|
||||
})
|
||||
|
||||
return {
|
||||
promise: promise,
|
||||
reject: reject,
|
||||
resolve: resolve,
|
||||
};
|
||||
resolve: resolve
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Low level interface to XO.
|
||||
function Api(url) {
|
||||
function Api (url) {
|
||||
// Super constructor.
|
||||
EventEmitter.call(this);
|
||||
EventEmitter.call(this)
|
||||
|
||||
// Fix the URL (ensure correct protocol and /api/ path).
|
||||
this._url = fixUrl(url || getCurrentUrl());
|
||||
this._url = fixUrl(url || getCurrentUrl())
|
||||
|
||||
// Will contains the WebSocket.
|
||||
this._socket = null;
|
||||
this._socket = null
|
||||
|
||||
// The JSON-RPC server.
|
||||
var this_ = this;
|
||||
var this_ = this
|
||||
this._jsonRpc = jsonRpc.createServer(function (message) {
|
||||
if (message.type === 'notification') {
|
||||
this_.emit('notification', message);
|
||||
this_.emit('notification', message)
|
||||
} else {
|
||||
// This object does not support requests.
|
||||
throw new MethodNotFound(message.method);
|
||||
throw new MethodNotFound(message.method)
|
||||
}
|
||||
}).on('data', function (message) {
|
||||
this_._socket.send(JSON.stringify(message));
|
||||
});
|
||||
this_._socket.send(JSON.stringify(message))
|
||||
})
|
||||
}
|
||||
inherits(Api, EventEmitter);
|
||||
inherits(Api, EventEmitter)
|
||||
|
||||
Api.prototype.close = function () {
|
||||
if (this._socket) {
|
||||
this._socket.close();
|
||||
this._socket.close()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Api.prototype.connect = Bluebird.method(function () {
|
||||
if (this._socket) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var deferred = makeDeferred();
|
||||
var deferred = makeDeferred()
|
||||
|
||||
var opts = {};
|
||||
var opts = {}
|
||||
if (startsWith(this._url, 'wss')) {
|
||||
// Due to imperfect TLS implementation in XO-Server.
|
||||
opts.rejectUnauthorized = false;
|
||||
opts.rejectUnauthorized = false
|
||||
}
|
||||
var socket = this._socket = new WebSocket(this._url, '', opts);
|
||||
var socket = this._socket = new WebSocket(this._url, '', opts)
|
||||
|
||||
// Used to avoid binding listeners to this object.
|
||||
var this_ = this;
|
||||
var this_ = this
|
||||
|
||||
// When the socket opens, send any queued requests.
|
||||
socket.addEventListener('open', function () {
|
||||
// Resolves the promise.
|
||||
deferred.resolve();
|
||||
deferred.resolve()
|
||||
|
||||
this_.emit('connected');
|
||||
});
|
||||
this_.emit('connected')
|
||||
})
|
||||
|
||||
socket.addEventListener('message', function (message) {
|
||||
this_._jsonRpc.write(message.data);
|
||||
});
|
||||
this_._jsonRpc.write(message.data)
|
||||
})
|
||||
|
||||
socket.addEventListener('close', function () {
|
||||
this_._socket = null;
|
||||
this_._socket = null
|
||||
|
||||
this_._jsonRpc.failPendingRequests(new ConnectionError());
|
||||
this_._jsonRpc.failPendingRequests(new ConnectionError())
|
||||
|
||||
// Only emit this event if connected before.
|
||||
if (deferred.promise.isFulfilled()) {
|
||||
this_.emit('disconnected');
|
||||
this_.emit('disconnected')
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
socket.addEventListener('error', function (error) {
|
||||
// Fails the connect promise if possible.
|
||||
deferred.reject(error);
|
||||
});
|
||||
deferred.reject(error)
|
||||
})
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
return deferred.promise
|
||||
})
|
||||
|
||||
Api.prototype.call = function (method, params) {
|
||||
var jsonRpc = this._jsonRpc;
|
||||
var jsonRpc = this._jsonRpc
|
||||
|
||||
return this.connect().then(function () {
|
||||
return jsonRpc.request(method, params);
|
||||
});
|
||||
};
|
||||
return jsonRpc.request(method, params)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = Api;
|
||||
module.exports = Api
|
||||
|
@ -1,76 +1,76 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var Bluebird = require('bluebird');
|
||||
var Bluebird = require('bluebird')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function returnThis() {
|
||||
function returnThis () {
|
||||
/* jshint validthis: true */
|
||||
|
||||
return this;
|
||||
return this
|
||||
}
|
||||
|
||||
// Returns an iterator to the Fibonacci sequence.
|
||||
function fibonacci(start) {
|
||||
var prev = 0;
|
||||
var curr = start || 1;
|
||||
function fibonacci (start) {
|
||||
var prev = 0
|
||||
var curr = start || 1
|
||||
|
||||
var iterator = {
|
||||
next: function () {
|
||||
var tmp = curr;
|
||||
curr += prev;
|
||||
prev = tmp;
|
||||
var tmp = curr
|
||||
curr += prev
|
||||
prev = tmp
|
||||
|
||||
return {
|
||||
done: false,
|
||||
value: prev,
|
||||
};
|
||||
},
|
||||
};
|
||||
value: prev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make the iterator a true iterable (ES6).
|
||||
if (typeof Symbol !== 'undefined') {
|
||||
iterator[Symbol.iterator] = returnThis;
|
||||
iterator[Symbol.iterator] = returnThis
|
||||
}
|
||||
|
||||
return iterator;
|
||||
return iterator
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function defaultGenerator() {
|
||||
return fibonacci(1e3);
|
||||
function defaultGenerator () {
|
||||
return fibonacci(1e3)
|
||||
}
|
||||
|
||||
function BackOff(opts) {
|
||||
function BackOff (opts) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
opts = {}
|
||||
}
|
||||
|
||||
this._attempts = 0;
|
||||
this._generator = opts.generator || defaultGenerator;
|
||||
this._iterator = this._generator();
|
||||
this._maxAttempts = opts.maxAttempts || Infinity;
|
||||
this._attempts = 0
|
||||
this._generator = opts.generator || defaultGenerator
|
||||
this._iterator = this._generator()
|
||||
this._maxAttempts = opts.maxAttempts || Infinity
|
||||
}
|
||||
|
||||
BackOff.prototype.wait = function () {
|
||||
var maxAttempts = this._maxAttempts;
|
||||
var maxAttempts = this._maxAttempts
|
||||
if (this._attempts++ > maxAttempts) {
|
||||
return Bluebird.reject(new Error(
|
||||
'maximum attempts reached (' + maxAttempts +')'
|
||||
));
|
||||
'maximum attempts reached (' + maxAttempts + ')'
|
||||
))
|
||||
}
|
||||
|
||||
return Bluebird.delay(this._iterator.next().value);
|
||||
};
|
||||
return Bluebird.delay(this._iterator.next().value)
|
||||
}
|
||||
|
||||
BackOff.prototype.reset = function () {
|
||||
this._attempts = 0;
|
||||
this._iterator = this._generator();
|
||||
};
|
||||
this._attempts = 0
|
||||
this._iterator = this._generator()
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
module.exports = BackOff;
|
||||
module.exports = BackOff
|
||||
|
@ -1,160 +1,160 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var forEach = require('lodash.foreach');
|
||||
var indexOf = require('lodash.indexof');
|
||||
var forEach = require('lodash.foreach')
|
||||
var indexOf = require('lodash.indexof')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function deleteProperties(obj) {
|
||||
function deleteProperties (obj) {
|
||||
/* jshint forin: false */
|
||||
var prop;
|
||||
var prop
|
||||
for (prop in obj) {
|
||||
delete obj[prop];
|
||||
delete obj[prop]
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function defaultKey(item) {
|
||||
return item.id || item._id || item;
|
||||
function defaultKey (item) {
|
||||
return item.id || item._id || item
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function getAll() {
|
||||
function getAll () {
|
||||
/* jshint validthis: true */
|
||||
return this._data;
|
||||
return this._data
|
||||
}
|
||||
|
||||
function getIndexes() {
|
||||
function getIndexes () {
|
||||
/* jshint validthis: true */
|
||||
return this._indexes;
|
||||
return this._indexes
|
||||
}
|
||||
|
||||
function Collection(opts) {
|
||||
function Collection (opts) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
opts = {}
|
||||
}
|
||||
|
||||
this._key = opts.key || defaultKey;
|
||||
this._key = opts.key || defaultKey
|
||||
|
||||
this._indexes = Object.create(null);
|
||||
this._indexes = Object.create(null)
|
||||
if (opts.indexes) {
|
||||
forEach(opts.indexes, function (field) {
|
||||
this[field] = Object.create(null);
|
||||
}, this._indexes);
|
||||
this[field] = Object.create(null)
|
||||
}, this._indexes)
|
||||
}
|
||||
|
||||
this._data = Object.create(null);
|
||||
this._data = Object.create(null)
|
||||
|
||||
// Expose public properties.
|
||||
Object.defineProperties(this, {
|
||||
all: {
|
||||
enumerable: true,
|
||||
get: getAll,
|
||||
get: getAll
|
||||
},
|
||||
indexes: {
|
||||
enumerable: true,
|
||||
get: getIndexes,
|
||||
},
|
||||
});
|
||||
get: getIndexes
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Collection.prototype.clear = function () {
|
||||
deleteProperties(this._data);
|
||||
forEach(this._indexes, deleteProperties);
|
||||
};
|
||||
deleteProperties(this._data)
|
||||
forEach(this._indexes, deleteProperties)
|
||||
}
|
||||
|
||||
function unsetItemFromIndex(index, field) {
|
||||
function unsetItemFromIndex (index, field) {
|
||||
/* jshint validthis: true */
|
||||
|
||||
var prop = this[field];
|
||||
var prop = this[field]
|
||||
if (!prop) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var items = index[prop];
|
||||
var items = index[prop]
|
||||
|
||||
var i = indexOf(items, this);
|
||||
var i = indexOf(items, this)
|
||||
if (i === -1) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// The index contains only this one item for this prop.
|
||||
if (items.length === 1) {
|
||||
delete index[prop];
|
||||
return;
|
||||
delete index[prop]
|
||||
return
|
||||
}
|
||||
|
||||
// Remove this item.
|
||||
items.splice(i, 1);
|
||||
items.splice(i, 1)
|
||||
}
|
||||
|
||||
// Internal unset method.
|
||||
function unset(item, key) {
|
||||
function unset (item, key) {
|
||||
/* jshint validthis: true */
|
||||
|
||||
delete this._data[key];
|
||||
delete this._data[key]
|
||||
|
||||
forEach(this._indexes, unsetItemFromIndex, item);
|
||||
forEach(this._indexes, unsetItemFromIndex, item)
|
||||
}
|
||||
|
||||
function setItemToIndex(index, field) {
|
||||
function setItemToIndex (index, field) {
|
||||
/* jshint validthis: true */
|
||||
|
||||
var prop = this[field];
|
||||
var prop = this[field]
|
||||
if (!prop) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var items = index[prop];
|
||||
var items = index[prop]
|
||||
if (items) {
|
||||
// Update the items list.
|
||||
items.push(this);
|
||||
items.push(this)
|
||||
} else {
|
||||
// Create the items list.
|
||||
index[prop] = [this];
|
||||
index[prop] = [this]
|
||||
}
|
||||
}
|
||||
|
||||
Collection.prototype.set = function (item) {
|
||||
var key = this._key(item);
|
||||
var key = this._key(item)
|
||||
if (!key) {
|
||||
// Ignore empty keys.
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var previous = this._data[key];
|
||||
var previous = this._data[key]
|
||||
if (previous) {
|
||||
unset.call(this, previous, key);
|
||||
unset.call(this, previous, key)
|
||||
}
|
||||
|
||||
this._data[key] = item;
|
||||
forEach(this._indexes, setItemToIndex, item);
|
||||
};
|
||||
this._data[key] = item
|
||||
forEach(this._indexes, setItemToIndex, item)
|
||||
}
|
||||
|
||||
Collection.prototype.unset = function (item) {
|
||||
var key = this._key(item);
|
||||
item = this._data[key];
|
||||
var key = this._key(item)
|
||||
item = this._data[key]
|
||||
if (!item) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
unset.call(this, item, this._key(item));
|
||||
};
|
||||
unset.call(this, item, this._key(item))
|
||||
}
|
||||
|
||||
Collection.prototype.setMultiple = function (items) {
|
||||
forEach(items, this.set, this);
|
||||
};
|
||||
Collection.prototype.unsetMultiple = function (items) {
|
||||
forEach(items, this.unset, this);
|
||||
};
|
||||
|
||||
//====================================================================
|
||||
|
||||
function createCollection(opts) {
|
||||
return new Collection(opts);
|
||||
forEach(items, this.set, this)
|
||||
}
|
||||
module.exports = createCollection;
|
||||
Collection.prototype.unsetMultiple = function (items) {
|
||||
forEach(items, this.unset, this)
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
function createCollection (opts) {
|
||||
return new Collection(opts)
|
||||
}
|
||||
module.exports = createCollection
|
||||
|
@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var makeError = require('make-error');
|
||||
var makeError = require('make-error')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
module.exports = makeError('ConnectionError');
|
||||
module.exports = makeError('ConnectionError')
|
||||
|
@ -1,34 +1,36 @@
|
||||
var xoLib = require('./');
|
||||
'use strict'
|
||||
|
||||
var xoLib = require('./')
|
||||
|
||||
var xo = new xoLib.Xo({
|
||||
url: 'localhost:9000',
|
||||
});
|
||||
url: 'localhost:9000'
|
||||
})
|
||||
xo.call('acl.get', {}).then(function (result) {
|
||||
console.log('baz', result);
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
});
|
||||
|
||||
xo.signIn({
|
||||
email: 'admin@admin.net',
|
||||
password: 'admin',
|
||||
}).then(function () {
|
||||
console.log('foo', xo.user);
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
});
|
||||
|
||||
xo.signIn({
|
||||
email: 'tom',
|
||||
password: 'tom',
|
||||
}).then(function () {
|
||||
console.log('bar', xo.user);
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
});
|
||||
|
||||
xo.call('acl.get', {}).then(function (result) {
|
||||
console.log('plop', result);
|
||||
console.log('baz', result)
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
})
|
||||
|
||||
xo.signIn({
|
||||
email: 'admin@admin.net',
|
||||
password: 'admin'
|
||||
}).then(function () {
|
||||
console.log('foo', xo.user)
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
})
|
||||
|
||||
xo.signIn({
|
||||
email: 'tom',
|
||||
password: 'tom'
|
||||
}).then(function () {
|
||||
console.log('bar', xo.user)
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
})
|
||||
|
||||
xo.call('acl.get', {}).then(function (result) {
|
||||
console.log('plop', result)
|
||||
}).catch(function (error) {
|
||||
console.log('error', error)
|
||||
})
|
||||
|
@ -1,21 +1,21 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
// Fix URL if necessary.
|
||||
var URL_RE = /^(?:(?:http|ws)(s)?:\/\/)?(.*?)\/*(?:\/api\/)?(\?.*?)?(?:#.*)?$/;
|
||||
function fixUrl(url) {
|
||||
var matches = URL_RE.exec(url);
|
||||
var isSecure = !!matches[1];
|
||||
var hostAndPath = matches[2];
|
||||
var search = matches[3];
|
||||
var URL_RE = /^(?:(?:http|ws)(s)?:\/\/)?(.*?)\/*(?:\/api\/)?(\?.*?)?(?:#.*)?$/
|
||||
function fixUrl (url) {
|
||||
var matches = URL_RE.exec(url)
|
||||
var isSecure = !!matches[1]
|
||||
var hostAndPath = matches[2]
|
||||
var search = matches[3]
|
||||
|
||||
return [
|
||||
isSecure ? 'wss' : 'ws',
|
||||
'://',
|
||||
hostAndPath,
|
||||
'/api/',
|
||||
search,
|
||||
].join('');
|
||||
search
|
||||
].join('')
|
||||
}
|
||||
module.exports = fixUrl;
|
||||
module.exports = fixUrl
|
||||
|
@ -1,48 +1,48 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var expect = require('must');
|
||||
var expect = require('must')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
/* jshint mocha: true */
|
||||
/* eslint-env mocha */
|
||||
|
||||
describe('fixUrl()', function () {
|
||||
var fixUrl = require('./fix-url');
|
||||
var fixUrl = require('./fix-url')
|
||||
|
||||
describe('protocol', function () {
|
||||
it('is added if missing', function () {
|
||||
expect(fixUrl('localhost/api/')).to.equal('ws://localhost/api/');
|
||||
});
|
||||
expect(fixUrl('localhost/api/')).to.equal('ws://localhost/api/')
|
||||
})
|
||||
|
||||
it('HTTP(s) is converted to WS(s)', function () {
|
||||
expect(fixUrl('http://localhost/api/')).to.equal('ws://localhost/api/');
|
||||
expect(fixUrl('https://localhost/api/')).to.equal('wss://localhost/api/');
|
||||
});
|
||||
expect(fixUrl('http://localhost/api/')).to.equal('ws://localhost/api/')
|
||||
expect(fixUrl('https://localhost/api/')).to.equal('wss://localhost/api/')
|
||||
})
|
||||
|
||||
it('is not added if already present', function () {
|
||||
expect(fixUrl('ws://localhost/api/')).to.equal('ws://localhost/api/');
|
||||
expect(fixUrl('wss://localhost/api/')).to.equal('wss://localhost/api/');
|
||||
});
|
||||
});
|
||||
expect(fixUrl('ws://localhost/api/')).to.equal('ws://localhost/api/')
|
||||
expect(fixUrl('wss://localhost/api/')).to.equal('wss://localhost/api/')
|
||||
})
|
||||
})
|
||||
|
||||
describe('/api/ path', function () {
|
||||
it('is added if missing', function () {
|
||||
expect(fixUrl('ws://localhost')).to.equal('ws://localhost/api/');
|
||||
expect(fixUrl('ws://localhost/')).to.equal('ws://localhost/api/');
|
||||
});
|
||||
expect(fixUrl('ws://localhost')).to.equal('ws://localhost/api/')
|
||||
expect(fixUrl('ws://localhost/')).to.equal('ws://localhost/api/')
|
||||
})
|
||||
|
||||
it('is not added if already present', function () {
|
||||
expect(fixUrl('ws://localhost/api/')).to.equal('ws://localhost/api/');
|
||||
});
|
||||
expect(fixUrl('ws://localhost/api/')).to.equal('ws://localhost/api/')
|
||||
})
|
||||
|
||||
it('removes the hash part', function () {
|
||||
expect(fixUrl('ws://localhost/#foo')).to.equal('ws://localhost/api/');
|
||||
});
|
||||
expect(fixUrl('ws://localhost/#foo')).to.equal('ws://localhost/api/')
|
||||
})
|
||||
|
||||
it('conserve the search part', function () {
|
||||
expect(fixUrl('ws://localhost/?foo')).to.equal('ws://localhost/api/?foo');
|
||||
});
|
||||
});
|
||||
});
|
||||
expect(fixUrl('ws://localhost/?foo')).to.equal('ws://localhost/api/?foo')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
// Expose Bluebird for now to ease integration (e.g. with Angular.js).
|
||||
exports.setScheduler = require('bluebird').setScheduler;
|
||||
exports.setScheduler = require('bluebird').setScheduler
|
||||
|
||||
exports.Api = require('./api');
|
||||
exports.Xo = require('./xo');
|
||||
exports.Api = require('./api')
|
||||
exports.Xo = require('./xo')
|
||||
|
@ -19,10 +19,12 @@
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha *.spec.js"
|
||||
"test": "standard && mocha '*.spec.js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"bluebird": "^2.9.6",
|
||||
"event-to-promise": "^0.3.2",
|
||||
"exec-promise": "^0.5.1",
|
||||
"json-rpc": "git://github.com/julien-f/js-json-rpc#v0.3.1",
|
||||
"lodash.assign": "^3.0.0",
|
||||
"lodash.foreach": "^3.0.1",
|
||||
@ -30,10 +32,12 @@
|
||||
"lodash.isstring": "^3.0.0",
|
||||
"lodash.startswith": "^3.0.0",
|
||||
"make-error": "^0.3.0",
|
||||
"pw": "0.0.4",
|
||||
"ws": "^0.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^2.1.0",
|
||||
"must": "^0.12.0"
|
||||
"must": "^0.12.0",
|
||||
"standard": "*"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var makeError = require('make-error');
|
||||
var makeError = require('make-error')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
module.exports = makeError('SessionError');
|
||||
module.exports = makeError('SessionError')
|
||||
|
@ -1,99 +1,99 @@
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
var Bluebird = require('bluebird');
|
||||
var isString = require('lodash.isstring');
|
||||
var startsWith = require('lodash.startswith');
|
||||
var Bluebird = require('bluebird')
|
||||
var isString = require('lodash.isstring')
|
||||
var startsWith = require('lodash.startswith')
|
||||
|
||||
var Api = require('./api');
|
||||
var BackOff = require('./back-off');
|
||||
var ConnectionError = require('./connection-error');
|
||||
var createCollection = require('./collection');
|
||||
var SessionError = require('./session-error');
|
||||
var Api = require('./api')
|
||||
var BackOff = require('./back-off')
|
||||
var ConnectionError = require('./connection-error')
|
||||
var createCollection = require('./collection')
|
||||
var SessionError = require('./session-error')
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function makeStandaloneDeferred() {
|
||||
var resolve, reject;
|
||||
function makeStandaloneDeferred () {
|
||||
var resolve, reject
|
||||
|
||||
var promise = new Bluebird(function (resolve_, reject_) {
|
||||
resolve = resolve_;
|
||||
reject = reject_;
|
||||
});
|
||||
promise.resolve = resolve;
|
||||
promise.reject = reject;
|
||||
resolve = resolve_
|
||||
reject = reject_
|
||||
})
|
||||
promise.resolve = resolve
|
||||
promise.reject = reject
|
||||
|
||||
return promise;
|
||||
return promise
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
function noop () {}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
function Xo(opts) {
|
||||
function Xo (opts) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
opts = {}
|
||||
} else if (isString(opts)) {
|
||||
opts = {
|
||||
url: opts,
|
||||
};
|
||||
url: opts
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
var api = new Api(opts.url);
|
||||
var api = new Api(opts.url)
|
||||
|
||||
api.on('connected', function () {
|
||||
this._backOff.reset();
|
||||
this.status = 'connected';
|
||||
this._backOff.reset()
|
||||
this.status = 'connected'
|
||||
|
||||
this._tryToOpenSession();
|
||||
}.bind(this));
|
||||
this._tryToOpenSession()
|
||||
}.bind(this))
|
||||
|
||||
api.on('disconnected', function () {
|
||||
this._closeSession();
|
||||
this._connect();
|
||||
}.bind(this));
|
||||
this._closeSession()
|
||||
this._connect()
|
||||
}.bind(this))
|
||||
|
||||
api.on('notification', function (notification) {
|
||||
if (notification.method !== 'all') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var method = (
|
||||
notification.params.type === 'exit' ?
|
||||
'unset' :
|
||||
'set'
|
||||
) + 'Multiple';
|
||||
) + 'Multiple'
|
||||
|
||||
this.objects[method](notification.params.items);
|
||||
}.bind(this));
|
||||
this.objects[method](notification.params.items)
|
||||
}.bind(this))
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
this.objects = createCollection({
|
||||
indexes: [
|
||||
'ref',
|
||||
'type',
|
||||
'UUID',
|
||||
'UUID'
|
||||
],
|
||||
key: function (item) {
|
||||
return item.UUID || item.ref;
|
||||
},
|
||||
});
|
||||
this.status = 'disconnected';
|
||||
this.user = null;
|
||||
return item.UUID || item.ref
|
||||
}
|
||||
})
|
||||
this.status = 'disconnected'
|
||||
this.user = null
|
||||
|
||||
this._api = api;
|
||||
this._backOff = new BackOff();
|
||||
this._credentials = opts.creadentials;
|
||||
this._session = makeStandaloneDeferred();
|
||||
this._signIn = null;
|
||||
this._api = api
|
||||
this._backOff = new BackOff()
|
||||
this._credentials = opts.creadentials
|
||||
this._session = makeStandaloneDeferred()
|
||||
this._signIn = null
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
this._connect();
|
||||
this._connect()
|
||||
}
|
||||
|
||||
Xo.prototype.call = function (method, params) {
|
||||
@ -102,35 +102,35 @@ Xo.prototype.call = function (method, params) {
|
||||
if (startsWith(method, 'session.')) {
|
||||
return Bluebird.reject(
|
||||
new Error('session.*() methods are disabled from this interface')
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return this._session.bind(this).then(function () {
|
||||
return this._api.call(method, params);
|
||||
return this._api.call(method, params)
|
||||
}).catch(ConnectionError, SessionError, function () {
|
||||
// Automatically requeue this call.
|
||||
return this.call(method, params);
|
||||
});
|
||||
};
|
||||
return this.call(method, params)
|
||||
})
|
||||
}
|
||||
|
||||
Xo.prototype.signIn = function (credentials) {
|
||||
this.signOut();
|
||||
this.signOut()
|
||||
|
||||
this._credentials = credentials;
|
||||
this._signIn = makeStandaloneDeferred();
|
||||
this._credentials = credentials
|
||||
this._signIn = makeStandaloneDeferred()
|
||||
|
||||
this._tryToOpenSession();
|
||||
this._tryToOpenSession()
|
||||
|
||||
return this._signIn;
|
||||
};
|
||||
return this._signIn
|
||||
}
|
||||
|
||||
Xo.prototype.signOut = function () {
|
||||
this._closeSession();
|
||||
this._credentials = null;
|
||||
this._closeSession()
|
||||
this._credentials = null
|
||||
|
||||
var signIn = this._signIn;
|
||||
var signIn = this._signIn
|
||||
if (signIn && signIn.isPending()) {
|
||||
signIn.reject(new SessionError('sign in aborted'));
|
||||
signIn.reject(new SessionError('sign in aborted'))
|
||||
}
|
||||
|
||||
return this.status === 'connected' ?
|
||||
@ -140,31 +140,30 @@ Xo.prototype.signOut = function () {
|
||||
|
||||
// Always return a promise.
|
||||
Bluebird.resolve()
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
Xo.prototype._connect = function _connect() {
|
||||
this.status = 'connecting';
|
||||
Xo.prototype._connect = function _connect () {
|
||||
this.status = 'connecting'
|
||||
|
||||
return this._api.connect().bind(this).catch(function (error) {
|
||||
console.warn('could not connect:', error);
|
||||
console.warn('could not connect:', error)
|
||||
|
||||
return this._backOff.wait().bind(this).then(_connect);
|
||||
});
|
||||
};
|
||||
return this._backOff.wait().bind(this).then(_connect)
|
||||
})
|
||||
}
|
||||
|
||||
Xo.prototype._closeSession = function () {
|
||||
if (!this._session.isPending()) {
|
||||
this._session = makeStandaloneDeferred();
|
||||
this._session = makeStandaloneDeferred()
|
||||
}
|
||||
|
||||
this.user = null;
|
||||
};
|
||||
this.user = null
|
||||
}
|
||||
|
||||
Xo.prototype._tryToOpenSession = function () {
|
||||
var credentials = this._credentials;
|
||||
var credentials = this._credentials
|
||||
if (!credentials || this.status !== 'connected') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
this._api.call(
|
||||
@ -174,33 +173,33 @@ Xo.prototype._tryToOpenSession = function () {
|
||||
credentials
|
||||
).bind(this).then(
|
||||
function (user) {
|
||||
this.user = user;
|
||||
this.user = user
|
||||
|
||||
this._api.call('xo.getAllObjects').bind(this).then(function (objects) {
|
||||
this.objects.clear();
|
||||
this.objects.setMultiple(objects);
|
||||
});
|
||||
this.objects.clear()
|
||||
this.objects.setMultiple(objects)
|
||||
})
|
||||
|
||||
// Validate the sign in.
|
||||
var signIn = this._signIn;
|
||||
var signIn = this._signIn
|
||||
if (signIn) {
|
||||
signIn.resolve();
|
||||
signIn.resolve()
|
||||
}
|
||||
|
||||
// Open the session.
|
||||
this._session.resolve();
|
||||
this._session.resolve()
|
||||
},
|
||||
|
||||
function (error) {
|
||||
// Reject the sign in.
|
||||
var signIn = this._signIn;
|
||||
var signIn = this._signIn
|
||||
if (signIn) {
|
||||
signIn.reject(error);
|
||||
signIn.reject(error)
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// ===================================================================
|
||||
|
||||
module.exports = Xo;
|
||||
module.exports = Xo
|
||||
|
Loading…
Reference in New Issue
Block a user