@matthesketh/utopia-email 0.0.5 → 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/dist/adapters/resend.cjs +4 -4
- package/dist/adapters/resend.d.cts +2 -1
- package/dist/adapters/resend.d.ts +2 -1
- package/dist/adapters/resend.js +4 -4
- package/dist/adapters/sendgrid.cjs +1 -1
- package/dist/adapters/sendgrid.d.cts +2 -6
- package/dist/adapters/sendgrid.d.ts +2 -6
- package/dist/adapters/sendgrid.js +1 -1
- package/dist/adapters/smtp.cjs +1 -1
- package/dist/adapters/smtp.d.cts +2 -1
- package/dist/adapters/smtp.d.ts +2 -1
- package/dist/adapters/smtp.js +1 -1
- package/dist/index.cjs +58 -29
- package/dist/index.d.cts +51 -50
- package/dist/index.d.ts +51 -50
- package/dist/index.js +66 -69
- package/dist/types-DJzgvyvE.d.cts +83 -0
- package/dist/types-DJzgvyvE.d.ts +83 -0
- package/package.json +3 -3
package/dist/adapters/resend.cjs
CHANGED
|
@@ -37,16 +37,16 @@ function resendAdapter(config) {
|
|
|
37
37
|
let client = null;
|
|
38
38
|
async function getClient() {
|
|
39
39
|
if (client) return client;
|
|
40
|
-
let
|
|
40
|
+
let ResendCtor;
|
|
41
41
|
try {
|
|
42
42
|
const mod = await import("resend");
|
|
43
|
-
|
|
43
|
+
ResendCtor = mod.Resend ?? mod.default;
|
|
44
44
|
} catch {
|
|
45
45
|
throw new Error(
|
|
46
46
|
'@matthesketh/utopia-email: "resend" package is required for the Resend adapter. Install it with: npm install resend'
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
|
-
client = new
|
|
49
|
+
client = new ResendCtor(config.apiKey);
|
|
50
50
|
return client;
|
|
51
51
|
}
|
|
52
52
|
return {
|
|
@@ -76,7 +76,7 @@ function resendAdapter(config) {
|
|
|
76
76
|
} catch (err) {
|
|
77
77
|
return {
|
|
78
78
|
success: false,
|
|
79
|
-
error: err.message
|
|
79
|
+
error: err instanceof Error ? err.message : String(err)
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
}
|
package/dist/adapters/resend.js
CHANGED
|
@@ -3,16 +3,16 @@ function resendAdapter(config) {
|
|
|
3
3
|
let client = null;
|
|
4
4
|
async function getClient() {
|
|
5
5
|
if (client) return client;
|
|
6
|
-
let
|
|
6
|
+
let ResendCtor;
|
|
7
7
|
try {
|
|
8
8
|
const mod = await import("resend");
|
|
9
|
-
|
|
9
|
+
ResendCtor = mod.Resend ?? mod.default;
|
|
10
10
|
} catch {
|
|
11
11
|
throw new Error(
|
|
12
12
|
'@matthesketh/utopia-email: "resend" package is required for the Resend adapter. Install it with: npm install resend'
|
|
13
13
|
);
|
|
14
14
|
}
|
|
15
|
-
client = new
|
|
15
|
+
client = new ResendCtor(config.apiKey);
|
|
16
16
|
return client;
|
|
17
17
|
}
|
|
18
18
|
return {
|
|
@@ -42,7 +42,7 @@ function resendAdapter(config) {
|
|
|
42
42
|
} catch (err) {
|
|
43
43
|
return {
|
|
44
44
|
success: false,
|
|
45
|
-
error: err.message
|
|
45
|
+
error: err instanceof Error ? err.message : String(err)
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { S as SendGridConfig, E as EmailAdapter } from '../types-
|
|
1
|
+
import { S as SendGridConfig, E as EmailAdapter } from '../types-DJzgvyvE.cjs';
|
|
2
|
+
import '@matthesketh/utopia-server/ssr-runtime';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* Create a SendGrid email adapter.
|
|
5
|
-
*
|
|
6
|
-
* Requires `@sendgrid/mail` as a peer dependency.
|
|
7
|
-
*/
|
|
8
4
|
declare function sendgridAdapter(config: SendGridConfig): EmailAdapter;
|
|
9
5
|
|
|
10
6
|
export { sendgridAdapter };
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { S as SendGridConfig, E as EmailAdapter } from '../types-
|
|
1
|
+
import { S as SendGridConfig, E as EmailAdapter } from '../types-DJzgvyvE.js';
|
|
2
|
+
import '@matthesketh/utopia-server/ssr-runtime';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* Create a SendGrid email adapter.
|
|
5
|
-
*
|
|
6
|
-
* Requires `@sendgrid/mail` as a peer dependency.
|
|
7
|
-
*/
|
|
8
4
|
declare function sendgridAdapter(config: SendGridConfig): EmailAdapter;
|
|
9
5
|
|
|
10
6
|
export { sendgridAdapter };
|
package/dist/adapters/smtp.cjs
CHANGED
package/dist/adapters/smtp.d.cts
CHANGED
package/dist/adapters/smtp.d.ts
CHANGED
package/dist/adapters/smtp.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -154,7 +154,13 @@ function selectorMatches(selector, element) {
|
|
|
154
154
|
if (selector.includes(">")) {
|
|
155
155
|
const parts2 = selector.split(/\s*>\s*/);
|
|
156
156
|
const targetSelector2 = parts2[parts2.length - 1].trim();
|
|
157
|
-
if (!matchesSimpleSelector(
|
|
157
|
+
if (!matchesSimpleSelector(
|
|
158
|
+
targetSelector2,
|
|
159
|
+
element.tag,
|
|
160
|
+
element.classes,
|
|
161
|
+
element.id,
|
|
162
|
+
element.attrs
|
|
163
|
+
)) {
|
|
158
164
|
return false;
|
|
159
165
|
}
|
|
160
166
|
let ancestors = element.ancestors;
|
|
@@ -184,7 +190,13 @@ function selectorMatches(selector, element) {
|
|
|
184
190
|
while (ancestorIdx >= 0) {
|
|
185
191
|
const ancestor = element.ancestors[ancestorIdx];
|
|
186
192
|
ancestorIdx--;
|
|
187
|
-
if (matchesSimpleSelector(
|
|
193
|
+
if (matchesSimpleSelector(
|
|
194
|
+
ancestorSelector,
|
|
195
|
+
ancestor.tag,
|
|
196
|
+
ancestor.classes,
|
|
197
|
+
ancestor.id,
|
|
198
|
+
ancestor.attrs
|
|
199
|
+
)) {
|
|
188
200
|
found = true;
|
|
189
201
|
break;
|
|
190
202
|
}
|
|
@@ -323,10 +335,7 @@ function inlineCSS(html, css) {
|
|
|
323
335
|
const originalTag = element.fullTag;
|
|
324
336
|
let newTag;
|
|
325
337
|
if (element.existingStyle) {
|
|
326
|
-
newTag = originalTag.replace(
|
|
327
|
-
/style="[^"]*"/,
|
|
328
|
-
`style="${mergedStyle}"`
|
|
329
|
-
);
|
|
338
|
+
newTag = originalTag.replace(/style="[^"]*"/, `style="${mergedStyle}"`);
|
|
330
339
|
} else {
|
|
331
340
|
const insertPos = originalTag.endsWith("/>") ? originalTag.length - 2 : originalTag.length - 1;
|
|
332
341
|
newTag = originalTag.slice(0, insertPos) + ` style="${mergedStyle}"` + originalTag.slice(insertPos);
|
|
@@ -452,7 +461,10 @@ function renderEmail(component, props, options) {
|
|
|
452
461
|
skipStyleBlock = false,
|
|
453
462
|
headContent
|
|
454
463
|
} = options ?? {};
|
|
455
|
-
const { html: bodyHtml, css } = (0, import_utopia_server.renderToString)(
|
|
464
|
+
const { html: bodyHtml, css } = (0, import_utopia_server.renderToString)(
|
|
465
|
+
component,
|
|
466
|
+
props
|
|
467
|
+
);
|
|
456
468
|
const inlinedBody = skipInlining ? bodyHtml : inlineCSS(bodyHtml, css);
|
|
457
469
|
const fullHtml = wrapEmailDocument({
|
|
458
470
|
bodyHtml: inlinedBody,
|
|
@@ -473,18 +485,7 @@ function renderEmail(component, props, options) {
|
|
|
473
485
|
function createMailer(adapter) {
|
|
474
486
|
return {
|
|
475
487
|
async send(options) {
|
|
476
|
-
const {
|
|
477
|
-
to,
|
|
478
|
-
from,
|
|
479
|
-
subject,
|
|
480
|
-
component,
|
|
481
|
-
props,
|
|
482
|
-
renderOptions,
|
|
483
|
-
cc,
|
|
484
|
-
bcc,
|
|
485
|
-
replyTo,
|
|
486
|
-
attachments
|
|
487
|
-
} = options;
|
|
488
|
+
const { to, from, subject, component, props, renderOptions, cc, bcc, replyTo, attachments } = options;
|
|
488
489
|
const rendered = renderEmail(component, props, {
|
|
489
490
|
...renderOptions,
|
|
490
491
|
subject
|
|
@@ -520,7 +521,11 @@ var EmailLayout = {
|
|
|
520
521
|
(0, import_ssr_runtime.setAttr)(table, "cellspacing", "0");
|
|
521
522
|
(0, import_ssr_runtime.setAttr)(table, "border", "0");
|
|
522
523
|
(0, import_ssr_runtime.setAttr)(table, "width", String(ctx.width));
|
|
523
|
-
(0, import_ssr_runtime.setAttr)(
|
|
524
|
+
(0, import_ssr_runtime.setAttr)(
|
|
525
|
+
table,
|
|
526
|
+
"style",
|
|
527
|
+
`max-width: ${ctx.width}px; width: 100%; margin: 0 auto; background-color: ${ctx.backgroundColor}; font-family: ${ctx.fontFamily}`
|
|
528
|
+
);
|
|
524
529
|
const tr = (0, import_ssr_runtime.createElement)("tr");
|
|
525
530
|
const td = (0, import_ssr_runtime.createElement)("td");
|
|
526
531
|
(0, import_ssr_runtime.setAttr)(td, "style", "padding: 0");
|
|
@@ -552,11 +557,19 @@ var EmailButton = {
|
|
|
552
557
|
const tr = (0, import_ssr_runtime2.createElement)("tr");
|
|
553
558
|
const td = (0, import_ssr_runtime2.createElement)("td");
|
|
554
559
|
(0, import_ssr_runtime2.setAttr)(td, "align", "center");
|
|
555
|
-
(0, import_ssr_runtime2.setAttr)(
|
|
560
|
+
(0, import_ssr_runtime2.setAttr)(
|
|
561
|
+
td,
|
|
562
|
+
"style",
|
|
563
|
+
`background-color: ${ctx.color}; border-radius: ${ctx.borderRadius}; padding: 12px 24px`
|
|
564
|
+
);
|
|
556
565
|
const a = (0, import_ssr_runtime2.createElement)("a");
|
|
557
566
|
(0, import_ssr_runtime2.setAttr)(a, "href", ctx.href);
|
|
558
|
-
(0, import_ssr_runtime2.setAttr)(
|
|
559
|
-
|
|
567
|
+
(0, import_ssr_runtime2.setAttr)(
|
|
568
|
+
a,
|
|
569
|
+
"style",
|
|
570
|
+
`color: ${ctx.textColor}; text-decoration: none; font-size: 16px; font-weight: bold; display: inline-block`
|
|
571
|
+
);
|
|
572
|
+
(0, import_ssr_runtime2.appendChild)(a, (0, import_ssr_runtime2.createTextNode)(String(ctx.text)));
|
|
560
573
|
(0, import_ssr_runtime2.appendChild)(td, a);
|
|
561
574
|
(0, import_ssr_runtime2.appendChild)(tr, td);
|
|
562
575
|
(0, import_ssr_runtime2.appendChild)(table, tr);
|
|
@@ -582,7 +595,11 @@ var EmailCard = {
|
|
|
582
595
|
(0, import_ssr_runtime3.setAttr)(table, "width", "100%");
|
|
583
596
|
const tr = (0, import_ssr_runtime3.createElement)("tr");
|
|
584
597
|
const td = (0, import_ssr_runtime3.createElement)("td");
|
|
585
|
-
(0, import_ssr_runtime3.setAttr)(
|
|
598
|
+
(0, import_ssr_runtime3.setAttr)(
|
|
599
|
+
td,
|
|
600
|
+
"style",
|
|
601
|
+
`background-color: ${ctx.backgroundColor}; padding: ${ctx.padding}; border-radius: ${ctx.borderRadius}; border: 1px solid ${ctx.borderColor}`
|
|
602
|
+
);
|
|
586
603
|
if (ctx.$slots.default) {
|
|
587
604
|
(0, import_ssr_runtime3.appendChild)(td, ctx.$slots.default());
|
|
588
605
|
}
|
|
@@ -609,7 +626,11 @@ var EmailDivider = {
|
|
|
609
626
|
(0, import_ssr_runtime4.setAttr)(table, "width", ctx.width);
|
|
610
627
|
const tr = (0, import_ssr_runtime4.createElement)("tr");
|
|
611
628
|
const td = (0, import_ssr_runtime4.createElement)("td");
|
|
612
|
-
(0, import_ssr_runtime4.setAttr)(
|
|
629
|
+
(0, import_ssr_runtime4.setAttr)(
|
|
630
|
+
td,
|
|
631
|
+
"style",
|
|
632
|
+
`border-bottom: ${ctx.height} solid ${ctx.color}; font-size: 1px; line-height: 1px; height: ${ctx.height}`
|
|
633
|
+
);
|
|
613
634
|
const nbsp = (0, import_ssr_runtime4.createElement)("span");
|
|
614
635
|
(0, import_ssr_runtime4.setAttr)(nbsp, "style", "display: block; height: 0; overflow: hidden");
|
|
615
636
|
(0, import_ssr_runtime4.appendChild)(td, nbsp);
|
|
@@ -628,7 +649,7 @@ var HEADING_SIZES = {
|
|
|
628
649
|
};
|
|
629
650
|
var EmailHeading = {
|
|
630
651
|
setup: (props) => ({
|
|
631
|
-
level: Math.min(3, Math.max(1, props.level
|
|
652
|
+
level: Math.min(3, Math.max(1, Number(props.level) || 1)),
|
|
632
653
|
color: props.color ?? "#333333",
|
|
633
654
|
align: props.align ?? "left"
|
|
634
655
|
}),
|
|
@@ -636,7 +657,11 @@ var EmailHeading = {
|
|
|
636
657
|
const tag = `h${ctx.level}`;
|
|
637
658
|
const el = (0, import_ssr_runtime5.createElement)(tag);
|
|
638
659
|
const fontSize = HEADING_SIZES[ctx.level] || "28px";
|
|
639
|
-
(0, import_ssr_runtime5.setAttr)(
|
|
660
|
+
(0, import_ssr_runtime5.setAttr)(
|
|
661
|
+
el,
|
|
662
|
+
"style",
|
|
663
|
+
`margin: 0 0 10px 0; font-size: ${fontSize}; line-height: 1.3; color: ${ctx.color}; text-align: ${ctx.align}`
|
|
664
|
+
);
|
|
640
665
|
if (ctx.$slots.default) {
|
|
641
666
|
(0, import_ssr_runtime5.appendChild)(el, ctx.$slots.default());
|
|
642
667
|
}
|
|
@@ -655,7 +680,11 @@ var EmailText = {
|
|
|
655
680
|
}),
|
|
656
681
|
render: (ctx) => {
|
|
657
682
|
const p = (0, import_ssr_runtime6.createElement)("p");
|
|
658
|
-
(0, import_ssr_runtime6.setAttr)(
|
|
683
|
+
(0, import_ssr_runtime6.setAttr)(
|
|
684
|
+
p,
|
|
685
|
+
"style",
|
|
686
|
+
`margin: 0 0 16px 0; font-size: ${ctx.fontSize}; line-height: ${ctx.lineHeight}; color: ${ctx.color}; text-align: ${ctx.align}`
|
|
687
|
+
);
|
|
659
688
|
if (ctx.$slots.default) {
|
|
660
689
|
(0, import_ssr_runtime6.appendChild)(p, ctx.$slots.default());
|
|
661
690
|
}
|
|
@@ -711,7 +740,7 @@ var EmailColumns = {
|
|
|
711
740
|
(0, import_ssr_runtime8.setAttr)(table, "border", "0");
|
|
712
741
|
(0, import_ssr_runtime8.setAttr)(table, "width", "100%");
|
|
713
742
|
const tr = (0, import_ssr_runtime8.createElement)("tr");
|
|
714
|
-
const columnCount = Math.min(4, Math.max(1, ctx.columns));
|
|
743
|
+
const columnCount = Math.min(4, Math.max(1, Number(ctx.columns) || 2));
|
|
715
744
|
const widthPercent = Math.floor(100 / columnCount);
|
|
716
745
|
for (let i = 0; i < columnCount; i++) {
|
|
717
746
|
const td = (0, import_ssr_runtime8.createElement)("td");
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { R as RenderEmailOptions, a as RenderEmailResult, E as EmailAdapter, M as MailerSendOptions, b as EmailResult } from './types-
|
|
2
|
-
export {
|
|
1
|
+
import { R as RenderEmailOptions, a as RenderEmailResult, E as EmailAdapter, M as MailerSendOptions, b as EmailResult, c as EmailComponentContext } from './types-DJzgvyvE.cjs';
|
|
2
|
+
export { d as EmailAttachment, e as EmailMessage, f as ResendConfig, S as SendGridConfig, g as SmtpConfig } from './types-DJzgvyvE.cjs';
|
|
3
3
|
import * as _matthesketh_utopia_server from '@matthesketh/utopia-server';
|
|
4
|
+
import '@matthesketh/utopia-server/ssr-runtime';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Render a UtopiaJS component as a complete email document.
|
|
@@ -12,7 +13,7 @@ import * as _matthesketh_utopia_server from '@matthesketh/utopia-server';
|
|
|
12
13
|
* 4. htmlToText(fullHtml) → plain text fallback
|
|
13
14
|
* 5. Return { html, text, subject? }
|
|
14
15
|
*/
|
|
15
|
-
declare function renderEmail(component:
|
|
16
|
+
declare function renderEmail(component: unknown, props?: Record<string, unknown>, options?: RenderEmailOptions): RenderEmailResult;
|
|
16
17
|
|
|
17
18
|
interface Mailer {
|
|
18
19
|
send(options: MailerSendOptions): Promise<EmailResult>;
|
|
@@ -49,87 +50,87 @@ declare function inlineCSS(html: string, css: string): string;
|
|
|
49
50
|
declare function htmlToText(html: string): string;
|
|
50
51
|
|
|
51
52
|
declare const EmailLayout: {
|
|
52
|
-
setup: (props: Record<string,
|
|
53
|
-
width:
|
|
54
|
-
backgroundColor:
|
|
55
|
-
fontFamily:
|
|
53
|
+
setup: (props: Record<string, unknown>) => {
|
|
54
|
+
width: {};
|
|
55
|
+
backgroundColor: {};
|
|
56
|
+
fontFamily: {};
|
|
56
57
|
};
|
|
57
|
-
render: (ctx:
|
|
58
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
declare const EmailButton: {
|
|
61
|
-
setup: (props: Record<string,
|
|
62
|
-
href:
|
|
63
|
-
text:
|
|
64
|
-
color:
|
|
65
|
-
textColor:
|
|
66
|
-
borderRadius:
|
|
62
|
+
setup: (props: Record<string, unknown>) => {
|
|
63
|
+
href: {};
|
|
64
|
+
text: {};
|
|
65
|
+
color: {};
|
|
66
|
+
textColor: {};
|
|
67
|
+
borderRadius: {};
|
|
67
68
|
};
|
|
68
|
-
render: (ctx:
|
|
69
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
declare const EmailCard: {
|
|
72
|
-
setup: (props: Record<string,
|
|
73
|
-
backgroundColor:
|
|
74
|
-
padding:
|
|
75
|
-
borderRadius:
|
|
76
|
-
borderColor:
|
|
73
|
+
setup: (props: Record<string, unknown>) => {
|
|
74
|
+
backgroundColor: {};
|
|
75
|
+
padding: {};
|
|
76
|
+
borderRadius: {};
|
|
77
|
+
borderColor: {};
|
|
77
78
|
};
|
|
78
|
-
render: (ctx:
|
|
79
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
declare const EmailDivider: {
|
|
82
|
-
setup: (props: Record<string,
|
|
83
|
-
color:
|
|
84
|
-
width:
|
|
85
|
-
height:
|
|
83
|
+
setup: (props: Record<string, unknown>) => {
|
|
84
|
+
color: {};
|
|
85
|
+
width: {};
|
|
86
|
+
height: {};
|
|
86
87
|
};
|
|
87
|
-
render: (ctx:
|
|
88
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
88
89
|
};
|
|
89
90
|
|
|
90
91
|
declare const EmailHeading: {
|
|
91
|
-
setup: (props: Record<string,
|
|
92
|
+
setup: (props: Record<string, unknown>) => {
|
|
92
93
|
level: number;
|
|
93
|
-
color:
|
|
94
|
-
align:
|
|
94
|
+
color: {};
|
|
95
|
+
align: {};
|
|
95
96
|
};
|
|
96
|
-
render: (ctx:
|
|
97
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
declare const EmailText: {
|
|
100
|
-
setup: (props: Record<string,
|
|
101
|
-
color:
|
|
102
|
-
fontSize:
|
|
103
|
-
lineHeight:
|
|
104
|
-
align:
|
|
101
|
+
setup: (props: Record<string, unknown>) => {
|
|
102
|
+
color: {};
|
|
103
|
+
fontSize: {};
|
|
104
|
+
lineHeight: {};
|
|
105
|
+
align: {};
|
|
105
106
|
};
|
|
106
|
-
render: (ctx:
|
|
107
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
107
108
|
};
|
|
108
109
|
|
|
109
110
|
declare const EmailImage: {
|
|
110
|
-
setup: (props: Record<string,
|
|
111
|
-
src:
|
|
112
|
-
alt:
|
|
113
|
-
width:
|
|
114
|
-
height:
|
|
115
|
-
align:
|
|
111
|
+
setup: (props: Record<string, unknown>) => {
|
|
112
|
+
src: {};
|
|
113
|
+
alt: {};
|
|
114
|
+
width: unknown;
|
|
115
|
+
height: unknown;
|
|
116
|
+
align: {};
|
|
116
117
|
};
|
|
117
|
-
render: (ctx:
|
|
118
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
declare const EmailColumns: {
|
|
121
|
-
setup: (props: Record<string,
|
|
122
|
-
columns:
|
|
123
|
-
gap:
|
|
122
|
+
setup: (props: Record<string, unknown>) => {
|
|
123
|
+
columns: {};
|
|
124
|
+
gap: {};
|
|
124
125
|
};
|
|
125
|
-
render: (ctx:
|
|
126
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
126
127
|
};
|
|
127
128
|
|
|
128
129
|
declare const EmailSpacer: {
|
|
129
|
-
setup: (props: Record<string,
|
|
130
|
-
height:
|
|
130
|
+
setup: (props: Record<string, unknown>) => {
|
|
131
|
+
height: {};
|
|
131
132
|
};
|
|
132
|
-
render: (ctx:
|
|
133
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
133
134
|
};
|
|
134
135
|
|
|
135
136
|
export { EmailAdapter, EmailButton, EmailCard, EmailColumns, EmailDivider, EmailHeading, EmailImage, EmailLayout, EmailResult, EmailSpacer, EmailText, MailerSendOptions, RenderEmailOptions, RenderEmailResult, createMailer, htmlToText, inlineCSS, renderEmail };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { R as RenderEmailOptions, a as RenderEmailResult, E as EmailAdapter, M as MailerSendOptions, b as EmailResult } from './types-
|
|
2
|
-
export {
|
|
1
|
+
import { R as RenderEmailOptions, a as RenderEmailResult, E as EmailAdapter, M as MailerSendOptions, b as EmailResult, c as EmailComponentContext } from './types-DJzgvyvE.js';
|
|
2
|
+
export { d as EmailAttachment, e as EmailMessage, f as ResendConfig, S as SendGridConfig, g as SmtpConfig } from './types-DJzgvyvE.js';
|
|
3
3
|
import * as _matthesketh_utopia_server from '@matthesketh/utopia-server';
|
|
4
|
+
import '@matthesketh/utopia-server/ssr-runtime';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Render a UtopiaJS component as a complete email document.
|
|
@@ -12,7 +13,7 @@ import * as _matthesketh_utopia_server from '@matthesketh/utopia-server';
|
|
|
12
13
|
* 4. htmlToText(fullHtml) → plain text fallback
|
|
13
14
|
* 5. Return { html, text, subject? }
|
|
14
15
|
*/
|
|
15
|
-
declare function renderEmail(component:
|
|
16
|
+
declare function renderEmail(component: unknown, props?: Record<string, unknown>, options?: RenderEmailOptions): RenderEmailResult;
|
|
16
17
|
|
|
17
18
|
interface Mailer {
|
|
18
19
|
send(options: MailerSendOptions): Promise<EmailResult>;
|
|
@@ -49,87 +50,87 @@ declare function inlineCSS(html: string, css: string): string;
|
|
|
49
50
|
declare function htmlToText(html: string): string;
|
|
50
51
|
|
|
51
52
|
declare const EmailLayout: {
|
|
52
|
-
setup: (props: Record<string,
|
|
53
|
-
width:
|
|
54
|
-
backgroundColor:
|
|
55
|
-
fontFamily:
|
|
53
|
+
setup: (props: Record<string, unknown>) => {
|
|
54
|
+
width: {};
|
|
55
|
+
backgroundColor: {};
|
|
56
|
+
fontFamily: {};
|
|
56
57
|
};
|
|
57
|
-
render: (ctx:
|
|
58
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
declare const EmailButton: {
|
|
61
|
-
setup: (props: Record<string,
|
|
62
|
-
href:
|
|
63
|
-
text:
|
|
64
|
-
color:
|
|
65
|
-
textColor:
|
|
66
|
-
borderRadius:
|
|
62
|
+
setup: (props: Record<string, unknown>) => {
|
|
63
|
+
href: {};
|
|
64
|
+
text: {};
|
|
65
|
+
color: {};
|
|
66
|
+
textColor: {};
|
|
67
|
+
borderRadius: {};
|
|
67
68
|
};
|
|
68
|
-
render: (ctx:
|
|
69
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
declare const EmailCard: {
|
|
72
|
-
setup: (props: Record<string,
|
|
73
|
-
backgroundColor:
|
|
74
|
-
padding:
|
|
75
|
-
borderRadius:
|
|
76
|
-
borderColor:
|
|
73
|
+
setup: (props: Record<string, unknown>) => {
|
|
74
|
+
backgroundColor: {};
|
|
75
|
+
padding: {};
|
|
76
|
+
borderRadius: {};
|
|
77
|
+
borderColor: {};
|
|
77
78
|
};
|
|
78
|
-
render: (ctx:
|
|
79
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
declare const EmailDivider: {
|
|
82
|
-
setup: (props: Record<string,
|
|
83
|
-
color:
|
|
84
|
-
width:
|
|
85
|
-
height:
|
|
83
|
+
setup: (props: Record<string, unknown>) => {
|
|
84
|
+
color: {};
|
|
85
|
+
width: {};
|
|
86
|
+
height: {};
|
|
86
87
|
};
|
|
87
|
-
render: (ctx:
|
|
88
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
88
89
|
};
|
|
89
90
|
|
|
90
91
|
declare const EmailHeading: {
|
|
91
|
-
setup: (props: Record<string,
|
|
92
|
+
setup: (props: Record<string, unknown>) => {
|
|
92
93
|
level: number;
|
|
93
|
-
color:
|
|
94
|
-
align:
|
|
94
|
+
color: {};
|
|
95
|
+
align: {};
|
|
95
96
|
};
|
|
96
|
-
render: (ctx:
|
|
97
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
declare const EmailText: {
|
|
100
|
-
setup: (props: Record<string,
|
|
101
|
-
color:
|
|
102
|
-
fontSize:
|
|
103
|
-
lineHeight:
|
|
104
|
-
align:
|
|
101
|
+
setup: (props: Record<string, unknown>) => {
|
|
102
|
+
color: {};
|
|
103
|
+
fontSize: {};
|
|
104
|
+
lineHeight: {};
|
|
105
|
+
align: {};
|
|
105
106
|
};
|
|
106
|
-
render: (ctx:
|
|
107
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
107
108
|
};
|
|
108
109
|
|
|
109
110
|
declare const EmailImage: {
|
|
110
|
-
setup: (props: Record<string,
|
|
111
|
-
src:
|
|
112
|
-
alt:
|
|
113
|
-
width:
|
|
114
|
-
height:
|
|
115
|
-
align:
|
|
111
|
+
setup: (props: Record<string, unknown>) => {
|
|
112
|
+
src: {};
|
|
113
|
+
alt: {};
|
|
114
|
+
width: unknown;
|
|
115
|
+
height: unknown;
|
|
116
|
+
align: {};
|
|
116
117
|
};
|
|
117
|
-
render: (ctx:
|
|
118
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
declare const EmailColumns: {
|
|
121
|
-
setup: (props: Record<string,
|
|
122
|
-
columns:
|
|
123
|
-
gap:
|
|
122
|
+
setup: (props: Record<string, unknown>) => {
|
|
123
|
+
columns: {};
|
|
124
|
+
gap: {};
|
|
124
125
|
};
|
|
125
|
-
render: (ctx:
|
|
126
|
+
render: (ctx: EmailComponentContext) => _matthesketh_utopia_server.VElement;
|
|
126
127
|
};
|
|
127
128
|
|
|
128
129
|
declare const EmailSpacer: {
|
|
129
|
-
setup: (props: Record<string,
|
|
130
|
-
height:
|
|
130
|
+
setup: (props: Record<string, unknown>) => {
|
|
131
|
+
height: {};
|
|
131
132
|
};
|
|
132
|
-
render: (ctx:
|
|
133
|
+
render: (ctx: Record<string, unknown>) => _matthesketh_utopia_server.VElement;
|
|
133
134
|
};
|
|
134
135
|
|
|
135
136
|
export { EmailAdapter, EmailButton, EmailCard, EmailColumns, EmailDivider, EmailHeading, EmailImage, EmailLayout, EmailResult, EmailSpacer, EmailText, MailerSendOptions, RenderEmailOptions, RenderEmailResult, createMailer, htmlToText, inlineCSS, renderEmail };
|
package/dist/index.js
CHANGED
|
@@ -116,7 +116,13 @@ function selectorMatches(selector, element) {
|
|
|
116
116
|
if (selector.includes(">")) {
|
|
117
117
|
const parts2 = selector.split(/\s*>\s*/);
|
|
118
118
|
const targetSelector2 = parts2[parts2.length - 1].trim();
|
|
119
|
-
if (!matchesSimpleSelector(
|
|
119
|
+
if (!matchesSimpleSelector(
|
|
120
|
+
targetSelector2,
|
|
121
|
+
element.tag,
|
|
122
|
+
element.classes,
|
|
123
|
+
element.id,
|
|
124
|
+
element.attrs
|
|
125
|
+
)) {
|
|
120
126
|
return false;
|
|
121
127
|
}
|
|
122
128
|
let ancestors = element.ancestors;
|
|
@@ -146,7 +152,13 @@ function selectorMatches(selector, element) {
|
|
|
146
152
|
while (ancestorIdx >= 0) {
|
|
147
153
|
const ancestor = element.ancestors[ancestorIdx];
|
|
148
154
|
ancestorIdx--;
|
|
149
|
-
if (matchesSimpleSelector(
|
|
155
|
+
if (matchesSimpleSelector(
|
|
156
|
+
ancestorSelector,
|
|
157
|
+
ancestor.tag,
|
|
158
|
+
ancestor.classes,
|
|
159
|
+
ancestor.id,
|
|
160
|
+
ancestor.attrs
|
|
161
|
+
)) {
|
|
150
162
|
found = true;
|
|
151
163
|
break;
|
|
152
164
|
}
|
|
@@ -285,10 +297,7 @@ function inlineCSS(html, css) {
|
|
|
285
297
|
const originalTag = element.fullTag;
|
|
286
298
|
let newTag;
|
|
287
299
|
if (element.existingStyle) {
|
|
288
|
-
newTag = originalTag.replace(
|
|
289
|
-
/style="[^"]*"/,
|
|
290
|
-
`style="${mergedStyle}"`
|
|
291
|
-
);
|
|
300
|
+
newTag = originalTag.replace(/style="[^"]*"/, `style="${mergedStyle}"`);
|
|
292
301
|
} else {
|
|
293
302
|
const insertPos = originalTag.endsWith("/>") ? originalTag.length - 2 : originalTag.length - 1;
|
|
294
303
|
newTag = originalTag.slice(0, insertPos) + ` style="${mergedStyle}"` + originalTag.slice(insertPos);
|
|
@@ -414,7 +423,10 @@ function renderEmail(component, props, options) {
|
|
|
414
423
|
skipStyleBlock = false,
|
|
415
424
|
headContent
|
|
416
425
|
} = options ?? {};
|
|
417
|
-
const { html: bodyHtml, css } = renderToString(
|
|
426
|
+
const { html: bodyHtml, css } = renderToString(
|
|
427
|
+
component,
|
|
428
|
+
props
|
|
429
|
+
);
|
|
418
430
|
const inlinedBody = skipInlining ? bodyHtml : inlineCSS(bodyHtml, css);
|
|
419
431
|
const fullHtml = wrapEmailDocument({
|
|
420
432
|
bodyHtml: inlinedBody,
|
|
@@ -435,18 +447,7 @@ function renderEmail(component, props, options) {
|
|
|
435
447
|
function createMailer(adapter) {
|
|
436
448
|
return {
|
|
437
449
|
async send(options) {
|
|
438
|
-
const {
|
|
439
|
-
to,
|
|
440
|
-
from,
|
|
441
|
-
subject,
|
|
442
|
-
component,
|
|
443
|
-
props,
|
|
444
|
-
renderOptions,
|
|
445
|
-
cc,
|
|
446
|
-
bcc,
|
|
447
|
-
replyTo,
|
|
448
|
-
attachments
|
|
449
|
-
} = options;
|
|
450
|
+
const { to, from, subject, component, props, renderOptions, cc, bcc, replyTo, attachments } = options;
|
|
450
451
|
const rendered = renderEmail(component, props, {
|
|
451
452
|
...renderOptions,
|
|
452
453
|
subject
|
|
@@ -468,11 +469,7 @@ function createMailer(adapter) {
|
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
// src/components/email-layout.ts
|
|
471
|
-
import {
|
|
472
|
-
createElement,
|
|
473
|
-
appendChild,
|
|
474
|
-
setAttr
|
|
475
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
472
|
+
import { createElement, appendChild, setAttr } from "@matthesketh/utopia-server/ssr-runtime";
|
|
476
473
|
var EmailLayout = {
|
|
477
474
|
setup: (props) => ({
|
|
478
475
|
width: props.width ?? 600,
|
|
@@ -486,7 +483,11 @@ var EmailLayout = {
|
|
|
486
483
|
setAttr(table, "cellspacing", "0");
|
|
487
484
|
setAttr(table, "border", "0");
|
|
488
485
|
setAttr(table, "width", String(ctx.width));
|
|
489
|
-
setAttr(
|
|
486
|
+
setAttr(
|
|
487
|
+
table,
|
|
488
|
+
"style",
|
|
489
|
+
`max-width: ${ctx.width}px; width: 100%; margin: 0 auto; background-color: ${ctx.backgroundColor}; font-family: ${ctx.fontFamily}`
|
|
490
|
+
);
|
|
490
491
|
const tr = createElement("tr");
|
|
491
492
|
const td = createElement("td");
|
|
492
493
|
setAttr(td, "style", "padding: 0");
|
|
@@ -523,11 +524,19 @@ var EmailButton = {
|
|
|
523
524
|
const tr = createElement2("tr");
|
|
524
525
|
const td = createElement2("td");
|
|
525
526
|
setAttr2(td, "align", "center");
|
|
526
|
-
setAttr2(
|
|
527
|
+
setAttr2(
|
|
528
|
+
td,
|
|
529
|
+
"style",
|
|
530
|
+
`background-color: ${ctx.color}; border-radius: ${ctx.borderRadius}; padding: 12px 24px`
|
|
531
|
+
);
|
|
527
532
|
const a = createElement2("a");
|
|
528
533
|
setAttr2(a, "href", ctx.href);
|
|
529
|
-
setAttr2(
|
|
530
|
-
|
|
534
|
+
setAttr2(
|
|
535
|
+
a,
|
|
536
|
+
"style",
|
|
537
|
+
`color: ${ctx.textColor}; text-decoration: none; font-size: 16px; font-weight: bold; display: inline-block`
|
|
538
|
+
);
|
|
539
|
+
appendChild2(a, createTextNode(String(ctx.text)));
|
|
531
540
|
appendChild2(td, a);
|
|
532
541
|
appendChild2(tr, td);
|
|
533
542
|
appendChild2(table, tr);
|
|
@@ -536,11 +545,7 @@ var EmailButton = {
|
|
|
536
545
|
};
|
|
537
546
|
|
|
538
547
|
// src/components/email-card.ts
|
|
539
|
-
import {
|
|
540
|
-
createElement as createElement3,
|
|
541
|
-
appendChild as appendChild3,
|
|
542
|
-
setAttr as setAttr3
|
|
543
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
548
|
+
import { createElement as createElement3, appendChild as appendChild3, setAttr as setAttr3 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
544
549
|
var EmailCard = {
|
|
545
550
|
setup: (props) => ({
|
|
546
551
|
backgroundColor: props.backgroundColor ?? "#ffffff",
|
|
@@ -557,7 +562,11 @@ var EmailCard = {
|
|
|
557
562
|
setAttr3(table, "width", "100%");
|
|
558
563
|
const tr = createElement3("tr");
|
|
559
564
|
const td = createElement3("td");
|
|
560
|
-
setAttr3(
|
|
565
|
+
setAttr3(
|
|
566
|
+
td,
|
|
567
|
+
"style",
|
|
568
|
+
`background-color: ${ctx.backgroundColor}; padding: ${ctx.padding}; border-radius: ${ctx.borderRadius}; border: 1px solid ${ctx.borderColor}`
|
|
569
|
+
);
|
|
561
570
|
if (ctx.$slots.default) {
|
|
562
571
|
appendChild3(td, ctx.$slots.default());
|
|
563
572
|
}
|
|
@@ -568,11 +577,7 @@ var EmailCard = {
|
|
|
568
577
|
};
|
|
569
578
|
|
|
570
579
|
// src/components/email-divider.ts
|
|
571
|
-
import {
|
|
572
|
-
createElement as createElement4,
|
|
573
|
-
appendChild as appendChild4,
|
|
574
|
-
setAttr as setAttr4
|
|
575
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
580
|
+
import { createElement as createElement4, appendChild as appendChild4, setAttr as setAttr4 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
576
581
|
var EmailDivider = {
|
|
577
582
|
setup: (props) => ({
|
|
578
583
|
color: props.color ?? "#e0e0e0",
|
|
@@ -588,7 +593,11 @@ var EmailDivider = {
|
|
|
588
593
|
setAttr4(table, "width", ctx.width);
|
|
589
594
|
const tr = createElement4("tr");
|
|
590
595
|
const td = createElement4("td");
|
|
591
|
-
setAttr4(
|
|
596
|
+
setAttr4(
|
|
597
|
+
td,
|
|
598
|
+
"style",
|
|
599
|
+
`border-bottom: ${ctx.height} solid ${ctx.color}; font-size: 1px; line-height: 1px; height: ${ctx.height}`
|
|
600
|
+
);
|
|
592
601
|
const nbsp = createElement4("span");
|
|
593
602
|
setAttr4(nbsp, "style", "display: block; height: 0; overflow: hidden");
|
|
594
603
|
appendChild4(td, nbsp);
|
|
@@ -599,11 +608,7 @@ var EmailDivider = {
|
|
|
599
608
|
};
|
|
600
609
|
|
|
601
610
|
// src/components/email-heading.ts
|
|
602
|
-
import {
|
|
603
|
-
createElement as createElement5,
|
|
604
|
-
appendChild as appendChild5,
|
|
605
|
-
setAttr as setAttr5
|
|
606
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
611
|
+
import { createElement as createElement5, appendChild as appendChild5, setAttr as setAttr5 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
607
612
|
var HEADING_SIZES = {
|
|
608
613
|
1: "28px",
|
|
609
614
|
2: "22px",
|
|
@@ -611,7 +616,7 @@ var HEADING_SIZES = {
|
|
|
611
616
|
};
|
|
612
617
|
var EmailHeading = {
|
|
613
618
|
setup: (props) => ({
|
|
614
|
-
level: Math.min(3, Math.max(1, props.level
|
|
619
|
+
level: Math.min(3, Math.max(1, Number(props.level) || 1)),
|
|
615
620
|
color: props.color ?? "#333333",
|
|
616
621
|
align: props.align ?? "left"
|
|
617
622
|
}),
|
|
@@ -619,7 +624,11 @@ var EmailHeading = {
|
|
|
619
624
|
const tag = `h${ctx.level}`;
|
|
620
625
|
const el = createElement5(tag);
|
|
621
626
|
const fontSize = HEADING_SIZES[ctx.level] || "28px";
|
|
622
|
-
setAttr5(
|
|
627
|
+
setAttr5(
|
|
628
|
+
el,
|
|
629
|
+
"style",
|
|
630
|
+
`margin: 0 0 10px 0; font-size: ${fontSize}; line-height: 1.3; color: ${ctx.color}; text-align: ${ctx.align}`
|
|
631
|
+
);
|
|
623
632
|
if (ctx.$slots.default) {
|
|
624
633
|
appendChild5(el, ctx.$slots.default());
|
|
625
634
|
}
|
|
@@ -628,11 +637,7 @@ var EmailHeading = {
|
|
|
628
637
|
};
|
|
629
638
|
|
|
630
639
|
// src/components/email-text.ts
|
|
631
|
-
import {
|
|
632
|
-
createElement as createElement6,
|
|
633
|
-
appendChild as appendChild6,
|
|
634
|
-
setAttr as setAttr6
|
|
635
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
640
|
+
import { createElement as createElement6, appendChild as appendChild6, setAttr as setAttr6 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
636
641
|
var EmailText = {
|
|
637
642
|
setup: (props) => ({
|
|
638
643
|
color: props.color ?? "#333333",
|
|
@@ -642,7 +647,11 @@ var EmailText = {
|
|
|
642
647
|
}),
|
|
643
648
|
render: (ctx) => {
|
|
644
649
|
const p = createElement6("p");
|
|
645
|
-
setAttr6(
|
|
650
|
+
setAttr6(
|
|
651
|
+
p,
|
|
652
|
+
"style",
|
|
653
|
+
`margin: 0 0 16px 0; font-size: ${ctx.fontSize}; line-height: ${ctx.lineHeight}; color: ${ctx.color}; text-align: ${ctx.align}`
|
|
654
|
+
);
|
|
646
655
|
if (ctx.$slots.default) {
|
|
647
656
|
appendChild6(p, ctx.$slots.default());
|
|
648
657
|
}
|
|
@@ -651,11 +660,7 @@ var EmailText = {
|
|
|
651
660
|
};
|
|
652
661
|
|
|
653
662
|
// src/components/email-image.ts
|
|
654
|
-
import {
|
|
655
|
-
createElement as createElement7,
|
|
656
|
-
appendChild as appendChild7,
|
|
657
|
-
setAttr as setAttr7
|
|
658
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
663
|
+
import { createElement as createElement7, appendChild as appendChild7, setAttr as setAttr7 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
659
664
|
var EmailImage = {
|
|
660
665
|
setup: (props) => ({
|
|
661
666
|
src: props.src ?? "",
|
|
@@ -688,11 +693,7 @@ var EmailImage = {
|
|
|
688
693
|
};
|
|
689
694
|
|
|
690
695
|
// src/components/email-columns.ts
|
|
691
|
-
import {
|
|
692
|
-
createElement as createElement8,
|
|
693
|
-
appendChild as appendChild8,
|
|
694
|
-
setAttr as setAttr8
|
|
695
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
696
|
+
import { createElement as createElement8, appendChild as appendChild8, setAttr as setAttr8 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
696
697
|
var EmailColumns = {
|
|
697
698
|
setup: (props) => ({
|
|
698
699
|
columns: props.columns ?? 2,
|
|
@@ -706,7 +707,7 @@ var EmailColumns = {
|
|
|
706
707
|
setAttr8(table, "border", "0");
|
|
707
708
|
setAttr8(table, "width", "100%");
|
|
708
709
|
const tr = createElement8("tr");
|
|
709
|
-
const columnCount = Math.min(4, Math.max(1, ctx.columns));
|
|
710
|
+
const columnCount = Math.min(4, Math.max(1, Number(ctx.columns) || 2));
|
|
710
711
|
const widthPercent = Math.floor(100 / columnCount);
|
|
711
712
|
for (let i = 0; i < columnCount; i++) {
|
|
712
713
|
const td = createElement8("td");
|
|
@@ -730,11 +731,7 @@ var EmailColumns = {
|
|
|
730
731
|
};
|
|
731
732
|
|
|
732
733
|
// src/components/email-spacer.ts
|
|
733
|
-
import {
|
|
734
|
-
createElement as createElement9,
|
|
735
|
-
appendChild as appendChild9,
|
|
736
|
-
setAttr as setAttr9
|
|
737
|
-
} from "@matthesketh/utopia-server/ssr-runtime";
|
|
734
|
+
import { createElement as createElement9, appendChild as appendChild9, setAttr as setAttr9 } from "@matthesketh/utopia-server/ssr-runtime";
|
|
738
735
|
var EmailSpacer = {
|
|
739
736
|
setup: (props) => ({
|
|
740
737
|
height: props.height ?? "20px"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as _matthesketh_utopia_server_ssr_runtime from '@matthesketh/utopia-server/ssr-runtime';
|
|
2
|
+
|
|
3
|
+
/** Slot function type for email components. Returns an SSR VNode. */
|
|
4
|
+
type SlotFn = () => Parameters<typeof _matthesketh_utopia_server_ssr_runtime.appendChild>[1];
|
|
5
|
+
/** Context object passed to email component render functions. */
|
|
6
|
+
interface EmailComponentContext extends Record<string, unknown> {
|
|
7
|
+
$slots: Record<string, SlotFn | undefined>;
|
|
8
|
+
}
|
|
9
|
+
interface RenderEmailOptions {
|
|
10
|
+
/** Email subject line (can also be set in MailerSendOptions). */
|
|
11
|
+
subject?: string;
|
|
12
|
+
/** Hidden preview text shown in email clients. */
|
|
13
|
+
previewText?: string;
|
|
14
|
+
/** Skip CSS inlining (keep styles in <style> block only). */
|
|
15
|
+
skipInlining?: boolean;
|
|
16
|
+
/** Skip the <style> block entirely (only inline styles). */
|
|
17
|
+
skipStyleBlock?: boolean;
|
|
18
|
+
/** Extra HTML to inject into <head>. */
|
|
19
|
+
headContent?: string;
|
|
20
|
+
}
|
|
21
|
+
interface RenderEmailResult {
|
|
22
|
+
/** Full email HTML document. */
|
|
23
|
+
html: string;
|
|
24
|
+
/** Plain text fallback. */
|
|
25
|
+
text: string;
|
|
26
|
+
/** Subject if provided via options. */
|
|
27
|
+
subject?: string;
|
|
28
|
+
}
|
|
29
|
+
interface EmailAdapter {
|
|
30
|
+
send(message: EmailMessage): Promise<EmailResult>;
|
|
31
|
+
}
|
|
32
|
+
interface EmailMessage {
|
|
33
|
+
to: string | string[];
|
|
34
|
+
from: string;
|
|
35
|
+
subject: string;
|
|
36
|
+
html: string;
|
|
37
|
+
text: string;
|
|
38
|
+
cc?: string | string[];
|
|
39
|
+
bcc?: string | string[];
|
|
40
|
+
replyTo?: string;
|
|
41
|
+
attachments?: EmailAttachment[];
|
|
42
|
+
headers?: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
interface EmailResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
messageId?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
interface EmailAttachment {
|
|
50
|
+
filename: string;
|
|
51
|
+
content: string | Buffer;
|
|
52
|
+
contentType?: string;
|
|
53
|
+
encoding?: string;
|
|
54
|
+
}
|
|
55
|
+
interface MailerSendOptions {
|
|
56
|
+
to: string | string[];
|
|
57
|
+
from: string;
|
|
58
|
+
subject?: string;
|
|
59
|
+
component: unknown;
|
|
60
|
+
props?: Record<string, unknown>;
|
|
61
|
+
renderOptions?: RenderEmailOptions;
|
|
62
|
+
cc?: string | string[];
|
|
63
|
+
bcc?: string | string[];
|
|
64
|
+
replyTo?: string;
|
|
65
|
+
attachments?: EmailAttachment[];
|
|
66
|
+
}
|
|
67
|
+
interface SmtpConfig {
|
|
68
|
+
host: string;
|
|
69
|
+
port: number;
|
|
70
|
+
secure?: boolean;
|
|
71
|
+
auth?: {
|
|
72
|
+
user: string;
|
|
73
|
+
pass: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
interface ResendConfig {
|
|
77
|
+
apiKey: string;
|
|
78
|
+
}
|
|
79
|
+
interface SendGridConfig {
|
|
80
|
+
apiKey: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type { EmailAdapter as E, MailerSendOptions as M, RenderEmailOptions as R, SendGridConfig as S, RenderEmailResult as a, EmailResult as b, EmailComponentContext as c, EmailAttachment as d, EmailMessage as e, ResendConfig as f, SmtpConfig as g };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as _matthesketh_utopia_server_ssr_runtime from '@matthesketh/utopia-server/ssr-runtime';
|
|
2
|
+
|
|
3
|
+
/** Slot function type for email components. Returns an SSR VNode. */
|
|
4
|
+
type SlotFn = () => Parameters<typeof _matthesketh_utopia_server_ssr_runtime.appendChild>[1];
|
|
5
|
+
/** Context object passed to email component render functions. */
|
|
6
|
+
interface EmailComponentContext extends Record<string, unknown> {
|
|
7
|
+
$slots: Record<string, SlotFn | undefined>;
|
|
8
|
+
}
|
|
9
|
+
interface RenderEmailOptions {
|
|
10
|
+
/** Email subject line (can also be set in MailerSendOptions). */
|
|
11
|
+
subject?: string;
|
|
12
|
+
/** Hidden preview text shown in email clients. */
|
|
13
|
+
previewText?: string;
|
|
14
|
+
/** Skip CSS inlining (keep styles in <style> block only). */
|
|
15
|
+
skipInlining?: boolean;
|
|
16
|
+
/** Skip the <style> block entirely (only inline styles). */
|
|
17
|
+
skipStyleBlock?: boolean;
|
|
18
|
+
/** Extra HTML to inject into <head>. */
|
|
19
|
+
headContent?: string;
|
|
20
|
+
}
|
|
21
|
+
interface RenderEmailResult {
|
|
22
|
+
/** Full email HTML document. */
|
|
23
|
+
html: string;
|
|
24
|
+
/** Plain text fallback. */
|
|
25
|
+
text: string;
|
|
26
|
+
/** Subject if provided via options. */
|
|
27
|
+
subject?: string;
|
|
28
|
+
}
|
|
29
|
+
interface EmailAdapter {
|
|
30
|
+
send(message: EmailMessage): Promise<EmailResult>;
|
|
31
|
+
}
|
|
32
|
+
interface EmailMessage {
|
|
33
|
+
to: string | string[];
|
|
34
|
+
from: string;
|
|
35
|
+
subject: string;
|
|
36
|
+
html: string;
|
|
37
|
+
text: string;
|
|
38
|
+
cc?: string | string[];
|
|
39
|
+
bcc?: string | string[];
|
|
40
|
+
replyTo?: string;
|
|
41
|
+
attachments?: EmailAttachment[];
|
|
42
|
+
headers?: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
interface EmailResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
messageId?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
interface EmailAttachment {
|
|
50
|
+
filename: string;
|
|
51
|
+
content: string | Buffer;
|
|
52
|
+
contentType?: string;
|
|
53
|
+
encoding?: string;
|
|
54
|
+
}
|
|
55
|
+
interface MailerSendOptions {
|
|
56
|
+
to: string | string[];
|
|
57
|
+
from: string;
|
|
58
|
+
subject?: string;
|
|
59
|
+
component: unknown;
|
|
60
|
+
props?: Record<string, unknown>;
|
|
61
|
+
renderOptions?: RenderEmailOptions;
|
|
62
|
+
cc?: string | string[];
|
|
63
|
+
bcc?: string | string[];
|
|
64
|
+
replyTo?: string;
|
|
65
|
+
attachments?: EmailAttachment[];
|
|
66
|
+
}
|
|
67
|
+
interface SmtpConfig {
|
|
68
|
+
host: string;
|
|
69
|
+
port: number;
|
|
70
|
+
secure?: boolean;
|
|
71
|
+
auth?: {
|
|
72
|
+
user: string;
|
|
73
|
+
pass: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
interface ResendConfig {
|
|
77
|
+
apiKey: string;
|
|
78
|
+
}
|
|
79
|
+
interface SendGridConfig {
|
|
80
|
+
apiKey: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type { EmailAdapter as E, MailerSendOptions as M, RenderEmailOptions as R, SendGridConfig as S, RenderEmailResult as a, EmailResult as b, EmailComponentContext as c, EmailAttachment as d, EmailMessage as e, ResendConfig as f, SmtpConfig as g };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matthesketh/utopia-email",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Template-based email rendering for UtopiaJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"dist"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@matthesketh/utopia-
|
|
59
|
-
"@matthesketh/utopia-
|
|
58
|
+
"@matthesketh/utopia-core": "0.2.0",
|
|
59
|
+
"@matthesketh/utopia-server": "0.2.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@sendgrid/mail": "^7.0.0 || ^8.0.0",
|