better-auth-cloudflare-email 0.1.0 → 0.2.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 CHANGED
@@ -130,7 +130,7 @@ import { betterAuth } from "better-auth";
130
130
  import { cloudflareEmail } from "better-auth-cloudflare-email";
131
131
 
132
132
  interface Env {
133
- EMAIL: import("./auth/cloudflare-email").EmailBinding;
133
+ EMAIL: import("better-auth-cloudflare-email").EmailBinding;
134
134
  DB: D1Database;
135
135
  }
136
136
 
@@ -214,7 +214,7 @@ await email.sendRaw({
214
214
  attachments: [{
215
215
  filename: "invoice.pdf",
216
216
  content: base64String,
217
- contentType: "application/pdf",
217
+ type: "application/pdf",
218
218
  disposition: "attachment",
219
219
  }],
220
220
  });
package/dist/index.cjs CHANGED
@@ -128,7 +128,7 @@ function createWorkersTransport(opts) {
128
128
  }
129
129
  function createApiTransport(opts) {
130
130
  const baseUrl = opts.baseUrl ?? "https://api.cloudflare.com/client/v4";
131
- const url = `${baseUrl}/accounts/${opts.accountId}/email-service/send`;
131
+ const url = `${baseUrl}/accounts/${opts.accountId}/email/sending/send`;
132
132
  return {
133
133
  async send(message) {
134
134
  const res = await fetch(url, {
@@ -144,7 +144,11 @@ function createApiTransport(opts) {
144
144
  throw new Error(`Cloudflare Email API error (${res.status}): ${body}`);
145
145
  }
146
146
  const json = await res.json();
147
- return { messageId: json.result?.messageId ?? "" };
147
+ if (!json.success) {
148
+ const msg = json.errors?.map((e) => e.message).join(", ") ?? "Unknown error";
149
+ throw new Error(`Cloudflare Email API error: ${msg}`);
150
+ }
151
+ return json.result ?? { delivered: [], permanent_bounces: [], queued: [] };
148
152
  }
149
153
  };
150
154
  }
package/dist/index.d.cts CHANGED
@@ -4,37 +4,50 @@
4
4
  * Two transports, one interface:
5
5
  *
6
6
  * // Inside a Cloudflare Worker — uses the send_email binding (zero latency, no API key)
7
- * import { cloudflareEmail } from "./cloudflare-email";
7
+ * import { cloudflareEmail } from "better-auth-cloudflare-email";
8
8
  * const email = cloudflareEmail.workers({ binding: env.EMAIL, from: "..." });
9
9
  *
10
10
  * // Anywhere else — uses the Cloudflare REST API
11
- * import { cloudflareEmail } from "./cloudflare-email";
11
+ * import { cloudflareEmail } from "better-auth-cloudflare-email";
12
12
  * const email = cloudflareEmail.api({ accountId: "...", apiToken: "...", from: "..." });
13
13
  *
14
14
  * Both return the same object shape — spread `email.config` into betterAuth()
15
15
  * and wire plugin callbacks identically.
16
16
  */
17
+ type EmailAddress = string | {
18
+ address: string;
19
+ name: string;
20
+ };
17
21
  interface EmailMessage {
18
22
  to: string | string[];
19
- from: string;
23
+ from: EmailAddress;
20
24
  subject: string;
21
25
  html?: string;
22
26
  text?: string;
23
27
  cc?: string | string[];
24
28
  bcc?: string | string[];
25
- replyTo?: string;
29
+ reply_to?: EmailAddress;
26
30
  headers?: Record<string, string>;
27
31
  attachments?: EmailAttachment[];
28
32
  }
29
- interface EmailAttachment {
33
+ type EmailAttachment = InlineAttachment | StandardAttachment;
34
+ interface InlineAttachment {
35
+ filename: string;
36
+ content: string;
37
+ type: string;
38
+ disposition: "inline";
39
+ content_id: string;
40
+ }
41
+ interface StandardAttachment {
30
42
  filename: string;
31
43
  content: string;
32
- contentType: string;
33
- disposition: "attachment" | "inline";
34
- contentId?: string;
44
+ type: string;
45
+ disposition: "attachment";
35
46
  }
36
47
  interface EmailSendResult {
37
- messageId: string;
48
+ delivered: string[];
49
+ permanent_bounces: string[];
50
+ queued: string[];
38
51
  }
39
52
  interface EmailTransport {
40
53
  send(message: EmailMessage): Promise<EmailSendResult>;
@@ -61,8 +74,8 @@ interface Templates {
61
74
  otp?: TemplateFn;
62
75
  }
63
76
  interface SharedOptions {
64
- /** Default "from" address, e.g. "MyApp <noreply@myapp.com>". */
65
- from: string;
77
+ /** Default "from" address. String or { address, name }. */
78
+ from: EmailAddress;
66
79
  /** Application name shown in email templates. Default: "Our App". */
67
80
  appName?: string;
68
81
  /** Override default email templates per type. */
@@ -74,9 +87,8 @@ interface EmailBinding {
74
87
  sendBatch?(messages: EmailMessage[]): Promise<{
75
88
  results: Array<{
76
89
  success: boolean;
77
- messageId?: string;
78
90
  error?: string;
79
- }>;
91
+ } & Partial<EmailSendResult>>;
80
92
  }>;
81
93
  }
82
94
  interface WorkersOptions extends SharedOptions {
@@ -220,4 +232,4 @@ declare const cloudflareEmail: {
220
232
  api(opts: ApiOptions): CloudflareEmailResult;
221
233
  };
222
234
 
223
- export { type ApiOptions, type EmailAttachment, type EmailBinding, type EmailMessage, type EmailSendResult, type EmailTransport, type TemplateData, type TemplateFn, type Templates, type WorkersOptions, cloudflareEmail };
235
+ export { type ApiOptions, type EmailAddress, type EmailAttachment, type EmailBinding, type EmailMessage, type EmailSendResult, type EmailTransport, type InlineAttachment, type StandardAttachment, type TemplateData, type TemplateFn, type Templates, type WorkersOptions, cloudflareEmail };
package/dist/index.d.ts CHANGED
@@ -4,37 +4,50 @@
4
4
  * Two transports, one interface:
5
5
  *
6
6
  * // Inside a Cloudflare Worker — uses the send_email binding (zero latency, no API key)
7
- * import { cloudflareEmail } from "./cloudflare-email";
7
+ * import { cloudflareEmail } from "better-auth-cloudflare-email";
8
8
  * const email = cloudflareEmail.workers({ binding: env.EMAIL, from: "..." });
9
9
  *
10
10
  * // Anywhere else — uses the Cloudflare REST API
11
- * import { cloudflareEmail } from "./cloudflare-email";
11
+ * import { cloudflareEmail } from "better-auth-cloudflare-email";
12
12
  * const email = cloudflareEmail.api({ accountId: "...", apiToken: "...", from: "..." });
13
13
  *
14
14
  * Both return the same object shape — spread `email.config` into betterAuth()
15
15
  * and wire plugin callbacks identically.
16
16
  */
17
+ type EmailAddress = string | {
18
+ address: string;
19
+ name: string;
20
+ };
17
21
  interface EmailMessage {
18
22
  to: string | string[];
19
- from: string;
23
+ from: EmailAddress;
20
24
  subject: string;
21
25
  html?: string;
22
26
  text?: string;
23
27
  cc?: string | string[];
24
28
  bcc?: string | string[];
25
- replyTo?: string;
29
+ reply_to?: EmailAddress;
26
30
  headers?: Record<string, string>;
27
31
  attachments?: EmailAttachment[];
28
32
  }
29
- interface EmailAttachment {
33
+ type EmailAttachment = InlineAttachment | StandardAttachment;
34
+ interface InlineAttachment {
35
+ filename: string;
36
+ content: string;
37
+ type: string;
38
+ disposition: "inline";
39
+ content_id: string;
40
+ }
41
+ interface StandardAttachment {
30
42
  filename: string;
31
43
  content: string;
32
- contentType: string;
33
- disposition: "attachment" | "inline";
34
- contentId?: string;
44
+ type: string;
45
+ disposition: "attachment";
35
46
  }
36
47
  interface EmailSendResult {
37
- messageId: string;
48
+ delivered: string[];
49
+ permanent_bounces: string[];
50
+ queued: string[];
38
51
  }
39
52
  interface EmailTransport {
40
53
  send(message: EmailMessage): Promise<EmailSendResult>;
@@ -61,8 +74,8 @@ interface Templates {
61
74
  otp?: TemplateFn;
62
75
  }
63
76
  interface SharedOptions {
64
- /** Default "from" address, e.g. "MyApp <noreply@myapp.com>". */
65
- from: string;
77
+ /** Default "from" address. String or { address, name }. */
78
+ from: EmailAddress;
66
79
  /** Application name shown in email templates. Default: "Our App". */
67
80
  appName?: string;
68
81
  /** Override default email templates per type. */
@@ -74,9 +87,8 @@ interface EmailBinding {
74
87
  sendBatch?(messages: EmailMessage[]): Promise<{
75
88
  results: Array<{
76
89
  success: boolean;
77
- messageId?: string;
78
90
  error?: string;
79
- }>;
91
+ } & Partial<EmailSendResult>>;
80
92
  }>;
81
93
  }
82
94
  interface WorkersOptions extends SharedOptions {
@@ -220,4 +232,4 @@ declare const cloudflareEmail: {
220
232
  api(opts: ApiOptions): CloudflareEmailResult;
221
233
  };
222
234
 
223
- export { type ApiOptions, type EmailAttachment, type EmailBinding, type EmailMessage, type EmailSendResult, type EmailTransport, type TemplateData, type TemplateFn, type Templates, type WorkersOptions, cloudflareEmail };
235
+ export { type ApiOptions, type EmailAddress, type EmailAttachment, type EmailBinding, type EmailMessage, type EmailSendResult, type EmailTransport, type InlineAttachment, type StandardAttachment, type TemplateData, type TemplateFn, type Templates, type WorkersOptions, cloudflareEmail };
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ function createWorkersTransport(opts) {
102
102
  }
103
103
  function createApiTransport(opts) {
104
104
  const baseUrl = opts.baseUrl ?? "https://api.cloudflare.com/client/v4";
105
- const url = `${baseUrl}/accounts/${opts.accountId}/email-service/send`;
105
+ const url = `${baseUrl}/accounts/${opts.accountId}/email/sending/send`;
106
106
  return {
107
107
  async send(message) {
108
108
  const res = await fetch(url, {
@@ -118,7 +118,11 @@ function createApiTransport(opts) {
118
118
  throw new Error(`Cloudflare Email API error (${res.status}): ${body}`);
119
119
  }
120
120
  const json = await res.json();
121
- return { messageId: json.result?.messageId ?? "" };
121
+ if (!json.success) {
122
+ const msg = json.errors?.map((e) => e.message).join(", ") ?? "Unknown error";
123
+ throw new Error(`Cloudflare Email API error: ${msg}`);
124
+ }
125
+ return json.result ?? { delivered: [], permanent_bounces: [], queued: [] };
122
126
  }
123
127
  };
124
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth-cloudflare-email",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Send emails through Cloudflare Email Service from Better Auth — Workers binding and REST API transports",
5
5
  "license": "MIT",
6
6
  "author": "Paul Stenhouse",