Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

email-templates

Package Overview
Dependencies
Maintainers
3
Versions
137
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

email-templates - npm Package Compare versions

Comparing version 2.0.0-beta.1 to 2.0.0-beta.2

examples/handlebars/index.js

13

lib/email-template.js

@@ -36,3 +36,5 @@ 'use strict';

var EmailTemplate = (function () {
function EmailTemplate(path, options) {
function EmailTemplate(path) {
var options = arguments[1] === undefined ? {} : arguments[1];
_classCallCheck(this, EmailTemplate);

@@ -43,2 +45,3 @@

this.dirname = (0, _path.basename)(path);
this.options = options;
debug('Creating Email template for path %s', (0, _path.basename)(path));

@@ -131,6 +134,6 @@ }

};
if (locals.juiceOptions) {
debug('Using juice options ', locals.juiceOptions);
juiceOptions = locals.juiceOptions || {};
juiceOptions.extraCss = (locals.juiceOptions.extraCss || '') + style;
if (_this4.options.juiceOptions) {
debug('Using juice options ', _this4.options.juiceOptions);
juiceOptions = _this4.options.juiceOptions || {};
juiceOptions.extraCss = (_this4.options.juiceOptions.extraCss || '') + style;
}

@@ -137,0 +140,0 @@ return (0, _juice2['default'])(html, juiceOptions);

@@ -49,3 +49,2 @@ 'use strict';

}
locals = (0, _lodash.defaults)(locals, options);
if (directory == null) {

@@ -55,3 +54,3 @@ return callback(new Error('templateName was not defined'));

var et = new _emailTemplate2['default']('' + templateDirectory + '/' + directory);
var et = new _emailTemplate2['default']('' + templateDirectory + '/' + directory, options);
if (locals === true) {

@@ -58,0 +57,0 @@ return callback(null, function (locals, dir, next) {

@@ -9,2 +9,7 @@ /**

Object.defineProperty(exports, '__esModule', {
value: true
});
exports.render = render;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

@@ -22,7 +27,5 @@

var _lodash = require('lodash');
var engineMap = {
// HTML Template engines
'hbs': _consolidate2['default'].handlebars.render,
'hbs': renderHbs,
'emblem': renderEmblem,

@@ -40,35 +43,43 @@ // CSS pre-processors

exports.render = function templateManager(filename, source, locals, callback) {
if (!source) return null;
function render(file, _x, callback) {
var locals = arguments[1] === undefined ? {} : arguments[1];
var filename = file.filename;
var content = file.content;
var engine = (0, _path.extname)(filename).slice(1);
locals.filename = filename;
locals.engine = '.' + engine;
return new _bluebird2['default'](function (resolve, reject) {
if (!content) return reject('No content in template');
if (!filename) return reject('Filename is null');
var engine = (0, _path.extname)(filename).slice(1);
return new _bluebird2['default'](function (resolve, reject) {
var fn;
locals.filename = filename;
locals.engine = '.' + engine;
locals.templatePath = (0, _path.dirname)(filename);
if (engine.length && _consolidate2['default'][engine] !== undefined) {
fn = _consolidate2['default'][engine].render;
// use consolidate.js if it supports this engine
return _consolidate2['default'][engine].render(content, locals, function (err, rendered) {
if (err) return reject(err);
resolve(rendered);
});
} else {
fn = engineMap[engine];
// or use the function defined in the engineMap
var fn = engineMap[engine];
return resolve(fn(content, locals));
}
if (!(0, _lodash.isFunction)(fn)) return reject('Can\'t render file with extension ' + engine);
fn(source, locals, function (err, rendered) {
if (err) return reject(err);
resolve(rendered);
});
return reject('Can\'t render file with extension ' + engine);
}).nodeify(callback);
};
}
// Deprecated. This engine is deprecated since v2.0
function renderEmblem(source, locals, cb) {
function renderEmblem(source, locals) {
var emblem = require('emblem');
var handlebars = require('handlebars');
console.warn('Please migrate your templates to other engine. Email Templates will stop supporting emblem on the next version');
var template = emblem.compile(handlebars, source);
cb(null, template(locals));
return _bluebird2['default'].resolve(template(locals));
}
// CSS pre-processors
function renderLess(source, locals, cb) {
function renderLess(source, locals) {
var less = require('less');

@@ -78,14 +89,14 @@ var dir = (0, _path.dirname)(locals.filename);

less.render(source, {
paths: [dir],
filename: base
}, function (err, output) {
if (err) {
return cb(err);
}
cb(null, output.css || output);
return new _bluebird2['default'](function (done, reject) {
less.render(source, {
paths: [dir],
filename: base
}, function (err, output) {
if (err) return reject(err);
done(output.css || output);
});
});
}
function renderStylus(source, locals, cb) {
function renderStylus(source, locals) {
var stylus = require('stylus');

@@ -96,12 +107,13 @@

var css = stylus.render(source, locals);
cb(null, css);
return _bluebird2['default'].resolve(css);
}
function renderStyl(source, locals, cb) {
function renderStyl(source, locals) {
var styl = require('styl');
cb(null, styl(source, locals).toString());
var css = styl(source, locals).toString();
return _bluebird2['default'].resolve(css);
}
function renderSass(source, locals, cb) {
function renderSass(source, locals) {
var sass = require('node-sass');

@@ -112,10 +124,22 @@

sass.render(locals, function (err, data) {
cb(err, data.css.toString());
return new _bluebird2['default'](function (done, reject) {
sass.render(locals, function (err, data) {
if (err) return reject(err);
done(data.css.toString());
});
});
}
function renderHbs(source, locals) {
return new _bluebird2['default'](function (done, reject) {
_consolidate2['default'].handlebars.render(source, locals, function (err, rendered) {
if (err) return reject(err);
done(rendered);
});
});
}
// Default wrapper for handling standard CSS and empty source.
function renderDefault(source, locals, cb) {
cb(null, source);
function renderDefault(source) {
return _bluebird2['default'].resolve(source);
}

@@ -24,4 +24,2 @@ 'use strict';

var _templateManager2 = _interopRequireDefault(_templateManager);
var readFileP = _bluebird2['default'].promisify(_fs.readFile);

@@ -56,3 +54,3 @@ var globP = _bluebird2['default'].promisify(_glob2['default']);

if (!file) return Promise.resolve(null);
return _templateManager2['default'].render(file.filename, file.content, options);
return (0, _templateManager.render)(file, options);
}
{
"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": "2.0.0-beta.1",
"version": "2.0.0-beta.2",
"author": "Nick Baugh <niftylettuce@gmail.com>",

@@ -55,3 +55,3 @@ "contributors": [

"compile": "babel src --modules common --out-dir lib",
"watch": "babel src --watch --modules common --out-dir lib",
"watch": "babel src --watch --modules common --out-dir lib --source-maps true",
"test": "mocha",

@@ -58,0 +58,0 @@ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",

@@ -11,6 +11,7 @@ import P from 'bluebird'

export default class EmailTemplate {
constructor (path, options) {
constructor (path, options = {}) {
this.files = {}
this.path = path
this.dirname = basename(path)
this.options = options
debug('Creating Email template for path %s', basename(path))

@@ -39,11 +40,11 @@ }

if (!html && !text) {
let err = new Error(`Neither html nor text template files found or are both empty in path ${this.dirname}`);
err.code = 'ENOENT';
throw err;
let err = new Error(`Neither html nor text template files found or are both empty in path ${this.dirname}`)
err.code = 'ENOENT'
throw err
}
if (html) {
debug('Found HTML file %s in %s', basename(html.filename), this.dirname);
debug('Found HTML file %s in %s', basename(html.filename), this.dirname)
}
this.files.html = html;
this.files.html = html

@@ -90,6 +91,6 @@ if (text) {

}
if (locals.juiceOptions) {
debug('Using juice options ', locals.juiceOptions)
juiceOptions = locals.juiceOptions || {}
juiceOptions.extraCss = (locals.juiceOptions.extraCss || '') + style
if (this.options.juiceOptions) {
debug('Using juice options ', this.options.juiceOptions)
juiceOptions = this.options.juiceOptions || {}
juiceOptions.extraCss = (this.options.juiceOptions.extraCss || '') + style
}

@@ -96,0 +97,0 @@ return juice(html, juiceOptions)

import {ensureDirectory} from './util'
import {isFunction, defaults} from 'lodash'
import {isFunction} from 'lodash'
import EmailTemplate from './email-template'

@@ -32,3 +32,2 @@ import Debug from 'debug'

}
locals = defaults(locals, options)
if (directory == null) {

@@ -38,3 +37,3 @@ return callback(new Error('templateName was not defined'))

var et = new EmailTemplate(`${templateDirectory}/${directory}`)
var et = new EmailTemplate(`${templateDirectory}/${directory}`, options)
if (locals === true) {

@@ -41,0 +40,0 @@ return callback(null, function (locals, dir, next) {

@@ -10,7 +10,6 @@ /**

import P from 'bluebird'
import {isFunction} from 'lodash'
var engineMap = {
// HTML Template engines
'hbs': cons.handlebars.render,
'hbs': renderHbs,
'emblem': renderEmblem,

@@ -28,21 +27,26 @@ // CSS pre-processors

exports.render = function templateManager (filename, source, locals, callback) {
if (!source) return null
export function render (file, locals = {}, callback) {
let {filename, content} = file
var engine = extname(filename).slice(1)
locals.filename = filename
locals.engine = '.' + engine
return new P(function (resolve, reject) {
if (!content) return reject('No content in template')
if (!filename) return reject('Filename is null')
let engine = extname(filename).slice(1)
return new P(function (resolve, reject) {
var fn
locals.filename = filename
locals.engine = '.' + engine
locals.templatePath = dirname(filename)
if (engine.length && cons[engine] !== undefined) {
fn = cons[engine].render
// use consolidate.js if it supports this engine
return cons[engine].render(content, locals, function (err, rendered) {
if (err) return reject(err)
resolve(rendered)
})
} else {
fn = engineMap[engine]
// or use the function defined in the engineMap
var fn = engineMap[engine]
return resolve(fn(content, locals))
}
if (!isFunction(fn)) return reject(`Can't render file with extension ${engine}`)
fn(source, locals, function (err, rendered) {
if (err) return reject(err)
resolve(rendered)
})
return reject(`Can't render file with extension ${engine}`)
})

@@ -53,12 +57,13 @@ .nodeify(callback)

// Deprecated. This engine is deprecated since v2.0
function renderEmblem (source, locals, cb) {
function renderEmblem (source, locals) {
const emblem = require('emblem')
const handlebars = require('handlebars')
console.warn('Please migrate your templates to other engine. Email Templates will stop supporting emblem on the next version')
var template = emblem.compile(handlebars, source)
cb(null, template(locals))
return P.resolve(template(locals))
}
// CSS pre-processors
function renderLess (source, locals, cb) {
function renderLess (source, locals) {
const less = require('less')

@@ -68,12 +73,14 @@ var dir = dirname(locals.filename)

less.render(source, {
paths: [dir],
filename: base
}, function (err, output) {
if (err) { return cb(err) }
cb(null, output.css || output)
return new P(function (done, reject) {
less.render(source, {
paths: [dir],
filename: base
}, function (err, output) {
if (err) return reject(err)
done(output.css || output)
})
})
}
function renderStylus (source, locals, cb) {
function renderStylus (source, locals) {
const stylus = require('stylus')

@@ -83,13 +90,14 @@

// calls properly when an error is generated.
var css = stylus.render(source, locals)
cb(null, css)
const css = stylus.render(source, locals)
return P.resolve(css)
}
function renderStyl (source, locals, cb) {
function renderStyl (source, locals) {
const styl = require('styl')
cb(null, styl(source, locals).toString())
const css = styl(source, locals).toString()
return P.resolve(css)
}
function renderSass (source, locals, cb) {
function renderSass (source, locals) {
const sass = require('node-sass')

@@ -100,10 +108,22 @@

sass.render(locals, function (err, data) {
cb(err, data.css.toString())
return new P(function (done, reject) {
sass.render(locals, function (err, data) {
if (err) return reject(err)
done(data.css.toString())
})
})
}
function renderHbs (source, locals) {
return new P(function (done, reject) {
cons.handlebars.render(source, locals, function (err, rendered) {
if (err) return reject(err)
done(rendered)
})
})
}
// Default wrapper for handling standard CSS and empty source.
function renderDefault (source, locals, cb) {
cb(null, source)
function renderDefault (source) {
return P.resolve(source)
}
import P from 'bluebird'
import {readFile, stat} from 'fs'
import glob from 'glob'
import tm from './template-manager'
import {render} from './template-manager'

@@ -38,4 +38,4 @@ const readFileP = P.promisify(readFile)

if (!file) return Promise.resolve(null)
return tm.render(file.filename, file.content, options)
return render(file, options)
}

@@ -102,4 +102,24 @@ /* global describe it beforeEach afterEach */

it('html with style element and juiceOptions', function (done) {
var html = '<style> h4 { color: red; }</style><h4><%= item %></h4>'
var css = 'h4 { color: blue; }'
fs.writeFileSync(path.join(templatePath, 'html.ejs'), html)
fs.writeFileSync(path.join(templatePath, 'style.ejs'), css)
var et = new EmailTemplate(templatePath, {
juiceOptions: { removeStyleTags: false }
})
et.render({ item: 'test' })
.then(function (results) {
expect(results.html).to.equal(
'<style> h4 { color: red; }</style><h4 style=\"color: blue;\">test</h4>')
done()
})
.catch(done)
})
})
})

@@ -230,5 +230,5 @@ /* global describe it beforeEach afterEach */

it('should render only text', function(done) {
var text = '<%= item%>';
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), text);
it('should render only text', function (done) {
var text = '<%= item%>'
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), text)

@@ -238,9 +238,9 @@ emailTemplates(templateDir, function (err, template) {

template(templateName, {item: 'test'}, function (err, html, text) {
expect(err).to.be.null;
expect(text).to.equal('test');
expect(html).to.not.be.ok;
done();
expect(err).to.be.null
expect(text).to.equal('test')
expect(html).to.not.be.ok
done()
})
})
});
})

@@ -260,5 +260,5 @@ it('on missing html and text file', function (done) {

it('on empty html and text file', function(done) {
fs.writeFileSync(path.join(templateDir, templateName, 'html.ejs'), '');
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), '');
it('on empty html and text file', function (done) {
fs.writeFileSync(path.join(templateDir, templateName, 'html.ejs'), '')
fs.writeFileSync(path.join(templateDir, templateName, 'text.ejs'), '')

@@ -270,8 +270,8 @@ emailTemplates(templateDir, function (err, template) {

expect(text).to.be.undefined
expect(err.message).to.contain('both empty in path');
expect(err.message).to.contain('both empty in path')
done()
})
})
});
})
})
})
})

@@ -24,9 +24,9 @@ /* global describe it beforeEach afterEach */

it('should render ejs', function (done) {
var opts = {
locals: {item: 'test'},
var file = {
filename: 'test.ejs',
source: '<h1><%= item%> <%= engine%></h1>'
content: '<h1><%= item%> <%= engine%></h1>'
}
var locals = {item: 'test'}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -40,12 +40,12 @@ expect(res).to.equal('<h1>test .ejs</h1>')

it('should render ejs with custom opening and closing tags', function (done) {
var opts = {
locals: {
item: 'test',
delimiter: '?'
},
var file = {
filename: 'test.ejs',
source: '<h1><?=item?> <?=engine?></h1>'
content: '<h1><?=item?> <?=engine?></h1>'
}
var locals = {
item: 'test',
delimiter: '?'
}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -58,9 +58,9 @@ expect(res).to.equal('<h1>test .ejs</h1>')

it('should render jade', function (done) {
var opts = {
locals: {item: 'test'},
var file = {
filename: 'test.jade',
source: 'h1= item\nh1= engine'
content: 'h1= item\nh1= engine'
}
var locals = {item: 'test'}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -74,9 +74,9 @@ expect(res).to.equal('<h1>test</h1><h1>.jade</h1>')

it('should render swig', function (done) {
var opts = {
locals: {item: 'test'},
var file = {
filename: 'test.swig',
source: '<h1>{{ item }} {{ engine }}</h1>'
content: '<h1>{{ item }} {{ engine }}</h1>'
}
var locals = {item: 'test'}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -90,9 +90,9 @@ expect(res).to.equal('<h1>test .swig</h1>')

it('should render handlebars', function (done) {
var opts = {
locals: {item: 'test'},
var file = {
filename: 'test.handlebars',
source: '<h1>{{ item }} {{ engine }}</h1>'
content: '<h1>{{ item }} {{ engine }}</h1>'
}
var locals = {item: 'test'}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -106,13 +106,14 @@ expect(res).to.equal('<h1>test .handlebars</h1>')

it('should render handlebars with helpers', function (done) {
var opts = {
locals: {
item: 'test',
helpers: {
uppercase: function (context) {return context.toUpperCase()}
}
},
var file = {
filename: 'test.hbs',
source: '<h1>{{uppercase item}} {{engine}}</h1>'
content: '<h1>{{uppercase item}} {{engine}}</h1>'
}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
var locals = {
item: 'test',
helpers: {
uppercase: function (context) {return context.toUpperCase()}
}
}
tm.render(file, locals, function (err, res) {
if (err) console.error(err.stack)
expect(err).to.be.null

@@ -125,9 +126,9 @@ expect(res).to.equal('<h1>TEST .hbs</h1>')

it('should render dust', function (done) {
var opts = {
locals: {item: 'test'},
var file = {
filename: 'test.dust',
source: '<h1>{item}\n</h1><h1>{engine}</h1>'
content: '<h1>{item}\n</h1><h1>{engine}</h1>'
}
var locals = {item: 'test'}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -141,9 +142,9 @@ expect(res).to.equal('<h1>test</h1><h1>.dust</h1>')

it('should render less', function (done) {
var opts = {
locals: {},
var file = {
filename: 'test.less',
source: '.class{ width: (1 + 1) }'
content: '.class{ width: (1 + 1) }'
}
var locals = {}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -164,9 +165,8 @@ expect(res).to.equal('.class {\n width: 2;\n}\n')

var opts = {
locals: {},
var file = {
filename: testMainLessFile,
source: fs.readFileSync(testMainLessFile).toString()
content: fs.readFileSync(testMainLessFile).toString()
}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, {}, function (err, res) {
expect(err).to.be.null

@@ -180,6 +180,7 @@ expect(res).to.equal('.body {\n color: #333333;\n}\n')

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) {
var file = {
filename: 'test.stylus',
content: 'body\n width: 2px\n'
}
tm.render(file, {}, function (err, res) {
expect(err).to.be.null

@@ -192,9 +193,9 @@ expect(res).to.equal('body {\n width: 2px;\n}\n')

it('should render styl', function (done) {
var opts = {
locals: {whitespace: true},
var file = {
filename: 'test.styl',
source: 'body\n color: blue'
content: 'body\n color: blue'
}
var locals = {whitespace: true}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, locals, function (err, res) {
expect(err).to.be.null

@@ -207,9 +208,8 @@ expect(res).to.equal('body {\n color: blue;\n}')

it('should render sass', function (done) {
var opts = {
locals: {},
var file = {
filename: 'test.sass',
source: '$gray: #ccc;body {color: $gray}'
content: '$gray: #ccc;body {color: $gray}'
}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, {}, function (err, res) {
expect(err).to.be.null

@@ -223,9 +223,8 @@ expect(res).to.equal('body {\n color: #ccc; }\n')

it('should render css', function (done) {
var opts = {
locals: {},
var file = {
filename: 'test.css',
source: 'body { color: #ccc; }'
content: 'body { color: #ccc; }'
}
tm.render(opts.filename, opts.source, opts.locals, function (err, res) {
tm.render(file, {}, function (err, res) {
expect(err).to.be.null

@@ -232,0 +231,0 @@ expect(res).to.equal('body { color: #ccc; }')

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc