@aphexcms/resend-adapter 0.1.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/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # @aphex/resend-adapter
2
+
3
+ Resend email adapter for Aphex CMS.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @aphex/resend-adapter resend
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Setup
14
+
15
+ ```typescript
16
+ // src/lib/server/email/index.ts
17
+ import { createResendAdapter } from '@aphex/resend-adapter';
18
+ import { RESEND_API_KEY } from '$env/static/private';
19
+
20
+ export const emailAdapter = createResendAdapter({
21
+ apiKey: RESEND_API_KEY
22
+ });
23
+ ```
24
+
25
+ ### Environment Variables
26
+
27
+ Add to your `.env` file:
28
+
29
+ ```bash
30
+ RESEND_API_KEY=re_your_api_key_here
31
+ ```
32
+
33
+ ### Sending Emails
34
+
35
+ ```typescript
36
+ import { emailAdapter } from '$lib/server/email';
37
+
38
+ // Send a single email
39
+ const result = await emailAdapter.send({
40
+ from: 'Acme <onboarding@resend.dev>',
41
+ to: 'user@example.com',
42
+ subject: 'Hello World',
43
+ html: '<p>Hello from Aphex CMS!</p>'
44
+ });
45
+
46
+ if (result.error) {
47
+ console.error('Failed to send email:', result.error);
48
+ } else {
49
+ console.log('Email sent successfully:', result.id);
50
+ }
51
+ ```
52
+
53
+ ### Batch Sending
54
+
55
+ ```typescript
56
+ const results = await emailAdapter.sendBatch([
57
+ {
58
+ from: 'Acme <onboarding@resend.dev>',
59
+ to: 'user1@example.com',
60
+ subject: 'Welcome',
61
+ html: '<p>Welcome user 1!</p>'
62
+ },
63
+ {
64
+ from: 'Acme <onboarding@resend.dev>',
65
+ to: 'user2@example.com',
66
+ subject: 'Welcome',
67
+ html: '<p>Welcome user 2!</p>'
68
+ }
69
+ ]);
70
+ ```
71
+
72
+ ### Advanced Options
73
+
74
+ ```typescript
75
+ await emailAdapter.send({
76
+ from: 'Acme <onboarding@resend.dev>',
77
+ to: ['user1@example.com', 'user2@example.com'],
78
+ cc: 'manager@example.com',
79
+ bcc: 'archive@example.com',
80
+ replyTo: 'support@example.com',
81
+ subject: 'Newsletter',
82
+ html: '<h1>Monthly Update</h1>',
83
+ text: 'Monthly Update',
84
+ tags: [
85
+ { name: 'category', value: 'newsletter' },
86
+ { name: 'month', value: 'january' }
87
+ ],
88
+ attachments: [
89
+ {
90
+ filename: 'invoice.pdf',
91
+ content: pdfBuffer
92
+ }
93
+ ]
94
+ });
95
+ ```
96
+
97
+ ## API Reference
98
+
99
+ ### `createResendAdapter(config)`
100
+
101
+ Creates a new Resend email adapter instance.
102
+
103
+ **Config:**
104
+
105
+ - `apiKey` (required): Your Resend API key
106
+
107
+ **Returns:** `EmailAdapter`
108
+
109
+ ### `EmailAdapter.send(options)`
110
+
111
+ Sends a single email.
112
+
113
+ **Options:**
114
+
115
+ - `from` (required): Sender email address
116
+ - `to` (required): Recipient email(s)
117
+ - `subject` (required): Email subject
118
+ - `html`: HTML content
119
+ - `text`: Plain text content
120
+ - `cc`: CC recipients
121
+ - `bcc`: BCC recipients
122
+ - `replyTo`: Reply-to address
123
+ - `tags`: Array of tags for tracking
124
+ - `attachments`: Array of file attachments
125
+
126
+ **Returns:** `Promise<SendEmailResult>`
127
+
128
+ ### `EmailAdapter.sendBatch(emails)`
129
+
130
+ Sends multiple emails in a batch.
131
+
132
+ **Parameters:**
133
+
134
+ - `emails`: Array of `SendEmailOptions`
135
+
136
+ **Returns:** `Promise<SendEmailResult[]>`
137
+
138
+ ## Learn More
139
+
140
+ - [Resend Documentation](https://resend.com/docs)
141
+ - [Aphex CMS Documentation](../../README.md)
@@ -0,0 +1,13 @@
1
+ import type { EmailAdapter, SendEmailOptions, SendEmailResult, EmailConfig } from '@aphexcms/cms-core/server';
2
+ export interface ResendConfig extends EmailConfig {
3
+ apiKey: string;
4
+ }
5
+ export declare class ResendAdapter implements EmailAdapter {
6
+ readonly name = "resend";
7
+ private resend;
8
+ constructor(config: ResendConfig);
9
+ send(options: SendEmailOptions): Promise<SendEmailResult>;
10
+ sendBatch(emails: SendEmailOptions[]): Promise<SendEmailResult[]>;
11
+ }
12
+ export declare function createResendAdapter(config: ResendConfig): EmailAdapter;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,YAAa,SAAQ,WAAW;IAChD,MAAM,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAc,YAAW,YAAY;IACjD,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,YAAY;IAO1B,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAoCzD,SAAS,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAyCvE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAEtE"}
package/dist/index.js ADDED
@@ -0,0 +1,84 @@
1
+ import { Resend } from 'resend';
2
+ export class ResendAdapter {
3
+ name = 'resend';
4
+ resend;
5
+ constructor(config) {
6
+ if (!config.apiKey) {
7
+ throw new Error('Resend API key is required');
8
+ }
9
+ this.resend = new Resend(config.apiKey);
10
+ }
11
+ async send(options) {
12
+ try {
13
+ const emailOptions = {
14
+ from: options.from,
15
+ to: Array.isArray(options.to) ? options.to : [options.to],
16
+ subject: options.subject,
17
+ html: options.html || '',
18
+ ...(options.text && { text: options.text }),
19
+ ...(options.cc && { cc: Array.isArray(options.cc) ? options.cc : [options.cc] }),
20
+ ...(options.bcc && { bcc: Array.isArray(options.bcc) ? options.bcc : [options.bcc] }),
21
+ ...(options.replyTo && { replyTo: options.replyTo }),
22
+ ...(options.tags && { tags: options.tags }),
23
+ ...(options.attachments && { attachments: options.attachments })
24
+ };
25
+ const { data, error } = await this.resend.emails.send(emailOptions);
26
+ if (error) {
27
+ return {
28
+ id: '',
29
+ error: error.message
30
+ };
31
+ }
32
+ return {
33
+ id: data?.id || '',
34
+ error: undefined
35
+ };
36
+ }
37
+ catch (error) {
38
+ return {
39
+ id: '',
40
+ error: error instanceof Error ? error.message : 'Unknown error'
41
+ };
42
+ }
43
+ }
44
+ async sendBatch(emails) {
45
+ try {
46
+ const { data, error } = await this.resend.batch.send(emails.map((email) => {
47
+ const batchEmail = {
48
+ from: email.from,
49
+ to: Array.isArray(email.to) ? email.to : [email.to],
50
+ subject: email.subject,
51
+ html: email.html || '',
52
+ ...(email.text && { text: email.text }),
53
+ ...(email.cc && { cc: Array.isArray(email.cc) ? email.cc : [email.cc] }),
54
+ ...(email.bcc && { bcc: Array.isArray(email.bcc) ? email.bcc : [email.bcc] }),
55
+ ...(email.replyTo && { replyTo: email.replyTo }),
56
+ ...(email.tags && { tags: email.tags }),
57
+ ...(email.attachments && { attachments: email.attachments })
58
+ };
59
+ return batchEmail;
60
+ }));
61
+ if (error) {
62
+ return emails.map(() => ({
63
+ id: '',
64
+ error: error.message
65
+ }));
66
+ }
67
+ return (data?.data?.map((result) => ({
68
+ id: result.id || '',
69
+ error: undefined
70
+ })) || []);
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
74
+ return emails.map(() => ({
75
+ id: '',
76
+ error: errorMessage
77
+ }));
78
+ }
79
+ }
80
+ }
81
+ export function createResendAdapter(config) {
82
+ return new ResendAdapter(config);
83
+ }
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@aphexcms/resend-adapter",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./schema": {
14
+ "types": "./dist/schema.d.ts",
15
+ "import": "./dist/schema.js",
16
+ "default": "./dist/schema.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "prepublishOnly": "pnpm build"
25
+ },
26
+ "dependencies": {
27
+ "@aphexcms/cms-core": "workspace:*",
28
+ "resend": "^4.0.1"
29
+ },
30
+ "peerDependencies": {
31
+ "@aphexcms/cms-core": "workspace:*"
32
+ },
33
+ "devDependencies": {
34
+ "@aphexcms/cms-core": "workspace:*",
35
+ "tsup": "^8.0.0",
36
+ "typescript": "^5.3.3"
37
+ }
38
+ }