email-templates
Advanced tools
Comparing version 1.3.0 to 2.0.0-beta
@@ -39,54 +39,45 @@ /** | ||
*/ | ||
var path = require('path'), | ||
templatesDir = path.resolve(__dirname, '..', 'templates'), | ||
emailTemplates = require('../../'), | ||
nodemailer = require('nodemailer'), | ||
kue = require('kue'); | ||
var path = require('path') | ||
var templatesDir = path.resolve(__dirname, '..', 'templates') | ||
var EmailTemplate = require('../../').EmailTemplate | ||
var nodemailer = require('nodemailer') | ||
var kue = require('kue') | ||
var EventEmitter = require('events').EventEmitter | ||
var events = require("events"); | ||
var deliver = new events.EventEmitter(); | ||
var deliver = new EventEmitter() | ||
var jobs = kue.createQueue() | ||
kue.app.listen(3000) | ||
var jobs = kue.createQueue(); | ||
kue.app.listen(3000); | ||
jobs.process('postbox', function (job, done) { | ||
deliver.emit(job.data.template, job.data, done) | ||
}) | ||
jobs.process('postbox', function(job, done) { | ||
deliver.emit(job.data.template, job.data, done); | ||
}); | ||
var template = new EmailTemplate(path.join(templatesDir, 'newsletter')) | ||
var transport = nodemailer.createTransport({ | ||
service: 'Gmail', | ||
auth: { | ||
user: 'some-user@gmail.com', | ||
pass: 'some-password' | ||
} | ||
}) | ||
deliver.on('newsletter', function (data, done) { | ||
template.render(data.params, function (err, results) { | ||
if (err) return done(err) | ||
emailTemplates(templatesDir, function(err, template) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
// Prepare nodemailer transport object | ||
var transport = nodemailer.createTransport("SMTP", { | ||
service: "Gmail", | ||
auth: { | ||
user: "some-user@gmail.com", | ||
pass: "some-password" | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: data.to, | ||
subject: data.title, | ||
html: results.html, | ||
text: results.text | ||
}, function (err, responseStatus) { | ||
if (err) { | ||
console.error(err) | ||
return done(err) | ||
} | ||
}); | ||
template('newsletter', true, function(err, batch) { | ||
deliver.on('newsletter', function(data, done) { | ||
batch(data.params, templatesDir, function(err, html, text) { | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: data.to, | ||
subject: data.title, | ||
html: html, | ||
text: text | ||
}, function(err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
done(err); | ||
} else { | ||
done(); | ||
console.log(responseStatus.message); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
console.log(responseStatus.message) | ||
done() | ||
}) | ||
}) | ||
}) |
@@ -6,128 +6,92 @@ | ||
var path = require('path') | ||
, templatesDir = path.resolve(__dirname, '..', 'templates') | ||
, emailTemplates = require('../../') | ||
, nodemailer = require('nodemailer'); | ||
// // **NOTE**: Did you know `nodemailer` can also be used to send SMTP email through Mandrill, Mailgun, Sendgrid and Postmark? | ||
// <https://github.com/andris9/nodemailer-wellknown#supported-services> | ||
emailTemplates(templatesDir, function(err, template) { | ||
var path = require('path') | ||
var EmailTemplate = require('../../').EmailTemplate | ||
var nodemailer = require('nodemailer') | ||
var wellknown = require('nodemailer-wellknown') | ||
var async = require('async') | ||
var templatesDir = path.resolve(__dirname, '..', 'templates') | ||
var template = new EmailTemplate(path.join(templatesDir, 'newsletter')) | ||
// Prepare nodemailer transport object | ||
var transport = nodemailer.createTransport({ | ||
service: 'sendgrid', | ||
auth: { | ||
user: 'some-user@gmail.com', | ||
pass: 'some-password' | ||
} | ||
}) | ||
// An example users object with formatted email function | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
} | ||
// Send a single email | ||
template.render(locals, function (err, results) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
return console.error(err) | ||
} | ||
// ## Send a single email | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: locals.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: results.html, | ||
text: results.text | ||
}, function (err, responseStatus) { | ||
if (err) { | ||
return console.error(err) | ||
} | ||
console.log(responseStatus.message) | ||
}) | ||
}) | ||
// Prepare nodemailer transport object | ||
var transport = nodemailer.createTransport("SMTP", { | ||
service: "Gmail", | ||
auth: { | ||
user: "some-user@gmail.com", | ||
pass: "some-password" | ||
} | ||
}); | ||
// ## Send a batch of emails and only load the template once | ||
// An example users object with formatted email function | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
}; | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
} | ||
] | ||
// Send a single email | ||
template('newsletter', locals, function(err, html, text) { | ||
// Send 10 mails at once | ||
async.mapLimit(users, 10, function (item, next) { | ||
template.render(item, function (err, results) { | ||
if (err) return next(err) | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: item.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: results.html, | ||
text: results.text | ||
}, function (err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: locals.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: html, | ||
// generateTextFromHTML: true, | ||
text: text | ||
}, function(err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(responseStatus.message); | ||
} | ||
}); | ||
return next(err) | ||
} | ||
}); | ||
// ## Send a batch of emails and only load the template once | ||
// Prepare nodemailer transport object | ||
var transportBatch = nodemailer.createTransport("SMTP", { | ||
service: "Gmail", | ||
auth: { | ||
user: "some-user@gmail.com", | ||
pass: "some-password" | ||
} | ||
}); | ||
// An example users object | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
} | ||
]; | ||
// Custom function for sending emails outside the loop | ||
// | ||
// NOTE: | ||
// We need to patch postmark.js module to support the API call | ||
// that will let us send a batch of up to 500 messages at once. | ||
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>) | ||
var Render = function(locals) { | ||
this.locals = locals; | ||
this.send = function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
transportBatch.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: locals.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: html, | ||
// generateTextFromHTML: true, | ||
text: text | ||
}, function(err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(responseStatus.message); | ||
} | ||
}); | ||
} | ||
}; | ||
this.batch = function(batch) { | ||
batch(this.locals, templatesDir, this.send); | ||
}; | ||
}; | ||
// Load the template and send the emails | ||
template('newsletter', true, function(err, batch) { | ||
for(var user in users) { | ||
var render = new Render(users[user]); | ||
render.batch(batch); | ||
} | ||
}); | ||
next(null, responseStatus.message) | ||
}) | ||
}) | ||
}, function (err) { | ||
if (err) { | ||
console.error(err) | ||
} | ||
}); | ||
console.log('Succesfully sent %d messages', users.length) | ||
}) |
@@ -9,3 +9,3 @@ | ||
// **NOTE**: Did you know `nodemailer` can also be used to send SMTP email through Postmark? | ||
// <https://github.com/andris9/Nodemailer#well-known-services-for-smtp> | ||
// <https://github.com/andris9/nodemailer-wellknown#supported-services> | ||
@@ -15,109 +15,81 @@ // For more message format options, see Postmark's developer documentation section: | ||
var path = require('path') | ||
, templatesDir = path.resolve(__dirname, '..', 'templates') | ||
, emailTemplates = require('../../') | ||
, postmark = require('postmark')('your-api-key'); | ||
var path = require('path') | ||
var EmailTemplate = require('../../').EmailTemplate | ||
var postmark = require('postmark') | ||
var _ = require('lodash') | ||
emailTemplates(templatesDir, function(err, template) { | ||
var templatesDir = path.resolve(__dirname, '..', 'templates') | ||
var client = new postmark.Client('your-server-key') | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
} | ||
// ## Send a single email | ||
var template = new EmailTemplate(path.join(templatesDir, 'newsletter')) | ||
// An example users object with formatted email function | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
}; | ||
// Send a single email | ||
template(locals, function (err, results) { | ||
if (err) { | ||
return console.error(err) | ||
} | ||
client.sendEmail({ | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: locals.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: results.html, | ||
TextBody: results.text | ||
}, function (err, response) { | ||
if (err) { | ||
console.error(err.status) | ||
console.error(err.message) | ||
return | ||
} | ||
console.log(response) | ||
}) | ||
}) | ||
// Send a single email | ||
template('newsletter', locals, function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
postmark.send({ | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: locals.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: html, | ||
TextBody: text | ||
}, function(err, response) { | ||
if (err) { | ||
console.log(err.status); | ||
console.log(err.message); | ||
} else { | ||
console.log(response); | ||
} | ||
}); | ||
} | ||
}); | ||
// Send a batch of emails and only load the template once | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
} | ||
] | ||
// ## Send a batch of emails and only load the template once | ||
// An example users object | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
// use promises this time. Use your favorite library such as bluebird | ||
// or use the native Promise included in node > 0.12 and io.js | ||
Promise.all(_.map(users, function (user) { | ||
return template.render(user) | ||
.then(function (results) { | ||
return { | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: user.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: results.html, | ||
TextBody: results.text | ||
} | ||
]; | ||
}) | ||
})) | ||
.then(function (messages) { | ||
client.sendEmailBatch(messages, function (err, batchResults) { | ||
// Throwing inside a promise will just reject the promise | ||
// not stop your server | ||
if (err) throw err | ||
// Custom function for sending emails outside the loop | ||
// | ||
// NOTE: | ||
// We need to patch postmark.js module to support the API call | ||
// that will let us send a batch of up to 500 messages at once. | ||
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>) | ||
var Render = function(locals) { | ||
this.locals = locals; | ||
this.send = function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
postmark.send({ | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: locals.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: html, | ||
TextBody: text | ||
}, function(err, response) { | ||
if (err) { | ||
console.log(err.status); | ||
console.log(err.message); | ||
} else { | ||
console.log(response); | ||
} | ||
}); | ||
} | ||
}; | ||
this.batch = function(batch) { | ||
batch(this.locals, templatesDir, this.send); | ||
}; | ||
}; | ||
// Load the template and send the emails | ||
template('newsletter', true, function(err, batch) { | ||
for(var user in users) { | ||
var render = new Render(users[user]); | ||
render.batch(batch); | ||
} | ||
}); | ||
} | ||
}); | ||
console.info('Messages sent to postmark') | ||
}) | ||
}) |
@@ -1,2 +0,1 @@ | ||
module.exports = require('./lib/main'); | ||
module.exports = require('./lib/main') |
287
lib/main.js
@@ -1,256 +0,75 @@ | ||
// node-email-templates | ||
// Copyright (c) 2012 Nick Baugh <niftylettuce@gmail.com> | ||
// MIT Licensed | ||
'use strict'; | ||
// Node.js module for rendering beautiful emails with [ejs][1] templates | ||
// and email-friendly inline CSS using [juice][2]. | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
// * Author: [@niftylettuce](https://twitter.com/#!/niftylettuce) | ||
// * Source: <https://github.com/niftylettuce/node-email-templates> | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
// # node-email-templates | ||
var _util = require('./util'); | ||
var path = require('path') | ||
, fs = require('fs') | ||
, async = require('async') | ||
, juice = require('juice') | ||
, glob = require('glob') | ||
, zlib = require('zlib') | ||
, _ = require('lodash') | ||
, tm = require('./templateManager') | ||
var _lodash = require('lodash'); | ||
var validBufferTypes = [ 'deflate', 'deflateRaw', 'gzip' ] | ||
var _emailTemplate = require('./email-template'); | ||
// # Email Template | ||
var EmailTemplate = function(templateDirectory, defaults, done) { | ||
var _emailTemplate2 = _interopRequireDefault(_emailTemplate); | ||
if (typeof defaults === 'function') done = defaults; | ||
var _debug = require('debug'); | ||
var that = this; | ||
var _debug2 = _interopRequireDefault(_debug); | ||
this.render = function(locals, templatePath, html, text, stylesheet, bufferType, callback) { | ||
// Check if `bufferType` is a function (callback), or string | ||
var isBuffer = false | ||
if (typeof bufferType === 'function') { | ||
callback = bufferType | ||
} else if (typeof bufferType === 'string') { | ||
// Ensure that `bufferType` is a valid `zlib` compression type | ||
if (_.contains(validBufferTypes, bufferType)) { | ||
throw new Error('`zlib.' + bufferType + '` does not exist or is not a valid buffer type') | ||
} else { | ||
isBuffer = true | ||
} | ||
} | ||
var _path = require('path'); | ||
// Check if `bufferType` is not an empty string, so we'll use the | ||
// global bufferType instead. | ||
if (this.bufferType !== '') { | ||
isBuffer = true | ||
bufferType = this.bufferType | ||
} | ||
var _consolidate = require('consolidate'); | ||
if (typeof html === 'function') { | ||
callback = html; | ||
html = this.html; | ||
} | ||
if (!html) html = this.html | ||
if (!text) text = this.text | ||
if (!stylesheet) stylesheet = this.stylesheet | ||
locals = _.defaults(locals, (typeof defaults === 'object') ? defaults : {}); | ||
locals.templatePath = this.templatePath | ||
var debug = (0, _debug2['default'])('email-templates:creator'); | ||
// Configure options for template and stylesheet files. | ||
var htmlOpts = { source: html, locals: locals } | ||
, textOpts = { source: text, locals: locals } | ||
, cssOpts = { source: stylesheet, locals: locals }; | ||
htmlOpts.filename = glob.sync(path.join(locals.templatePath, '*html.*'))[0]; | ||
textOpts.filename = glob.sync(path.join(locals.templatePath, '*text.*'))[0]; | ||
cssOpts.filename = glob.sync(path.join(locals.templatePath, '*style.*'))[0]; | ||
// Render all templates and stylesheets. | ||
async.map([htmlOpts, textOpts, cssOpts], tm.render.bind(tm), function(err, results) { | ||
if (err) return callback(err) | ||
html = results[0] | ||
text = results[1] | ||
stylesheet = results[2] | ||
// Make a copy of the juiceOptions object so we can add the stylesheet. | ||
var juiceOptions = (typeof locals.juiceOptions === 'object' ? _.assign({}, locals.juiceOptions) : {}) | ||
juiceOptions.extraCss = (juiceOptions.extraCss || "") + stylesheet | ||
// Inject available styles into HTML. | ||
html = (stylesheet) ? juice(html, juiceOptions) : html | ||
// Return a compressed buffer if needed. | ||
if (isBuffer) { | ||
async.map([ new Buffer(html), new Buffer(text) ], zlib[bufferType], function(err, buffers) { | ||
if (err) return callback(err) | ||
html = buffers[0] | ||
text = buffers[1] | ||
callback(null, html, text) | ||
}) | ||
}else { | ||
callback(null, html, text) | ||
} | ||
}) | ||
}; | ||
// Ensure the `templateDirectory` is not undefined | ||
if (typeof templateDirectory === 'undefined') | ||
function exportable(templateDirectory, options, done) { | ||
if ((0, _lodash.isFunction)(options)) { | ||
done = options; | ||
options = {}; | ||
} | ||
if (!templateDirectory) { | ||
return done(new Error('templateDirectory is undefined')); | ||
} | ||
// Ensure the `templateDirectory` is a valid directory path | ||
fs.stat(templateDirectory, function(err, stats) { | ||
return (0, _util.ensureDirectory)(templateDirectory, function (err) { | ||
if (err) return done(err); | ||
debug('Creating Email Templates in %s', (0, _path.basename)(templateDirectory)); | ||
return done(null, template(templateDirectory, options)); | ||
}); | ||
} | ||
if (err) return done(new Error(err)); | ||
function template(templateDirectory, options) { | ||
return function _template(directory, locals, callback) { | ||
if ((0, _lodash.isFunction)(locals)) { | ||
callback = locals; | ||
locals = {}; | ||
} | ||
locals = (0, _lodash.defaults)(locals, options); | ||
if (directory == null) { | ||
return callback(new Error('templateName was not defined')); | ||
} | ||
if (!stats.isDirectory()) | ||
return done(new Error('templateDirectory is not a valid directory path')); | ||
done(null, function(templateName, locals, bufferType, callback) { | ||
var scopeInfo = { | ||
'templatePath': '', | ||
'stylesheet': '', | ||
'text': '', | ||
'html': '', | ||
'bufferType':'' | ||
}; | ||
// Check if `bufferType` is a function (callback), or string | ||
var isBuffer = false | ||
if (typeof bufferType === 'function') { | ||
callback = bufferType | ||
} else if (typeof bufferType === 'string') { | ||
// Ensure that `bufferType` is a valid `zlib` compression type | ||
if (_.contains(validBufferTypes, bufferType)) { | ||
throw new Error('`zlib.' + bufferType + '` does not exist or is not a valid buffer type') | ||
} else { | ||
isBuffer = true | ||
} | ||
} | ||
// Fallback if user doesn't pass all the args | ||
var batchEmail = false; | ||
if (typeof locals !== 'undefined' && typeof locals === 'function') { | ||
callback = locals; | ||
locals = {}; | ||
} else if (typeof callback !== 'undefined' && typeof callback === 'function') { | ||
if (typeof locals === 'undefined' || !locals instanceof Object) { | ||
locals = {}; | ||
} else if (locals === true) { | ||
// We are trying to load the template into memory, but not render it | ||
// This lets us send batches of emails using the same template | ||
// and we only are loading the assets once | ||
batchEmail = true; | ||
} | ||
} | ||
// Batch load function | ||
var batchCheck = function() { | ||
if (batchEmail) { | ||
if (isBuffer) scopeInfo.bufferType = bufferType | ||
return callback(null, that.render.bind(scopeInfo)); | ||
} | ||
if (isBuffer) { | ||
that.render.call(scopeInfo, locals, templatePath, null, null, null, bufferType, callback); | ||
} else { | ||
that.render.call(scopeInfo, locals, templatePath, null, null, null, callback); | ||
} | ||
}; | ||
// Ensure the `templateName` is valid | ||
if (templateName === undefined) return callback('templateName was not defined'); | ||
// Set the full path to the template | ||
var templatePath = scopeInfo.templatePath = path.join(templateDirectory, templateName); | ||
// Ensure the `templateName` is a valid directory path | ||
fs.stat(templatePath, function(err, stats) { | ||
if (err) return callback(err); | ||
if (!stats.isDirectory()) | ||
return callback(templatePath + ' is not a valid directory path'); | ||
// Ensure that at least an html file exists inside | ||
scopeInfo.html = glob.sync(templatePath + '/*html.*')[0] || ''; | ||
fs.stat(scopeInfo.html, function(err, stats) { | ||
if (err) return callback(err); | ||
if (!stats.isFile()) return callback(scopeInfo.html + ' is not a valid file path'); | ||
// Read the html file | ||
fs.readFile(scopeInfo.html, 'utf8', function(err, data) { | ||
if (err) return callback(err); | ||
if (data === '') return callback(scopeInfo.html + ' was an empty file'); | ||
else scopeInfo.html = data; | ||
// Set asset paths | ||
scopeInfo.text = glob.sync(templatePath + '/*text.*')[0] || ''; | ||
scopeInfo.stylesheet = glob.sync(templatePath + '/*style.*')[0] || ''; | ||
async.map([scopeInfo.text, scopeInfo.stylesheet], checkExists, function(err, results) { | ||
if (err) return callback(err); | ||
if (!results[0]) scopeInfo.text = false | ||
if (!results[1]) scopeInfo.stylesheet = false | ||
if (scopeInfo.text && scopeInfo.stylesheet) { | ||
async.map([scopeInfo.text, scopeInfo.stylesheet], fs.readFile, function(err, results) { | ||
if (err) return callback(err); | ||
results[0] = results[0].toString('utf8'); | ||
results[1] = results[1].toString('utf8'); | ||
if (results[0] === '') scopeInfo.text = false; | ||
if (results[1] === '') scopeInfo.stylesheet = false; | ||
scopeInfo.text = results[0]; | ||
scopeInfo.stylesheet = results[1]; | ||
batchCheck(); | ||
}); | ||
} else if (scopeInfo.text && !scopeInfo.stylesheet) { | ||
fs.readFile(scopeInfo.text, 'utf8', function(err, data) { | ||
if (err) return callback(err); | ||
if (data === '') return callback(scopeInfo.text + ' was empty'); | ||
scopeInfo.text = data; | ||
batchCheck(); | ||
}); | ||
} else if (!scopeInfo.text && scopeInfo.stylesheet) { | ||
fs.readFile(scopeInfo.stylesheet, 'utf8', function(err, data) { | ||
if (err) return callback(err); | ||
if (data === '') return callback(scopeInfo.stylesheet + ' was empty'); | ||
scopeInfo.stylesheet = data; | ||
batchCheck(); | ||
}); | ||
} else { | ||
batchCheck(); | ||
} | ||
}); | ||
}); | ||
var et = new _emailTemplate2['default']('' + templateDirectory + '/' + directory); | ||
if (locals === true) { | ||
return callback(null, function (locals, dir, next) { | ||
et.render(locals, function (err, result) { | ||
result = result || {}; | ||
next(err, result.html, result.text); | ||
}); | ||
}); | ||
}); | ||
function checkExists(item, callback) { | ||
function cb(exists) { | ||
return callback(null, exists) | ||
} | ||
// node >= v0.8.x | ||
if (fs.exists) return fs.exists(item, cb) | ||
// other versions of node fallback to path.exists | ||
return path.exists(item, cb) | ||
} | ||
et.render(locals, function (err, result) { | ||
result = result || {}; | ||
callback(err, result.html, result.text); | ||
}); | ||
}; | ||
} | ||
}); | ||
}; | ||
exportable.EmailTemplate = _emailTemplate2['default']; | ||
exportable.requires = _consolidate.requires; | ||
module.exports = function(templateDirectory, defaults, done) { | ||
return new EmailTemplate(templateDirectory, defaults, done); | ||
}; | ||
exports['default'] = exportable; | ||
module.exports = exports['default']; |
{ | ||
"name": "email-templates", | ||
"description": "Node.js module for rendering beautiful emails with ejs, jade, swig, hbs, or handlebars templates and email-friendly inline CSS using juice.", | ||
"version": "1.3.0", | ||
"version": "2.0.0-beta", | ||
"author": "Nick Baugh <niftylettuce@gmail.com>", | ||
@@ -53,35 +53,41 @@ "contributors": [ | ||
"scripts": { | ||
"prepublish": "npm prune", | ||
"test": "mocha --reporter spec --bail --require test/support/should test/", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --require test/support/should test/", | ||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --require test/support/should test/" | ||
"prepublish": "npm run compile && npm prune", | ||
"compile": "babel src --modules common --out-dir lib", | ||
"watch": "babel src --watch --modules common --out-dir lib", | ||
"test": "mocha", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot", | ||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly" | ||
}, | ||
"dependencies": { | ||
"bluebird": "^2.9.25", | ||
"consolidate": "^0.12.0", | ||
"debug": "^2.2.0", | ||
"glob": "^5.0.0", | ||
"juice": "^1.0.0", | ||
"consolidate": "^0.11.0", | ||
"async": "^0.9.0", | ||
"lodash": "^3.5.0", | ||
"glob": "^4.0.0" | ||
"lodash": "^3.5.0" | ||
}, | ||
"devDependencies": { | ||
"nodemailer": "^0.3.44", | ||
"postmark": "^0.1.8", | ||
"mocha": "^2.1.0", | ||
"async": "^0.9.0", | ||
"babel": "^5.4.3", | ||
"chai": "^2.0.0", | ||
"mkdirp": "^0.3.5", | ||
"rimraf": "^2.2.8", | ||
"ejs": "^1.0.0", | ||
"swig": "^1.3.2", | ||
"dustjs-linkedin": "^2.4.0", | ||
"ejs": "^2.3.0", | ||
"handlebars": "^3.0.0", | ||
"istanbul": "^0.3.2", | ||
"jade": "^1.3.1", | ||
"handlebars": "^1.3.0", | ||
"emblem": "~0.3.16", | ||
"dustjs-linkedin": "^2.4.0", | ||
"less": "^1.7.0", | ||
"stylus": "^0.45.1", | ||
"styl": "^0.2.7", | ||
"less": "^2.5.0", | ||
"mkdirp": "^0.5.1", | ||
"mocha": "^2.1.0", | ||
"node-sass": "^3.1.1", | ||
"nodemailer": "^1.3.4", | ||
"nodemailer-wellknown": "^0.1.5", | ||
"postmark": "^1.0.0", | ||
"rimraf": "^2.2.8", | ||
"sinon": "^1.10.2", | ||
"sinon-chai": "^2.7.0", | ||
"istanbul": "^0.3.2" | ||
"styl": "^0.2.7", | ||
"stylus": "^0.51.1", | ||
"swig": "^1.3.2" | ||
}, | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -88,0 +94,0 @@ "url": "https://github.com/niftylettuce/node-email-templates/issues/new" |
351
Readme.md
@@ -11,2 +11,3 @@ | ||
[![Gitter][gitter-image]][gitter-url] | ||
[![js-standard-style][standard-image]][standard-url] | ||
@@ -56,7 +57,2 @@ Node.js NPM package for rendering beautiful emails with your template engine and CSS pre-processor of choice coupled with email-friendly inline CSS using [juice][juice]. | ||
This module depends on [jsdom](https://github.com/tmpvar/jsdom) which requires the ability to compile C++ on your localhost. Before installing, please verify that you have the prerequisites installed for your OS. | ||
* [OSX requirements](https://github.com/tmpvar/jsdom#mac) | ||
* [Linux requirements](https://github.com/tmpvar/jsdom#linux) | ||
#### Important Note for Windows Users | ||
@@ -72,9 +68,6 @@ | ||
```bash | ||
npm install -S email-templates | ||
``` | ||
Install `email-templates` and the engines you wish to use by adding them to your `package.json` dependencies. | ||
> Starting with version `1.1.1` you must install the engines you wish to use by adding them to your `package.json` dependencies. | ||
```bash | ||
npm install --save email-templates | ||
npm install -S [ejs|jade|swig|handlebars|emblem|dust-linkedin] | ||
@@ -89,29 +82,23 @@ ``` | ||
```bash | ||
npm install -S email-templates | ||
npm install --save email-templates@2 | ||
``` | ||
2. Install the template engine you intend to use: | ||
- `ejs@^1.0.0` | ||
- `jade@^1.3.1` | ||
- `swig@^1.3.2` | ||
- `handlebars@^1.3.0` | ||
- `emblem@~0.3.16` | ||
- `dust-linkedin@^2.4.0` | ||
- `less@^1.7.0` | ||
- `stylus@^^0.45.1` | ||
- `styl@^0.2.7` | ||
- `node-sass@^3.1.1` | ||
- `ejs@^2.0.0` | ||
- `jade@^1.9.0` | ||
- `swig@^1.4.2` | ||
- `handlebars@^3.0.0` | ||
- `dust-linkedin@^2.7.0` | ||
```bash | ||
npm install -S <engine> | ||
``` | ||
- `less@^2.5.0` | ||
- `stylus@^^0.51.0` | ||
- `styl@^0.2.9` | ||
- `node-sass@^3.0.0` | ||
3. Create a folder called `templates` inside your root directory (or elsewhere). | ||
```bash | ||
mkdir templates | ||
npm install --save <engine> | ||
``` | ||
4. For each of your email templates (e.g. a welcome email to send to users when they register on your site), respectively name and create a folder inside the `templates` folder. | ||
3. For each of your email templates (e.g. a welcome email to send to users when they register on your site), respectively name and create a folder. | ||
@@ -122,3 +109,3 @@ ```bash | ||
5. Add the following files inside the template's folder: | ||
4. Add the following files inside the template's folder: | ||
* `html.{{ext}}` (**required**) | ||
@@ -132,7 +119,5 @@ * `text.{{ext}}` (**optional**) | ||
6. You may use the `include` directive from [ejs][ejs] (for example, to include a common header or footer). See the `/examples` folder for details. | ||
5. You may use the `include` directive from [ejs][ejs] (for example, to include a common header or footer). See the `/examples` folder for details. | ||
7. Utilize one of the examples below for your respective email module and start sending beautiful emails! | ||
## Template Engine Options | ||
@@ -144,9 +129,7 @@ | ||
```js | ||
// ... | ||
emailTemplates(templatesDir, { open: '{{', close: '}}' }, function(err, template) { | ||
// ... | ||
```javascript | ||
emailTemplates(templatesDir, { delimiter: '?' }, function (err, template) { | ||
``` | ||
> You can also pass <a href="https://github.com/visionmedia/ejs#options" target="_blank">other options from EJS's documentation</a>. | ||
> You can also pass <a href="https://github.com/mde/ejs#options" target="_blank">other options from EJS's documentation</a>. | ||
@@ -174,2 +157,34 @@ Want to add a helper or partial to Handlebars? | ||
Render a single template (having only loaded the template once). | ||
```js | ||
var EmailTemplate = require('email-templates').EmailTemplate | ||
var path = require('path') | ||
var templateDir = path.join(__dirname, 'templates', 'newsletter') | ||
var newsletter = new EmailTemplate(templateDir) | ||
var user = {name: 'Joe', pasta: 'spaghetti'} | ||
newsletter.render(user, function (err, results) { | ||
// result.html | ||
// result.text | ||
}) | ||
var async = require('async') | ||
var users = [ | ||
{name: 'John', pasta: 'Rigatoni'}, | ||
{name: 'Luca', pasta: 'Tortellini'} | ||
] | ||
async.each(users, function (user, next) { | ||
newsletter.render(user, function (err, results) { | ||
if (err) return next(err) | ||
// result.html | ||
// result.text | ||
}) | ||
}, function (err) { | ||
// | ||
}) | ||
``` | ||
Render a template for a single email or render multiple (having only loaded the template once). | ||
@@ -179,4 +194,4 @@ | ||
var path = require('path') | ||
, templatesDir = path.join(__dirname, 'templates') | ||
, emailTemplates = require('email-templates'); | ||
var templatesDir = path.join(__dirname, 'templates') | ||
var emailTemplates = require('email-templates'); | ||
@@ -236,258 +251,6 @@ emailTemplates(templatesDir, function(err, template) { | ||
### [Nodemailer][nodemailer] | ||
### More | ||
```js | ||
var path = require('path') | ||
, templatesDir = path.resolve(__dirname, '..', 'templates') | ||
, emailTemplates = require('email-templates') | ||
, nodemailer = require('nodemailer'); | ||
Please check the [examples directory](https://github.com/niftylettuce/node-email-templates/tree/master/examples) | ||
emailTemplates(templatesDir, function(err, template) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
// ## Send a single email | ||
// Prepare nodemailer transport object | ||
var transport = nodemailer.createTransport("SMTP", { | ||
service: "Gmail", | ||
auth: { | ||
user: "some-user@gmail.com", | ||
pass: "some-password" | ||
} | ||
}); | ||
// An example users object with formatted email function | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
}; | ||
// Send a single email | ||
template('newsletter', locals, function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
transport.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: locals.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: html, | ||
// generateTextFromHTML: true, | ||
text: text | ||
}, function(err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(responseStatus.message); | ||
} | ||
}); | ||
} | ||
}); | ||
// ## Send a batch of emails and only load the template once | ||
// Prepare nodemailer transport object | ||
var transportBatch = nodemailer.createTransport("SMTP", { | ||
service: "Gmail", | ||
auth: { | ||
user: "some-user@gmail.com", | ||
pass: "some-password" | ||
} | ||
}); | ||
// An example users object | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
} | ||
]; | ||
// Custom function for sending emails outside the loop | ||
// | ||
// NOTE: | ||
// We need to patch postmark.js module to support the API call | ||
// that will let us send a batch of up to 500 messages at once. | ||
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>) | ||
var Render = function(locals) { | ||
this.locals = locals; | ||
this.send = function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
transportBatch.sendMail({ | ||
from: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
to: locals.email, | ||
subject: 'Mangia gli spaghetti con polpette!', | ||
html: html, | ||
// generateTextFromHTML: true, | ||
text: text | ||
}, function(err, responseStatus) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
console.log(responseStatus.message); | ||
} | ||
}); | ||
} | ||
}; | ||
this.batch = function(batch) { | ||
batch(this.locals, templatesDir, this.send); | ||
}; | ||
}; | ||
// Load the template and send the emails | ||
template('newsletter', true, function(err, batch) { | ||
for(var user in users) { | ||
var render = new Render(users[user]); | ||
render.batch(batch); | ||
} | ||
}); | ||
} | ||
}); | ||
``` | ||
### [Postmark][postmark] | ||
This example utilizes [Postmark.js][postmarkjs]. | ||
> Did you know `nodemailer` can also be used to send SMTP email through Postmark? See [this section][nodemailer-smtp] of their Readme for more info. | ||
For more message format options, see [this section][postmark-msg-format] of Postmark's developer documentation section. | ||
```js | ||
var path = require('path') | ||
, templatesDir = path.resolve(__dirname, '..', 'templates') | ||
, emailTemplates = require('email-templates') | ||
, postmark = require('postmark')('your-api-key'); | ||
emailTemplates(templatesDir, function(err, template) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
// ## Send a single email | ||
// An example users object with formatted email function | ||
var locals = { | ||
email: 'mamma.mia@spaghetti.com', | ||
name: { | ||
first: 'Mamma', | ||
last: 'Mia' | ||
} | ||
}; | ||
// Send a single email | ||
template('newsletter', locals, function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
postmark.send({ | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: locals.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: html, | ||
TextBody: text | ||
}, function(err, response) { | ||
if (err) { | ||
console.log(err.status); | ||
console.log(err.message); | ||
} else { | ||
console.log(response); | ||
} | ||
}); | ||
} | ||
}); | ||
// ## Send a batch of emails and only load the template once | ||
// An example users object | ||
var users = [ | ||
{ | ||
email: 'pappa.pizza@spaghetti.com', | ||
name: { | ||
first: 'Pappa', | ||
last: 'Pizza' | ||
} | ||
}, | ||
{ | ||
email: 'mister.geppetto@spaghetti.com', | ||
name: { | ||
first: 'Mister', | ||
last: 'Geppetto' | ||
} | ||
} | ||
]; | ||
// Custom function for sending emails outside the loop | ||
// | ||
// NOTE: | ||
// We need to patch postmark.js module to support the API call | ||
// that will let us send a batch of up to 500 messages at once. | ||
// (e.g. <https://github.com/diy/trebuchet/blob/master/lib/index.js#L160>) | ||
var Render = function(locals) { | ||
this.locals = locals; | ||
this.send = function(err, html, text) { | ||
if (err) { | ||
console.log(err); | ||
} else { | ||
postmark.send({ | ||
From: 'Spicy Meatball <spicy.meatball@spaghetti.com>', | ||
To: locals.email, | ||
Subject: 'Mangia gli spaghetti con polpette!', | ||
HtmlBody: html, | ||
TextBody: text | ||
}, function(err, response) { | ||
if (err) { | ||
console.log(err.status); | ||
console.log(err.message); | ||
} else { | ||
console.log(response); | ||
} | ||
}); | ||
} | ||
}; | ||
this.batch = function(batch) { | ||
batch(this.locals, templatesDir, this.send); | ||
}; | ||
}; | ||
// Load the template and send the emails | ||
template('newsletter', true, function(err, batch) { | ||
for(user in users) { | ||
var render = new Render(users[user]); | ||
render.batch(batch); | ||
} | ||
}); | ||
} | ||
}); | ||
``` | ||
## Conventions | ||
See [nifty-conventions][nifty-conventions] for code guidelines, general project requirements, and git workflow. | ||
## Contributors | ||
@@ -545,1 +308,3 @@ | ||
[transactional-email-templates]: https://github.com/mailgun/transactional-email-templates | ||
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat | ||
[standard-url]: https://github.com/feross/standard |
@@ -1,13 +0,13 @@ | ||
var tm = require('../lib/templateManager') | ||
, path = require('path') | ||
, expect = require('chai').expect | ||
, fs = require('fs') | ||
, tmpDir = path.join(__dirname, '..', '.tmproj') | ||
, mkdirp = require('mkdirp') | ||
, rimraf = require('rimraf') | ||
/* global describe it beforeEach afterEach */ | ||
var tm = require('../src/template-manager') | ||
var path = require('path') | ||
var expect = require('chai').expect | ||
var fs = require('fs') | ||
var tmpDir = path.join(__dirname, '..', '.test-templates') | ||
var mkdirp = require('mkdirp') | ||
var rimraf = require('rimraf') | ||
describe('Template manager', function() { | ||
///////////////////////////////////////////////////////////////////////////// | ||
describe('Template manager', function () { | ||
// Setup | ||
beforeEach(function(done) { | ||
beforeEach(function (done) { | ||
// Setup a tmp directory for test files. | ||
@@ -17,3 +17,3 @@ mkdirp(tmpDir, done) | ||
afterEach(function(done) { | ||
afterEach(function (done) { | ||
// Destroy all test files. | ||
@@ -23,5 +23,4 @@ rimraf(tmpDir, done) | ||
///////////////////////////////////////////////////////////////////////////// | ||
// Tests | ||
it('should render ejs', function(done) { | ||
it('should render ejs', function (done) { | ||
var opts = { | ||
@@ -33,5 +32,5 @@ locals: {item: 'test'}, | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test .ejs</h1>'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('<h1>test .ejs</h1>') | ||
@@ -46,10 +45,9 @@ done() | ||
item: 'test', | ||
open: '{{', | ||
close: '}}' | ||
delimiter: '?' | ||
}, | ||
filename: 'test.ejs', | ||
source: '<h1>{{=item}} {{=engine}}</h1>' | ||
source: '<h1><?=item?> <?=engine?></h1>' | ||
} | ||
tm.render(opts, function(err, res) { | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
@@ -61,3 +59,3 @@ expect(res).to.equal('<h1>test .ejs</h1>') | ||
it('should render jade', function(done) { | ||
it('should render jade', function (done) { | ||
var opts = { | ||
@@ -69,5 +67,5 @@ locals: {item: 'test'}, | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test</h1><h1>.jade</h1>'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('<h1>test</h1><h1>.jade</h1>') | ||
@@ -78,3 +76,3 @@ done() | ||
it('should render swig', function(done) { | ||
it('should render swig', function (done) { | ||
var opts = { | ||
@@ -86,5 +84,5 @@ locals: {item: 'test'}, | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test .swig</h1>'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('<h1>test .swig</h1>') | ||
@@ -95,3 +93,3 @@ done() | ||
it('should render handlebars', function(done) { | ||
it('should render handlebars', function (done) { | ||
var opts = { | ||
@@ -103,5 +101,5 @@ locals: {item: 'test'}, | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test .handlebars</h1>'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('<h1>test .handlebars</h1>') | ||
@@ -112,3 +110,3 @@ done() | ||
it ('should render handlebars with helpers', function(done) { | ||
it('should render handlebars with helpers', function (done) { | ||
var opts = { | ||
@@ -118,9 +116,9 @@ locals: { | ||
helpers: { | ||
uppercase: function(context) {return context.toUpperCase()} | ||
uppercase: function (context) {return context.toUpperCase()} | ||
} | ||
}, | ||
filename: 'test.hbs', | ||
source: '<h1>{{uppercase item}} {{engine}}</h1>', | ||
source: '<h1>{{uppercase item}} {{engine}}</h1>' | ||
} | ||
tm.render(opts, function(err, res) { | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
@@ -132,20 +130,5 @@ expect(res).to.equal('<h1>TEST .hbs</h1>') | ||
it('should render emblem', function(done) { | ||
it('should render dust', function (done) { | ||
var opts = { | ||
locals: {item: 'test'}, | ||
filename: 'test.emblem', | ||
source: 'h1 {{ item }}\nh1 {{ engine }}' | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test</h1><h1>.emblem</h1>'); | ||
done() | ||
}) | ||
}) | ||
it('should render dust', function(done) { | ||
var opts = { | ||
locals: {item: 'test'}, | ||
filename: 'test.dust', | ||
@@ -155,5 +138,5 @@ source: '<h1>{item}\n</h1><h1>{engine}</h1>' | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('<h1>test</h1><h1>.dust</h1>'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('<h1>test</h1><h1>.dust</h1>') | ||
@@ -164,12 +147,12 @@ done() | ||
it('should render less', function(done) { | ||
it('should render less', function (done) { | ||
var opts = { | ||
locals : {}, | ||
filename : 'test.less', | ||
source : '.class{ width: (1 + 1) }' | ||
locals: {}, | ||
filename: 'test.less', | ||
source: '.class{ width: (1 + 1) }' | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('.class {\n width: 2;\n}\n'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('.class {\n width: 2;\n}\n') | ||
@@ -180,3 +163,3 @@ done() | ||
it('should render less with @import statement', function(done) { | ||
it('should render less with @import statement', function (done) { | ||
var testMainLessFile = path.join(tmpDir, 'main.less') | ||
@@ -190,10 +173,10 @@ var testIncludesFile = path.join(tmpDir, 'includes.less') | ||
var opts = { | ||
locals : {}, | ||
filename : testMainLessFile, | ||
source : fs.readFileSync(testMainLessFile).toString() | ||
locals: {}, | ||
filename: testMainLessFile, | ||
source: fs.readFileSync(testMainLessFile).toString() | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('.body {\n color: #333333;\n}\n'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('.body {\n color: #333333;\n}\n') | ||
@@ -204,22 +187,22 @@ done() | ||
it('should render stylus', function(done) { | ||
var opts = {locals: {}}; | ||
opts.filename = 'test.stylus'; | ||
opts.source = 'body\n width: 2px\n'; | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('body {\n width: 2px;\n}\n'); | ||
done(); | ||
it('should render stylus', function (done) { | ||
var opts = {locals: {}} | ||
opts.filename = 'test.stylus' | ||
opts.source = 'body\n width: 2px\n' | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('body {\n width: 2px;\n}\n') | ||
done() | ||
}) | ||
}) | ||
it('should render styl', function(done) { | ||
it('should render styl', function (done) { | ||
var opts = { | ||
locals : {whitespace: true}, | ||
filename : 'test.styl', | ||
source : 'body\n color: blue' | ||
locals: {whitespace: true}, | ||
filename: 'test.styl', | ||
source: 'body\n color: blue' | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('body {\n color: blue;\n}') | ||
@@ -230,12 +213,12 @@ done() | ||
it('should render sass', function(done) { | ||
it('should render sass', function (done) { | ||
var opts = { | ||
locals : {}, | ||
filename : 'test.sass', | ||
source : '$gray: #ccc;body {color: $gray}' | ||
locals: {}, | ||
filename: 'test.sass', | ||
source: '$gray: #ccc;body {color: $gray}' | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('body {\n color: #ccc; }\n'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('body {\n color: #ccc; }\n') | ||
@@ -246,12 +229,12 @@ done() | ||
it('should render css', function(done) { | ||
it('should render css', function (done) { | ||
var opts = { | ||
locals : {}, | ||
filename : 'test.css', | ||
source : 'body { color: #ccc; }' | ||
locals: {}, | ||
filename: 'test.css', | ||
source: 'body { color: #ccc; }' | ||
} | ||
tm.render(opts, function(err, res) { | ||
expect(err).to.be.null; | ||
expect(res).to.equal('body { color: #ccc; }'); | ||
tm.render(opts.filename, opts.source, opts.locals, function (err, res) { | ||
expect(err).to.be.null | ||
expect(res).to.equal('body { color: #ccc; }') | ||
@@ -258,0 +241,0 @@ done() |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
215517
44
1756
6
21
1
299
5
1
+ Addedbluebird@^2.9.25
+ Addeddebug@^2.2.0
+ Addedbluebird@2.11.0(transitive)
+ Addedconsolidate@0.12.1(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addedglob@5.0.15(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedms@2.0.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
- Removedasync@^0.9.0
- Removedconsolidate@0.11.0(transitive)
- Removedglob@4.5.3(transitive)
- Removedminimatch@2.0.10(transitive)
Updatedconsolidate@^0.12.0
Updatedglob@^5.0.0