@emailens/engine 0.6.0 → 0.7.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 +92 -6
- package/dist/compile/index.d.cts +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/index.cjs +448 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -4
- package/dist/index.d.ts +42 -4
- package/dist/index.js +445 -9
- package/dist/index.js.map +1 -1
- package/dist/{react-email-BQljgXbo.d.cts → react-email-CYOtHJch.d.cts} +48 -1
- package/dist/{react-email-BQljgXbo.d.ts → react-email-CYOtHJch.d.ts} +48 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @emailens/engine
|
|
2
2
|
|
|
3
|
-
Email compatibility engine that transforms CSS per email client, analyzes compatibility, scores results, simulates dark mode, provides framework-aware fix snippets, and runs spam, accessibility, link, and
|
|
3
|
+
Email compatibility engine that transforms CSS per email client, analyzes compatibility, scores results, simulates dark mode, provides framework-aware fix snippets, and runs spam, accessibility, link, image, inbox preview, size, and template variable analysis.
|
|
4
4
|
|
|
5
5
|
Supports **12 email clients**: Gmail (Web, Android, iOS), Outlook (365, Windows), Apple Mail (macOS, iOS), Yahoo Mail, Samsung Mail, Thunderbird, HEY Mail, and Superhuman.
|
|
6
6
|
|
|
@@ -49,13 +49,22 @@ console.log(report.links.totalLinks);
|
|
|
49
49
|
|
|
50
50
|
console.log(report.images.total);
|
|
51
51
|
// 0
|
|
52
|
+
|
|
53
|
+
console.log(report.inboxPreview.subject);
|
|
54
|
+
// "Newsletter"
|
|
55
|
+
|
|
56
|
+
console.log(report.size.clipped);
|
|
57
|
+
// false
|
|
58
|
+
|
|
59
|
+
console.log(report.templateVariables.unresolvedCount);
|
|
60
|
+
// 0
|
|
52
61
|
```
|
|
53
62
|
|
|
54
63
|
## API Reference
|
|
55
64
|
|
|
56
65
|
### `auditEmail(html: string, options?: AuditOptions): AuditReport`
|
|
57
66
|
|
|
58
|
-
**Unified API** — runs all email analysis checks in a single call. Returns compatibility warnings + scores, spam analysis, link validation, accessibility audit, and
|
|
67
|
+
**Unified API** — runs all 8 email analysis checks in a single call. Returns compatibility warnings + scores, spam analysis, link validation, accessibility audit, image analysis, inbox preview extraction, size checking, and template variable detection.
|
|
59
68
|
|
|
60
69
|
Internally parses the HTML once and shares the DOM across all analyzers.
|
|
61
70
|
|
|
@@ -74,12 +83,15 @@ const report = auditEmail(html, {
|
|
|
74
83
|
// report.links — LinkReport
|
|
75
84
|
// report.accessibility — AccessibilityReport
|
|
76
85
|
// report.images — ImageReport
|
|
86
|
+
// report.inboxPreview — InboxPreview
|
|
87
|
+
// report.size — SizeReport
|
|
88
|
+
// report.templateVariables — TemplateReport
|
|
77
89
|
```
|
|
78
90
|
|
|
79
91
|
**`AuditOptions`:**
|
|
80
92
|
- `framework?: "jsx" | "mjml" | "maizzle"` — attach framework-specific fix snippets
|
|
81
93
|
- `spam?: SpamAnalysisOptions` — options for spam analysis
|
|
82
|
-
- `skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility">` — skip specific checks
|
|
94
|
+
- `skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility" | "inboxPreview" | "size" | "templateVariables">` — skip specific checks
|
|
83
95
|
|
|
84
96
|
---
|
|
85
97
|
|
|
@@ -99,6 +111,9 @@ const spam = session.analyzeSpam();
|
|
|
99
111
|
const links = session.validateLinks();
|
|
100
112
|
const a11y = session.checkAccessibility();
|
|
101
113
|
const images = session.analyzeImages();
|
|
114
|
+
const preview = session.extractInboxPreview();
|
|
115
|
+
const size = session.checkSize();
|
|
116
|
+
const templates = session.checkTemplateVariables();
|
|
102
117
|
|
|
103
118
|
// Or run everything at once:
|
|
104
119
|
const report = session.audit();
|
|
@@ -122,6 +137,9 @@ const darkMode = session.simulateDarkMode("gmail-web");
|
|
|
122
137
|
| `validateLinks()` | Yes | Link validation |
|
|
123
138
|
| `checkAccessibility()` | Yes | Accessibility audit |
|
|
124
139
|
| `analyzeImages()` | Yes | Image analysis |
|
|
140
|
+
| `extractInboxPreview()` | Yes | Subject line and preheader extraction |
|
|
141
|
+
| `checkSize()` | Yes | Gmail clipping size check |
|
|
142
|
+
| `checkTemplateVariables()` | Yes | Unresolved template variable detection |
|
|
125
143
|
| `transformForClient(clientId)` | No | Transform for one client |
|
|
126
144
|
| `transformForAllClients()` | No | Transform for all 12 clients |
|
|
127
145
|
| `simulateDarkMode(clientId)` | No | Dark mode simulation |
|
|
@@ -219,6 +237,47 @@ const report = analyzeImages(html);
|
|
|
219
237
|
|
|
220
238
|
**Checks:** missing dimensions, oversized data URIs, missing alt, WebP/SVG format, missing `display:block`, tracking pixels, high image count.
|
|
221
239
|
|
|
240
|
+
### `extractInboxPreview(html: string): InboxPreview`
|
|
241
|
+
|
|
242
|
+
Extracts subject line (from `<title>`) and preheader text from the email HTML. Returns per-client truncation data showing how subject and preheader will appear across 8 email clients.
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { extractInboxPreview } from "@emailens/engine";
|
|
246
|
+
|
|
247
|
+
const preview = extractInboxPreview(html);
|
|
248
|
+
// { subject: "Newsletter", preheader: "This week's highlights...",
|
|
249
|
+
// subjectLength: 10, preheaderLength: 28,
|
|
250
|
+
// truncation: [...], issues: [...] }
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Checks:** missing `<title>`, subject too long, missing preheader, preheader too short/long, `‌ ` padding hack, emoji in subject.
|
|
254
|
+
|
|
255
|
+
### `checkSize(html: string): SizeReport`
|
|
256
|
+
|
|
257
|
+
Checks email HTML byte size for Gmail clipping issues. Gmail clips messages larger than ~102KB, hiding content behind a "View entire message" link.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { checkSize } from "@emailens/engine";
|
|
261
|
+
|
|
262
|
+
const report = checkSize(html);
|
|
263
|
+
// { htmlBytes: 45230, humanSize: "44.2 KB", clipped: false, issues: [] }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Checks:** Gmail clipping threshold (102KB), approaching clip threshold warning (90KB).
|
|
267
|
+
|
|
268
|
+
### `checkTemplateVariables(html: string): TemplateReport`
|
|
269
|
+
|
|
270
|
+
Scans email HTML for unresolved template/merge variables in text content and key attributes (`href`, `src`, `alt`).
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { checkTemplateVariables } from "@emailens/engine";
|
|
274
|
+
|
|
275
|
+
const report = checkTemplateVariables(html);
|
|
276
|
+
// { unresolvedCount: 0, issues: [] }
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Detects:** `{{var}}` (Handlebars/Mustache), `${var}` (ES template literals), `<%= %>` (ERB/EJS), `*|TAG|*` (Mailchimp), `%%tag%%` (Salesforce), `{merge_field}` (single-brace).
|
|
280
|
+
|
|
222
281
|
---
|
|
223
282
|
|
|
224
283
|
### `transformForClient(html, clientId, framework?): TransformResult`
|
|
@@ -329,7 +388,7 @@ try {
|
|
|
329
388
|
|
|
330
389
|
The engine internally parses HTML using [Cheerio](https://cheerio.js.org/). For a typical 50–100KB email, each `cheerio.load()` call takes 5–15ms. Without optimization, calling multiple analysis functions on the same HTML would parse it repeatedly.
|
|
331
390
|
|
|
332
|
-
**`auditEmail()`** parses the HTML once and shares the DOM across all
|
|
391
|
+
**`auditEmail()`** parses the HTML once and shares the DOM across all 8 analyzers (compatibility, spam, links, accessibility, images, inbox preview, size, template variables). Previously each analyzer parsed independently — this eliminates ~80% of parsing overhead in the audit path.
|
|
333
392
|
|
|
334
393
|
**`createSession()`** extends this optimization to any combination of calls. When you need to call `analyzeEmail()` + `analyzeSpam()` + `validateLinks()` + other checks on the same HTML, a session shares a single parse across all of them.
|
|
335
394
|
|
|
@@ -337,7 +396,7 @@ The engine internally parses HTML using [Cheerio](https://cheerio.js.org/). For
|
|
|
337
396
|
|
|
338
397
|
| Operation | Complexity | Notes |
|
|
339
398
|
|---|---|---|
|
|
340
|
-
| `auditEmail()` | 1 parse +
|
|
399
|
+
| `auditEmail()` | 1 parse + 8 analyses | Shared DOM, most efficient for full reports |
|
|
341
400
|
| `createSession()` | 1 parse upfront | Amortized across all subsequent analysis calls |
|
|
342
401
|
| `analyzeEmail()` | 1 parse + CSS property scan | Scans `<style>` blocks + inline styles × 12 clients |
|
|
343
402
|
| `transformForAllClients()` | 12 parses (1 per client) | Each client mutates its own DOM copy |
|
|
@@ -471,6 +530,9 @@ interface AuditReport {
|
|
|
471
530
|
links: LinkReport;
|
|
472
531
|
accessibility: AccessibilityReport;
|
|
473
532
|
images: ImageReport;
|
|
533
|
+
inboxPreview: InboxPreview;
|
|
534
|
+
size: SizeReport;
|
|
535
|
+
templateVariables: TemplateReport;
|
|
474
536
|
}
|
|
475
537
|
|
|
476
538
|
interface EmailSession {
|
|
@@ -483,11 +545,35 @@ interface EmailSession {
|
|
|
483
545
|
validateLinks(): LinkReport;
|
|
484
546
|
checkAccessibility(): AccessibilityReport;
|
|
485
547
|
analyzeImages(): ImageReport;
|
|
548
|
+
extractInboxPreview(): InboxPreview;
|
|
549
|
+
checkSize(): SizeReport;
|
|
550
|
+
checkTemplateVariables(): TemplateReport;
|
|
486
551
|
transformForClient(clientId): TransformResult;
|
|
487
552
|
transformForAllClients(): TransformResult[];
|
|
488
553
|
simulateDarkMode(clientId): { html; warnings };
|
|
489
554
|
}
|
|
490
555
|
|
|
556
|
+
interface InboxPreview {
|
|
557
|
+
subject: string | null;
|
|
558
|
+
preheader: string | null;
|
|
559
|
+
subjectLength: number;
|
|
560
|
+
preheaderLength: number;
|
|
561
|
+
truncation: ClientTruncation[];
|
|
562
|
+
issues: InboxPreviewIssue[];
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
interface SizeReport {
|
|
566
|
+
htmlBytes: number;
|
|
567
|
+
humanSize: string;
|
|
568
|
+
clipped: boolean;
|
|
569
|
+
issues: SizeIssue[];
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
interface TemplateReport {
|
|
573
|
+
unresolvedCount: number;
|
|
574
|
+
issues: TemplateIssue[];
|
|
575
|
+
}
|
|
576
|
+
|
|
491
577
|
interface SpamReport {
|
|
492
578
|
score: number; // 0–100 (100 = clean)
|
|
493
579
|
level: "low" | "medium" | "high";
|
|
@@ -519,7 +605,7 @@ interface ImageReport {
|
|
|
519
605
|
bun test
|
|
520
606
|
```
|
|
521
607
|
|
|
522
|
-
|
|
608
|
+
525 tests covering analysis, transformation, dark mode simulation, framework-aware fixes, AI fix generation, token estimation, spam scoring, link validation, accessibility checking, image analysis, inbox preview extraction, size checking, template variable detection, session API, security hardening, integration pipelines, and accuracy benchmarks.
|
|
523
609
|
|
|
524
610
|
## License
|
|
525
611
|
|
package/dist/compile/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { s as InputFormat } from '../react-email-CYOtHJch.cjs';
|
|
2
|
+
export { k as CompileError, l as CompileReactEmailOptions, u as SandboxStrategy, K as compileReactEmail } from '../react-email-CYOtHJch.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Compile an MJML source string into an HTML email string.
|
package/dist/compile/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { s as InputFormat } from '../react-email-CYOtHJch.js';
|
|
2
|
+
export { k as CompileError, l as CompileReactEmailOptions, u as SandboxStrategy, K as compileReactEmail } from '../react-email-CYOtHJch.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Compile an MJML source string into an HTML email string.
|