UNPKG

hermesjs

Version:

Real-time messaging framework

205 lines (182 loc) 6.21 kB
class HermesRouter { /** * Instantiates a HermesRouter. * * @param {Object} options * @param {String} [options.pathSeparator='/'] The character to use when joining paths. */ constructor (options) { this.options = { ...{ pathSeparator: '/' }, ...options }; this.middlewares = []; this.outboundMiddlewares = []; this.errorMiddlewares = []; this.outboundErrorMiddlewares = []; } /** * Use a middleware for inbound messages. Please, note that when passing a HermesRouter as a param, * this function will make use of inbound and outbound middlewares. * * @param {String} [topic] The topic you want to scope the middleware to. * @param {Function|HermesRouter} ...middlewares A function or HermesRouter to use as a middleware. */ use (...args) { if (!args || !args.length) { console.error(`HermesRouter.use() requires at least one argument.`); return; } if (args.length === 1 && args[0] instanceof HermesRouter) { this.addMiddlewares(args[0].getMiddlewares()); this.addErrorMiddlewares(args[0].getErrorMiddlewares()); this.addOutboundMiddlewares(args[0].getOutboundMiddlewares()); this.addOutboundErrorMiddlewares(args[0].getOutboundErrorMiddlewares()); } else if (args.length === 2 && typeof args[0] === 'string' && args[1] instanceof HermesRouter) { this.addMiddlewares(args[1].getMiddlewares(), args[0]); this.addErrorMiddlewares(args[1].getErrorMiddlewares(), args[0]); this.addOutboundMiddlewares(args[1].getOutboundMiddlewares(), args[0]); this.addOutboundErrorMiddlewares(args[1].getOutboundErrorMiddlewares(), args[0]); } else { let topic; let functions = []; if (typeof args[0] === 'string') { topic = args[0]; functions = args.splice(1); } else { functions = args; } const mws = functions.map(fn => ({ topic, fn })); mws.forEach(mw => { if (typeof mw.fn !== 'function') return; if (mw.fn.length <= 2) { this.addMiddlewares([mw]); } else { this.addErrorMiddlewares([mw]); } }); } } /** * Use a middleware for outbound messages. * * @param {String} [topic] The topic you want to scope the middleware to. * @param {Function|HermesRouter} ...middlewares A function or HermesRouter to use as a middleware. */ useOutbound (...args) { if (!args || !args.length) { console.error(`HermesRouter.useOutbound() requires at least one argument.`); return; } if (args.length === 1 && args[0] instanceof HermesRouter) { this.addOutboundMiddlewares(args[0].getOutboundMiddlewares()); this.addOutboundErrorMiddlewares(args[0].getOutboundErrorMiddlewares()); } else if (args.length === 2 && typeof args[0] === 'string' && args[1] instanceof HermesRouter) { this.addOutboundMiddlewares(args[1].getOutboundMiddlewares(), args[0]); this.addOutboundErrorMiddlewares(args[1].getOutboundErrorMiddlewares(), args[0]); } else { let topic; let functions = []; if (typeof args[0] === 'string') { topic = args[0]; functions = args.splice(1); } else { functions = args; } const mws = functions.map(fn => ({ topic, fn })); mws.forEach(mw => { if (typeof mw.fn !== 'function') return; if (mw.fn.length <= 2) { this.addOutboundMiddlewares([mw]); } else { this.addOutboundErrorMiddlewares([mw]); } }); } } /** * Returns all the inbound middlewares. * @return {Array<Function>} */ getMiddlewares () { return this.middlewares; } /** * Returns all the outbound middlewares. * @return {Array<Function>} */ getOutboundMiddlewares () { return this.outboundMiddlewares; } /** * Returns all the inbound error middlewares. * @return {Array<Function>} */ getErrorMiddlewares () { return this.errorMiddlewares; } /** * Returns all the outbound error middlewares. * @return {Array<Function>} */ getOutboundErrorMiddlewares () { return this.outboundErrorMiddlewares; } /** * Adds a normalized middleware to a target collection. * * @param {Array} target The target collection. * @param {Array} middlewares The middlewares to add to the collection. * @param {String} [topic] The scope topic. * @private */ _addMiddlewares (target, middlewares, topic) { middlewares.forEach(mw => { if (topic) { const compoundTopic = mw.topic ? `${topic}${this.options.pathSeparator}${mw.topic}` : topic; target.push({ ...mw, ...{ topic: compoundTopic } }); } else { target.push(mw); } }); } /** * Adds a normalized middleware to the inbound middlewares collection. * * @param {Array} middlewares The middlewares to add to the collection. * @param {String} [topic] The scope topic. */ addMiddlewares (middlewares, topic) { this._addMiddlewares(this.middlewares, middlewares, topic); } /** * Adds a normalized middleware to the outbound middlewares collection. * * @param {Array} middlewares The middlewares to add to the collection. * @param {String} [topic] The scope topic. */ addOutboundMiddlewares (middlewares, topic) { this._addMiddlewares(this.outboundMiddlewares, middlewares, topic); } /** * Adds a normalized middleware to the inbound error middlewares collection. * * @param {Array} errorMiddlewares The middlewares to add to the collection. * @param {String} [topic] The scope topic. */ addErrorMiddlewares (errorMiddlewares, topic) { this._addMiddlewares(this.errorMiddlewares, errorMiddlewares, topic); } /** * Adds a normalized middleware to the outbound error middlewares collection. * * @param {Array} errorMiddlewares The middlewares to add to the collection. * @param {String} [topic] The scope topic. */ addOutboundErrorMiddlewares (errorMiddlewares, topic) { this._addMiddlewares(this.outboundErrorMiddlewares, errorMiddlewares, topic); } } module.exports = HermesRouter;