@emailens/engine 0.7.0 → 0.8.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 +123 -32
- package/dist/{chunk-ZQF2XUIJ.js → chunk-2NMEKWO5.js} +2 -13
- package/dist/{chunk-3NDQOTPM.js → chunk-E4QE4WXE.js} +2 -2
- package/dist/{chunk-URZ4XPST.js → chunk-HBKZMR7V.js} +2 -2
- package/dist/{chunk-OY3DGZVU.js → chunk-PW6EUG2G.js} +2 -2
- package/dist/chunk-Z22AD2IU.js +14 -0
- package/dist/{chunk-ZQF2XUIJ.js.map → chunk-Z22AD2IU.js.map} +1 -1
- package/dist/compile/index.d.cts +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/compile/index.js +8 -7
- package/dist/compile/index.js.map +1 -1
- package/dist/index.cjs +3250 -511
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -5
- package/dist/index.d.ts +41 -5
- package/dist/index.js +3247 -512
- package/dist/index.js.map +1 -1
- package/dist/maizzle-KKJF7XY7.js +9 -0
- package/dist/mjml-C46UWTTK.js +9 -0
- package/dist/react-email-C-p8ZL37.d.cts +58 -0
- package/dist/react-email-DcseUoOu.d.ts +58 -0
- package/dist/react-email-QKHRTEJW.js +9 -0
- package/dist/react-email-QKHRTEJW.js.map +1 -0
- package/dist/server.cjs +368 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +80 -0
- package/dist/server.d.ts +80 -0
- package/dist/server.js +342 -0
- package/dist/server.js.map +1 -0
- package/dist/{react-email-CYOtHJch.d.cts → types-4P9AtKm_.d.cts} +18 -54
- package/dist/{react-email-CYOtHJch.d.ts → types-4P9AtKm_.d.ts} +18 -54
- package/package.json +13 -6
- package/dist/maizzle-Y2CLJ7GB.js +0 -8
- package/dist/mjml-D7IOYXXK.js +0 -8
- package/dist/react-email-4TW6IDAA.js +0 -8
- /package/dist/{maizzle-Y2CLJ7GB.js.map → chunk-2NMEKWO5.js.map} +0 -0
- /package/dist/{chunk-3NDQOTPM.js.map → chunk-E4QE4WXE.js.map} +0 -0
- /package/dist/{chunk-URZ4XPST.js.map → chunk-HBKZMR7V.js.map} +0 -0
- /package/dist/{chunk-OY3DGZVU.js.map → chunk-PW6EUG2G.js.map} +0 -0
- /package/dist/{mjml-D7IOYXXK.js.map → maizzle-KKJF7XY7.js.map} +0 -0
- /package/dist/{react-email-4TW6IDAA.js.map → mjml-C46UWTTK.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,64 +1,82 @@
|
|
|
1
1
|
# @emailens/engine
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Your email looks perfect in Apple Mail. Gmail strips half the CSS. Outlook renders it in Word.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@emailens/engine` analyzes your HTML against 250+ CSS properties across 12 email clients, scores compatibility, and shows you exactly what to fix — before you hit send.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Quick Start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install @emailens/engine
|
|
11
|
-
# or
|
|
12
|
-
bun add @emailens/engine
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
Requires Node.js >= 18.
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
13
|
```typescript
|
|
20
14
|
import { auditEmail } from "@emailens/engine";
|
|
21
15
|
|
|
16
|
+
// Flexbox + gap + box-shadow — all Outlook killers
|
|
22
17
|
const html = `<html lang="en">
|
|
23
|
-
<head><title>
|
|
24
|
-
<style
|
|
18
|
+
<head><title>Weekly Update</title>
|
|
19
|
+
<style>
|
|
20
|
+
.card { border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
|
21
|
+
</style>
|
|
25
22
|
</head>
|
|
26
23
|
<body>
|
|
27
24
|
<div class="card" style="display: flex; gap: 16px;">
|
|
28
25
|
<div>Column A</div>
|
|
29
26
|
<div>Column B</div>
|
|
30
27
|
</div>
|
|
31
|
-
<a href="https://example.com/unsubscribe">Unsubscribe</a>
|
|
32
28
|
</body>
|
|
33
29
|
</html>`;
|
|
34
30
|
|
|
35
|
-
// Run all checks in one call
|
|
36
31
|
const report = auditEmail(html, { framework: "jsx" });
|
|
37
32
|
|
|
33
|
+
console.log(report.compatibility.scores["outlook-windows"]);
|
|
34
|
+
// { score: 30, errors: 3, warnings: 3, info: 1 }
|
|
35
|
+
// ↑ Outlook uses Word — flexbox, gap, box-shadow, border-radius all break
|
|
36
|
+
|
|
38
37
|
console.log(report.compatibility.scores["gmail-web"]);
|
|
39
38
|
// { score: 75, errors: 0, warnings: 5, info: 0 }
|
|
40
39
|
|
|
41
|
-
console.log(report.spam);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// 88
|
|
40
|
+
console.log(report.spam.score); // 100 (clean)
|
|
41
|
+
console.log(report.accessibility.score); // 88
|
|
42
|
+
console.log(report.size.clipped); // false (under Gmail's 102KB limit)
|
|
43
|
+
```
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
// 1
|
|
45
|
+
Score too low? Fix it automatically:
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
```typescript
|
|
48
|
+
import { generateAiFix, AI_FIX_SYSTEM_PROMPT } from "@emailens/engine";
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const { code } = await generateAiFix({
|
|
51
|
+
originalHtml: html,
|
|
52
|
+
warnings: report.compatibility.warnings,
|
|
53
|
+
scores: report.compatibility.scores,
|
|
54
|
+
scope: "outlook-windows",
|
|
55
|
+
format: "jsx",
|
|
56
|
+
provider: async (prompt) => {
|
|
57
|
+
// Any LLM — Claude, GPT, etc.
|
|
58
|
+
const msg = await anthropic.messages.create({
|
|
59
|
+
model: "claude-sonnet-4-6",
|
|
60
|
+
max_tokens: 8192,
|
|
61
|
+
system: AI_FIX_SYSTEM_PROMPT,
|
|
62
|
+
messages: [{ role: "user", content: prompt }],
|
|
63
|
+
});
|
|
64
|
+
return msg.content[0].type === "text" ? msg.content[0].text : "";
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
// code → JSX with <Table> layout, VML roundrects, inline fallbacks
|
|
68
|
+
```
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
// false
|
|
70
|
+
## What It Catches
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
- **CSS compatibility** — 250+ properties tested across 12 email clients, with fix snippets and AI-powered auto-fix
|
|
73
|
+
- **Spam scoring** — 45+ signals modeled after SpamAssassin, CAN-SPAM, and GDPR
|
|
74
|
+
- **Accessibility** — WCAG contrast ratios, alt text, semantic structure, heading hierarchy
|
|
75
|
+
- **Link validation** — broken hrefs, insecure HTTP, `javascript:` protocols, deceptive URLs
|
|
76
|
+
- **Image analysis** — missing dimensions, oversized data URIs, tracking pixels, WebP/SVG format
|
|
77
|
+
- **Inbox preview** — subject/preheader truncation per client, Gmail clipping detection
|
|
78
|
+
- **Domain authentication** — SPF, DKIM, DMARC, MX, and BIMI DNS record validation
|
|
79
|
+
- **Template variables** — unresolved merge tags across 6 template systems (Handlebars, ERB, Mailchimp, etc.)
|
|
62
80
|
|
|
63
81
|
## API Reference
|
|
64
82
|
|
|
@@ -140,6 +158,7 @@ const darkMode = session.simulateDarkMode("gmail-web");
|
|
|
140
158
|
| `extractInboxPreview()` | Yes | Subject line and preheader extraction |
|
|
141
159
|
| `checkSize()` | Yes | Gmail clipping size check |
|
|
142
160
|
| `checkTemplateVariables()` | Yes | Unresolved template variable detection |
|
|
161
|
+
| `checkDeliverability(domain)` | — | DNS deliverability check (async, SPF/DKIM/DMARC/MX/BIMI) |
|
|
143
162
|
| `transformForClient(clientId)` | No | Transform for one client |
|
|
144
163
|
| `transformForAllClients()` | No | Transform for all 12 clients |
|
|
145
164
|
| `simulateDarkMode(clientId)` | No | Dark mode simulation |
|
|
@@ -184,7 +203,9 @@ Get only warnings that require HTML restructuring (`fixType: "structural"`).
|
|
|
184
203
|
|
|
185
204
|
### `analyzeSpam(html: string, options?: SpamAnalysisOptions): SpamReport`
|
|
186
205
|
|
|
187
|
-
Analyzes an HTML email for spam
|
|
206
|
+
Analyzes an HTML email for spam scoring issues. Returns a 0–100 score (100 = clean) and an array of issues. Uses heuristic rules modeled after SpamAssassin, CAN-SPAM, and GDPR.
|
|
207
|
+
|
|
208
|
+
> **Note:** Spam scoring heuristics — not a real spam filter. This checks for common anti-patterns that trigger spam filters but cannot predict actual inbox placement. For real spam testing, use the `checkSpamAssassin()` integration or a dedicated service.
|
|
188
209
|
|
|
189
210
|
```typescript
|
|
190
211
|
import { analyzeSpam } from "@emailens/engine";
|
|
@@ -280,6 +301,49 @@ const report = checkTemplateVariables(html);
|
|
|
280
301
|
|
|
281
302
|
---
|
|
282
303
|
|
|
304
|
+
### `checkDeliverability(domain, options?): Promise<DeliverabilityReport>`
|
|
305
|
+
|
|
306
|
+
Validates email deliverability for a domain by checking MX, SPF, DKIM, DMARC, and BIMI DNS records. All DNS queries have a 5-second timeout. No external dependencies — uses `node:dns/promises`.
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import { checkDeliverability } from "@emailens/engine";
|
|
310
|
+
|
|
311
|
+
const report = await checkDeliverability("example.com");
|
|
312
|
+
console.log(report.score); // 0-100
|
|
313
|
+
console.log(report.checks); // individual check results
|
|
314
|
+
console.log(report.issues); // actionable issues
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Checks:**
|
|
318
|
+
- **MX** — domain can receive email
|
|
319
|
+
- **SPF** — authorized senders (`v=spf1`), flags dangerous `+all`
|
|
320
|
+
- **DKIM** — probes 15 common selectors (`google`, `selector1`, `default`, `dkim`, etc.)
|
|
321
|
+
- **DMARC** — policy enforcement (`v=DMARC1`), warns on `p=none`
|
|
322
|
+
- **BIMI** — brand indicator (optional, nice-to-have)
|
|
323
|
+
|
|
324
|
+
Also available as a session method: `session.checkDeliverability("example.com")`.
|
|
325
|
+
|
|
326
|
+
> **Note:** This is standalone async — not wired into the synchronous `auditEmail()` pipeline.
|
|
327
|
+
|
|
328
|
+
### `checkSpamAssassin(input, options?): Promise<SpamAssassinResult | null>`
|
|
329
|
+
|
|
330
|
+
Opt-in integration with a local SpamAssassin installation. Shells out to `spamc` (daemon) or `spamassassin` (standalone) via `execFile`. Returns `null` if SpamAssassin is not installed.
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import { checkSpamAssassin } from "@emailens/engine";
|
|
334
|
+
|
|
335
|
+
const result = await checkSpamAssassin(rawRfc2822Message);
|
|
336
|
+
if (result) {
|
|
337
|
+
console.log(result.score); // e.g. 3.2
|
|
338
|
+
console.log(result.isSpam); // true if score >= threshold
|
|
339
|
+
console.log(result.rules); // matched SpamAssassin rules
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
> **Note:** Requires a full RFC 2822 message (headers + body), not just HTML.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
283
347
|
### `transformForClient(html, clientId, framework?): TransformResult`
|
|
284
348
|
|
|
285
349
|
Transforms HTML for a specific email client — strips unsupported CSS, inlines `<style>` blocks (for Gmail), removes unsupported elements.
|
|
@@ -597,15 +661,42 @@ interface ImageReport {
|
|
|
597
661
|
issues: ImageIssue[];
|
|
598
662
|
images: ImageInfo[];
|
|
599
663
|
}
|
|
664
|
+
|
|
665
|
+
interface DeliverabilityReport {
|
|
666
|
+
domain: string;
|
|
667
|
+
checks: DeliverabilityCheck[];
|
|
668
|
+
score: number; // 0-100
|
|
669
|
+
issues: DeliverabilityIssue[];
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
interface DeliverabilityCheck {
|
|
673
|
+
name: "spf" | "dkim" | "dmarc" | "mx" | "bimi";
|
|
674
|
+
status: "pass" | "fail" | "warn" | "skip";
|
|
675
|
+
message: string;
|
|
676
|
+
detail?: string;
|
|
677
|
+
record?: string;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
interface SpamAssassinResult {
|
|
681
|
+
score: number;
|
|
682
|
+
threshold: number;
|
|
683
|
+
isSpam: boolean;
|
|
684
|
+
rules: Array<{ name: string; score: number; description: string }>;
|
|
685
|
+
rawOutput: string;
|
|
686
|
+
}
|
|
600
687
|
```
|
|
601
688
|
|
|
602
|
-
##
|
|
689
|
+
## Contributing
|
|
690
|
+
|
|
691
|
+
Contributions are welcome! Please [open an issue](https://github.com/nicholasgriffintn/emailens/issues) to discuss your idea before submitting a PR.
|
|
603
692
|
|
|
604
693
|
```bash
|
|
605
694
|
bun test
|
|
606
695
|
```
|
|
607
696
|
|
|
608
|
-
|
|
697
|
+
574 tests covering CSS analysis (250+ properties), 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, DNS deliverability checking, session API, security hardening, integration pipelines, accuracy benchmarks, and battle tests.
|
|
698
|
+
|
|
699
|
+
**Project structure:** analysis modules live in `src/`, each with a corresponding test file in `tests/`. The engine parses HTML once and shares the DOM across all analyzers.
|
|
609
700
|
|
|
610
701
|
## License
|
|
611
702
|
|
|
@@ -30,20 +30,9 @@ var __objRest = (source, exclude) => {
|
|
|
30
30
|
return target;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
// src/compile/errors.ts
|
|
34
|
-
var CompileError = class extends Error {
|
|
35
|
-
constructor(message, format, phase) {
|
|
36
|
-
super(message);
|
|
37
|
-
this.name = "CompileError";
|
|
38
|
-
this.format = format;
|
|
39
|
-
this.phase = phase;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
33
|
export {
|
|
44
34
|
__spreadValues,
|
|
45
35
|
__spreadProps,
|
|
46
|
-
__objRest
|
|
47
|
-
CompileError
|
|
36
|
+
__objRest
|
|
48
37
|
};
|
|
49
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
//# sourceMappingURL=chunk-2NMEKWO5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompileError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z22AD2IU.js";
|
|
4
4
|
|
|
5
5
|
// src/compile/mjml.ts
|
|
6
6
|
var MAX_SOURCE_SIZE = 512e3;
|
|
@@ -61,4 +61,4 @@ async function compileMjml(source) {
|
|
|
61
61
|
export {
|
|
62
62
|
compileMjml
|
|
63
63
|
};
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
64
|
+
//# sourceMappingURL=chunk-E4QE4WXE.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompileError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z22AD2IU.js";
|
|
4
4
|
|
|
5
5
|
// src/compile/react-email.ts
|
|
6
6
|
var MAX_SOURCE_SIZE = 256e3;
|
|
@@ -356,4 +356,4 @@ async function executeInQuickJs(code, React, ReactEmailComponents) {
|
|
|
356
356
|
export {
|
|
357
357
|
compileReactEmail
|
|
358
358
|
};
|
|
359
|
-
//# sourceMappingURL=chunk-
|
|
359
|
+
//# sourceMappingURL=chunk-HBKZMR7V.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompileError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z22AD2IU.js";
|
|
4
4
|
|
|
5
5
|
// src/compile/maizzle.ts
|
|
6
6
|
var MAX_SOURCE_SIZE = 512e3;
|
|
@@ -75,4 +75,4 @@ async function compileMaizzle(source) {
|
|
|
75
75
|
export {
|
|
76
76
|
compileMaizzle
|
|
77
77
|
};
|
|
78
|
-
//# sourceMappingURL=chunk-
|
|
78
|
+
//# sourceMappingURL=chunk-PW6EUG2G.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/compile/errors.ts
|
|
2
|
+
var CompileError = class extends Error {
|
|
3
|
+
constructor(message, format, phase) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "CompileError";
|
|
6
|
+
this.format = format;
|
|
7
|
+
this.phase = phase;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
CompileError
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=chunk-Z22AD2IU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/compile/errors.ts"],"sourcesContent":["import type { InputFormat } from \"../types.js\";\r\n\r\n/**\r\n * Unified error class for all email compilation failures.\r\n *\r\n * Replaces the per-format error classes (ReactEmailCompileError,\r\n * MjmlCompileError, MaizzleCompileError) with a single class that\r\n * carries the source format and failure phase.\r\n */\r\nexport class CompileError extends Error {\r\n override name = \"CompileError\";\r\n readonly format: Exclude<InputFormat, \"html\">;\r\n readonly phase: \"validation\" | \"transpile\" | \"execution\" | \"render\" | \"compile\";\r\n\r\n constructor(\r\n message: string,\r\n format: CompileError[\"format\"],\r\n phase: CompileError[\"phase\"],\r\n ) {\r\n super(message);\r\n this.format = format;\r\n this.phase = phase;\r\n }\r\n}\r\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/compile/errors.ts"],"sourcesContent":["import type { InputFormat } from \"../types.js\";\r\n\r\n/**\r\n * Unified error class for all email compilation failures.\r\n *\r\n * Replaces the per-format error classes (ReactEmailCompileError,\r\n * MjmlCompileError, MaizzleCompileError) with a single class that\r\n * carries the source format and failure phase.\r\n */\r\nexport class CompileError extends Error {\r\n override name = \"CompileError\";\r\n readonly format: Exclude<InputFormat, \"html\">;\r\n readonly phase: \"validation\" | \"transpile\" | \"execution\" | \"render\" | \"compile\";\r\n\r\n constructor(\r\n message: string,\r\n format: CompileError[\"format\"],\r\n phase: CompileError[\"phase\"],\r\n ) {\r\n super(message);\r\n this.format = format;\r\n this.phase = phase;\r\n }\r\n}\r\n"],"mappings":";AASO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAKtC,YACE,SACA,QACA,OACA;AACA,UAAM,OAAO;AATf,SAAS,OAAO;AAUd,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AACF;","names":[]}
|
package/dist/compile/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { u as InputFormat } from '../types-4P9AtKm_.cjs';
|
|
2
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy, c as compileReactEmail } from '../react-email-C-p8ZL37.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 { u as InputFormat } from '../types-4P9AtKm_.js';
|
|
2
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy, c as compileReactEmail } from '../react-email-DcseUoOu.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Compile an MJML source string into an HTML email string.
|
package/dist/compile/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compileReactEmail
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-HBKZMR7V.js";
|
|
4
4
|
import {
|
|
5
5
|
compileMjml
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-E4QE4WXE.js";
|
|
7
7
|
import {
|
|
8
8
|
compileMaizzle
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-PW6EUG2G.js";
|
|
10
10
|
import {
|
|
11
11
|
CompileError
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-Z22AD2IU.js";
|
|
13
|
+
import "../chunk-2NMEKWO5.js";
|
|
13
14
|
|
|
14
15
|
// src/compile/index.ts
|
|
15
16
|
import { extname } from "path";
|
|
@@ -18,15 +19,15 @@ async function compile(source, format, filePath) {
|
|
|
18
19
|
case "html":
|
|
19
20
|
return source;
|
|
20
21
|
case "jsx": {
|
|
21
|
-
const { compileReactEmail: compileReactEmail2 } = await import("../react-email-
|
|
22
|
+
const { compileReactEmail: compileReactEmail2 } = await import("../react-email-QKHRTEJW.js");
|
|
22
23
|
return compileReactEmail2(source);
|
|
23
24
|
}
|
|
24
25
|
case "mjml": {
|
|
25
|
-
const { compileMjml: compileMjml2 } = await import("../mjml-
|
|
26
|
+
const { compileMjml: compileMjml2 } = await import("../mjml-C46UWTTK.js");
|
|
26
27
|
return compileMjml2(source);
|
|
27
28
|
}
|
|
28
29
|
case "maizzle": {
|
|
29
|
-
const { compileMaizzle: compileMaizzle2 } = await import("../maizzle-
|
|
30
|
+
const { compileMaizzle: compileMaizzle2 } = await import("../maizzle-KKJF7XY7.js");
|
|
30
31
|
return compileMaizzle2(source);
|
|
31
32
|
}
|
|
32
33
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/compile/index.ts"],"sourcesContent":["import { extname } from \"node:path\";\r\nimport type { InputFormat } from \"../types.js\";\r\n\r\nexport { CompileError } from \"./errors.js\";\r\nexport { compileReactEmail } from \"./react-email.js\";\r\nexport type { SandboxStrategy, CompileReactEmailOptions } from \"./react-email.js\";\r\nexport { compileMjml } from \"./mjml.js\";\r\nexport { compileMaizzle } from \"./maizzle.js\";\r\n\r\n/**\r\n * Compile source to HTML based on format.\r\n * Returns the HTML unchanged if format is \"html\".\r\n * Lazily imports per-format compilers to avoid loading unnecessary deps.\r\n */\r\nexport async function compile(\r\n source: string,\r\n format: InputFormat,\r\n filePath?: string,\r\n): Promise<string> {\r\n switch (format) {\r\n case \"html\":\r\n return source;\r\n\r\n case \"jsx\": {\r\n const { compileReactEmail } = await import(\"./react-email.js\");\r\n return compileReactEmail(source);\r\n }\r\n\r\n case \"mjml\": {\r\n const { compileMjml } = await import(\"./mjml.js\");\r\n return compileMjml(source);\r\n }\r\n\r\n case \"maizzle\": {\r\n const { compileMaizzle } = await import(\"./maizzle.js\");\r\n return compileMaizzle(source);\r\n }\r\n\r\n default:\r\n throw new Error(`Unknown format: \"${format}\". Use html, jsx, mjml, or maizzle.`);\r\n }\r\n}\r\n\r\n/**\r\n * Auto-detect input format from file extension.\r\n */\r\nexport function detectFormat(filePath: string): InputFormat {\r\n const ext = extname(filePath).toLowerCase();\r\n\r\n switch (ext) {\r\n case \".tsx\":\r\n case \".jsx\":\r\n return \"jsx\";\r\n case \".mjml\":\r\n return \"mjml\";\r\n case \".html\":\r\n case \".htm\":\r\n return \"html\";\r\n default:\r\n return \"html\";\r\n }\r\n}\r\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/compile/index.ts"],"sourcesContent":["import { extname } from \"node:path\";\r\nimport type { InputFormat } from \"../types.js\";\r\n\r\nexport { CompileError } from \"./errors.js\";\r\nexport { compileReactEmail } from \"./react-email.js\";\r\nexport type { SandboxStrategy, CompileReactEmailOptions } from \"./react-email.js\";\r\nexport { compileMjml } from \"./mjml.js\";\r\nexport { compileMaizzle } from \"./maizzle.js\";\r\n\r\n/**\r\n * Compile source to HTML based on format.\r\n * Returns the HTML unchanged if format is \"html\".\r\n * Lazily imports per-format compilers to avoid loading unnecessary deps.\r\n */\r\nexport async function compile(\r\n source: string,\r\n format: InputFormat,\r\n filePath?: string,\r\n): Promise<string> {\r\n switch (format) {\r\n case \"html\":\r\n return source;\r\n\r\n case \"jsx\": {\r\n const { compileReactEmail } = await import(\"./react-email.js\");\r\n return compileReactEmail(source);\r\n }\r\n\r\n case \"mjml\": {\r\n const { compileMjml } = await import(\"./mjml.js\");\r\n return compileMjml(source);\r\n }\r\n\r\n case \"maizzle\": {\r\n const { compileMaizzle } = await import(\"./maizzle.js\");\r\n return compileMaizzle(source);\r\n }\r\n\r\n default:\r\n throw new Error(`Unknown format: \"${format}\". Use html, jsx, mjml, or maizzle.`);\r\n }\r\n}\r\n\r\n/**\r\n * Auto-detect input format from file extension.\r\n */\r\nexport function detectFormat(filePath: string): InputFormat {\r\n const ext = extname(filePath).toLowerCase();\r\n\r\n switch (ext) {\r\n case \".tsx\":\r\n case \".jsx\":\r\n return \"jsx\";\r\n case \".mjml\":\r\n return \"mjml\";\r\n case \".html\":\r\n case \".htm\":\r\n return \"html\";\r\n default:\r\n return \"html\";\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAcxB,eAAsB,QACpB,QACA,QACA,UACiB;AACjB,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IAET,KAAK,OAAO;AACV,YAAM,EAAE,mBAAAA,mBAAkB,IAAI,MAAM,OAAO,4BAAkB;AAC7D,aAAOA,mBAAkB,MAAM;AAAA,IACjC;AAAA,IAEA,KAAK,QAAQ;AACX,YAAM,EAAE,aAAAC,aAAY,IAAI,MAAM,OAAO,qBAAW;AAChD,aAAOA,aAAY,MAAM;AAAA,IAC3B;AAAA,IAEA,KAAK,WAAW;AACd,YAAM,EAAE,gBAAAC,gBAAe,IAAI,MAAM,OAAO,wBAAc;AACtD,aAAOA,gBAAe,MAAM;AAAA,IAC9B;AAAA,IAEA;AACE,YAAM,IAAI,MAAM,oBAAoB,MAAM,qCAAqC;AAAA,EACnF;AACF;AAKO,SAAS,aAAa,UAA+B;AAC1D,QAAM,MAAM,QAAQ,QAAQ,EAAE,YAAY;AAE1C,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;","names":["compileReactEmail","compileMjml","compileMaizzle"]}
|