@emailens/engine 0.10.3 → 0.11.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 +30 -27
- package/dist/{chunk-HBKZMR7V.js → chunk-UFSYNSDP.js} +1 -1
- package/dist/chunk-UFSYNSDP.js.map +1 -0
- package/dist/compile/index.cjs.map +1 -1
- package/dist/compile/index.d.cts +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/compile/index.js +2 -2
- package/dist/index.cjs +1063 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +107 -15
- package/dist/index.d.ts +107 -15
- package/dist/index.js +1055 -170
- package/dist/index.js.map +1 -1
- package/dist/{react-email-DwBWB2kr.d.ts → react-email-BWIfwG7U.d.cts} +5 -5
- package/dist/{react-email-QKHRTEJW.js → react-email-CVZZNVZ2.js} +2 -2
- package/dist/{react-email-DTzVpGgB.d.cts → react-email-D24HkW2Z.d.ts} +5 -5
- package/dist/server.cjs +10 -10
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +10 -10
- package/dist/server.js.map +1 -1
- package/dist/{types-BLR3-Fzo.d.cts → types-BFhPXh3c.d.cts} +25 -9
- package/dist/{types-BLR3-Fzo.d.ts → types-BFhPXh3c.d.ts} +25 -9
- package/package.json +7 -3
- package/dist/chunk-HBKZMR7V.js.map +0 -1
- /package/dist/{react-email-QKHRTEJW.js.map → react-email-CVZZNVZ2.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { E as EmailClient, F as Framework, T as TransformResult, C as CSSWarning, a as CodeFix, D as DiffResult, b as ExportPromptOptions, A as AiProvider, c as AiFixResult, S as SupportLevel, d as SpamAnalysisOptions, e as SpamReport, L as LinkReport, f as AccessibilityReport, I as ImageReport,
|
|
2
|
-
export {
|
|
3
|
-
|
|
1
|
+
import { E as EmailClient, F as Framework, T as TransformResult, C as CSSWarning, a as CodeFix, D as DiffResult, b as ExportPromptOptions, A as AiProvider, c as AiFixResult, S as SupportLevel, d as SpamAnalysisOptions, e as SpamReport, L as LinkReport, f as AccessibilityReport, g as AccessibilityIssue, I as ImageReport, h as InboxPreview, i as SizeReport, j as TemplateReport, O as OverflowReport, V as VisualReport, k as DesignReport, l as DeliverabilityReport } from './types-BFhPXh3c.cjs';
|
|
2
|
+
export { B as BaseIssue, m as ClientTruncation, n as DeliverabilityCheck, o as DeliverabilityIssue, p as DesignIssue, q as EstimateOptions, r as ExportScope, s as FixType, t as ImageInfo, u as ImageIssue, v as InboxPreviewIssue, w as InputFormat, x as LinkIssue, y as OverflowIssue, P as PreviewResult, z as Severity, G as SizeIssue, H as SourceLocation, J as SpamIssue, K as TemplateIssue, M as TokenEstimate, N as TokenEstimateWithWarnings, Q as VisualIssue, R as estimateAiFixTokens, U as generateFixPrompt, W as heuristicTokenCount } from './types-BFhPXh3c.cjs';
|
|
3
|
+
import * as cheerio from 'cheerio';
|
|
4
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-BWIfwG7U.cjs';
|
|
4
5
|
|
|
5
6
|
declare const EMAIL_CLIENTS: EmailClient[];
|
|
6
7
|
declare function getClient(id: string): EmailClient | undefined;
|
|
@@ -13,7 +14,7 @@ interface ParseOptions {
|
|
|
13
14
|
/**
|
|
14
15
|
* Record source positions so issues carry a `loc`. Costs a little parse time
|
|
15
16
|
* (parse5 tracks a location record per node and per attribute), so it is
|
|
16
|
-
* opt-in for callers that need to point at the source
|
|
17
|
+
* opt-in for callers that need to point at the source: editors, CI
|
|
17
18
|
* annotations, agents.
|
|
18
19
|
*/
|
|
19
20
|
positions?: boolean;
|
|
@@ -24,7 +25,7 @@ interface ParseOptions {
|
|
|
24
25
|
* for all target email clients.
|
|
25
26
|
*
|
|
26
27
|
* The `framework` parameter controls which fix snippets are attached
|
|
27
|
-
* to warnings
|
|
28
|
+
* to warnings; it does NOT change which warnings fire. Analysis always
|
|
28
29
|
* runs on compiled HTML (what email clients actually receive). Fix
|
|
29
30
|
* snippets reference source-level constructs so users know how to
|
|
30
31
|
* modify their framework source code.
|
|
@@ -128,7 +129,7 @@ interface GenerateAiFixOptions extends ExportPromptOptions {
|
|
|
128
129
|
* to build a structured prompt, then delegates to an LLM for context-aware
|
|
129
130
|
* structural fixes that static snippets cannot handle.
|
|
130
131
|
*
|
|
131
|
-
* The engine stays provider-agnostic
|
|
132
|
+
* The engine stays provider-agnostic: consumers pass their own `AiProvider`
|
|
132
133
|
* callback (Anthropic SDK, Vercel AI SDK, OpenRouter, etc.).
|
|
133
134
|
*
|
|
134
135
|
* @example
|
|
@@ -166,10 +167,10 @@ declare function generateAiFix(options: GenerateAiFixOptions): Promise<AiFixResu
|
|
|
166
167
|
* System prompt for the AI fix provider. Consumers should pass this as
|
|
167
168
|
* the `system` parameter to their LLM call for best results.
|
|
168
169
|
*/
|
|
169
|
-
declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer specializing in cross-client HTML email compatibility. You fix emails to render correctly across all email clients.\n\nRules:\n- Return ONLY the fixed code inside a single code fence. No explanations before or after.\n- Preserve all existing content, text, links, and visual design.\n- For structural issues (fixType: \"structural\"), you MUST restructure the HTML
|
|
170
|
+
declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer specializing in cross-client HTML email compatibility. You fix emails to render correctly across all email clients.\n\nRules:\n- Return ONLY the fixed code inside a single code fence. No explanations before or after.\n- Preserve all existing content, text, links, and visual design.\n- For structural issues (fixType: \"structural\"), you MUST restructure the HTML; CSS-only changes will not work.\n- Common structural patterns:\n - word-break/overflow-wrap unsupported \u2192 wrap text in <table><tr><td> with constrained width\n - display:flex/grid \u2192 convert to <table> layout (match the original column count and proportions)\n - border-radius in Outlook \u2192 use VML <v:roundrect> with <!--[if mso]> conditionals\n - background-image in Outlook \u2192 use VML <v:rect> with <v:fill>\n - max-width in Outlook \u2192 wrap in <!--[if mso]><table width=\"N\"> conditional\n - position:absolute \u2192 use <table> cells for layout\n - <svg> \u2192 replace with <img> pointing to a hosted PNG\n- For CSS-only issues (fixType: \"css\"), swap properties or add fallbacks.\n- For \"Layout & Visual Issues\", apply the provided Fix directly: add the background-color fallback beneath a gradient/image, append a web-safe font to the stack, and constrain fixed widths wider than the frame to width:100% with max-width.\n- Apply ALL fixes from the issues list: do not skip any.\n- Use the framework syntax specified (JSX/MJML/Maizzle/HTML).\n- For JSX: use camelCase style props, React Email components, and proper TypeScript types.\n- For MJML: use mj-* elements and attributes.\n- For Maizzle: use Tailwind CSS classes.";
|
|
170
171
|
|
|
171
172
|
/**
|
|
172
|
-
* CSS/HTML feature support matrix
|
|
173
|
+
* CSS/HTML feature support matrix, auto-generated from caniemail.com.
|
|
173
174
|
* Last synced: 2026-07-28
|
|
174
175
|
* caniemail last updated: 2026-07-20 09:56:37 +0000
|
|
175
176
|
*
|
|
@@ -186,11 +187,11 @@ declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer speciali
|
|
|
186
187
|
* - hey-mail: caniemail.com (WebKit-based)
|
|
187
188
|
* - superhuman: Manual overrides (Chromium/Blink-based, best-effort estimates)
|
|
188
189
|
*
|
|
189
|
-
* DO NOT EDIT
|
|
190
|
+
* DO NOT EDIT; regenerate with: bun run sync:caniemail
|
|
190
191
|
*/
|
|
191
192
|
declare const CSS_SUPPORT: Record<string, Record<string, SupportLevel>>;
|
|
192
193
|
/**
|
|
193
|
-
* Caveat notes per (feature, client) from caniemail
|
|
194
|
+
* Caveat notes per (feature, client) from caniemail: the "why" behind a
|
|
194
195
|
* partial/buggy/unsupported rating. Sparse: only cells with a note appear.
|
|
195
196
|
*/
|
|
196
197
|
declare const CSS_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
|
|
@@ -208,6 +209,19 @@ declare const COMPOUND_VALUE_FEATURES: readonly ["::after", "::before", "::first
|
|
|
208
209
|
/** CSS function features (e.g., "linear-gradient"). */
|
|
209
210
|
declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
|
|
210
211
|
|
|
212
|
+
/**
|
|
213
|
+
* caniemail's page for each feature, for a diagnostic's `codeDescription`.
|
|
214
|
+
*
|
|
215
|
+
* 250 of 255 features. The rest have no caniemail entry of
|
|
216
|
+
* their own and get no link, which is the honest outcome: a link to a 404
|
|
217
|
+
* is worse than none.
|
|
218
|
+
*
|
|
219
|
+
* DO NOT EDIT; regenerate with: bun run sync:feature-urls
|
|
220
|
+
*/
|
|
221
|
+
declare const FEATURE_URLS: Record<string, string>;
|
|
222
|
+
/** Where to read about a rule, when there is somewhere. */
|
|
223
|
+
declare function featureUrl(code: string): string | undefined;
|
|
224
|
+
|
|
211
225
|
/**
|
|
212
226
|
* Properties whose "partial" rating is value-level: the property usually
|
|
213
227
|
* renders fine and only specific values hit the caveat. For these the warning
|
|
@@ -226,7 +240,7 @@ declare const VALUE_CAVEAT_PROPS: ReadonlySet<string>;
|
|
|
226
240
|
* applies if either does.
|
|
227
241
|
*
|
|
228
242
|
* Returns true (report it) for a property that isn't value-gated, and for one
|
|
229
|
-
* where we never saw a value
|
|
243
|
+
* where we never saw a value: an at-rule, a pseudo-class, a detected CSS
|
|
230
244
|
* function.
|
|
231
245
|
*/
|
|
232
246
|
declare function caveatApplies(prop: string, values: readonly string[] | undefined, notes: string[] | undefined): boolean;
|
|
@@ -254,6 +268,20 @@ declare function analyzeSpam(html: string, options?: SpamAnalysisOptions): SpamR
|
|
|
254
268
|
*/
|
|
255
269
|
declare function validateLinks(html: string, options?: ParseOptions): LinkReport;
|
|
256
270
|
|
|
271
|
+
/**
|
|
272
|
+
* The render a cascade is being resolved for.
|
|
273
|
+
*
|
|
274
|
+
* An email has more than one correct answer: the same CSS produces a different
|
|
275
|
+
* palette on a phone and in dark mode, and a contrast bug can live in only one
|
|
276
|
+
* of them. Resolving against an explicit context is what lets the same
|
|
277
|
+
* machinery grade all three.
|
|
278
|
+
*/
|
|
279
|
+
interface RenderContext {
|
|
280
|
+
/** Viewport width in px, for width media queries. */
|
|
281
|
+
width: number;
|
|
282
|
+
/** Whether `prefers-color-scheme: dark` matches. */
|
|
283
|
+
dark: boolean;
|
|
284
|
+
}
|
|
257
285
|
/**
|
|
258
286
|
* Audit an HTML email for accessibility issues.
|
|
259
287
|
*
|
|
@@ -262,6 +290,43 @@ declare function validateLinks(html: string, options?: ParseOptions): LinkReport
|
|
|
262
290
|
* color contrast. Returns a 0–100 score and detailed issues.
|
|
263
291
|
*/
|
|
264
292
|
declare function checkAccessibility(html: string, options?: ParseOptions): AccessibilityReport;
|
|
293
|
+
/**
|
|
294
|
+
* Contrast failures inside the email's own `@media (prefers-color-scheme: dark)`
|
|
295
|
+
* styles.
|
|
296
|
+
*
|
|
297
|
+
* This is the other half of dark mode, and the half the author actually
|
|
298
|
+
* controls: Apple Mail, Superhuman, Thunderbird and friends do not invert
|
|
299
|
+
* anything, they just apply the dark block as written. A dark background
|
|
300
|
+
* paired with body text that was never re-coloured is invisible there, and no
|
|
301
|
+
* amount of inversion analysis finds it; the bug is in the CSS, not in what
|
|
302
|
+
* the client does to it.
|
|
303
|
+
*
|
|
304
|
+
* Free to run: same DOM, resolved against a dark render, so positions stay
|
|
305
|
+
* valid. Emails with no dark block resolve identically to the light pass and
|
|
306
|
+
* report nothing.
|
|
307
|
+
*/
|
|
308
|
+
declare function checkDarkStylesContrastFromDom($: cheerio.CheerioAPI, lightIssues?: AccessibilityIssue[]): AccessibilityIssue[];
|
|
309
|
+
/**
|
|
310
|
+
* Contrast failures that only appear at mobile width. See
|
|
311
|
+
* {@link checkMobileContrastFromDom}.
|
|
312
|
+
*/
|
|
313
|
+
declare function checkMobileContrast(html: string, options?: ParseOptions): AccessibilityIssue[];
|
|
314
|
+
/**
|
|
315
|
+
* Contrast failures an email has *only* in dark mode.
|
|
316
|
+
*
|
|
317
|
+
* Clients that invert colours do it selectively, so a palette that passes in
|
|
318
|
+
* light mode can collapse to unreadable once inverted, mid-tone text left
|
|
319
|
+
* alone on a background repainted near-black. This runs the ordinary contrast
|
|
320
|
+
* check over the simulated dark render and reports what is new there.
|
|
321
|
+
*
|
|
322
|
+
* Pass `lightIssues` when the light-mode report is already in hand (the audit
|
|
323
|
+
* has it) to skip re-running the light pass.
|
|
324
|
+
*
|
|
325
|
+
* ponytail: deduped by the element description, so two genuinely identical
|
|
326
|
+
* elements collapse into one report. Track them individually only if the
|
|
327
|
+
* per-element count turns out to matter.
|
|
328
|
+
*/
|
|
329
|
+
declare function checkDarkModeContrast(html: string, lightIssues?: AccessibilityIssue[]): AccessibilityIssue[];
|
|
265
330
|
|
|
266
331
|
/**
|
|
267
332
|
* Analyze images in an HTML email for best practices.
|
|
@@ -314,12 +379,18 @@ declare function checkOverflow(html: string, options?: ParseOptions): OverflowRe
|
|
|
314
379
|
*/
|
|
315
380
|
declare function checkVisual(html: string, options?: ParseOptions): VisualReport;
|
|
316
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Report design drift in an HTML email: near-identical colours, and properties
|
|
384
|
+
* carrying more distinct values than a design system would.
|
|
385
|
+
*/
|
|
386
|
+
declare function checkDesignConsistency(html: string, options?: ParseOptions): DesignReport;
|
|
387
|
+
|
|
317
388
|
interface AuditOptions extends ParseOptions {
|
|
318
389
|
framework?: Framework;
|
|
319
390
|
/** Options for spam analysis */
|
|
320
391
|
spam?: SpamAnalysisOptions;
|
|
321
392
|
/** Skip specific checks */
|
|
322
|
-
skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility" | "inboxPreview" | "size" | "templateVariables" | "overflow" | "visual">;
|
|
393
|
+
skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility" | "inboxPreview" | "size" | "templateVariables" | "overflow" | "visual" | "darkContrast" | "mobileContrast" | "design">;
|
|
323
394
|
}
|
|
324
395
|
interface AuditReport {
|
|
325
396
|
compatibility: {
|
|
@@ -340,6 +411,12 @@ interface AuditReport {
|
|
|
340
411
|
templateVariables: TemplateReport;
|
|
341
412
|
overflow: OverflowReport;
|
|
342
413
|
visual: VisualReport;
|
|
414
|
+
/** Contrast failures present only once a client inverts colours. */
|
|
415
|
+
darkContrast: AccessibilityIssue[];
|
|
416
|
+
/** Contrast failures present only below the email's mobile breakpoint. */
|
|
417
|
+
mobileContrast: AccessibilityIssue[];
|
|
418
|
+
/** Design drift: near-identical colours, and properties with no system left. */
|
|
419
|
+
design: DesignReport;
|
|
343
420
|
}
|
|
344
421
|
/**
|
|
345
422
|
* Run all email analysis checks in a single call.
|
|
@@ -440,7 +517,7 @@ interface EmailSession {
|
|
|
440
517
|
* Simulate dark mode for a specific client.
|
|
441
518
|
*
|
|
442
519
|
* Creates an isolated DOM copy per call (simulation mutates the DOM).
|
|
443
|
-
* Operates on the **original** HTML
|
|
520
|
+
* Operates on the **original** HTML, if you need dark mode on
|
|
444
521
|
* already-transformed HTML, use the standalone `simulateDarkMode()` instead.
|
|
445
522
|
*/
|
|
446
523
|
simulateDarkMode(clientId: string): {
|
|
@@ -453,7 +530,7 @@ interface EmailSession {
|
|
|
453
530
|
* DOM across all read-only analysis operations.
|
|
454
531
|
*
|
|
455
532
|
* Use this when you need to call multiple analysis functions on the
|
|
456
|
-
* same HTML
|
|
533
|
+
* same HTML: it eliminates redundant `cheerio.load()` calls.
|
|
457
534
|
*
|
|
458
535
|
* @example
|
|
459
536
|
* ```typescript
|
|
@@ -535,6 +612,21 @@ declare function wcagGrade(ratio: number): WcagGrade;
|
|
|
535
612
|
* Returns the flattened [r, g, b] as 0-255 values.
|
|
536
613
|
*/
|
|
537
614
|
declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [number, number, number];
|
|
615
|
+
/**
|
|
616
|
+
* Convert sRGB to OKLab.
|
|
617
|
+
*
|
|
618
|
+
* OKLab is built so that straight-line distance between two points matches how
|
|
619
|
+
* different the colours look, which sRGB emphatically does not: `#333` and
|
|
620
|
+
* `#343434` are far apart in RGB terms and identical to a reader.
|
|
621
|
+
*/
|
|
622
|
+
declare function rgbToOklab(rgba: RGBA): [number, number, number];
|
|
623
|
+
/**
|
|
624
|
+
* Perceptual distance between two colours, as OKLab delta-E.
|
|
625
|
+
*
|
|
626
|
+
* Roughly: under ~0.02 the two are the same colour to a reader, and around
|
|
627
|
+
* ~0.1 they are clearly different.
|
|
628
|
+
*/
|
|
629
|
+
declare function colorDistance(a: RGBA, b: RGBA): number;
|
|
538
630
|
|
|
539
631
|
/**
|
|
540
632
|
* Downlevel modern CSS in HTML emails to maximize email client compatibility.
|
|
@@ -562,4 +654,4 @@ declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [n
|
|
|
562
654
|
*/
|
|
563
655
|
declare function downlevelCSS(html: string): string;
|
|
564
656
|
|
|
565
|
-
export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
|
|
657
|
+
export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityIssue, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DesignReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, FEATURE_URLS, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, type RenderContext, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkDarkModeContrast, checkDarkStylesContrastFromDom, checkDesignConsistency, checkMobileContrast, checkOverflow, checkSize, checkTemplateVariables, checkVisual, colorDistance, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, featureUrl, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, rgbToOklab, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { E as EmailClient, F as Framework, T as TransformResult, C as CSSWarning, a as CodeFix, D as DiffResult, b as ExportPromptOptions, A as AiProvider, c as AiFixResult, S as SupportLevel, d as SpamAnalysisOptions, e as SpamReport, L as LinkReport, f as AccessibilityReport, I as ImageReport,
|
|
2
|
-
export {
|
|
3
|
-
|
|
1
|
+
import { E as EmailClient, F as Framework, T as TransformResult, C as CSSWarning, a as CodeFix, D as DiffResult, b as ExportPromptOptions, A as AiProvider, c as AiFixResult, S as SupportLevel, d as SpamAnalysisOptions, e as SpamReport, L as LinkReport, f as AccessibilityReport, g as AccessibilityIssue, I as ImageReport, h as InboxPreview, i as SizeReport, j as TemplateReport, O as OverflowReport, V as VisualReport, k as DesignReport, l as DeliverabilityReport } from './types-BFhPXh3c.js';
|
|
2
|
+
export { B as BaseIssue, m as ClientTruncation, n as DeliverabilityCheck, o as DeliverabilityIssue, p as DesignIssue, q as EstimateOptions, r as ExportScope, s as FixType, t as ImageInfo, u as ImageIssue, v as InboxPreviewIssue, w as InputFormat, x as LinkIssue, y as OverflowIssue, P as PreviewResult, z as Severity, G as SizeIssue, H as SourceLocation, J as SpamIssue, K as TemplateIssue, M as TokenEstimate, N as TokenEstimateWithWarnings, Q as VisualIssue, R as estimateAiFixTokens, U as generateFixPrompt, W as heuristicTokenCount } from './types-BFhPXh3c.js';
|
|
3
|
+
import * as cheerio from 'cheerio';
|
|
4
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-D24HkW2Z.js';
|
|
4
5
|
|
|
5
6
|
declare const EMAIL_CLIENTS: EmailClient[];
|
|
6
7
|
declare function getClient(id: string): EmailClient | undefined;
|
|
@@ -13,7 +14,7 @@ interface ParseOptions {
|
|
|
13
14
|
/**
|
|
14
15
|
* Record source positions so issues carry a `loc`. Costs a little parse time
|
|
15
16
|
* (parse5 tracks a location record per node and per attribute), so it is
|
|
16
|
-
* opt-in for callers that need to point at the source
|
|
17
|
+
* opt-in for callers that need to point at the source: editors, CI
|
|
17
18
|
* annotations, agents.
|
|
18
19
|
*/
|
|
19
20
|
positions?: boolean;
|
|
@@ -24,7 +25,7 @@ interface ParseOptions {
|
|
|
24
25
|
* for all target email clients.
|
|
25
26
|
*
|
|
26
27
|
* The `framework` parameter controls which fix snippets are attached
|
|
27
|
-
* to warnings
|
|
28
|
+
* to warnings; it does NOT change which warnings fire. Analysis always
|
|
28
29
|
* runs on compiled HTML (what email clients actually receive). Fix
|
|
29
30
|
* snippets reference source-level constructs so users know how to
|
|
30
31
|
* modify their framework source code.
|
|
@@ -128,7 +129,7 @@ interface GenerateAiFixOptions extends ExportPromptOptions {
|
|
|
128
129
|
* to build a structured prompt, then delegates to an LLM for context-aware
|
|
129
130
|
* structural fixes that static snippets cannot handle.
|
|
130
131
|
*
|
|
131
|
-
* The engine stays provider-agnostic
|
|
132
|
+
* The engine stays provider-agnostic: consumers pass their own `AiProvider`
|
|
132
133
|
* callback (Anthropic SDK, Vercel AI SDK, OpenRouter, etc.).
|
|
133
134
|
*
|
|
134
135
|
* @example
|
|
@@ -166,10 +167,10 @@ declare function generateAiFix(options: GenerateAiFixOptions): Promise<AiFixResu
|
|
|
166
167
|
* System prompt for the AI fix provider. Consumers should pass this as
|
|
167
168
|
* the `system` parameter to their LLM call for best results.
|
|
168
169
|
*/
|
|
169
|
-
declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer specializing in cross-client HTML email compatibility. You fix emails to render correctly across all email clients.\n\nRules:\n- Return ONLY the fixed code inside a single code fence. No explanations before or after.\n- Preserve all existing content, text, links, and visual design.\n- For structural issues (fixType: \"structural\"), you MUST restructure the HTML
|
|
170
|
+
declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer specializing in cross-client HTML email compatibility. You fix emails to render correctly across all email clients.\n\nRules:\n- Return ONLY the fixed code inside a single code fence. No explanations before or after.\n- Preserve all existing content, text, links, and visual design.\n- For structural issues (fixType: \"structural\"), you MUST restructure the HTML; CSS-only changes will not work.\n- Common structural patterns:\n - word-break/overflow-wrap unsupported \u2192 wrap text in <table><tr><td> with constrained width\n - display:flex/grid \u2192 convert to <table> layout (match the original column count and proportions)\n - border-radius in Outlook \u2192 use VML <v:roundrect> with <!--[if mso]> conditionals\n - background-image in Outlook \u2192 use VML <v:rect> with <v:fill>\n - max-width in Outlook \u2192 wrap in <!--[if mso]><table width=\"N\"> conditional\n - position:absolute \u2192 use <table> cells for layout\n - <svg> \u2192 replace with <img> pointing to a hosted PNG\n- For CSS-only issues (fixType: \"css\"), swap properties or add fallbacks.\n- For \"Layout & Visual Issues\", apply the provided Fix directly: add the background-color fallback beneath a gradient/image, append a web-safe font to the stack, and constrain fixed widths wider than the frame to width:100% with max-width.\n- Apply ALL fixes from the issues list: do not skip any.\n- Use the framework syntax specified (JSX/MJML/Maizzle/HTML).\n- For JSX: use camelCase style props, React Email components, and proper TypeScript types.\n- For MJML: use mj-* elements and attributes.\n- For Maizzle: use Tailwind CSS classes.";
|
|
170
171
|
|
|
171
172
|
/**
|
|
172
|
-
* CSS/HTML feature support matrix
|
|
173
|
+
* CSS/HTML feature support matrix, auto-generated from caniemail.com.
|
|
173
174
|
* Last synced: 2026-07-28
|
|
174
175
|
* caniemail last updated: 2026-07-20 09:56:37 +0000
|
|
175
176
|
*
|
|
@@ -186,11 +187,11 @@ declare const AI_FIX_SYSTEM_PROMPT = "You are an expert email developer speciali
|
|
|
186
187
|
* - hey-mail: caniemail.com (WebKit-based)
|
|
187
188
|
* - superhuman: Manual overrides (Chromium/Blink-based, best-effort estimates)
|
|
188
189
|
*
|
|
189
|
-
* DO NOT EDIT
|
|
190
|
+
* DO NOT EDIT; regenerate with: bun run sync:caniemail
|
|
190
191
|
*/
|
|
191
192
|
declare const CSS_SUPPORT: Record<string, Record<string, SupportLevel>>;
|
|
192
193
|
/**
|
|
193
|
-
* Caveat notes per (feature, client) from caniemail
|
|
194
|
+
* Caveat notes per (feature, client) from caniemail: the "why" behind a
|
|
194
195
|
* partial/buggy/unsupported rating. Sparse: only cells with a note appear.
|
|
195
196
|
*/
|
|
196
197
|
declare const CSS_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
|
|
@@ -208,6 +209,19 @@ declare const COMPOUND_VALUE_FEATURES: readonly ["::after", "::before", "::first
|
|
|
208
209
|
/** CSS function features (e.g., "linear-gradient"). */
|
|
209
210
|
declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
|
|
210
211
|
|
|
212
|
+
/**
|
|
213
|
+
* caniemail's page for each feature, for a diagnostic's `codeDescription`.
|
|
214
|
+
*
|
|
215
|
+
* 250 of 255 features. The rest have no caniemail entry of
|
|
216
|
+
* their own and get no link, which is the honest outcome: a link to a 404
|
|
217
|
+
* is worse than none.
|
|
218
|
+
*
|
|
219
|
+
* DO NOT EDIT; regenerate with: bun run sync:feature-urls
|
|
220
|
+
*/
|
|
221
|
+
declare const FEATURE_URLS: Record<string, string>;
|
|
222
|
+
/** Where to read about a rule, when there is somewhere. */
|
|
223
|
+
declare function featureUrl(code: string): string | undefined;
|
|
224
|
+
|
|
211
225
|
/**
|
|
212
226
|
* Properties whose "partial" rating is value-level: the property usually
|
|
213
227
|
* renders fine and only specific values hit the caveat. For these the warning
|
|
@@ -226,7 +240,7 @@ declare const VALUE_CAVEAT_PROPS: ReadonlySet<string>;
|
|
|
226
240
|
* applies if either does.
|
|
227
241
|
*
|
|
228
242
|
* Returns true (report it) for a property that isn't value-gated, and for one
|
|
229
|
-
* where we never saw a value
|
|
243
|
+
* where we never saw a value: an at-rule, a pseudo-class, a detected CSS
|
|
230
244
|
* function.
|
|
231
245
|
*/
|
|
232
246
|
declare function caveatApplies(prop: string, values: readonly string[] | undefined, notes: string[] | undefined): boolean;
|
|
@@ -254,6 +268,20 @@ declare function analyzeSpam(html: string, options?: SpamAnalysisOptions): SpamR
|
|
|
254
268
|
*/
|
|
255
269
|
declare function validateLinks(html: string, options?: ParseOptions): LinkReport;
|
|
256
270
|
|
|
271
|
+
/**
|
|
272
|
+
* The render a cascade is being resolved for.
|
|
273
|
+
*
|
|
274
|
+
* An email has more than one correct answer: the same CSS produces a different
|
|
275
|
+
* palette on a phone and in dark mode, and a contrast bug can live in only one
|
|
276
|
+
* of them. Resolving against an explicit context is what lets the same
|
|
277
|
+
* machinery grade all three.
|
|
278
|
+
*/
|
|
279
|
+
interface RenderContext {
|
|
280
|
+
/** Viewport width in px, for width media queries. */
|
|
281
|
+
width: number;
|
|
282
|
+
/** Whether `prefers-color-scheme: dark` matches. */
|
|
283
|
+
dark: boolean;
|
|
284
|
+
}
|
|
257
285
|
/**
|
|
258
286
|
* Audit an HTML email for accessibility issues.
|
|
259
287
|
*
|
|
@@ -262,6 +290,43 @@ declare function validateLinks(html: string, options?: ParseOptions): LinkReport
|
|
|
262
290
|
* color contrast. Returns a 0–100 score and detailed issues.
|
|
263
291
|
*/
|
|
264
292
|
declare function checkAccessibility(html: string, options?: ParseOptions): AccessibilityReport;
|
|
293
|
+
/**
|
|
294
|
+
* Contrast failures inside the email's own `@media (prefers-color-scheme: dark)`
|
|
295
|
+
* styles.
|
|
296
|
+
*
|
|
297
|
+
* This is the other half of dark mode, and the half the author actually
|
|
298
|
+
* controls: Apple Mail, Superhuman, Thunderbird and friends do not invert
|
|
299
|
+
* anything, they just apply the dark block as written. A dark background
|
|
300
|
+
* paired with body text that was never re-coloured is invisible there, and no
|
|
301
|
+
* amount of inversion analysis finds it; the bug is in the CSS, not in what
|
|
302
|
+
* the client does to it.
|
|
303
|
+
*
|
|
304
|
+
* Free to run: same DOM, resolved against a dark render, so positions stay
|
|
305
|
+
* valid. Emails with no dark block resolve identically to the light pass and
|
|
306
|
+
* report nothing.
|
|
307
|
+
*/
|
|
308
|
+
declare function checkDarkStylesContrastFromDom($: cheerio.CheerioAPI, lightIssues?: AccessibilityIssue[]): AccessibilityIssue[];
|
|
309
|
+
/**
|
|
310
|
+
* Contrast failures that only appear at mobile width. See
|
|
311
|
+
* {@link checkMobileContrastFromDom}.
|
|
312
|
+
*/
|
|
313
|
+
declare function checkMobileContrast(html: string, options?: ParseOptions): AccessibilityIssue[];
|
|
314
|
+
/**
|
|
315
|
+
* Contrast failures an email has *only* in dark mode.
|
|
316
|
+
*
|
|
317
|
+
* Clients that invert colours do it selectively, so a palette that passes in
|
|
318
|
+
* light mode can collapse to unreadable once inverted, mid-tone text left
|
|
319
|
+
* alone on a background repainted near-black. This runs the ordinary contrast
|
|
320
|
+
* check over the simulated dark render and reports what is new there.
|
|
321
|
+
*
|
|
322
|
+
* Pass `lightIssues` when the light-mode report is already in hand (the audit
|
|
323
|
+
* has it) to skip re-running the light pass.
|
|
324
|
+
*
|
|
325
|
+
* ponytail: deduped by the element description, so two genuinely identical
|
|
326
|
+
* elements collapse into one report. Track them individually only if the
|
|
327
|
+
* per-element count turns out to matter.
|
|
328
|
+
*/
|
|
329
|
+
declare function checkDarkModeContrast(html: string, lightIssues?: AccessibilityIssue[]): AccessibilityIssue[];
|
|
265
330
|
|
|
266
331
|
/**
|
|
267
332
|
* Analyze images in an HTML email for best practices.
|
|
@@ -314,12 +379,18 @@ declare function checkOverflow(html: string, options?: ParseOptions): OverflowRe
|
|
|
314
379
|
*/
|
|
315
380
|
declare function checkVisual(html: string, options?: ParseOptions): VisualReport;
|
|
316
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Report design drift in an HTML email: near-identical colours, and properties
|
|
384
|
+
* carrying more distinct values than a design system would.
|
|
385
|
+
*/
|
|
386
|
+
declare function checkDesignConsistency(html: string, options?: ParseOptions): DesignReport;
|
|
387
|
+
|
|
317
388
|
interface AuditOptions extends ParseOptions {
|
|
318
389
|
framework?: Framework;
|
|
319
390
|
/** Options for spam analysis */
|
|
320
391
|
spam?: SpamAnalysisOptions;
|
|
321
392
|
/** Skip specific checks */
|
|
322
|
-
skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility" | "inboxPreview" | "size" | "templateVariables" | "overflow" | "visual">;
|
|
393
|
+
skip?: Array<"spam" | "links" | "accessibility" | "images" | "compatibility" | "inboxPreview" | "size" | "templateVariables" | "overflow" | "visual" | "darkContrast" | "mobileContrast" | "design">;
|
|
323
394
|
}
|
|
324
395
|
interface AuditReport {
|
|
325
396
|
compatibility: {
|
|
@@ -340,6 +411,12 @@ interface AuditReport {
|
|
|
340
411
|
templateVariables: TemplateReport;
|
|
341
412
|
overflow: OverflowReport;
|
|
342
413
|
visual: VisualReport;
|
|
414
|
+
/** Contrast failures present only once a client inverts colours. */
|
|
415
|
+
darkContrast: AccessibilityIssue[];
|
|
416
|
+
/** Contrast failures present only below the email's mobile breakpoint. */
|
|
417
|
+
mobileContrast: AccessibilityIssue[];
|
|
418
|
+
/** Design drift: near-identical colours, and properties with no system left. */
|
|
419
|
+
design: DesignReport;
|
|
343
420
|
}
|
|
344
421
|
/**
|
|
345
422
|
* Run all email analysis checks in a single call.
|
|
@@ -440,7 +517,7 @@ interface EmailSession {
|
|
|
440
517
|
* Simulate dark mode for a specific client.
|
|
441
518
|
*
|
|
442
519
|
* Creates an isolated DOM copy per call (simulation mutates the DOM).
|
|
443
|
-
* Operates on the **original** HTML
|
|
520
|
+
* Operates on the **original** HTML, if you need dark mode on
|
|
444
521
|
* already-transformed HTML, use the standalone `simulateDarkMode()` instead.
|
|
445
522
|
*/
|
|
446
523
|
simulateDarkMode(clientId: string): {
|
|
@@ -453,7 +530,7 @@ interface EmailSession {
|
|
|
453
530
|
* DOM across all read-only analysis operations.
|
|
454
531
|
*
|
|
455
532
|
* Use this when you need to call multiple analysis functions on the
|
|
456
|
-
* same HTML
|
|
533
|
+
* same HTML: it eliminates redundant `cheerio.load()` calls.
|
|
457
534
|
*
|
|
458
535
|
* @example
|
|
459
536
|
* ```typescript
|
|
@@ -535,6 +612,21 @@ declare function wcagGrade(ratio: number): WcagGrade;
|
|
|
535
612
|
* Returns the flattened [r, g, b] as 0-255 values.
|
|
536
613
|
*/
|
|
537
614
|
declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [number, number, number];
|
|
615
|
+
/**
|
|
616
|
+
* Convert sRGB to OKLab.
|
|
617
|
+
*
|
|
618
|
+
* OKLab is built so that straight-line distance between two points matches how
|
|
619
|
+
* different the colours look, which sRGB emphatically does not: `#333` and
|
|
620
|
+
* `#343434` are far apart in RGB terms and identical to a reader.
|
|
621
|
+
*/
|
|
622
|
+
declare function rgbToOklab(rgba: RGBA): [number, number, number];
|
|
623
|
+
/**
|
|
624
|
+
* Perceptual distance between two colours, as OKLab delta-E.
|
|
625
|
+
*
|
|
626
|
+
* Roughly: under ~0.02 the two are the same colour to a reader, and around
|
|
627
|
+
* ~0.1 they are clearly different.
|
|
628
|
+
*/
|
|
629
|
+
declare function colorDistance(a: RGBA, b: RGBA): number;
|
|
538
630
|
|
|
539
631
|
/**
|
|
540
632
|
* Downlevel modern CSS in HTML emails to maximize email client compatibility.
|
|
@@ -562,4 +654,4 @@ declare function alphaBlend(fg: RGBA, bgR: number, bgG: number, bgB: number): [n
|
|
|
562
654
|
*/
|
|
563
655
|
declare function downlevelCSS(html: string): string;
|
|
564
656
|
|
|
565
|
-
export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkOverflow, checkSize, checkTemplateVariables, checkVisual, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
|
|
657
|
+
export { AI_FIX_SYSTEM_PROMPT, AT_RULE_FEATURES, AccessibilityIssue, AccessibilityReport, AiFixResult, AiProvider, type AuditOptions, type AuditReport, COMPOUND_VALUE_FEATURES, CSSWarning, CSS_FUNCTION_FEATURES, CSS_SUPPORT, CSS_SUPPORT_NOTES, CodeFix, type CreateSessionOptions, DeliverabilityReport, DesignReport, DiffResult, EMAIL_CLIENTS, EMPTY_DELIVERABILITY, EmailClient, type EmailSession, ExportPromptOptions, FEATURE_URLS, Framework, GENERIC_LINK_TEXT, type GenerateAiFixOptions, HTML_ELEMENT_FEATURES, ImageReport, InboxPreview, LinkReport, MAX_HTML_SIZE, MAX_WARNING_LOCATIONS, OverflowReport, type ParseOptions, type RGBA, type RenderContext, STRUCTURAL_FIX_PROPERTIES, SizeReport, SpamAnalysisOptions, SpamReport, SupportLevel, TemplateReport, TransformResult, VALUE_CAVEAT_PROPS, VisualReport, type WcagGrade, alphaBlend, analyzeEmail, analyzeImages, analyzeSpam, auditEmail, caveatApplies, checkAccessibility, checkDarkModeContrast, checkDarkStylesContrastFromDom, checkDesignConsistency, checkMobileContrast, checkOverflow, checkSize, checkTemplateVariables, checkVisual, colorDistance, contrastRatio, createSession, diffResults, downlevelCSS, errorWarnings, extractInboxPreview, featureUrl, formatRgb, generateAiFix, generateCompatibilityScore, getClient, getCodeFix, getSuggestion, parseColor, relativeLuminance, rgbToOklab, simulateDarkMode, structuralWarnings, toPlainText, transformForAllClients, transformForClient, validateLinks, warningsForClient, wcagGrade };
|