Skip to content

Commit ff75d4f

Browse files
committed
feat: added support for stream attachments (closes forwardemail/email-templates#383)
1 parent d0faba8 commit ff75d4f

File tree

6 files changed

+201
-132
lines changed

6 files changed

+201
-132
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@babel/runtime": "^7.6.3",
2424
"dayjs": "^1.8.16",
2525
"debug": "^4.1.1",
26+
"mailparser": "^2.7.7",
2627
"nodemailer": "^6.3.1",
2728
"open": "^6.4.0",
2829
"pify": "^4.0.1",

src/index.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
const fs = require('fs');
22
const os = require('os');
33
const path = require('path');
4-
const debug = require('debug')('preview-email');
4+
55
const dayjs = require('dayjs');
6+
const debug = require('debug')('preview-email');
67
const nodemailer = require('nodemailer');
78
const open = require('open');
89
const pify = require('pify');
910
const pug = require('pug');
1011
const uuid = require('uuid');
12+
const { simpleParser } = require('mailparser');
1113

1214
const writeFile = pify(fs.writeFile);
1315

1416
const transport = nodemailer.createTransport({
15-
jsonTransport: true
17+
streamTransport: true,
18+
buffer: true
1619
});
1720

1821
const templateFilePath = path.join(__dirname, '..', 'template.pug');
@@ -34,11 +37,14 @@ const previewEmail = async (message, options) => {
3437

3538
const res = await transport.sendMail(message);
3639

37-
res.message = JSON.parse(res.message);
40+
const parsed = await simpleParser(res.message);
41+
42+
console.log('parsed', parsed);
43+
console.log('parsed.attachments', parsed.attachments);
3844

3945
const html = await renderFilePromise(
4046
options.template,
41-
Object.assign(res.message, {
47+
Object.assign(parsed, {
4248
cache: true,
4349
pretty: true,
4450
dayjs

template.pug

Lines changed: 25 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ html
1010
style(type='text/css').
1111
body {
1212
font-family: arial, sans-serif;
13-
}
14-
h1 {
15-
font-size: 18px;
16-
padding: 10px;
17-
font-weight: normal;
13+
padding-left: 20px;
14+
padding-right: 20px;
1815
}
1916
table {
2017
padding-left: 10px;
@@ -31,7 +28,6 @@ html
3128
padding: 6px 16px 6px 0
3229
}
3330
iframe {
34-
margin: 0 auto;
3531
border: 0;
3632
height: 100%;
3733
width: 100%;
@@ -40,129 +36,31 @@ html
4036
display: block;
4137
border: 1px solid black;
4238
}
43-
p {
44-
text-align: center;
45-
}
4639

4740
body
48-
49-
if subject
50-
h1= subject
51-
hr
52-
table
53-
if from
54-
tr
55-
th from
56-
td= `${from.name} <${from.address}>`.trim()
57-
if to
58-
tr
59-
th to
60-
td
61-
if Array.isArray(to)
62-
each t, ti in to
63-
= `${t.name} <${t.address}>`.trim()
64-
if to.length - 1 !== ti
65-
= ', '
66-
else
67-
= `${to.name} <${to.address}>`.trim()
68-
if cc
69-
tr
70-
th cc
71-
td
72-
if Array.isArray(cc)
73-
each c, ci in cc
74-
= `${c.name} <${c.address}>`.trim()
75-
if cc.length - 1 !== ci
76-
= ', '
77-
else
78-
= `${cc.name} <${cc.address}>`.trim()
79-
if bcc
80-
tr
81-
th bcc
82-
td
83-
if Array.isArray(bcc)
84-
each bc, bci in bcc
85-
= `${bc.name} <${bc.address}>`.trim()
86-
if bcc.length - 1 !== bci
87-
= ', '
88-
else
89-
= `${bcc.name} <${bcc.address}>`.trim()
90-
if subject
91-
tr
92-
th subject
93-
td: strong= subject
94-
if attachments && attachments.length > 0
95-
tr
96-
th attachments
97-
td
98-
ul
99-
each a in attachments
100-
li
101-
a(href=`data:${a.contentType}${a.encoding ? `;${a.encoding}` : ''},${a.content}`, download=a.filename, target='_blank')
102-
if a.filename
103-
= `${a.filename}`
104-
else
105-
= 'Unnamed file'
106-
if sender
107-
tr
108-
th sender
109-
td= sender
110-
if replyTo
111-
tr
112-
th replyTo
113-
td
114-
if Array.isArray(replyTo)
115-
each t, ti in replyTo
116-
= `${t.name} <${t.address}>`.trim()
117-
if to.length - 1 !== ti
118-
= ', '
119-
else
120-
= `${replyTo.name} <${replyTo.address}>`.trim()
121-
if inReplyTo
122-
tr
123-
th inReplyTo
124-
td= inReplyTo
125-
if references
126-
tr
127-
th references
128-
if Array.isArray(references)
129-
td= references.join(', ')
130-
else
131-
td= references
132-
if messageId
133-
tr
134-
th messageId
135-
td= messageId
136-
if !date
137-
- date = new Date()
138-
tr
139-
th date
140-
td= dayjs(date).format('ddd, MMM D, YYYY') + ' at ' + dayjs(date).format('h:mm A')
141-
if headers && typeof headers === 'object' && Object.keys(headers).length > 0
142-
tr
143-
th headers
144-
td
145-
each header, hi in Object.keys(headers)
146-
strong= `${header}: `
147-
= headers[header]
148-
if Object.keys(headers).length - 1 !== hi
149-
= ', '
150-
if list && typeof list === 'object' && Object.keys(list).length > 0
151-
tr
152-
th list
153-
td
154-
each key, ki in Object.keys(list)
155-
strong= `${key}: `
156-
if typeof list[key] === 'object'
157-
= list[key].url
41+
if headers.get('subject')
42+
p: strong Subject:
43+
p= headers.get('subject')
44+
p: strong Headers:
45+
pre
46+
code
47+
each headerLine, i in headerLines
48+
= headerLine.line
49+
if i < headerLines.length - 1
50+
br
51+
if attachments && attachments.length > 0
52+
p: strong Attachments:
53+
ul
54+
each a in attachments
55+
li
56+
a(href=`data:${a.contentType};base64,${a.content.toString('base64')}`, download=a.filename, target='_blank')
57+
if a.filename
58+
= `${a.filename}`
15859
else
159-
= list[key]
160-
if Object.keys(list).length - 1 !== ki
161-
= ', '
162-
hr
60+
= 'Unnamed file'
16361
if html
164-
iframe(seamless='seamless', srcdoc=`<base target='_top'>${html}`)
62+
p: strong HTML:
63+
p: iframe(seamless='seamless', srcdoc=`<base target='_top'>${html}`)
16564
if text
166-
hr
167-
p: small TEXT VERSION:
168-
iframe(seamless='seamless', srcdoc=`<pre>${text}</pre>`)
65+
p: strong TEXT:
66+
p: iframe(seamless='seamless', srcdoc=`<pre>${text}</pre>`)

test/test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
const fs = require('fs');
12
const path = require('path');
3+
24
const test = require('ava');
35
const nodemailer = require('nodemailer');
46

@@ -22,7 +24,11 @@ test('opens a preview email', async t => {
2224
attachments: [
2325
{ filename: 'hello-world.txt', content: 'Hello world' },
2426
{ path: path.join(__dirname, '..', '.editorconfig') },
25-
{ path: path.join(__dirname, '..', 'demo.png') }
27+
{ path: path.join(__dirname, '..', 'demo.png') },
28+
{
29+
filename: 'test.txt',
30+
content: fs.createReadStream(path.join(__dirname, 'test.txt'))
31+
}
2632
],
2733
headers: {
2834
'X-Some-Custom-Header': 'Some Custom Value'

test/test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world

0 commit comments

Comments
 (0)