UNPKG

coffea

Version:

event based and extensible nodejs irc client library with multi-network support

244 lines (219 loc) 6.07 kB
/*jslint node: true*/ "use strict"; var CoffeaEvent = require('./event'); var Message = require('./parser/Message'); /** * Parse channel list `str`. * * @param {String} str * @return {Array} * @api private */ exports.channelList = function (str) { return str.split(',').map(function (chan) { return chan.toLowerCase(); }); }; /** * Parse nick from `msg`. * * @param {Object} msg * @return {String} * @api private */ exports.nick = function (msg) { return msg.prefix.split('!')[0]; }; /** * Emit the relevant events. * * @param {Object} instance * @param {String} network * @param {String} event * @param {Object} data * @param {Error} err * @return {Array} Array of Booleans - `true` if event has listeners. `false` otherwise. * @api private */ exports.emit = function (instance, network, event, data) { if (!data) { data = {}; } var err; // an Error was passed, emit it as error and reset data if (data instanceof Error) { err = data; data = {}; } var event_obj = new CoffeaEvent(instance, network); if (data instanceof Message) { event_obj._message = data; } for (var key in data) { if (data.hasOwnProperty(key)) { event_obj[key] = data[key]; } } event_obj.name = event; var retErr; if (err) { retErr = instance.emit('error', err, event_obj); } var ret1 = instance.emit(event, err, event_obj); var ret2 = instance.emit(network + ":" + event, err, event_obj); var ret3 = instance.emit('event', event, err, event_obj); return [ret1, ret2, ret3, retErr]; // Maybe this comes in very handy, I'm not too sure though. }; /** * Convert to array * * @param {String} val * @return {Array} * @api private */ exports.toArray = function (val) { return Array.isArray(val) ? val : [val]; }; /** * Extract network from User/Channel object * * @param {Object} target * @return {String} * @api private */ exports.extractNetwork = function extractNetwork(target) { if (typeof target.getNetwork === 'function') { return target.getNetwork(); } else { return; } }; /** * Convert target object to string * * @param {Object} target * @return {String} * @api private */ exports.targetString = function targetString(target) { if (target.client) { if (target.client.isUser(target)) { return target.getNick(); } else if (target.client.isChannel(target)) { return target.getName(); } else { return target.toString(); } } return target; }; /** * Parse target string/object * @param {object|string} target_raw * @return {object} {network: string, target: string} */ exports.parseTarget = function (target_raw) { var target, network; if (typeof target_raw !== "string") { // extract network from channel/user object network = exports.extractNetwork(target_raw); target = exports.targetString(target_raw); } else { if (target_raw.indexOf(':') > -1) { var splits = target_raw.split(':'); if (splits.length > 1) { network = splits[0]; target = splits[1]; } } else { target = target_raw; } } return {network: network, target: target}; }; /** * Merge the contents of two objects together into the first object. * * @param {Object} a * @param {Object} b * @return {Object} * @api private */ exports.extend = function (a, b) { for (var prop in b) { if (b.hasOwnProperty(prop)) { a[prop] = b[prop]; } } return a; }; /** * Inherit a class * * @param {Function} childClass * @param {Function} parentClass * @api private */ exports.inherit = function (childClass, parentClass) { var F = function(){}; // defining temp empty function F.prototype = parentClass.prototype; F.prototype.constructor = F; childClass.prototype = new F(); childClass.prototype.constructor = childClass; // restoring proper constructor for child class parentClass.prototype.constructor = parentClass; // restoring proper constructor for parent class childClass.prototype.parent = parentClass.prototype; // store parent }; /** * Internal function to strip a user defined message * to make sure it doesn't exceed the maximum size * * @param {string} leading leading string / irc command * @param {string} msg user defined message * @param {object} me user object * @param {Function} fn * @api private */ exports.stripMessage = function stripMessage(leading, msg, me, fn) { var maxlen = 512 - (1 + me.getNick().length + 1 + me.getUsername().length + 1 + me.getHostname().length + 1) - leading.length - 2; /*jslint regexp: true*/ msg.match(new RegExp('.{1,' + maxlen + '}', 'g')).forEach(function (str) { if (str[0] === ' ') { //leading whitespace str = str.substring(1); } if (str[str.length - 1] === ' ') { //trailing whitespace str = str.substring(0, str.length - 1); } fn(str); }); /*jslint regexp: false*/ }; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; var ARGUMENT_NAMES = /([^\s,]+)/g; /** * Internal function to get param names from a function * * @param {Function} func the function you want to get params from * @api private */ exports.getParamNames = function getParamNames(func) { var fnStr = func.toString().replace(STRIP_COMMENTS, ''); var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); if (result === null) { result = []; } return result; }; /** * SSL Error * * @param {string} message Error message * @api private */ exports.SSLError = function SSLError(message) { this.name = 'SSLError'; this.message = message || 'SSL Connection Error'; }; exports.SSLError.prototype = new Error(); exports.SSLError.prototype.constructor = exports.SSLError;