New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

help-esb

Package Overview
Dependencies
Maintainers
4
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

help-esb - npm Package Compare versions

Comparing version 0.5.1 to 0.6.0

4

examples/read.js

@@ -6,5 +6,5 @@ var HelpEsb = require('../help-esb');

client.on('group.asdf', function(data) {
client.on('group.asdf', function(message) {
console.log('Received data:');
console.log(data);
console.log(message.toJSON());
});

@@ -11,0 +11,0 @@

@@ -6,4 +6,4 @@ var HelpEsb = require('../help-esb');

client.rpcReceive('rpc-test', function(data) {
return {greeting: 'Hello ' + data.name};
client.rpcReceive('rpc-test', function(message) {
return {greeting: 'Hello ' + message.get('name')};
});

@@ -10,0 +10,0 @@

@@ -5,7 +5,11 @@ var HelpEsb = require('../help-esb');

client.rpcSend('rpc-test', {name: 'nubs'})
var util = require('util');
client.rpcSend('org-settings-set', {routingStrategy: 'helpdotcom', organizationId: '2b9ad7bd-3aba-407c-83ce-9e95581a11bf'})
//client.rpcSend('chat-transcript-get', {roomId: 'd6e6ca50-e87d-4231-827b-799f7a665ffb', organizationId: '2b9ad7bd-3aba-407c-83ce-9e95581a11bf'})
.timeout(5000)
.then(function(response) {
.then(function(message) {
console.log('Received response:');
console.log(response);
console.log(util.inspect(message.toJSON(), {depth: null, colors: true}));
console.log(message.get());
}).catch(function(error) {

@@ -12,0 +16,0 @@ console.warn('Received error:');

@@ -14,5 +14,16 @@ (function(root, factory) {

require('uuid'),
require('lodash')
require('lodash'),
require('object-path')
);
}(this, function(HelpEsb, net, EventEmitter, util, url, Promise, uuid, _) {
}(this, function(
HelpEsb,
net,
EventEmitter,
util,
url,
Promise,
uuid,
_,
objectPath
) {
'use strict';

@@ -31,4 +42,4 @@

// client.on('type.error', console.error);
// client.on('group.subscriptionChannel1', function(data) {
// // Process data
// client.on('group.subscriptionChannel1', function(message) {
// // Process message
// });

@@ -40,4 +51,4 @@ //

// client.login('clientName');
// client.rpcReceive('subscriptionChannel1', function(data) {
// // Process data
// client.rpcReceive('subscriptionChannel1', function(message) {
// // Process message
// return result;

@@ -56,2 +67,4 @@ // });

this._options = _.extend({debug: false}, options);
this.mb = new HelpEsb.MessageBuilder(this);
};

@@ -71,6 +84,4 @@

return this._authentication = this._rpcSend({
meta: {type: 'login'},
data: {name: name, subscriptions: []}
}).timeout(10000);
return this._authentication = this._rpcSend(this.mb.login(name))
.timeout(10000);
};

@@ -89,6 +100,3 @@

this._subscriptions[group] = this._authPromise().then(function() {
return this._rpcSend({
meta: {type: 'subscribe'},
data: {channel: group}
}).timeout(10000);
return this._rpcSend(this.mb.subscribe(group)).timeout(10000);
}.bind(this));

@@ -101,13 +109,25 @@ }

// ### HelpEsb.Client.send
// Sends a payload message to the ESB with the given data. Returns a promise
// that, like the [subscribe](#helpesb-client-subscribe) call, is fulfilled
// when the message is sent, but does not indicate whether the message was
// received by the ESB or by any subscribers. For RPC-esque behavior, use
// [rpcSend](#helpesb-client-rpcsend).
// Sends a payload message to the ESB with the given message. Returns a
// promise that, like the [subscribe](#helpesb-client-subscribe) call, is
// fulfilled when the message is sent, but does not indicate whether the
// message was received by the ESB or by any subscribers. For RPC-esque
// behavior, use [rpcSend](#helpesb-client-rpcsend).
//
// Optionally, you can also pass a second message instance that indicates
// which request message this message is in regards to. This allows for
// following full request cycle reporting with the ESB. We can track the
// requests down through multiple layers using this `inre` flag, and then the
// responses can come back up using `replyTo` and we can reconstruct the
// topography of the calls after the fact.
//
// client.send('target', {id: 1234, message: 'Hello!'});
HelpEsb.Client.prototype.send = function(group, data, replyCallback) {
HelpEsb.Client.prototype.send = function(
group,
message,
inre,
replyCallback
) {
return this._authPromise().then(function() {
return this._send(
{meta: {type: 'sendMessage', group: group}, data: data},
this.mb.send(group, this.mb.coerce(message), inre),
replyCallback

@@ -127,11 +147,12 @@ );

//
// client.rpcSend('foo', {name: 'John'}).then(function(response) {
// console.log(response);
// }).catch(function(error) {
// console.error(error);
// });
HelpEsb.Client.prototype.rpcSend = function(group, data) {
// client.rpcSend('foo', {name: 'John'})
// .then(function(response) {
// console.log(response.toJSON());
// }).catch(function(error) {
// console.error(error);
// });
HelpEsb.Client.prototype.rpcSend = function(group, message, inre) {
var send = Promise.promisify(HelpEsb.Client.prototype.send).bind(this);
return this.subscribe(group + '-result').then(function() {
return send(group, data).spread(this._checkRpcResult);
return send(group, message, inre).then(this._checkRpcResult);
}.bind(this));

@@ -147,4 +168,4 @@ };

//
// client.rpcReceive('foo', function(data) {
// return {greeting: 'Hello ' + (data.name || 'Stranger')};
// client.rpcReceive('foo', function(message) {
// return {greeting: 'Hello ' + message.get('name', 'Stranger')};
// });

@@ -154,3 +175,3 @@ //

//
// client.rpcReceive('foo', function(data) {
// client.rpcReceive('foo', function(message) {
// return request.getAsync('http://www.google.com');

@@ -162,3 +183,3 @@ // });

//
// client.rpcReceive('foo', function(data) {
// client.rpcReceive('foo', function(message) {
// throw new Error('Not implemented!');

@@ -168,4 +189,4 @@ // });

this.subscribe(group);
this.on('group.' + group, function(data, incomingMeta) {
var meta = {type: 'sendMessage', replyTo: incomingMeta.id};
this.on('group.' + group, function(message) {
var meta = {type: 'sendMessage', replyTo: message.getMeta('id')};

@@ -176,27 +197,29 @@ // Link up our reply to the incoming request but on the "result" group.

// CC the groups in the incoming messages CC list.
if (incomingMeta.cc && typeof incomingMeta.cc.group !== 'undefined') {
groups = groups.concat(incomingMeta.cc.group);
if (message.hasMeta('cc.group')) {
groups = groups.concat(message.getMeta('cc.group'));
}
if (typeof incomingMeta.session !== 'undefined') {
meta.session = incomingMeta.session;
if (message.hasMeta('session')) {
meta.session = message.getMeta('session');
}
var sendToGroup = function(meta, data, group) {
return this._send({meta: _.extend({group: group}, meta), data: data});
var sendToGroup = function(message, group) {
return this._send(this.mb.send(group, message));
}.bind(this);
var sendToAll = function(meta, data) {
return Promise.all(groups.map(_.partial(sendToGroup, meta, data)));
var sendToAll = function(message) {
return Promise.all(groups.map(_.partial(sendToGroup, message)));
};
Promise.try(cb.bind({}, data, incomingMeta)).then(function(data) {
return sendToAll(_.extend({result: 'SUCCESS'}, meta), data);
Promise.try(cb.bind({}, message)).then(function(message) {
return sendToAll(
this.mb.success(
this.mb.extend({meta: meta}, this.mb.coerce(message))
)
);
}.bind(this)).catch(function(error) {
var reason = error instanceof Error ? error.toString() : error;
var errorMeta = _.extend({reason: reason}, meta);
return sendToAll(
_.extend({result: 'FAILURE', reason: reason}, meta),
data
);
return sendToAll(this.mb.failure({meta: errorMeta}));
}.bind(this));

@@ -214,2 +237,21 @@ }.bind(this));

// ### HelpEsb.Client.decorateMessage
// Formats the message with client-specific values needed by the ESB. This
// includes the `from` key in the meta to reference the logged in client
// channel id.
//
// You probably don't need to call this yourself as it is called by the
// `MessageBuilder`.
HelpEsb.Client.prototype.decorateMessage = function(message) {
if (
this._authentication !== null &&
this._authentication.isFulfilled() &&
this._authentication.value().has('channelId')
) {
message.meta.from = this._authentication.value().get('channelId');
}
return message;
};
// ---

@@ -272,21 +314,22 @@ // ### Private Methods

// Format the packet for the ESB and send it over the socket. JSON encodes
// Format the message for the ESB and send it over the socket. JSON encodes
// the message and appends a newline as the delimiter between messages.
HelpEsb.Client.prototype._send = function(packet, replyCallback) {
packet = this._massageOutboundPacket(packet);
HelpEsb.Client.prototype._send = function(message, replyCallback) {
// Register a callback for replies to this message if a callback is given.
if (replyCallback) {
this.once('replyTo.' + packet.meta.id, _.partial(replyCallback, null));
this.once(
'replyTo.' + message.getMeta('id'),
_.partial(replyCallback, null)
);
}
return this._sendRaw(JSON.stringify(packet) + '\n');
return this._sendRaw(JSON.stringify(message) + '\n');
};
// Sends the packet like **_send**, but returns a promise for a response from
// some other service. This uses the autogen message id and relies on the
// other service properly publishing a message with a proper replyTo.
HelpEsb.Client.prototype._rpcSend = function(packet) {
// Sends the message like **_send**, but returns a promise for a response
// from some other service. This uses the autogen message id and relies on
// the other service properly publishing a message with a proper replyTo.
HelpEsb.Client.prototype._rpcSend = function(message) {
var send = Promise.promisify(HelpEsb.Client.prototype._send).bind(this);
return send(packet).spread(this._checkRpcResult);
return send(message).then(this._checkRpcResult);
};

@@ -296,19 +339,19 @@

// successful.
HelpEsb.Client.prototype._checkRpcResult = function(data, meta) {
if (meta.result !== 'SUCCESS') {
return Promise.reject(meta.reason);
HelpEsb.Client.prototype._checkRpcResult = function(message) {
if (message.getMeta('result') !== 'SUCCESS') {
return Promise.reject(message.getMeta('reason'));
}
return Promise.resolve(data);
return Promise.resolve(message);
};
// Wait on the socket connection and once it is avaialable send the given
// string data returning a promise of the data being sent.
HelpEsb.Client.prototype._sendRaw = function(data) {
// string packet returning a promise of the packet being sent.
HelpEsb.Client.prototype._sendRaw = function(packet) {
if (this._options.debug) {
console.log('help-esb SENDING', data);
console.log('help-esb SENDING', packet);
}
return this._socketConnection.then(function() {
return this._socket.writeAsync(data);
return this._socket.writeAsync(packet);
}.bind(this));

@@ -336,5 +379,5 @@ };

// Handles a single packet of data. The data is expected to be JSON, and if
// it isn't, a `type.error` event will be emitted. Otherwise, an event for
// each of the meta fields (e.g., `type.error`, `group.someGroup`,
// Handles a single packet of data. The packet is expected to be JSON, and
// if it isn't, a `type.error` event will be emitted. Otherwise, an event
// for each of the meta fields (e.g., `type.error`, `group.someGroup`,
// `replyTo.SOME_ID`) will be emitted.

@@ -353,4 +396,9 @@ //

var message;
try {
packet = JSON.parse(packet);
message = new HelpEsb.Message(JSON.parse(packet));
if (!message.hasMeta('type')) {
throw new Error('Invalid format detected for packet');
}
} catch (e) {

@@ -361,12 +409,3 @@ this.emit('type.error', e);

if (
typeof packet.meta !== 'object' ||
typeof packet.meta.type !== 'string' ||
typeof packet.data === 'undefined'
) {
this.emit('type.error', 'Invalid format detected for packet', packet);
return;
}
// Emits key.value events with the data and meta. If the value is an
// Emits key.value events with the message. If the value is an
// array, it iterates over the array and emits events on each value in the

@@ -381,27 +420,11 @@ // array. Returns true if any of the events were handled.

return this.emit(key + '.' + value, packet.data, packet.meta);
return this.emit(key + '.' + value, message);
}.bind(this);
this.emit('*', packet.data, packet.meta);
if (!_.any(_.map(packet.meta, emitKeyValue))) {
this.emit('*.unhandled', packet.data, packet.meta);
this.emit('*', message);
if (!_.any(_.map(message.getMeta(), emitKeyValue))) {
this.emit('*.unhandled', message);
}
};
// Process the packet to ensure it conforms to the ESB requirements. Sets
// the message id in the metadata for the packet if it wasn't already set.
HelpEsb.Client.prototype._massageOutboundPacket = function(packet) {
packet.meta.id = packet.meta.id || uuid.v4();
if (
this._authentication !== null &&
this._authentication.isFulfilled() &&
typeof this._authentication.value().channelId !== 'undefined'
) {
packet.meta.from = this._authentication.value().channelId;
}
return packet;
};
// This will return a failed promise if authentication hasn't been attempted

@@ -414,3 +437,145 @@ // yet.

// ## HelpEsb.MessageBuilder
// The `MessageBuilder` is a helper object that can build a `HelpEsb.Message`
// according to standard message types.
// ### HelpEsb.MessageBuilder *constructor*
// Initializes the object with access to the `HelpEsb.Client` instance used
// to decorate messages further.
HelpEsb.MessageBuilder = function(client) {
this._client = client;
};
// ### HelpEsb.MessageBuilder.login
// Creates a standard login message for the given client name.
HelpEsb.MessageBuilder.prototype.login = function(name) {
return new HelpEsb.Message({
meta: {type: 'login'},
data: {name: name, subscriptions: []}
});
};
// ### HelpEsb.MessageBuilder.subscribe
// Creates a standard subscribe message for the given group name.
HelpEsb.MessageBuilder.prototype.subscribe = function(group) {
return this.create({meta: {type: 'subscribe'}, data: {channel: group}});
};
// ### HelpEsb.MessageBuilder.send
// Creates a standard `sendMessage` message, extending off of the given
// message.
HelpEsb.MessageBuilder.prototype.send = function(group, message, inre) {
return this.extend(
{
meta: {
type: 'sendMessage',
group: group,
inre: inre && inre.getMeta('id')
}
},
message
);
};
// ### HelpEsb.MessageBuilder.success
// Creates a standard success message which has a result status, extending
// off of the given message.
HelpEsb.MessageBuilder.prototype.success = function(message) {
return this.extend({meta: {result: 'SUCCESS'}}, message);
};
// ### HelpEsb.MessageBuilder.failure
// Creates a standard failure message which has a result status, extending
// off of the given message.
HelpEsb.MessageBuilder.prototype.failure = function(message) {
return this.extend({meta: {result: 'FAILURE'}}, message);
};
// ### HelpEsb.MessageBuilder.create
// Creates a `HelpEsb.Message` object that has been decorated by the client.
HelpEsb.MessageBuilder.prototype.create = function(message) {
return new HelpEsb.Message(this._client.decorateMessage(message));
};
// ### HelpEsb.MessageBuilder.build
// Creates a `HelpEsb.Message` object that has been decorated by the client
// from its constituent data and meta parameters.
HelpEsb.MessageBuilder.prototype.build = function(data, meta) {
return this.create({meta: meta || {}, data: data || {}});
};
// ### HelpEsb.MessageBuilder.coerce
// Coerces the passed argument into a message, returning it as is if it is a
// `HelpEsb.Message` object, or building it from its `data` (and optional
// `meta`) otherwise.
HelpEsb.MessageBuilder.prototype.coerce = function(data, meta) {
return data instanceof HelpEsb.Message ? data : this.build(data, meta);
};
// ### HelpEsb.MessageBuilder.extend
// Extends a message (`Message` object or POJO) with other message(s).
// Returns a new message that is the combined data/meta parts from all of the
// passed message arguments.
HelpEsb.MessageBuilder.prototype.extend = function(/* object, extension */) {
var params = _.map(arguments, function(arg) {
return _.clone(arg instanceof HelpEsb.Message ? arg.toJSON() : arg);
});
return this.build(
_.extend.apply({}, [{}].concat(_.pluck(params, 'data'))),
_.extend.apply({}, [{}].concat(_.pluck(params, 'meta')))
);
};
// ## HelpEsb.Message
// A data object representing an ESB message. Also provides some convenience
// methods.
// ### HelpEsb.Message *constructor*
// Initiates the message based on the given message object. Initializes the
// meta and data fields appropriately, including adding a message id if one
// does not exist.
HelpEsb.Message = function(message) {
this._data = _.has(message, 'data') ? message.data : {};
this._meta = _.extend({id: uuid.v4()}, message.meta);
};
// ### HelpEsb.Message.get
// Get the data property with the given dot-delimited path. For example,
//
// message = new HelpEsb.Message({foo: {bar: 'baz'}});
// message.get('foo.bar') === 'baz';
//
// You can also provide a default value to return instead of `undefined` for
// values that don't exist.
HelpEsb.Message.prototype.get = function(path, def) {
return objectPath.get(this._data, path, def);
};
// ### HelpEsb.Message.getMeta
// Like [get](#helpesb-message-get), but for the meta fields.
HelpEsb.Message.prototype.getMeta = function(path, def) {
return objectPath.get(this._meta, path, def);
};
// ### HelpEsb.Message.has
// Checks for the existence of the data proper with the given dot-delimited
// path.
HelpEsb.Message.prototype.has = function(path) {
return objectPath.has(this._data, path);
};
// ### HelpEsb.Message.hasMeta
// Like [has](#helpesb-message-has), but for the meta fields.
HelpEsb.Message.prototype.hasMeta = function(path) {
return objectPath.has(this._meta, path);
};
// ### HelpEsb.Message.toJSON
// Converts the message into its canonical form for JSON serialization.
HelpEsb.Message.prototype.toJSON = function() {
return {meta: this._meta, data: this._data};
};
return HelpEsb;
}));
{
"name": "help-esb",
"version": "0.5.1",
"version": "0.6.0",
"description": "A client for the Help.com team's ESB.",

@@ -13,4 +13,5 @@ "main": "help-esb.js",

"dependencies": {
"bluebird": "~2.3",
"bluebird": "~2.9",
"lodash": "~2.4",
"object-path": "~0.9.0",
"uuid": "~2.0"

@@ -17,0 +18,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc