正在显示
5 个修改的文件
包含
150 行增加
和
16 行删除
| @@ -165,6 +165,7 @@ app.listen(settings.port, function() { | @@ -165,6 +165,7 @@ app.listen(settings.port, function() { | ||
| 165 | 165 | ||
| 166 | ## Components | 166 | ## Components |
| 167 | 167 | ||
| 168 | +* [email](#email) | ||
| 168 | * [error-handler](#error-handler) | 169 | * [error-handler](#error-handler) |
| 169 | * [knex](#knex) | 170 | * [knex](#knex) |
| 170 | * [logger](#logger) | 171 | * [logger](#logger) |
| @@ -175,6 +176,31 @@ app.listen(settings.port, function() { | @@ -175,6 +176,31 @@ app.listen(settings.port, function() { | ||
| 175 | * [settings](#settings) | 176 | * [settings](#settings) |
| 176 | * [update-notifier](#update-notifier) | 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 | ### error-handler | 204 | ### error-handler |
| 179 | 205 | ||
| 180 | > Returns [Express][express] route middleware for error handling. | 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,9 +53,28 @@ exports = module.exports = function(settings) { | ||
| 53 | transports: transports | 53 | transports: transports |
| 54 | }) | 54 | }) |
| 55 | 55 | ||
| 56 | + if (settings.server.env === 'development') | ||
| 57 | + logger = expandErrors(logger) | ||
| 56 | 58 | ||
| 57 | return logger | 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 | exports['@singleton'] = true | 80 | exports['@singleton'] = true |
| @@ -5,20 +5,24 @@ var _ = require('underscore') | @@ -5,20 +5,24 @@ var _ = require('underscore') | ||
| 5 | var util = require('util') | 5 | var util = require('util') |
| 6 | var mergeDefaults = require('merge-defaults') | 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 | var settings = {} | 10 | var settings = {} |
| 11 | 11 | ||
| 12 | var env = process.env.NODE_ENV || 'development' | 12 | var env = process.env.NODE_ENV || 'development' |
| 13 | 13 | ||
| 14 | - if (!_.isObject(local)) | ||
| 15 | - local = {} | ||
| 16 | - | ||
| 17 | - mergeDefaults(config, local) | ||
| 18 | - | ||
| 19 | if (!_.isObject(config[env])) | 14 | if (!_.isObject(config[env])) |
| 20 | throw new Error(util.format('Unknown environment %s', env)) | 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 | mergeDefaults(settings, config[env], config.defaults) | 26 | mergeDefaults(settings, config[env], config.defaults) |
| 23 | 27 | ||
| 24 | return settings | 28 | return settings |
| @@ -26,13 +30,4 @@ exports = module.exports = function(config, local) { | @@ -26,13 +30,4 @@ exports = module.exports = function(config, local) { | ||
| 26 | } | 30 | } |
| 27 | 31 | ||
| 28 | exports['@singleton'] = true | 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,8 +32,10 @@ | ||
| 32 | "chalk": "^0.4.0", | 32 | "chalk": "^0.4.0", |
| 33 | "commander": "^2.2.0", | 33 | "commander": "^2.2.0", |
| 34 | "connect-redis": "~2.0.0", | 34 | "connect-redis": "~2.0.0", |
| 35 | + "email-templates": "^1.1.2", | ||
| 35 | "express-session": "^1.2.1", | 36 | "express-session": "^1.2.1", |
| 36 | "merge-defaults": "^0.1.0", | 37 | "merge-defaults": "^0.1.0", |
| 38 | + "nodemailer": "^1.3.0", | ||
| 37 | "to-camel-case": "^0.2.1", | 39 | "to-camel-case": "^0.2.1", |
| 38 | "underscore": "^1.6.0", | 40 | "underscore": "^1.6.0", |
| 39 | "update-notifier": "^0.2.0", | 41 | "update-notifier": "^0.2.0", |
请
注册
或
登录
后发表评论