@storecraft/mailer-smtp 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/index.js +77 -0
- package/index.utils.js +15 -0
- package/jsconfig.json +10 -0
- package/package.json +36 -0
- package/tests/test.js +32 -0
- package/types.public.d.ts +9 -0
package/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# SMTP proxy client for Node.js
|
2
|
+
|
3
|
+
<div style="text-align:center">
|
4
|
+
<img src='https://storecraft.app/storecraft-color.svg'
|
5
|
+
width='90%' />
|
6
|
+
</div><hr/><br/>
|
7
|
+
|
8
|
+
## Features
|
9
|
+
- Send emails using a known smtp server
|
10
|
+
- uses `nodemailer` under the hood
|
11
|
+
|
12
|
+
```bash
|
13
|
+
npm i @storecraft/mailer-smtp
|
14
|
+
```
|
15
|
+
|
16
|
+
## Howto
|
17
|
+
|
18
|
+
```js
|
19
|
+
import { MailerSmtpNode } from '@storecraft/mailer-smtp';
|
20
|
+
|
21
|
+
const mailer = new MailerSmtpNode(
|
22
|
+
{
|
23
|
+
host: "smtp.sendgrid.net",
|
24
|
+
port: 465,
|
25
|
+
secure: true, // true for 465, false for other ports
|
26
|
+
auth: {
|
27
|
+
user: 'apikey', // generated ethereal user
|
28
|
+
pass: process.env.SEND_GRID_SECRET, // generated ethereal password
|
29
|
+
},
|
30
|
+
}
|
31
|
+
);
|
32
|
+
|
33
|
+
let { success, native_response } = await mailer.email({
|
34
|
+
from: {name: 'bob 👻', address: process.env.FROM_EMAIL }, // sender address
|
35
|
+
to: [ { address: process.env.TO_EMAIL } ], // list of receivers
|
36
|
+
subject: 'subject test', // Subject line
|
37
|
+
text: 'plain text test', // plain text body
|
38
|
+
html: '<p>html test</p>', // html body
|
39
|
+
});
|
40
|
+
|
41
|
+
```
|
42
|
+
|
43
|
+
```text
|
44
|
+
Author: Tomer Shalev (tomer.shalev@gmail.com)
|
45
|
+
```
|
package/index.js
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
import nodemailer from "nodemailer"
|
2
|
+
import SMTPTransport from "nodemailer/lib/smtp-transport/index.js";
|
3
|
+
import { attachment_convert } from "./index.utils.js";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @typedef {nodemailer.Transporter<SMTPTransport.SentMessageInfo>} NodemailerClient
|
7
|
+
* @typedef {import("./types.public.d.ts").Config} Config
|
8
|
+
* @typedef {import('@storecraft/core/mailer').mailer<Config>} mailer
|
9
|
+
* @implements {mailer}
|
10
|
+
*
|
11
|
+
* mailer with nodemailer for node.js
|
12
|
+
*/
|
13
|
+
export class MailerSmtpNode {
|
14
|
+
|
15
|
+
/** @type {Config} */ #_config;
|
16
|
+
/** @type {NodemailerClient} */ #_client;
|
17
|
+
|
18
|
+
/**
|
19
|
+
*
|
20
|
+
* @param {Config} config
|
21
|
+
*/
|
22
|
+
constructor(config) {
|
23
|
+
this.#_config = config;
|
24
|
+
this.#_client = nodemailer.createTransport(
|
25
|
+
config
|
26
|
+
);
|
27
|
+
}
|
28
|
+
|
29
|
+
get config() { return this.#_config; }
|
30
|
+
get client() { return this.#_client; }
|
31
|
+
|
32
|
+
/**
|
33
|
+
*
|
34
|
+
* @type {mailer["email"]}
|
35
|
+
*/
|
36
|
+
async email(o) {
|
37
|
+
let r;
|
38
|
+
try {
|
39
|
+
r = await this.client.sendMail(
|
40
|
+
{
|
41
|
+
from: { address: o.from.address, name: o.from.name ?? ''},
|
42
|
+
to: o.to.map(
|
43
|
+
t => (
|
44
|
+
{
|
45
|
+
address: t.address,
|
46
|
+
name: t.name ?? ''
|
47
|
+
}
|
48
|
+
)
|
49
|
+
),
|
50
|
+
subject: o.subject,
|
51
|
+
text: o.text,
|
52
|
+
html: o.html,
|
53
|
+
attachments: o.attachments?.map(
|
54
|
+
a => (
|
55
|
+
{
|
56
|
+
cid: a.content_id,
|
57
|
+
contentDisposition: a.disposition,
|
58
|
+
filename: a.filename,
|
59
|
+
contentType: a.content_type,
|
60
|
+
content: attachment_convert(a.content)
|
61
|
+
}
|
62
|
+
)
|
63
|
+
)
|
64
|
+
}
|
65
|
+
);
|
66
|
+
} catch(e) {
|
67
|
+
console.log(e);
|
68
|
+
}
|
69
|
+
|
70
|
+
return {
|
71
|
+
success: Boolean(r),
|
72
|
+
native_response: r
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
}
|
77
|
+
|
package/index.utils.js
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
import { Readable } from 'node:stream'
|
2
|
+
|
3
|
+
/**
|
4
|
+
* convert:
|
5
|
+
* - arraybuffer -> Buffer
|
6
|
+
* - readablestream -> readable
|
7
|
+
* @param {import('@storecraft/core/mailer').MailObject["attachments"][0]["content"]} c
|
8
|
+
*/
|
9
|
+
export const attachment_convert = c => {
|
10
|
+
if(c instanceof ArrayBuffer)
|
11
|
+
return Buffer.from(c);
|
12
|
+
else if(c instanceof ReadableStream)
|
13
|
+
return Readable.fromWeb(c);
|
14
|
+
else return c;
|
15
|
+
}
|
package/jsconfig.json
ADDED
package/package.json
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"name": "@storecraft/mailer-smtp",
|
3
|
+
"version": "1.0.1",
|
4
|
+
"description": "Official SMTP email provider for node, deno and bun for storecraft",
|
5
|
+
"license": "MIT",
|
6
|
+
"author": "Tomer Shalev (https://github.com/store-craft)",
|
7
|
+
"homepage": "https://github.com/store-craft/storecraft",
|
8
|
+
"repository": {
|
9
|
+
"type": "git",
|
10
|
+
"url": "https://github.com/store-craft/storecraft.git",
|
11
|
+
"directory": "packages/mailers/mailer-smtp"
|
12
|
+
},
|
13
|
+
"keywords": [
|
14
|
+
"commerce",
|
15
|
+
"dashboard",
|
16
|
+
"code",
|
17
|
+
"storecraft"
|
18
|
+
],
|
19
|
+
"type": "module",
|
20
|
+
"main": "index.js",
|
21
|
+
"types": "./types.public.d.ts",
|
22
|
+
"scripts": {
|
23
|
+
"mailer-smtp:test": "uvu -c",
|
24
|
+
"mailer-smtp:publish": "npm publish --access public"
|
25
|
+
},
|
26
|
+
"dependencies": {
|
27
|
+
"nodemailer": "^6.9.9"
|
28
|
+
},
|
29
|
+
"devDependencies": {
|
30
|
+
"@storecraft/core": "^1.0.0",
|
31
|
+
"@types/nodemailer": "^6.4.14",
|
32
|
+
"@types/node": "^20.11.0",
|
33
|
+
"uvu": "^0.5.6",
|
34
|
+
"dotenv": "^16.3.1"
|
35
|
+
}
|
36
|
+
}
|
package/tests/test.js
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import 'dotenv/config';
|
2
|
+
import { test } from 'uvu';
|
3
|
+
import * as assert from 'uvu/assert';
|
4
|
+
import { MailerSmtpNode } from '../index.js';
|
5
|
+
|
6
|
+
const mailer = new MailerSmtpNode(
|
7
|
+
{
|
8
|
+
host: "smtp.sendgrid.net",
|
9
|
+
port: 465,
|
10
|
+
secure: true, // true for 465, false for other ports
|
11
|
+
auth: {
|
12
|
+
user: 'apikey', // generated ethereal user
|
13
|
+
pass: process.env.SEND_GRID_SECRET, // generated ethereal password
|
14
|
+
},
|
15
|
+
}
|
16
|
+
)
|
17
|
+
|
18
|
+
test('send email', async () => {
|
19
|
+
|
20
|
+
let { success, native_response } = await mailer.email({
|
21
|
+
from: {name: 'bob 👻', address: process.env.FROM_EMAIL }, // sender address
|
22
|
+
to: [ { address: process.env.TO_EMAIL } ], // list of receivers
|
23
|
+
subject: 'nodemailer test', // Subject line
|
24
|
+
text: 'nodemailer test text', // plain text body
|
25
|
+
html: '<p>nodemailer test html</p>', // html body
|
26
|
+
});
|
27
|
+
|
28
|
+
assert.ok(success, `failed with native_response ${JSON.stringify(native_response, null, 2)}`)
|
29
|
+
|
30
|
+
});
|
31
|
+
|
32
|
+
test.run();
|