正在显示
5 个修改的文件
包含
150 行增加
和
16 行删除
| ... | ... | @@ -165,6 +165,7 @@ app.listen(settings.port, function() { |
| 165 | 165 | |
| 166 | 166 | ## Components |
| 167 | 167 | |
| 168 | +* [email](#email) | |
| 168 | 169 | * [error-handler](#error-handler) |
| 169 | 170 | * [knex](#knex) |
| 170 | 171 | * [logger](#logger) |
| ... | ... | @@ -175,6 +176,31 @@ app.listen(settings.port, function() { |
| 175 | 176 | * [settings](#settings) |
| 176 | 177 | * [update-notifier](#update-notifier) |
| 177 | 178 | |
| 179 | ||
| 180 | + | |
| 181 | +> Returns a function which accepts templateName, locals, headers, transport, and callback arguments. This component uses | |
| 182 | + | |
| 183 | +[View source](lib/boot/email) | |
| 184 | + | |
| 185 | +```js | |
| 186 | +// example - email | |
| 187 | + | |
| 188 | +// TODO: finish this! | |
| 189 | + | |
| 190 | +// mention that transport defaults to settings.email.transport | |
| 191 | + | |
| 192 | +// mention that headers inherits settings.email.headers | |
| 193 | + | |
| 194 | +// but only if you don't set `headers.useDefaults: false` | |
| 195 | + | |
| 196 | +// note that is also uses `settings.email.templates` object | |
| 197 | +// which can have `dir` string and `options` object for node email-templates pkg | |
| 198 | + | |
| 199 | +// also document about having `transport` of `settings.email.transport` be an | |
| 200 | +// actual transporter already pre-created (possibly with plugins like html-to-text) | |
| 201 | + | |
| 202 | +``` | |
| 203 | + | |
| 178 | 204 | ### error-handler |
| 179 | 205 | |
| 180 | 206 | > Returns [Express][express] route middleware for error handling. | ... | ... |
lib/boot/email.js
0 → 100644
| 1 | + | |
| 2 | +// # boot - email | |
| 3 | + | |
| 4 | +var nodemailer = require('nodemailer') | |
| 5 | +var emailTemplates = require('email-templates') | |
| 6 | +var _ = require('underscore') | |
| 7 | + | |
| 8 | +exports = module.exports = function(settings) { | |
| 9 | + | |
| 10 | + // check to make sure we defined a default email object | |
| 11 | + if (!_.isObject(settings.email)) | |
| 12 | + throw new Error('Settings did not have an `email` object') | |
| 13 | + | |
| 14 | + // check to make sure settings.email.templates is defined | |
| 15 | + if (!_.isObject(settings.email.templates)) | |
| 16 | + throw new Error('Settings did not have a `settings.email.templates` object') | |
| 17 | + | |
| 18 | + // check to make sure settings.email.templates.dir is defined | |
| 19 | + if (!_.isString(settings.email.templates.dir)) | |
| 20 | + throw new Error('Settings did not have a `settings.email.templates.dir` string') | |
| 21 | + | |
| 22 | + var templateName, locals, headers, callback, transporter | |
| 23 | + | |
| 24 | + function renderTemplate(_templateName, _locals, _headers, transport, _callback) { | |
| 25 | + | |
| 26 | + templateName = _templateName | |
| 27 | + locals = _locals | |
| 28 | + headers = _headers | |
| 29 | + callback = _callback | |
| 30 | + | |
| 31 | + // add ability to override default transport defined in settings | |
| 32 | + if (_.isFunction(transport)) { | |
| 33 | + | |
| 34 | + // check to make sure we defined a default transport object | |
| 35 | + if (!_.isObject(settings.email.transport)) | |
| 36 | + throw new Error('Settings did not have an `email.transport` object') | |
| 37 | + | |
| 38 | + callback = transport | |
| 39 | + | |
| 40 | + // | |
| 41 | + // if the transport defined in settings is an actual transport | |
| 42 | + // (as opposed to just a config object) then we need to use that | |
| 43 | + // instead of creating a transport - to do so we'll look for the | |
| 44 | + // `.transporter` property that gets added to all transport objects | |
| 45 | + // <https://github.com/andris9/Nodemailer/blob/master/src/nodemailer.js#L39> | |
| 46 | + // | |
| 47 | + // the reason we have this support added is in case users add plugins to | |
| 48 | + // their transporter, for example the `nodemailer-html-to-text` plugin | |
| 49 | + // <https://github.com/andris9/nodemailer-html-to-text> | |
| 50 | + // | |
| 51 | + if (_.has(settings.email.transport, 'transporter')) | |
| 52 | + transporter = settings.email.transport | |
| 53 | + else | |
| 54 | + transporter = nodemailer.createTransport(settings.email.transport) | |
| 55 | + | |
| 56 | + } else { | |
| 57 | + transporter = nodemailer.createTransport(transport) | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (_.isObject(settings.email.templates.options)) | |
| 61 | + return emailTemplates(settings.email.templates.dir, settings.email.templates.options, createTemplate) | |
| 62 | + | |
| 63 | + emailTemplates(settings.email.templates.dir, createTemplate) | |
| 64 | + | |
| 65 | + } | |
| 66 | + | |
| 67 | + function createTemplate(err, template) { | |
| 68 | + if (err) throw err | |
| 69 | + template(templateName, locals, createEmail(headers)) | |
| 70 | + } | |
| 71 | + | |
| 72 | + function createEmail(headers) { | |
| 73 | + return function(err, html, text) { | |
| 74 | + if (err) return callback(err) | |
| 75 | + // if we defined a default headers object, then inherit it here | |
| 76 | + // but only if we didn't set `useDefaults` to false in the headers | |
| 77 | + if (_.isObject(settings.email.headers) && !headers.useDefaults) | |
| 78 | + headers = _.defaults(headers, settings.email.headers) | |
| 79 | + if (_.isString(html)) | |
| 80 | + headers.html = html | |
| 81 | + if (_.isString(text)) | |
| 82 | + headers.text = text | |
| 83 | + transporter.sendMail(headers, callback) | |
| 84 | + } | |
| 85 | + } | |
| 86 | + | |
| 87 | + return renderTemplate | |
| 88 | + | |
| 89 | +} | |
| 90 | + | |
| 91 | +exports['@singleton'] = true | |
| 92 | +exports['@require'] = [ 'igloo/settings' ] | ... | ... |
| ... | ... | @@ -53,9 +53,28 @@ exports = module.exports = function(settings) { |
| 53 | 53 | transports: transports |
| 54 | 54 | }) |
| 55 | 55 | |
| 56 | + if (settings.server.env === 'development') | |
| 57 | + logger = expandErrors(logger) | |
| 56 | 58 | |
| 57 | 59 | return logger |
| 58 | 60 | |
| 61 | + // Extend a winston by making it expand errors when passed in as the | |
| 62 | + // second argument (the first argument is the log level). | |
| 63 | + // <https://gist.github.com/johndgiese/59bd96360ce411042294> | |
| 64 | + // <https://gist.github.com/getvega/6211610> | |
| 65 | + function expandErrors(logger) { | |
| 66 | + var oldLogFunc = logger.log | |
| 67 | + logger.log = function() { | |
| 68 | + var args = Array.prototype.slice.call(arguments, 0) | |
| 69 | + if (args.length >= 2 && args[1] instanceof Error) { | |
| 70 | + args[1] = args[1].stack | |
| 71 | + } | |
| 72 | + return oldLogFunc.apply(this, args) | |
| 73 | + }; | |
| 74 | + return logger | |
| 75 | + } | |
| 76 | + | |
| 77 | + | |
| 59 | 78 | } |
| 60 | 79 | |
| 61 | 80 | exports['@singleton'] = true | ... | ... |
| ... | ... | @@ -5,20 +5,24 @@ var _ = require('underscore') |
| 5 | 5 | var util = require('util') |
| 6 | 6 | var mergeDefaults = require('merge-defaults') |
| 7 | 7 | |
| 8 | -exports = module.exports = function(config, local) { | |
| 8 | +exports = module.exports = function(IoC, config) { | |
| 9 | 9 | |
| 10 | 10 | var settings = {} |
| 11 | 11 | |
| 12 | 12 | var env = process.env.NODE_ENV || 'development' |
| 13 | 13 | |
| 14 | - if (!_.isObject(local)) | |
| 15 | - local = {} | |
| 16 | - | |
| 17 | - mergeDefaults(config, local) | |
| 18 | - | |
| 19 | 14 | if (!_.isObject(config[env])) |
| 20 | 15 | throw new Error(util.format('Unknown environment %s', env)) |
| 21 | 16 | |
| 17 | + if (env === 'development') { | |
| 18 | + try { | |
| 19 | + var local = IoC.create('local') | |
| 20 | + if (_.isObject(local)) | |
| 21 | + mergeDefaults(settings, local) | |
| 22 | + } catch(e) { | |
| 23 | + } | |
| 24 | + } | |
| 25 | + | |
| 22 | 26 | mergeDefaults(settings, config[env], config.defaults) |
| 23 | 27 | |
| 24 | 28 | return settings |
| ... | ... | @@ -26,13 +30,4 @@ exports = module.exports = function(config, local) { |
| 26 | 30 | } |
| 27 | 31 | |
| 28 | 32 | exports['@singleton'] = true |
| 29 | -exports['@require'] = ['config'] | |
| 30 | - | |
| 31 | -var fs = require('fs') | |
| 32 | -var path = require('path') | |
| 33 | -var localPath = path.join(__dirname, '..', '..', '..', '..' ,'boot', 'local.js') | |
| 34 | - | |
| 35 | -// Include local.js if it exists at boot/local.js | |
| 36 | -if (fs.existsSync(localPath)) { | |
| 37 | - exports['@require'].push('local') | |
| 38 | -} | |
| 33 | +exports['@require'] = [ '$container', 'config' ] | ... | ... |
| ... | ... | @@ -32,8 +32,10 @@ |
| 32 | 32 | "chalk": "^0.4.0", |
| 33 | 33 | "commander": "^2.2.0", |
| 34 | 34 | "connect-redis": "~2.0.0", |
| 35 | + "email-templates": "^1.1.2", | |
| 35 | 36 | "express-session": "^1.2.1", |
| 36 | 37 | "merge-defaults": "^0.1.0", |
| 38 | + "nodemailer": "^1.3.0", | |
| 37 | 39 | "to-camel-case": "^0.2.1", |
| 38 | 40 | "underscore": "^1.6.0", |
| 39 | 41 | "update-notifier": "^0.2.0", | ... | ... |
请
注册
或
登录
后发表评论