@formepdf/resend 0.5.0 → 0.6.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 CHANGED
@@ -11,9 +11,51 @@ npm install @formepdf/resend resend @formepdf/react @formepdf/core
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
+ import { renderDocument } from '@formepdf/core';
14
15
  import { sendPdf } from '@formepdf/resend';
16
+ import { MyInvoice } from './templates/invoice';
15
17
 
16
- await sendPdf({
18
+ // Render the PDF first — works in plain .ts files
19
+ const pdfBytes = await renderDocument(MyInvoice({ customer, items }));
20
+
21
+ // Then email it
22
+ const { data, error } = await sendPdf({
23
+ resendApiKey: process.env.RESEND_API_KEY,
24
+ from: 'Acme Corp <billing@acme.com>',
25
+ to: customer.email,
26
+ subject: 'Invoice #001',
27
+ pdf: pdfBytes,
28
+ filename: 'invoice-001.pdf',
29
+ });
30
+ ```
31
+
32
+ Generate the PDF separately, email it with `sendPdf`. You control the rendering, and the same bytes can go to email + storage + whatever else. Returns Resend's `{ data, error }` directly.
33
+
34
+ ## Render Callback
35
+
36
+ For one-liners in `.tsx` files:
37
+
38
+ ```typescript
39
+ import { sendPdf } from '@formepdf/resend';
40
+ import { MyTemplate } from './my-template';
41
+
42
+ const { data, error } = await sendPdf({
43
+ resendApiKey: process.env.RESEND_API_KEY,
44
+ from: 'billing@acme.com',
45
+ to: 'customer@email.com',
46
+ subject: 'Your document',
47
+ render: () => MyTemplate({ name: 'Jane' }),
48
+ });
49
+ ```
50
+
51
+ ## Built-in Templates
52
+
53
+ Skip the render step and use a built-in template:
54
+
55
+ ```typescript
56
+ import { sendPdf } from '@formepdf/resend';
57
+
58
+ const { data, error } = await sendPdf({
17
59
  resendApiKey: process.env.RESEND_API_KEY,
18
60
  from: 'Acme Corp <billing@acme.com>',
19
61
  to: 'customer@email.com',
@@ -35,23 +77,6 @@ await sendPdf({
35
77
  });
36
78
  ```
37
79
 
38
- One call. PDF rendered, email sent, invoice attached.
39
-
40
- ## Custom Templates
41
-
42
- ```typescript
43
- import { sendPdf } from '@formepdf/resend';
44
- import { MyTemplate } from './my-template';
45
-
46
- await sendPdf({
47
- resendApiKey: process.env.RESEND_API_KEY,
48
- from: 'billing@acme.com',
49
- to: 'customer@email.com',
50
- subject: 'Your document',
51
- render: () => MyTemplate({ name: 'Jane' }),
52
- });
53
- ```
54
-
55
80
  ## Add PDF to an Existing Resend Call
56
81
 
57
82
  ```typescript
@@ -76,7 +101,7 @@ await resend.emails.send({
76
101
 
77
102
  ### `sendPdf(options)`
78
103
 
79
- Render a PDF and email it. Returns `Promise<{ id: string }>` (Resend's email ID).
104
+ Render a PDF and email it. Returns Resend's `{ data, error }` shape directly.
80
105
 
81
106
  | Option | Type | Required | Description |
82
107
  |--------|------|----------|-------------|
@@ -84,9 +109,10 @@ Render a PDF and email it. Returns `Promise<{ id: string }>` (Resend's email ID)
84
109
  | `from` | `string` | Yes | Sender address |
85
110
  | `to` | `string \| string[]` | Yes | Recipient(s) |
86
111
  | `subject` | `string` | Yes | Email subject |
87
- | `template` | `string` | One of template/render | Built-in template name |
112
+ | `pdf` | `Uint8Array` | One of pdf/render/template | Pre-rendered PDF bytes |
113
+ | `render` | `() => ReactElement` | One of pdf/render/template | Render callback |
114
+ | `template` | `string` | One of pdf/render/template | Built-in template name |
88
115
  | `data` | `object` | With template | Data for the template |
89
- | `render` | `() => ReactElement` | One of template/render | Custom render function |
90
116
  | `filename` | `string` | No | PDF filename (default: `{template}.pdf`) |
91
117
  | `html` | `string` | No | Email body HTML |
92
118
  | `text` | `string` | No | Email body plain text |
@@ -1,4 +1,2 @@
1
1
  import type { SendPdfOptions } from './types.js';
2
- export declare function sendPdf(options: SendPdfOptions): Promise<{
3
- id: string;
4
- }>;
2
+ export declare function sendPdf(options: SendPdfOptions): Promise<import("resend").CreateEmailResponse>;
package/dist/send-pdf.js CHANGED
@@ -3,22 +3,25 @@ import { renderDocument } from '@formepdf/core';
3
3
  import { getTemplate } from './templates/index.js';
4
4
  import { buildDefaultEmail } from './default-email.js';
5
5
  export async function sendPdf(options) {
6
- const { resendApiKey, from, to, subject, template, data, render, filename, html, text, react, cc, bcc, replyTo, tags, headers, } = options;
7
- let element;
8
- if (render) {
9
- element = render();
6
+ const { resendApiKey, from, to, subject, filename, html, text, react, cc, bcc, replyTo, tags, headers, } = options;
7
+ let pdfBytes;
8
+ if ('pdf' in options && options.pdf) {
9
+ pdfBytes = options.pdf;
10
10
  }
11
- else if (template) {
12
- const templateFn = getTemplate(template);
11
+ else if ('render' in options && options.render) {
12
+ pdfBytes = await renderDocument(options.render());
13
+ }
14
+ else if ('template' in options && options.template) {
15
+ const templateFn = getTemplate(options.template);
13
16
  if (!templateFn) {
14
- throw new Error(`Unknown template: "${template}". Use listTemplates() to see available templates.`);
17
+ throw new Error(`Unknown template: "${options.template}". Use listTemplates() to see available templates.`);
15
18
  }
16
- element = templateFn(data || {});
19
+ pdfBytes = await renderDocument(templateFn(options.data || {}));
17
20
  }
18
21
  else {
19
- throw new Error('Either "template" or "render" must be provided.');
22
+ throw new Error('One of "pdf", "render", or "template" must be provided.');
20
23
  }
21
- const pdfBytes = await renderDocument(element);
24
+ const template = 'template' in options ? options.template : undefined;
22
25
  const pdfFilename = filename || `${template || 'document'}.pdf`;
23
26
  const attachment = {
24
27
  filename: pdfFilename,
@@ -27,6 +30,7 @@ export async function sendPdf(options) {
27
30
  let emailHtml = html;
28
31
  let emailText = text;
29
32
  if (!html && !text && !react) {
33
+ const data = 'data' in options ? options.data : undefined;
30
34
  const defaultEmail = buildDefaultEmail(template, data);
31
35
  emailHtml = defaultEmail.html;
32
36
  emailText = defaultEmail.text;
@@ -54,9 +58,5 @@ export async function sendPdf(options) {
54
58
  emailPayload.tags = tags;
55
59
  if (headers)
56
60
  emailPayload.headers = headers;
57
- const { data: result, error } = await resend.emails.send(emailPayload);
58
- if (error) {
59
- throw new Error(`Resend error: ${error.message}`);
60
- }
61
- return { id: result.id };
61
+ return resend.emails.send(emailPayload);
62
62
  }
package/dist/types.d.ts CHANGED
@@ -17,17 +17,25 @@ interface BaseOptions {
17
17
  }[];
18
18
  headers?: Record<string, string>;
19
19
  }
20
+ interface PdfBytesOptions extends BaseOptions {
21
+ pdf: Uint8Array;
22
+ template?: never;
23
+ data?: never;
24
+ render?: never;
25
+ }
20
26
  interface TemplateOptions extends BaseOptions {
27
+ pdf?: never;
21
28
  template: string;
22
29
  data?: Record<string, any>;
23
30
  render?: never;
24
31
  }
25
32
  interface RenderOptions extends BaseOptions {
33
+ pdf?: never;
26
34
  template?: never;
27
35
  data?: never;
28
36
  render: () => ReactElement;
29
37
  }
30
- export type SendPdfOptions = TemplateOptions | RenderOptions;
38
+ export type SendPdfOptions = PdfBytesOptions | TemplateOptions | RenderOptions;
31
39
  export interface RenderAttachOptions {
32
40
  template?: string;
33
41
  data?: Record<string, any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formepdf/resend",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Render a PDF and email it in one call — Forme + Resend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,8 +12,8 @@
12
12
  "dist"
13
13
  ],
14
14
  "dependencies": {
15
- "@formepdf/react": "0.5.0",
16
- "@formepdf/core": "0.5.0"
15
+ "@formepdf/react": "0.6.1",
16
+ "@formepdf/core": "0.6.1"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "resend": ">=3.0.0"