resend 0.1.2 → 0.8.0
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/build/package.json +45 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +5 -0
- package/build/src/interfaces.d.ts +19 -0
- package/build/src/interfaces.js +2 -0
- package/build/src/resend.d.ts +9 -0
- package/build/src/resend.js +57 -0
- package/build/src/resend.spec.d.ts +1 -0
- package/build/src/resend.spec.js +89 -0
- package/package.json +39 -5
- package/readme.md +82 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "resend",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "build/src/index.js",
|
|
6
|
+
"typings": "build/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"build/"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -p .",
|
|
12
|
+
"lint": "tslint -p tsconfig.json -c tslint.json",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"prettier": "prettier \"src/**/*.{js,ts,tsx}\" --check",
|
|
16
|
+
"format": "prettier \"src/**/*.{js,ts,tsx}\" --write",
|
|
17
|
+
"prepublishOnly": "yarn run build"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/resend-inc/resend-node.git"
|
|
22
|
+
},
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/resend-inc/resend-node/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/resend-inc/resend-node#readme",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@react-email/render": "^0.0.1",
|
|
31
|
+
"axios": "0.27.2"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "28.1.7",
|
|
35
|
+
"@types/node": "18.6.4",
|
|
36
|
+
"@types/react": "18.0.17",
|
|
37
|
+
"axios-mock-adapter": "1.21.2",
|
|
38
|
+
"jest": "28.1.3",
|
|
39
|
+
"prettier": "2.7.1",
|
|
40
|
+
"supertest": "6.2.4",
|
|
41
|
+
"ts-jest": "28.0.8",
|
|
42
|
+
"tslint": "6.1.3",
|
|
43
|
+
"typescript": "4.7.4"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
export interface SendEmailData {
|
|
3
|
+
/** Sender email address. */
|
|
4
|
+
from: string;
|
|
5
|
+
/** Recipient email address. Max 50. */
|
|
6
|
+
to: string | string[];
|
|
7
|
+
/** Bcc recipient email address. Max 50. */
|
|
8
|
+
bcc?: string | string[];
|
|
9
|
+
/** Cc recipient email address. Max 50. */
|
|
10
|
+
cc?: string | string[];
|
|
11
|
+
/** Email subject. */
|
|
12
|
+
subject?: string;
|
|
13
|
+
/** The HTML version of the message. */
|
|
14
|
+
text?: string;
|
|
15
|
+
/** The plain text version of the message. */
|
|
16
|
+
html?: string;
|
|
17
|
+
/** The React version of the message. */
|
|
18
|
+
react?: ReactElement;
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SendEmailData } from './interfaces';
|
|
2
|
+
export declare class Resend {
|
|
3
|
+
readonly apiKey?: string | undefined;
|
|
4
|
+
readonly baseUrl: string;
|
|
5
|
+
private readonly headers;
|
|
6
|
+
private readonly request;
|
|
7
|
+
constructor(apiKey?: string | undefined);
|
|
8
|
+
sendEmail(data: SendEmailData): Promise<object>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.Resend = void 0;
|
|
16
|
+
const axios_1 = __importDefault(require("axios"));
|
|
17
|
+
const render_1 = require("@react-email/render");
|
|
18
|
+
const package_json_1 = require("../package.json");
|
|
19
|
+
class Resend {
|
|
20
|
+
constructor(apiKey) {
|
|
21
|
+
this.apiKey = apiKey;
|
|
22
|
+
if (!apiKey) {
|
|
23
|
+
this.apiKey = process.env.RESEND_API_KEY;
|
|
24
|
+
if (!this.apiKey) {
|
|
25
|
+
throw new Error('Missing API key. Pass it to the constructor `new Resend("re_123")`');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
this.apiKey = apiKey;
|
|
29
|
+
this.baseUrl = process.env.RESEND_BASE_URL || 'https://api.resend.com';
|
|
30
|
+
this.headers = {
|
|
31
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
32
|
+
'User-Agent': `node:${package_json_1.version}`,
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
};
|
|
35
|
+
this.request = axios_1.default.create({
|
|
36
|
+
baseURL: this.baseUrl,
|
|
37
|
+
headers: this.headers,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
sendEmail(data) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
try {
|
|
43
|
+
const path = `${this.baseUrl}/email`;
|
|
44
|
+
if (data.react) {
|
|
45
|
+
data.html = (0, render_1.render)(data.react);
|
|
46
|
+
delete data.react;
|
|
47
|
+
}
|
|
48
|
+
const response = yield this.request(path, { method: 'POST', data });
|
|
49
|
+
return response.data;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.Resend = Resend;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const resend_1 = require("./resend");
|
|
16
|
+
const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
|
|
17
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
|
+
const mock = new axios_mock_adapter_1.default(axios_1.default);
|
|
19
|
+
const resend = new resend_1.Resend('re_924b3rjh2387fbewf823');
|
|
20
|
+
describe('Resend', () => {
|
|
21
|
+
afterEach(() => mock.resetHistory());
|
|
22
|
+
it('throws API key error', () => {
|
|
23
|
+
expect(() => new resend_1.Resend()).toThrowErrorMatchingSnapshot();
|
|
24
|
+
});
|
|
25
|
+
it('sends email', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
const payload = {
|
|
27
|
+
from: 'bu@resend.com',
|
|
28
|
+
to: 'zeno@resend.com',
|
|
29
|
+
subject: 'Hello World',
|
|
30
|
+
};
|
|
31
|
+
mock.onPost('https://api.resend.com/email', payload).replyOnce(200, {
|
|
32
|
+
id: '1234',
|
|
33
|
+
from: 'bu@resend.com',
|
|
34
|
+
to: 'zeno@resend.com',
|
|
35
|
+
created_at: '123',
|
|
36
|
+
});
|
|
37
|
+
const data = yield resend.sendEmail(payload);
|
|
38
|
+
expect(data).toMatchSnapshot();
|
|
39
|
+
}));
|
|
40
|
+
it('sends email with multiple recipients', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const payload = {
|
|
42
|
+
from: 'admin@resend.com',
|
|
43
|
+
to: ['bu@resend.com', 'zeno@resend.com'],
|
|
44
|
+
subject: 'Hello World',
|
|
45
|
+
};
|
|
46
|
+
mock.onPost('https://api.resend.com/email', payload).replyOnce(200, {
|
|
47
|
+
id: '1234',
|
|
48
|
+
from: 'admin@resend.com',
|
|
49
|
+
to: ['bu@resend.com', 'zeno@resend.com'],
|
|
50
|
+
created_at: '123',
|
|
51
|
+
});
|
|
52
|
+
const data = yield resend.sendEmail(payload);
|
|
53
|
+
expect(data).toMatchSnapshot();
|
|
54
|
+
}));
|
|
55
|
+
it('sends email with multiple bcc recipients', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
const payload = {
|
|
57
|
+
from: 'admin@resend.com',
|
|
58
|
+
to: 'bu@resend.com',
|
|
59
|
+
bcc: ['foo@resend.com', 'bar@resend.com'],
|
|
60
|
+
subject: 'Hello World',
|
|
61
|
+
};
|
|
62
|
+
mock.onPost('https://api.resend.com/email', payload).replyOnce(200, {
|
|
63
|
+
id: '1234',
|
|
64
|
+
from: 'admin@resend.com',
|
|
65
|
+
to: 'bu@resend.com',
|
|
66
|
+
bcc: ['foo@resend.com', 'bar@resend.com'],
|
|
67
|
+
created_at: '123',
|
|
68
|
+
});
|
|
69
|
+
const data = yield resend.sendEmail(payload);
|
|
70
|
+
expect(data).toMatchSnapshot();
|
|
71
|
+
}));
|
|
72
|
+
it('sends email with multiple cc recipients', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const payload = {
|
|
74
|
+
from: 'admin@resend.com',
|
|
75
|
+
to: 'bu@resend.com',
|
|
76
|
+
cc: ['foo@resend.com', 'bar@resend.com'],
|
|
77
|
+
subject: 'Hello World',
|
|
78
|
+
};
|
|
79
|
+
mock.onPost('https://api.resend.com/email', payload).replyOnce(200, {
|
|
80
|
+
id: '1234',
|
|
81
|
+
from: 'admin@resend.com',
|
|
82
|
+
to: 'bu@resend.com',
|
|
83
|
+
cc: ['foo@resend.com', 'bar@resend.com'],
|
|
84
|
+
created_at: '123',
|
|
85
|
+
});
|
|
86
|
+
const data = yield resend.sendEmail(payload);
|
|
87
|
+
expect(data).toMatchSnapshot();
|
|
88
|
+
}));
|
|
89
|
+
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "build/src/index.js",
|
|
6
|
+
"typings": "build/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"build/"
|
|
9
|
+
],
|
|
6
10
|
"scripts": {
|
|
7
|
-
"
|
|
11
|
+
"build": "tsc -p .",
|
|
12
|
+
"lint": "tslint -p tsconfig.json -c tslint.json",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"prettier": "prettier \"src/**/*.{js,ts,tsx}\" --check",
|
|
16
|
+
"format": "prettier \"src/**/*.{js,ts,tsx}\" --write",
|
|
17
|
+
"prepublishOnly": "yarn run build"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/resend-inc/resend-node.git"
|
|
8
22
|
},
|
|
9
23
|
"author": "",
|
|
10
|
-
"license": "
|
|
11
|
-
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/resend-inc/resend-node/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/resend-inc/resend-node#readme",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@react-email/render": "^0.0.1",
|
|
31
|
+
"axios": "0.27.2"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "28.1.7",
|
|
35
|
+
"@types/node": "18.6.4",
|
|
36
|
+
"@types/react": "18.0.17",
|
|
37
|
+
"axios-mock-adapter": "1.21.2",
|
|
38
|
+
"jest": "28.1.3",
|
|
39
|
+
"prettier": "2.7.1",
|
|
40
|
+
"supertest": "6.2.4",
|
|
41
|
+
"ts-jest": "28.0.8",
|
|
42
|
+
"tslint": "6.1.3",
|
|
43
|
+
"typescript": "4.7.4"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Resend Node.js SDK
|
|
2
|
+
|
|
3
|
+
Node.js library for the Resend API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install resend
|
|
9
|
+
# or
|
|
10
|
+
yarn add resend
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
First, you need to get an API key, which is available in the [Resend Dashboard](https://resend.com).
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { Resend } from 'resend';
|
|
19
|
+
const resend = new Resend('re_123');
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Send your first email:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
await resend.sendEmail({
|
|
28
|
+
from: 'you@example.com',
|
|
29
|
+
to: 'user@gmail.com',
|
|
30
|
+
subject: 'hello world',
|
|
31
|
+
text: 'it works!',
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Send email using HTML
|
|
36
|
+
|
|
37
|
+
Send an email custom HTML content:
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
await resend.sendEmail({
|
|
41
|
+
from: 'you@example.com',
|
|
42
|
+
to: 'user@gmail.com',
|
|
43
|
+
subject: 'hello world',
|
|
44
|
+
html: '<strong>it works!</strong>',
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Send email using React
|
|
49
|
+
|
|
50
|
+
Start by creating your email template as a React component.
|
|
51
|
+
|
|
52
|
+
```jsx
|
|
53
|
+
import React from 'react'
|
|
54
|
+
|
|
55
|
+
export default function EmailTemplate(props) {
|
|
56
|
+
const { firstName, product } = props
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div>
|
|
60
|
+
<h1>Welcome, {firstName}!</h1>
|
|
61
|
+
<p>Thanks for trying {product}. We’re thrilled to have you on board.</p>
|
|
62
|
+
</div>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then import the template component and pass it to the `react` property.
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
import EmailTemplate from '../components/EmailTemplate'
|
|
71
|
+
|
|
72
|
+
await resend.sendEmail({
|
|
73
|
+
from: 'you@example.com',
|
|
74
|
+
to: 'user@gmail.com',
|
|
75
|
+
subject: 'hello world',
|
|
76
|
+
react: <EmailTemplate firstName="John" product="MyApp" />,
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT License
|