schema-client
Advanced tools
Comparing version 2.2.0 to 2.2.1
@@ -28,12 +28,12 @@ /** | ||
events.EventEmitter.call(this); | ||
events.EventEmitter.call(this); | ||
this.server = null; | ||
this.server = null; | ||
if (clientId) { | ||
this.init(clientId, clientKey, options); | ||
} | ||
if (callback) { | ||
this.connect(callback); | ||
} | ||
if (clientId) { | ||
this.init(clientId, clientKey, options); | ||
} | ||
if (callback) { | ||
this.connect(callback); | ||
} | ||
}; | ||
@@ -52,30 +52,30 @@ | ||
options = options || {}; | ||
options = options || {}; | ||
if (typeof clientKey === 'object') { | ||
options = clientKey; | ||
clientKey = undefined; | ||
} else if (typeof clientId === 'object') { | ||
options = clientId; | ||
clientId = undefined; | ||
} | ||
if (typeof clientKey === 'object') { | ||
options = clientKey; | ||
clientKey = undefined; | ||
} else if (typeof clientId === 'object') { | ||
options = clientId; | ||
clientId = undefined; | ||
} | ||
this.params = { | ||
clientId: clientId || options.id, | ||
clientKey: clientKey || options.key, | ||
host: options.host || DEFAULT_HOST, | ||
port: options.port || DEFAULT_PORT, | ||
verifyCert: options.verifyCert !== undefined ? options.verifyCert : DEFAULT_VERIFY_CERT, | ||
version: options.version || DEFAULT_VERSION, | ||
session: options.session, | ||
route: options.route, | ||
routeClientId: options.route && options.route.client | ||
}; | ||
this.params = { | ||
clientId: clientId || options.id, | ||
clientKey: clientKey || options.key, | ||
host: options.host || DEFAULT_HOST, | ||
port: options.port || DEFAULT_PORT, | ||
verifyCert: options.verifyCert !== undefined ? options.verifyCert : DEFAULT_VERIFY_CERT, | ||
version: options.version || DEFAULT_VERSION, | ||
session: options.session, | ||
route: options.route, | ||
routeClientId: options.route && options.route.client | ||
}; | ||
if (!this.params.clientId) { | ||
throw new Error('Schema client `id` is required to initialize'); | ||
} | ||
if (!this.params.clientKey) { | ||
throw new Error('Schema client `key` is required to initialize'); | ||
} | ||
if (!this.params.clientId) { | ||
throw new Error('Schema client `id` is required to initialize'); | ||
} | ||
if (!this.params.clientKey) { | ||
throw new Error('Schema client `key` is required to initialize'); | ||
} | ||
}; | ||
@@ -90,37 +90,37 @@ | ||
var self = this; | ||
this.server = new Schema.Connection( | ||
this.params.host, | ||
this.params.port, | ||
{ | ||
verifyCert: this.params.verifyCert | ||
}, | ||
function() { | ||
callback && callback(self); | ||
self.emit('connect', self); | ||
} | ||
); | ||
this.server.on('close', function() { | ||
self.emit('close'); | ||
}); | ||
this.server.on('error', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Error: '+err); | ||
} | ||
}); | ||
this.server.on('error.network', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Network Error: '+err, 'network'); | ||
} | ||
}); | ||
this.server.on('error.protocol', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Protocol Error: '+err, 'protocol'); | ||
} | ||
}); | ||
this.server.on('error.server', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Server Error: '+err, 'server'); | ||
} | ||
}); | ||
var self = this; | ||
this.server = new Schema.Connection( | ||
this.params.host, | ||
this.params.port, | ||
{ | ||
verifyCert: this.params.verifyCert | ||
}, | ||
function() { | ||
callback && callback(self); | ||
self.emit('connect', self); | ||
} | ||
); | ||
this.server.on('close', function() { | ||
self.emit('close'); | ||
}); | ||
this.server.on('error', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Error: '+err); | ||
} | ||
}); | ||
this.server.on('error.network', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Network Error: '+err, 'network'); | ||
} | ||
}); | ||
this.server.on('error.protocol', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Protocol Error: '+err, 'protocol'); | ||
} | ||
}); | ||
this.server.on('error.server', function(err) { | ||
if (events.EventEmitter.listenerCount(self, 'error')) { | ||
self.emit('error', 'Server Error: '+err, 'server'); | ||
} | ||
}); | ||
}; | ||
@@ -138,62 +138,62 @@ | ||
if (typeof data === 'function') { | ||
callback = data; | ||
data = null; | ||
} | ||
if (typeof data === 'function') { | ||
callback = data; | ||
data = null; | ||
} | ||
// TODO: implement $cached | ||
// TODO: implement $cached | ||
if (!this.server) { | ||
this.connect(); | ||
} | ||
if (!this.server) { | ||
this.connect(); | ||
} | ||
// Resolve data as promised | ||
var promises = this.promisifyData(data); | ||
if (promises.length) { | ||
return Promise.all(promises).bind(this).then(function() { | ||
this.request(method, url, data, callback); | ||
}); | ||
} | ||
// Resolve data as promised | ||
var promises = this.promisifyData(data); | ||
if (promises.length) { | ||
return Promise.all(promises).bind(this).then(function() { | ||
this.request(method, url, data, callback); | ||
}); | ||
} | ||
// Prepare url and data for request | ||
url = url && url.toString ? url.toString() : ''; | ||
data = {$data: data}; | ||
// Prepare url and data for request | ||
url = url && url.toString ? url.toString() : ''; | ||
data = {$data: data}; | ||
if (this.authed !== true) { | ||
data.$client = this.params.clientId; | ||
data.$key = this.params.clientKey; | ||
if (this.authed !== true) { | ||
data.$client = this.params.clientId; | ||
data.$key = this.params.clientKey; | ||
if (this.params.route) { | ||
data.$route = this.params.route; | ||
} | ||
if (this.params.route) { | ||
data.$route = this.params.route; | ||
} | ||
} | ||
var self = this; | ||
return new Promise(function(resolve, reject) { | ||
var responder = function(err, data, response) { | ||
if (callback) { | ||
callback(err, data, response); | ||
} | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(data, response); | ||
} | ||
}; | ||
self.server.request(method, url, data, function(response) { | ||
if (response.$auth) { | ||
if (response.$end) { | ||
// Connection ended, retry auth | ||
return self.request(method, url, data.$data, callback); | ||
} else { | ||
self.authed = true; | ||
return self.auth(response.$auth, function(response) { | ||
return self.respond(method, url, response, responder); | ||
}); | ||
} | ||
} else { | ||
return self.respond(method, url, response, responder); | ||
} | ||
}); | ||
var self = this; | ||
return new Promise(function(resolve, reject) { | ||
var responder = function(err, data, response) { | ||
if (callback) { | ||
callback(err, data, response); | ||
} | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(data, response); | ||
} | ||
}; | ||
self.server.request(method, url, data, function(response) { | ||
if (response.$auth) { | ||
if (response.$end) { | ||
// Connection ended, retry auth | ||
return self.request(method, url, data.$data, callback); | ||
} else { | ||
self.authed = true; | ||
return self.auth(response.$auth, function(response) { | ||
return self.respond(method, url, response, responder); | ||
}); | ||
} | ||
} else { | ||
return self.respond(method, url, response, responder); | ||
} | ||
}); | ||
}); | ||
}; | ||
@@ -210,32 +210,32 @@ | ||
if (!data) { | ||
return []; | ||
} | ||
if (!data) { | ||
return []; | ||
} | ||
function thenResolvePromisedValue(data, key) { | ||
data[key].then(function(val) { | ||
data[key] = val; | ||
}); | ||
} | ||
function thenResolvePromisedValue(data, key) { | ||
data[key].then(function(val) { | ||
data[key] = val; | ||
}); | ||
} | ||
var promises = []; | ||
if (typeof data === 'object') { | ||
var keys = Object.keys(data); | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
if (data[key] && data[key].then) { | ||
promises.push(data[key]); | ||
thenResolvePromisedValue(data, key); | ||
} | ||
} | ||
} else if (data instanceof Array) { | ||
for (var i = 0; i < data.length; i++) { | ||
if (data[i] && data[i].then) { | ||
promises.push(data[i]); | ||
thenResolvePromisedValue(data, i); | ||
} | ||
} | ||
var promises = []; | ||
if (typeof data === 'object') { | ||
var keys = Object.keys(data); | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
if (data[key] && data[key].then) { | ||
promises.push(data[key]); | ||
thenResolvePromisedValue(data, key); | ||
} | ||
} | ||
} else if (data instanceof Array) { | ||
for (var i = 0; i < data.length; i++) { | ||
if (data[i] && data[i].then) { | ||
promises.push(data[i]); | ||
thenResolvePromisedValue(data, i); | ||
} | ||
} | ||
} | ||
return promises; | ||
return promises; | ||
}; | ||
@@ -253,19 +253,19 @@ | ||
var err = undefined; | ||
var data = undefined; | ||
var err = undefined; | ||
var data = undefined; | ||
if (response) { | ||
if (response.$error) { | ||
err = response.$error; | ||
} | ||
if (response.$data && (typeof response.$data === 'object')) { | ||
data = Client.createResource(response.$url || url, response, this); | ||
} else { | ||
data = response.$data; | ||
} | ||
if (response) { | ||
if (response.$error) { | ||
err = response.$error; | ||
} | ||
if (response.$data && (typeof response.$data === 'object')) { | ||
data = Client.createResource(response.$url || url, response, this); | ||
} else { | ||
response = {$error: 'Empty response from server', $status: 500}; | ||
err = response.$error; | ||
data = response.$data; | ||
} | ||
return callback.call(this, err, data, response); | ||
} else { | ||
response = {$error: 'Empty response from server', $status: 500}; | ||
err = response.$error; | ||
} | ||
return callback.call(this, err, data, response); | ||
}; | ||
@@ -282,3 +282,3 @@ | ||
Client.prototype.get = function(url, data, callback) { | ||
return this.request('get', url, data, callback); | ||
return this.request('get', url, data, callback); | ||
}; | ||
@@ -290,3 +290,3 @@ | ||
Client.prototype.put = function(url, data, callback) { | ||
return this.request('put', url, data, callback); | ||
return this.request('put', url, data, callback); | ||
}; | ||
@@ -298,3 +298,3 @@ | ||
Client.prototype.post = function(url, data, callback) { | ||
return this.request('post', url, data, callback); | ||
return this.request('post', url, data, callback); | ||
}; | ||
@@ -306,3 +306,3 @@ | ||
Client.prototype.delete = function(url, data, callback) { | ||
return this.request('delete', url, data, callback); | ||
return this.request('delete', url, data, callback); | ||
}; | ||
@@ -319,50 +319,50 @@ | ||
var self = this; | ||
var clientId = this.params.clientId; | ||
var clientKey = this.params.clientKey; | ||
var self = this; | ||
var clientId = this.params.clientId; | ||
var clientKey = this.params.clientKey; | ||
if (typeof nonce === 'function') { | ||
callback = nonce; | ||
nonce = null; | ||
} | ||
if (typeof nonce === 'function') { | ||
callback = nonce; | ||
nonce = null; | ||
} | ||
if (!this.server) { | ||
this.connect(); | ||
} | ||
if (!this.server) { | ||
this.connect(); | ||
} | ||
// 1) Get nonce | ||
if (!nonce) { | ||
return this.server.request('auth', function(nonce) { | ||
self.auth(nonce, callback); | ||
}); | ||
} | ||
// 1) Get nonce | ||
if (!nonce) { | ||
return this.server.request('auth', function(nonce) { | ||
self.auth(nonce, callback); | ||
}); | ||
} | ||
// 2) Create key hash | ||
var keyHash = crypto.createHash('md5') | ||
.update(clientId + "::" + clientKey) | ||
.digest('hex'); | ||
// 2) Create key hash | ||
var keyHash = crypto.createHash('md5') | ||
.update(clientId + "::" + clientKey) | ||
.digest('hex'); | ||
// 3) Create auth key | ||
var authKey = crypto.createHash('md5') | ||
.update(nonce + clientId + keyHash) | ||
.digest('hex'); | ||
// 3) Create auth key | ||
var authKey = crypto.createHash('md5') | ||
.update(nonce + clientId + keyHash) | ||
.digest('hex'); | ||
// 4) Authenticate with client creds and options | ||
var creds = { | ||
client: clientId, | ||
key: authKey | ||
}; | ||
if (this.params.version) { | ||
creds.$v = this.params.version; | ||
} | ||
if (this.params.session) { | ||
creds.$session = this.params.session; | ||
} | ||
if (this.params.route) { | ||
creds.$route = this.params.route; | ||
} | ||
// 4) Authenticate with client creds and options | ||
var creds = { | ||
client: clientId, | ||
key: authKey | ||
}; | ||
if (this.params.version) { | ||
creds.$v = this.params.version; | ||
} | ||
if (this.params.session) { | ||
creds.$session = this.params.session; | ||
} | ||
if (this.params.route) { | ||
creds.$route = this.params.route; | ||
} | ||
// TODO: send local $ip address | ||
// TODO: send local $ip address | ||
return this.server.request('auth', creds, callback); | ||
return this.server.request('auth', creds, callback); | ||
}; | ||
@@ -377,5 +377,5 @@ | ||
if (this.server) { | ||
this.server.close(); | ||
} | ||
if (this.server) { | ||
this.server.close(); | ||
} | ||
}; | ||
@@ -393,3 +393,3 @@ | ||
Client.create = function(clientId, clientKey, options, callback) { | ||
return new Client(clientId, clientKey, options, callback); | ||
return new Client(clientId, clientKey, options, callback); | ||
}; | ||
@@ -406,6 +406,6 @@ | ||
Client.createResource = function(url, response, client) { | ||
if (response && response.$data && 'count' in response.$data && response.$data.results) { | ||
return new Schema.Collection(url, response, client); | ||
} | ||
return new Schema.Record(url, response, client); | ||
if (response && response.$data && 'count' in response.$data && response.$data.results) { | ||
return new Schema.Collection(url, response, client); | ||
} | ||
return new Schema.Record(url, response, client); | ||
}; | ||
@@ -412,0 +412,0 @@ |
@@ -22,22 +22,22 @@ /** | ||
events.EventEmitter.call(this); | ||
events.EventEmitter.call(this); | ||
this.stream = null; | ||
this.connected = false; | ||
this.buffer = []; | ||
this.requestBuffer = []; | ||
this.stream = null; | ||
this.connected = false; | ||
this.buffer = []; | ||
this.requestBuffer = []; | ||
this.host = host; | ||
this.port = port; | ||
this.host = host; | ||
this.port = port; | ||
options = options || {}; | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
this.options = options; | ||
options = options || {}; | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
this.options = options; | ||
if (callback) { | ||
this.connect(callback); | ||
} | ||
if (callback) { | ||
this.connect(callback); | ||
} | ||
}; | ||
@@ -54,21 +54,21 @@ | ||
var self = this; | ||
var proto = this.options.clear ? net : tls; | ||
var self = this; | ||
var proto = this.options.clear ? net : tls; | ||
this.stream = proto.connect({ | ||
host: this.host, | ||
port: this.port, | ||
rejectUnauthorized: this.options.verifyCert === false ? false : true | ||
}, function() { | ||
self.connected = true; | ||
self.flushRequestBuffer(); | ||
callback && callback(self); | ||
self.emit('connect'); | ||
}); | ||
this.stream.on('error', this.close.bind(this)); | ||
this.stream.on('data', this.receive.bind(this)); | ||
this.stream.on('close', this.close.bind(this)); | ||
this.stream.on('timeout', this.close.bind(this)); | ||
this.stream.setEncoding('utf8'); | ||
this.stream.setTimeout(10000); | ||
this.stream = proto.connect({ | ||
host: this.host, | ||
port: this.port, | ||
rejectUnauthorized: this.options.verifyCert === false ? false : true | ||
}, function() { | ||
self.connected = true; | ||
self.flushRequestBuffer(); | ||
callback && callback(self); | ||
self.emit('connect'); | ||
}); | ||
this.stream.on('error', this.close.bind(this)); | ||
this.stream.on('data', this.receive.bind(this)); | ||
this.stream.on('close', this.close.bind(this)); | ||
this.stream.on('timeout', this.close.bind(this)); | ||
this.stream.setEncoding('utf8'); | ||
this.stream.setTimeout(10000); | ||
}; | ||
@@ -85,19 +85,19 @@ | ||
// Copy args to avoid leaking | ||
var args = new Array(arguments.length); | ||
for (var i = 0; i < arguments.length; i++) { | ||
args[i] = arguments[i]; | ||
} | ||
// Copy args to avoid leaking | ||
var args = new Array(arguments.length); | ||
for (var i = 0; i < arguments.length; i++) { | ||
args[i] = arguments[i]; | ||
} | ||
this.requestBuffer.push(args); | ||
this.requestBuffer.push(args); | ||
if (!this.connected) { | ||
if (!this.stream) { | ||
this.connect(); | ||
} | ||
return; | ||
if (!this.connected) { | ||
if (!this.stream) { | ||
this.connect(); | ||
} | ||
return; | ||
} | ||
var request = JSON.stringify(args.slice(0, -1)); | ||
this.stream.write(request + "\n"); | ||
var request = JSON.stringify(args.slice(0, -1)); | ||
this.stream.write(request + "\n"); | ||
}; | ||
@@ -112,18 +112,18 @@ | ||
// Split buffer data on newline char | ||
for (var i = 0, j = 0; i < buffer.length; i++) { | ||
if (buffer[i] === '\n') { | ||
this.buffer.push(buffer.slice(j, i)); | ||
// Split buffer data on newline char | ||
for (var i = 0, j = 0; i < buffer.length; i++) { | ||
if (buffer[i] === '\n') { | ||
this.buffer.push(buffer.slice(j, i)); | ||
var data = this.buffer.join(''); | ||
var data = this.buffer.join(''); | ||
this.buffer = []; | ||
this.receiveResponse(data); | ||
this.buffer = []; | ||
this.receiveResponse(data); | ||
j = i + 1; | ||
} | ||
j = i + 1; | ||
} | ||
if (j < buffer.length) { | ||
this.buffer.push(buffer.slice(j, buffer.length)); | ||
} | ||
} | ||
if (j < buffer.length) { | ||
this.buffer.push(buffer.slice(j, buffer.length)); | ||
} | ||
}; | ||
@@ -138,36 +138,36 @@ | ||
var response; | ||
var responder = this.requestBuffer.shift().pop(); | ||
var response; | ||
var responder = this.requestBuffer.shift().pop(); | ||
try { | ||
response = JSON.parse(data); | ||
} catch (err) { | ||
response = 'Unable to parse response from server ('+data+')'; | ||
this.emit('error.protocol', response); | ||
return responder({ | ||
$status: 500, | ||
$error: response | ||
}); | ||
} | ||
try { | ||
response = JSON.parse(data); | ||
} catch (err) { | ||
response = 'Unable to parse response from server ('+data+')'; | ||
this.emit('error.protocol', response); | ||
return responder({ | ||
$status: 500, | ||
$error: response | ||
}); | ||
} | ||
if (!response || typeof response !== 'object') { | ||
response = 'Invalid response from server ('+data+')'; | ||
this.emit('error.protocol', response); | ||
return responder({ | ||
$status: 500, | ||
$error: response | ||
}); | ||
} | ||
if (!response || typeof response !== 'object') { | ||
response = 'Invalid response from server ('+data+')'; | ||
this.emit('error.protocol', response); | ||
return responder({ | ||
$status: 500, | ||
$error: response | ||
}); | ||
} | ||
if (response.$error) { | ||
this.emit('error.server', response.$error); | ||
} | ||
if (response.$end) { | ||
this.close(); | ||
} | ||
if (response.$error) { | ||
this.emit('error.server', response.$error); | ||
} | ||
if (response.$end) { | ||
this.close(); | ||
} | ||
// Note: response always returns in the same order as request | ||
if (typeof responder === 'function') { | ||
responder(response); | ||
} | ||
// Note: response always returns in the same order as request | ||
if (typeof responder === 'function') { | ||
responder(response); | ||
} | ||
}; | ||
@@ -180,27 +180,27 @@ | ||
if (!this.connected) { | ||
return; | ||
} | ||
if (!this.connected) { | ||
return; | ||
} | ||
if (this.stream && this.stream.writable) { | ||
this.stream.end(); | ||
} | ||
if (this.stream && this.stream.writable) { | ||
this.stream.end(); | ||
} | ||
this.connected = false; | ||
this.stream = null; | ||
this.emit('close'); | ||
this.connected = false; | ||
this.stream = null; | ||
this.emit('close'); | ||
var hasRequests = this.requestBuffer.length; | ||
if (error || hasRequests) { | ||
this.emit('error.network', error || DEFAULT_NETWORK_ERROR); | ||
} | ||
var hasRequests = this.requestBuffer.length; | ||
if (error || hasRequests) { | ||
this.emit('error.network', error || DEFAULT_NETWORK_ERROR); | ||
} | ||
var responder; | ||
while (--hasRequests >= 0) { | ||
responder = this.requestBuffer.shift().pop(); | ||
responder({ | ||
$status: 500, | ||
$error: error || DEFAULT_NETWORK_ERROR | ||
}); | ||
} | ||
var responder; | ||
while (--hasRequests >= 0) { | ||
responder = this.requestBuffer.shift().pop(); | ||
responder({ | ||
$status: 500, | ||
$error: error || DEFAULT_NETWORK_ERROR | ||
}); | ||
} | ||
}; | ||
@@ -215,10 +215,10 @@ | ||
if (!this.connected) { | ||
return; | ||
} | ||
if (!this.connected) { | ||
return; | ||
} | ||
var hasRequests = this.requestBuffer.length; | ||
while (--hasRequests >= 0) { | ||
this.request.apply(this, this.requestBuffer.shift()); | ||
} | ||
var hasRequests = this.requestBuffer.length; | ||
while (--hasRequests >= 0) { | ||
this.request.apply(this, this.requestBuffer.shift()); | ||
} | ||
}; | ||
@@ -225,0 +225,0 @@ |
{ | ||
"name": "schema-client", | ||
"version": "2.2.0", | ||
"version": "2.2.1", | ||
"description": "Schema API Client for NodeJS", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
97042