UNPKG

postmailer

Version:

HTTP POST -> SMTP proxy, as Express middleware

120 lines (111 loc) 3.48 kB
var EventPlus = require('eventplus'); var UriTemplate = require('uri-templates'); function nameFromUrl(url) { return (url + "").replace(/.*?\:\/\//, ''); } function Transform(obj, options) { var receiveTemplates = [].concat(obj.receive || obj.url || []).map(function (spec) { if (typeof spec === 'string') return UriTemplate(spec); return spec; }); var sendTemplates = [].concat(obj.send || obj.url || []).map(function (spec) { if (typeof spec === 'string') return UriTemplate(spec); return spec; }); var canonicalTemplates = [].concat(obj.canonical || obj.url || obj.receive || []).map(function (spec) { if (typeof spec === 'string') return UriTemplate(spec); return spec; }); var allTemplates = receiveTemplates.concat(sendTemplates).concat(canonicalTemplates); var name = obj.name; var defaultParams = options.defaultParams || {}; function firstMatch(matchTemplates, replacementTemplates, urls) { urls = [].concat(urls); for (var i = 0; i < matchTemplates.length; i++) { for (var j = 0; j < urls.length; j++) { // TODO: normalise to mailto: addresses var url = urls[j]; var params = matchTemplates[i].fromUri(url); if (params) { var urls = []; replacementTemplates.forEach(function (template) { var url = template.fill(params); if (options.strict) { // Check round-trip consistency of params var roundTripParams = template.fromUri(url); for (var key in roundTripParams) { if (roundTripParams[key] != (params[key] || defaultParams[key])) { return; } } for (var key in params) { if (params[key] != (roundTripParams[key] || defaultParams[key])) { return; } } } urls.push(url); }); var match = { matchedUrl: url, urls: urls, params: params }; if (typeof name === 'function') { match.name = name(params, match); } else { match.name = name || nameFromUrl(match.urls[0]); } return match; } } } return null; } this.match = function (urls) { return firstMatch(receiveTemplates, sendTemplates, urls); }; this.canonical = function (url) { var match = firstMatch(allTemplates, canonicalTemplates, url); return match ? match.urls : []; } } Transform.prototype = {}; function Hub(options) { if (!(this instanceof Hub)) return new Hub(options); EventPlus.call(this); var transforms = [].concat(options.mapping || []).map(function (transformSpec) { return new Transform(transformSpec, options); }); this.match = function (urls) { for (var i = 0; i < transforms.length; i++) { var match = transforms[i].match(urls); if (match) return match; } return null; }; this.canonical = function (url) { var result = []; for (var i = 0; i < transforms.length; i++) { result = result.concat(transforms[i].canonical(urls)); } // Last option is original URL result.push(url); return result; }; // Mail and chat events must be handled this.on('mail', function (mail) { var error = new Error('Unhandled mail message for ' + mail.target.name); error.mail = mail; error.urls = mail.target.urls; this.emit('error', error); }); this.on('chat', function (chat) { var error = new Error('Unhandled chat message for ' + chat.target.name); error.chat = chat; error.urls = chat.target.urls; this.emit('error', error); }); } Hub.prototype = Object.create(EventPlus.prototype); module.exports = Hub;