@emailens/engine 0.11.9 → 0.12.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.
@@ -0,0 +1,11 @@
1
+ import {
2
+ compileMaizzle,
3
+ isMaizzle6
4
+ } from "./chunk-OA6VNA5L.js";
5
+ import "./chunk-Z22AD2IU.js";
6
+ import "./chunk-2NMEKWO5.js";
7
+ export {
8
+ compileMaizzle,
9
+ isMaizzle6
10
+ };
11
+ //# sourceMappingURL=maizzle-R5KU3HHZ.js.map
@@ -1,4 +1,4 @@
1
- import { x as InputFormat } from './types-DiseE-UH.js';
1
+ import { _ as InputFormat } from './types-hQYXbiqj.js';
2
2
 
3
3
  /**
4
4
  * Unified error class for all email compilation failures.
@@ -1,4 +1,4 @@
1
- import { x as InputFormat } from './types-DiseE-UH.cjs';
1
+ import { _ as InputFormat } from './types-hQYXbiqj.cjs';
2
2
 
3
3
  /**
4
4
  * Unified error class for all email compilation failures.
package/dist/server.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { promises } from 'node:dns';
2
- import { m as DeliverabilityReport } from './types-DiseE-UH.cjs';
2
+ import { m as DeliverabilityReport } from './types-hQYXbiqj.cjs';
3
3
 
4
4
  /**
5
5
  * DNS-based email deliverability checker.
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { promises } from 'node:dns';
2
- import { m as DeliverabilityReport } from './types-DiseE-UH.js';
2
+ import { m as DeliverabilityReport } from './types-hQYXbiqj.js';
3
3
 
4
4
  /**
5
5
  * DNS-based email deliverability checker.
@@ -98,11 +98,97 @@ declare function estimateAiFixTokens(options: EstimateOptions): Promise<TokenEst
98
98
  */
99
99
  declare function heuristicTokenCount(text: string): number;
100
100
 
101
+ /**
102
+ * CSS/HTML feature support matrix, auto-generated from caniemail.com.
103
+ * Last synced: 2026-09-02
104
+ * caniemail last updated: 2026-08-10 15:16:24 +0000
105
+ *
106
+ * 298 features and 14 image formats across 21 email clients.
107
+ *
108
+ * Support levels:
109
+ * - "supported": fully supported
110
+ * - "partial": partially supported (with caveats)
111
+ * - "unsupported": not supported at all
112
+ * - "unknown": no data available
113
+ *
114
+ * Data sources:
115
+ * - Most clients: caniemail.com API (verified data)
116
+ * - hey-mail: caniemail.com (WebKit-based)
117
+ * - superhuman: Manual overrides (Chromium/Blink-based, best-effort estimates)
118
+ *
119
+ * A client we ship as one entry although caniemail tests it on several
120
+ * platforms (Proton Mail, AOL, Thunderbird) is graded on its worst
121
+ * platform. Gmail, Outlook, Yahoo and Apple Mail ship as separate clients
122
+ * per platform instead.
123
+ *
124
+ * DO NOT EDIT; regenerate with: bun run sync:caniemail
125
+ */
126
+ /** The clients every row answers for, in report order. */
127
+ declare const SUPPORT_CLIENTS: readonly ["gmail-web", "gmail-android", "gmail-ios", "outlook-web", "outlook-windows", "outlook-windows-legacy", "outlook-ios", "outlook-android", "outlook-macos", "apple-mail-macos", "apple-mail-ios", "yahoo-mail", "yahoo-mail-android", "yahoo-mail-ios", "samsung-mail", "thunderbird", "hey-mail", "protonmail", "aol", "fastmail", "superhuman"];
128
+ declare const CSS_SUPPORT: Record<string, Record<ClientId, SupportLevel>>;
129
+ /**
130
+ * Caveat notes per (feature, client) from caniemail: the "why" behind a
131
+ * partial/buggy/unsupported rating. Sparse: only cells with a note appear.
132
+ */
133
+ declare const CSS_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
134
+ /**
135
+ * Image format support, keyed by format. Kept out of CSS_SUPPORT because an
136
+ * image format is a property of the `src`, not of a stylesheet: the image
137
+ * analyzer looks these up, the CSS analyzer never should.
138
+ */
139
+ /** The image formats caniemail grades. */
140
+ declare const IMAGE_FORMATS: readonly ["apng", "avif", "base64", "bmp", "gif", "hdr", "heif", "ico", "jpg", "mp4", "png", "svg", "tiff", "webp"];
141
+ declare const IMAGE_SUPPORT: Record<string, Record<ClientId, SupportLevel>>;
142
+ /** Caveat notes per (image format, client), same shape as CSS_SUPPORT_NOTES. */
143
+ declare const IMAGE_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
144
+ /**
145
+ * Features a client merely ignores when it "does not support" them: the
146
+ * email renders the same either way, so these report as info, not warnings.
147
+ */
148
+ declare const GRACEFUL_FEATURES: ReadonlySet<string>;
149
+ /**
150
+ * Properties that require HTML structural changes (not just CSS swaps)
151
+ * to fix. These cannot be solved by replacing one CSS value with another.
152
+ */
153
+ declare const STRUCTURAL_FIX_PROPERTIES: Set<string>;
154
+ /** HTML element features in the support matrix (for data-driven detection). */
155
+ declare const HTML_ELEMENT_FEATURES: readonly ["<abbr>", "<acronym>", "<address>", "<audio>", "<base>", "<bdi>", "<blockquote>", "<body>", "<button type=\"reset\">", "<button type=\"submit\">", "<code>", "<del>", "<dfn>", "<dialog>", "<div>", "<form>", "<h1>", "<hr>", "<img>", "<input type=\"checkbox\">", "<input type=\"hidden\">", "<input type=\"radio\">", "<input type=\"reset\">", "<input type=\"submit\">", "<input type=\"text\">", "<link>", "<marquee>", "<meter>", "<object>", "<p>", "<picture>", "<pre>", "<progress>", "<rp>", "<rt>", "<ruby>", "<select>", "<small>", "<span>", "<strike>", "<strong>", "<style>", "<svg>", "<table>", "<textarea>", "<ul>", "<video>", "<wbr>"];
156
+ /** HTML attribute features. Each key is also the cheerio selector that finds it. */
157
+ declare const HTML_ATTRIBUTE_FEATURES: readonly ["[align]", "[aria-describedby]", "[aria-hidden]", "[aria-label]", "[aria-labelledby]", "[aria-live]", "[background]", "[cellpadding]", "[cellspacing]", "[command]", "[dir]", "[height]", "[hidden]", "[lang]", "[loading]", "[popover]", "[required]", "[role]", "[srcset]", "[target]", "[valign]", "[width]"];
158
+ /** Document-level and link-shaped HTML features; each has a bespoke detector. */
159
+ declare const HTML_MISC_FEATURES: readonly ["amp4email", "anchor-links", "doctype", "html-comments", "html5-semantics", "image-maps", "mailto-links", "meta-color-scheme"];
160
+ /** CSS at-rule features, including the media features that qualify `@media`. */
161
+ declare const AT_RULE_FEATURES: readonly ["@font-face", "@import", "@keyframes", "@media", "@media device-pixel-ratio", "@media hover", "@media orientation", "@media prefers-color-scheme", "@media prefers-reduced-motion", "@supports"];
162
+ /** One property paired with one value, e.g. "display:flex". */
163
+ declare const COMPOUND_VALUE_FEATURES: readonly ["display:flex", "display:grid", "display:none"];
164
+ /** Pseudo-classes, pseudo-elements and combinators, e.g. ":hover", "::after". */
165
+ declare const SELECTOR_FEATURES: readonly ["::after", "::before", "::first-letter", "::first-line", "::marker", "::placeholder", ":adjacent-sibling", ":attribute-selector", ":chaining", ":checked", ":child-combinator", ":class-selector", ":descendant-combinator", ":first-child", ":first-of-type", ":focus", ":focus-visible", ":focus-within", ":general-sibling", ":grouping", ":has", ":hover", ":id-selector", ":lang", ":last-child", ":last-of-type", ":link", ":not", ":nth-child", ":nth-last-child", ":nth-of-type", ":only-child", ":only-of-type", ":target", ":type-selector", ":universal-selector", ":visited"];
166
+ /** CSS function features (e.g., "linear-gradient"). */
167
+ declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
168
+ /** Plain CSS property names: what an inline style or declaration can match. */
169
+ declare const CSS_PROPERTY_FEATURES: readonly ["!important", "accent-color", "align-items", "animation", "aspect-ratio", "backdrop-filter", "background", "background-blend-mode", "background-clip", "background-color", "background-image", "background-origin", "background-position", "background-repeat", "background-size", "bimi", "block-size", "border", "border-collapse", "border-image", "border-inline", "border-inline-individual", "border-inline-longhand", "border-radius", "border-radius-logical", "border-spacing", "bottom", "box-shadow", "box-sizing", "caption-side", "clear", "clip-path", "color", "color-scheme", "column-count", "columns", "css-comments", "cursor", "custom-properties", "direction", "display", "empty-cells", "filter", "flex-direction", "flex-wrap", "float", "font", "font-family", "font-kerning", "font-size", "font-size-adjust", "font-stretch", "font-weight", "gap", "grid-template-columns", "height", "hyphenate-character", "hyphenate-limit-chars", "hyphens", "inert", "inline-size", "inset", "justify-content", "left", "letter-spacing", "light-dark", "line-height", "list-style", "list-style-image", "list-style-position", "list-style-type", "margin", "margin-block-start-end", "margin-inline-block", "margin-inline-start-end", "mask-image", "max-block-size", "max-height", "max-inline-size", "max-width", "min-block-size", "min-height", "min-inline-size", "min-width", "mix-blend-mode", "modern-color", "nesting", "object-fit", "object-position", "opacity", "orphans", "outline", "outline-offset", "overflow", "overflow-wrap", "padding", "padding-block-start-end", "padding-inline-block", "padding-inline-start-end", "position", "pseudo-class-active", "pseudo-class-default", "pseudo-class-nth-last-of-type", "resize", "rgb", "rgba", "right", "scroll-snap", "shape-margin", "shape-outside", "system-ui", "tab-size", "table-layout", "text-align", "text-align-last", "text-decoration", "text-decoration-color", "text-decoration-line", "text-decoration-skip-ink", "text-decoration-style", "text-decoration-thickness", "text-emphasis", "text-emphasis-position", "text-indent", "text-justify", "text-orientation", "text-overflow", "text-shadow", "text-transform", "text-underline-offset", "text-underline-position", "text-wrap", "top", "transform", "transition", "unit-ch", "unit-cm", "unit-em", "unit-ex", "unit-in", "unit-initial", "unit-mm", "unit-pc", "unit-percent", "unit-pt", "unit-px", "unit-rem", "unit-vh", "unit-vmax", "unit-vmin", "unit-vw", "user-select", "vertical-align", "visibility", "white-space", "white-space-collapse", "widows", "width", "word-break", "word-spacing", "writing-mode", "z-index"];
170
+ /** Every feature key in CSS_SUPPORT, as a type. */
171
+ type FeatureKey = (typeof HTML_ELEMENT_FEATURES)[number] | (typeof HTML_ATTRIBUTE_FEATURES)[number] | (typeof HTML_MISC_FEATURES)[number] | (typeof AT_RULE_FEATURES)[number] | (typeof COMPOUND_VALUE_FEATURES)[number] | (typeof SELECTOR_FEATURES)[number] | (typeof CSS_FUNCTION_FEATURES)[number] | (typeof CSS_PROPERTY_FEATURES)[number];
172
+ /** An image format caniemail grades. */
173
+ type ImageFormat = (typeof IMAGE_FORMATS)[number];
174
+ /** A client the matrix answers for. */
175
+ type ClientId = (typeof SUPPORT_CLIENTS)[number];
176
+ /**
177
+ * When caniemail last re-tested each feature. A feature's row is only as
178
+ * current as its test date, whatever the file's sync date says.
179
+ */
180
+ declare const FEATURE_LAST_TESTED: Record<string, string>;
181
+
101
182
  type SupportLevel = "supported" | "partial" | "unsupported" | "unknown";
102
183
  type Framework = "jsx" | "mjml" | "maizzle";
103
184
  type InputFormat = "html" | Framework;
104
185
  interface EmailClient {
105
- id: string;
186
+ /**
187
+ * Not a free string: the matrix answers for exactly these clients, so a
188
+ * client we ship without a column (or a column with no client) is a compile
189
+ * error rather than a silently empty section of every report.
190
+ */
191
+ id: ClientId;
106
192
  name: string;
107
193
  category: "webmail" | "desktop" | "mobile";
108
194
  engine: string;
@@ -340,10 +426,31 @@ interface SizeIssue extends BaseIssue {
340
426
  }
341
427
  interface SizeReport {
342
428
  htmlBytes: number;
429
+ /** Bytes of CSS inside `<style>` elements, summed across all of them. */
430
+ styleBytes: number;
343
431
  humanSize: string;
344
432
  clipped: boolean;
345
433
  issues: SizeIssue[];
346
434
  }
435
+ interface StyleSurvivalIssue extends BaseIssue {
436
+ /**
437
+ * The clients that discard the CSS. Required, not optional: the consuming
438
+ * app groups findings per client, and an issue that cannot name its clients
439
+ * does not surface at all.
440
+ */
441
+ clients: string[];
442
+ detail?: string;
443
+ /**
444
+ * Where in the framework's source the offending CSS came from. Present only
445
+ * when the caller named a framework: the stylesheet that ships is assembled
446
+ * by the compiler, so "edit your <style> block" is the wrong instruction for
447
+ * someone whose source has no <style> block.
448
+ */
449
+ frameworkNote?: string;
450
+ }
451
+ interface StyleSurvivalReport {
452
+ issues: StyleSurvivalIssue[];
453
+ }
347
454
  interface OverflowIssue extends BaseIssue {
348
455
  detail?: string;
349
456
  }
@@ -409,4 +516,4 @@ interface DesignReport {
409
516
  };
410
517
  }
411
518
 
412
- export { type AiProvider as A, type BaseIssue as B, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, type OverflowIssue as G, type Severity as H, type ImageReport as I, type SizeIssue as J, type SourceLocation as K, type LinkReport as L, type SpamIssue as M, type TemplateIssue as N, type OverflowReport as O, type PreviewResult as P, type TokenEstimate as Q, type TokenEstimateWithWarnings as R, type SupportLevel as S, type TransformResult as T, type VisualIssue as U, type VmlReport as V, type VmlIssue as W, estimateAiFixTokens as X, generateFixPrompt as Y, heuristicTokenCount as Z, type CodeFix as a, type ExportPromptOptions as b, type AiFixResult as c, type SpamAnalysisOptions as d, type SpamReport as e, type AccessibilityReport as f, type AccessibilityIssue as g, type InboxPreview as h, type SizeReport as i, type TemplateReport as j, type VisualReport as k, type DesignReport as l, type DeliverabilityReport as m, type ClientTruncation as n, type DeliverabilityCheck as o, type DeliverabilityIssue as p, type DesignIssue as q, type EstimateOptions as r, type ExportScope as s, type FixType as t, type ImageInfo as u, type ImageIssue as v, type InboxPreviewIssue as w, type InputFormat as x, type LinkInfo as y, type LinkIssue as z };
519
+ export { type LinkInfo as $, type AiProvider as A, type BaseIssue as B, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, FEATURE_LAST_TESTED as G, type FeatureKey as H, type ImageReport as I, type FixType as J, GRACEFUL_FEATURES as K, type LinkReport as L, HTML_ATTRIBUTE_FEATURES as M, HTML_ELEMENT_FEATURES as N, type OverflowReport as O, HTML_MISC_FEATURES as P, IMAGE_FORMATS as Q, IMAGE_SUPPORT as R, type StyleSurvivalReport as S, type TransformResult as T, IMAGE_SUPPORT_NOTES as U, type VmlReport as V, type ImageFormat as W, type ImageInfo as X, type ImageIssue as Y, type InboxPreviewIssue as Z, type InputFormat as _, type CodeFix as a, type LinkIssue as a0, type OverflowIssue as a1, type PreviewResult as a2, SELECTOR_FEATURES as a3, STRUCTURAL_FIX_PROPERTIES as a4, SUPPORT_CLIENTS as a5, type Severity as a6, type SizeIssue as a7, type SourceLocation as a8, type SpamIssue as a9, type SupportLevel as aa, type TemplateIssue as ab, type TokenEstimate as ac, type TokenEstimateWithWarnings as ad, type VisualIssue as ae, type VmlIssue as af, estimateAiFixTokens as ag, generateFixPrompt as ah, heuristicTokenCount as ai, type ExportPromptOptions as b, type AiFixResult as c, type SpamAnalysisOptions as d, type SpamReport as e, type AccessibilityReport as f, type AccessibilityIssue as g, type InboxPreview as h, type SizeReport as i, type TemplateReport as j, type VisualReport as k, type DesignReport as l, type DeliverabilityReport as m, AT_RULE_FEATURES as n, COMPOUND_VALUE_FEATURES as o, CSS_FUNCTION_FEATURES as p, CSS_PROPERTY_FEATURES as q, CSS_SUPPORT as r, CSS_SUPPORT_NOTES as s, type ClientId as t, type ClientTruncation as u, type DeliverabilityCheck as v, type DeliverabilityIssue as w, type DesignIssue as x, type EstimateOptions as y, type ExportScope as z };
@@ -98,11 +98,97 @@ declare function estimateAiFixTokens(options: EstimateOptions): Promise<TokenEst
98
98
  */
99
99
  declare function heuristicTokenCount(text: string): number;
100
100
 
101
+ /**
102
+ * CSS/HTML feature support matrix, auto-generated from caniemail.com.
103
+ * Last synced: 2026-09-02
104
+ * caniemail last updated: 2026-08-10 15:16:24 +0000
105
+ *
106
+ * 298 features and 14 image formats across 21 email clients.
107
+ *
108
+ * Support levels:
109
+ * - "supported": fully supported
110
+ * - "partial": partially supported (with caveats)
111
+ * - "unsupported": not supported at all
112
+ * - "unknown": no data available
113
+ *
114
+ * Data sources:
115
+ * - Most clients: caniemail.com API (verified data)
116
+ * - hey-mail: caniemail.com (WebKit-based)
117
+ * - superhuman: Manual overrides (Chromium/Blink-based, best-effort estimates)
118
+ *
119
+ * A client we ship as one entry although caniemail tests it on several
120
+ * platforms (Proton Mail, AOL, Thunderbird) is graded on its worst
121
+ * platform. Gmail, Outlook, Yahoo and Apple Mail ship as separate clients
122
+ * per platform instead.
123
+ *
124
+ * DO NOT EDIT; regenerate with: bun run sync:caniemail
125
+ */
126
+ /** The clients every row answers for, in report order. */
127
+ declare const SUPPORT_CLIENTS: readonly ["gmail-web", "gmail-android", "gmail-ios", "outlook-web", "outlook-windows", "outlook-windows-legacy", "outlook-ios", "outlook-android", "outlook-macos", "apple-mail-macos", "apple-mail-ios", "yahoo-mail", "yahoo-mail-android", "yahoo-mail-ios", "samsung-mail", "thunderbird", "hey-mail", "protonmail", "aol", "fastmail", "superhuman"];
128
+ declare const CSS_SUPPORT: Record<string, Record<ClientId, SupportLevel>>;
129
+ /**
130
+ * Caveat notes per (feature, client) from caniemail: the "why" behind a
131
+ * partial/buggy/unsupported rating. Sparse: only cells with a note appear.
132
+ */
133
+ declare const CSS_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
134
+ /**
135
+ * Image format support, keyed by format. Kept out of CSS_SUPPORT because an
136
+ * image format is a property of the `src`, not of a stylesheet: the image
137
+ * analyzer looks these up, the CSS analyzer never should.
138
+ */
139
+ /** The image formats caniemail grades. */
140
+ declare const IMAGE_FORMATS: readonly ["apng", "avif", "base64", "bmp", "gif", "hdr", "heif", "ico", "jpg", "mp4", "png", "svg", "tiff", "webp"];
141
+ declare const IMAGE_SUPPORT: Record<string, Record<ClientId, SupportLevel>>;
142
+ /** Caveat notes per (image format, client), same shape as CSS_SUPPORT_NOTES. */
143
+ declare const IMAGE_SUPPORT_NOTES: Record<string, Record<string, string[]>>;
144
+ /**
145
+ * Features a client merely ignores when it "does not support" them: the
146
+ * email renders the same either way, so these report as info, not warnings.
147
+ */
148
+ declare const GRACEFUL_FEATURES: ReadonlySet<string>;
149
+ /**
150
+ * Properties that require HTML structural changes (not just CSS swaps)
151
+ * to fix. These cannot be solved by replacing one CSS value with another.
152
+ */
153
+ declare const STRUCTURAL_FIX_PROPERTIES: Set<string>;
154
+ /** HTML element features in the support matrix (for data-driven detection). */
155
+ declare const HTML_ELEMENT_FEATURES: readonly ["<abbr>", "<acronym>", "<address>", "<audio>", "<base>", "<bdi>", "<blockquote>", "<body>", "<button type=\"reset\">", "<button type=\"submit\">", "<code>", "<del>", "<dfn>", "<dialog>", "<div>", "<form>", "<h1>", "<hr>", "<img>", "<input type=\"checkbox\">", "<input type=\"hidden\">", "<input type=\"radio\">", "<input type=\"reset\">", "<input type=\"submit\">", "<input type=\"text\">", "<link>", "<marquee>", "<meter>", "<object>", "<p>", "<picture>", "<pre>", "<progress>", "<rp>", "<rt>", "<ruby>", "<select>", "<small>", "<span>", "<strike>", "<strong>", "<style>", "<svg>", "<table>", "<textarea>", "<ul>", "<video>", "<wbr>"];
156
+ /** HTML attribute features. Each key is also the cheerio selector that finds it. */
157
+ declare const HTML_ATTRIBUTE_FEATURES: readonly ["[align]", "[aria-describedby]", "[aria-hidden]", "[aria-label]", "[aria-labelledby]", "[aria-live]", "[background]", "[cellpadding]", "[cellspacing]", "[command]", "[dir]", "[height]", "[hidden]", "[lang]", "[loading]", "[popover]", "[required]", "[role]", "[srcset]", "[target]", "[valign]", "[width]"];
158
+ /** Document-level and link-shaped HTML features; each has a bespoke detector. */
159
+ declare const HTML_MISC_FEATURES: readonly ["amp4email", "anchor-links", "doctype", "html-comments", "html5-semantics", "image-maps", "mailto-links", "meta-color-scheme"];
160
+ /** CSS at-rule features, including the media features that qualify `@media`. */
161
+ declare const AT_RULE_FEATURES: readonly ["@font-face", "@import", "@keyframes", "@media", "@media device-pixel-ratio", "@media hover", "@media orientation", "@media prefers-color-scheme", "@media prefers-reduced-motion", "@supports"];
162
+ /** One property paired with one value, e.g. "display:flex". */
163
+ declare const COMPOUND_VALUE_FEATURES: readonly ["display:flex", "display:grid", "display:none"];
164
+ /** Pseudo-classes, pseudo-elements and combinators, e.g. ":hover", "::after". */
165
+ declare const SELECTOR_FEATURES: readonly ["::after", "::before", "::first-letter", "::first-line", "::marker", "::placeholder", ":adjacent-sibling", ":attribute-selector", ":chaining", ":checked", ":child-combinator", ":class-selector", ":descendant-combinator", ":first-child", ":first-of-type", ":focus", ":focus-visible", ":focus-within", ":general-sibling", ":grouping", ":has", ":hover", ":id-selector", ":lang", ":last-child", ":last-of-type", ":link", ":not", ":nth-child", ":nth-last-child", ":nth-of-type", ":only-child", ":only-of-type", ":target", ":type-selector", ":universal-selector", ":visited"];
166
+ /** CSS function features (e.g., "linear-gradient"). */
167
+ declare const CSS_FUNCTION_FEATURES: readonly ["calc", "clamp", "conic-gradient", "fit-content", "linear-gradient", "max", "min", "radial-gradient"];
168
+ /** Plain CSS property names: what an inline style or declaration can match. */
169
+ declare const CSS_PROPERTY_FEATURES: readonly ["!important", "accent-color", "align-items", "animation", "aspect-ratio", "backdrop-filter", "background", "background-blend-mode", "background-clip", "background-color", "background-image", "background-origin", "background-position", "background-repeat", "background-size", "bimi", "block-size", "border", "border-collapse", "border-image", "border-inline", "border-inline-individual", "border-inline-longhand", "border-radius", "border-radius-logical", "border-spacing", "bottom", "box-shadow", "box-sizing", "caption-side", "clear", "clip-path", "color", "color-scheme", "column-count", "columns", "css-comments", "cursor", "custom-properties", "direction", "display", "empty-cells", "filter", "flex-direction", "flex-wrap", "float", "font", "font-family", "font-kerning", "font-size", "font-size-adjust", "font-stretch", "font-weight", "gap", "grid-template-columns", "height", "hyphenate-character", "hyphenate-limit-chars", "hyphens", "inert", "inline-size", "inset", "justify-content", "left", "letter-spacing", "light-dark", "line-height", "list-style", "list-style-image", "list-style-position", "list-style-type", "margin", "margin-block-start-end", "margin-inline-block", "margin-inline-start-end", "mask-image", "max-block-size", "max-height", "max-inline-size", "max-width", "min-block-size", "min-height", "min-inline-size", "min-width", "mix-blend-mode", "modern-color", "nesting", "object-fit", "object-position", "opacity", "orphans", "outline", "outline-offset", "overflow", "overflow-wrap", "padding", "padding-block-start-end", "padding-inline-block", "padding-inline-start-end", "position", "pseudo-class-active", "pseudo-class-default", "pseudo-class-nth-last-of-type", "resize", "rgb", "rgba", "right", "scroll-snap", "shape-margin", "shape-outside", "system-ui", "tab-size", "table-layout", "text-align", "text-align-last", "text-decoration", "text-decoration-color", "text-decoration-line", "text-decoration-skip-ink", "text-decoration-style", "text-decoration-thickness", "text-emphasis", "text-emphasis-position", "text-indent", "text-justify", "text-orientation", "text-overflow", "text-shadow", "text-transform", "text-underline-offset", "text-underline-position", "text-wrap", "top", "transform", "transition", "unit-ch", "unit-cm", "unit-em", "unit-ex", "unit-in", "unit-initial", "unit-mm", "unit-pc", "unit-percent", "unit-pt", "unit-px", "unit-rem", "unit-vh", "unit-vmax", "unit-vmin", "unit-vw", "user-select", "vertical-align", "visibility", "white-space", "white-space-collapse", "widows", "width", "word-break", "word-spacing", "writing-mode", "z-index"];
170
+ /** Every feature key in CSS_SUPPORT, as a type. */
171
+ type FeatureKey = (typeof HTML_ELEMENT_FEATURES)[number] | (typeof HTML_ATTRIBUTE_FEATURES)[number] | (typeof HTML_MISC_FEATURES)[number] | (typeof AT_RULE_FEATURES)[number] | (typeof COMPOUND_VALUE_FEATURES)[number] | (typeof SELECTOR_FEATURES)[number] | (typeof CSS_FUNCTION_FEATURES)[number] | (typeof CSS_PROPERTY_FEATURES)[number];
172
+ /** An image format caniemail grades. */
173
+ type ImageFormat = (typeof IMAGE_FORMATS)[number];
174
+ /** A client the matrix answers for. */
175
+ type ClientId = (typeof SUPPORT_CLIENTS)[number];
176
+ /**
177
+ * When caniemail last re-tested each feature. A feature's row is only as
178
+ * current as its test date, whatever the file's sync date says.
179
+ */
180
+ declare const FEATURE_LAST_TESTED: Record<string, string>;
181
+
101
182
  type SupportLevel = "supported" | "partial" | "unsupported" | "unknown";
102
183
  type Framework = "jsx" | "mjml" | "maizzle";
103
184
  type InputFormat = "html" | Framework;
104
185
  interface EmailClient {
105
- id: string;
186
+ /**
187
+ * Not a free string: the matrix answers for exactly these clients, so a
188
+ * client we ship without a column (or a column with no client) is a compile
189
+ * error rather than a silently empty section of every report.
190
+ */
191
+ id: ClientId;
106
192
  name: string;
107
193
  category: "webmail" | "desktop" | "mobile";
108
194
  engine: string;
@@ -340,10 +426,31 @@ interface SizeIssue extends BaseIssue {
340
426
  }
341
427
  interface SizeReport {
342
428
  htmlBytes: number;
429
+ /** Bytes of CSS inside `<style>` elements, summed across all of them. */
430
+ styleBytes: number;
343
431
  humanSize: string;
344
432
  clipped: boolean;
345
433
  issues: SizeIssue[];
346
434
  }
435
+ interface StyleSurvivalIssue extends BaseIssue {
436
+ /**
437
+ * The clients that discard the CSS. Required, not optional: the consuming
438
+ * app groups findings per client, and an issue that cannot name its clients
439
+ * does not surface at all.
440
+ */
441
+ clients: string[];
442
+ detail?: string;
443
+ /**
444
+ * Where in the framework's source the offending CSS came from. Present only
445
+ * when the caller named a framework: the stylesheet that ships is assembled
446
+ * by the compiler, so "edit your <style> block" is the wrong instruction for
447
+ * someone whose source has no <style> block.
448
+ */
449
+ frameworkNote?: string;
450
+ }
451
+ interface StyleSurvivalReport {
452
+ issues: StyleSurvivalIssue[];
453
+ }
347
454
  interface OverflowIssue extends BaseIssue {
348
455
  detail?: string;
349
456
  }
@@ -409,4 +516,4 @@ interface DesignReport {
409
516
  };
410
517
  }
411
518
 
412
- export { type AiProvider as A, type BaseIssue as B, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, type OverflowIssue as G, type Severity as H, type ImageReport as I, type SizeIssue as J, type SourceLocation as K, type LinkReport as L, type SpamIssue as M, type TemplateIssue as N, type OverflowReport as O, type PreviewResult as P, type TokenEstimate as Q, type TokenEstimateWithWarnings as R, type SupportLevel as S, type TransformResult as T, type VisualIssue as U, type VmlReport as V, type VmlIssue as W, estimateAiFixTokens as X, generateFixPrompt as Y, heuristicTokenCount as Z, type CodeFix as a, type ExportPromptOptions as b, type AiFixResult as c, type SpamAnalysisOptions as d, type SpamReport as e, type AccessibilityReport as f, type AccessibilityIssue as g, type InboxPreview as h, type SizeReport as i, type TemplateReport as j, type VisualReport as k, type DesignReport as l, type DeliverabilityReport as m, type ClientTruncation as n, type DeliverabilityCheck as o, type DeliverabilityIssue as p, type DesignIssue as q, type EstimateOptions as r, type ExportScope as s, type FixType as t, type ImageInfo as u, type ImageIssue as v, type InboxPreviewIssue as w, type InputFormat as x, type LinkInfo as y, type LinkIssue as z };
519
+ export { type LinkInfo as $, type AiProvider as A, type BaseIssue as B, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, FEATURE_LAST_TESTED as G, type FeatureKey as H, type ImageReport as I, type FixType as J, GRACEFUL_FEATURES as K, type LinkReport as L, HTML_ATTRIBUTE_FEATURES as M, HTML_ELEMENT_FEATURES as N, type OverflowReport as O, HTML_MISC_FEATURES as P, IMAGE_FORMATS as Q, IMAGE_SUPPORT as R, type StyleSurvivalReport as S, type TransformResult as T, IMAGE_SUPPORT_NOTES as U, type VmlReport as V, type ImageFormat as W, type ImageInfo as X, type ImageIssue as Y, type InboxPreviewIssue as Z, type InputFormat as _, type CodeFix as a, type LinkIssue as a0, type OverflowIssue as a1, type PreviewResult as a2, SELECTOR_FEATURES as a3, STRUCTURAL_FIX_PROPERTIES as a4, SUPPORT_CLIENTS as a5, type Severity as a6, type SizeIssue as a7, type SourceLocation as a8, type SpamIssue as a9, type SupportLevel as aa, type TemplateIssue as ab, type TokenEstimate as ac, type TokenEstimateWithWarnings as ad, type VisualIssue as ae, type VmlIssue as af, estimateAiFixTokens as ag, generateFixPrompt as ah, heuristicTokenCount as ai, type ExportPromptOptions as b, type AiFixResult as c, type SpamAnalysisOptions as d, type SpamReport as e, type AccessibilityReport as f, type AccessibilityIssue as g, type InboxPreview as h, type SizeReport as i, type TemplateReport as j, type VisualReport as k, type DesignReport as l, type DeliverabilityReport as m, AT_RULE_FEATURES as n, COMPOUND_VALUE_FEATURES as o, CSS_FUNCTION_FEATURES as p, CSS_PROPERTY_FEATURES as q, CSS_SUPPORT as r, CSS_SUPPORT_NOTES as s, type ClientId as t, type ClientTruncation as u, type DeliverabilityCheck as v, type DeliverabilityIssue as w, type DesignIssue as x, type EstimateOptions as y, type ExportScope as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emailens/engine",
3
- "version": "0.11.9",
3
+ "version": "0.12.1",
4
4
  "description": "Email compatibility engine for HTML, MJML, Maizzle and React Email: transforms CSS per email client, scores compatibility, simulates dark mode, suggests fixes, and runs spam, accessibility, link and image quality analysis.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/compile/maizzle.ts"],"sourcesContent":["import { CompileError } from \"./errors.js\";\r\n\r\n/** Maximum Maizzle source size: 512KB */\r\nconst MAX_SOURCE_SIZE = 512_000;\r\n\r\n/** Compilation timeout: 15 seconds */\r\nconst COMPILE_TIMEOUT_MS = 15_000;\r\n\r\n/**\r\n * PostHTML directives that perform file-system reads or network fetches.\r\n *\r\n * Maizzle's PostHTML pipeline resolves these at compile time: a template\r\n * like `<extends src=\"/etc/passwd\">` causes the server to read that path\r\n * and include the content in rendered output (server-side file read). We\r\n * reject any input containing these directives rather than stripping them,\r\n * because stripping is error-prone with nested or malformed markup.\r\n *\r\n * Affected plugins: posthtml-extend, posthtml-fetch, posthtml-components,\r\n * posthtml-include, posthtml-modules.\r\n */\r\nconst DANGEROUS_DIRECTIVE_RE =\r\n /<\\s*(?:extends|component|fetch|include|module|slot|fill|raw|block|yield)\\b/i;\r\n\r\n/**\r\n * Compile a Maizzle template string into an HTML email string.\r\n *\r\n * Pipeline:\r\n * 1. Validate input (size, basic structure check)\r\n * 2. Reject inputs containing PostHTML file-access directives\r\n * 3. Compile using @maizzle/framework\r\n *\r\n * Security:\r\n * - PostHTML file-system directives are rejected at validation time\r\n * to prevent server-side file reads and SSRF.\r\n * - Template expressions ({{ expr }}) are evaluated by posthtml-expressions\r\n * with empty `locals`, so unknown identifiers like `process` or `require`\r\n * return the literal string '{local}' rather than accessing Node.js globals.\r\n * - A hard timeout prevents pathological PostCSS/Tailwind inputs from\r\n * hanging indefinitely.\r\n *\r\n * Requires peer dependency: @maizzle/framework\r\n */\r\nexport async function compileMaizzle(source: string): Promise<string> {\r\n // ── 1. Validate ──────────────────────────────────────────────────────\r\n if (!source || !source.trim()) {\r\n throw new CompileError(\"Maizzle source must not be empty.\", \"maizzle\", \"validation\");\r\n }\r\n\r\n if (source.length > MAX_SOURCE_SIZE) {\r\n throw new CompileError(\r\n `Maizzle source exceeds ${MAX_SOURCE_SIZE / 1000}KB limit.`,\r\n \"maizzle\",\r\n \"validation\",\r\n );\r\n }\r\n\r\n // ── 2. Block file-system and network PostHTML directives ─────────────\r\n if (DANGEROUS_DIRECTIVE_RE.test(source)) {\r\n throw new CompileError(\r\n \"Maizzle templates may not use <extends>, <component>, <fetch>, <include>, \" +\r\n \"<module>, <slot>, <fill>, <raw>, <block>, or <yield> directives. These directives \" +\r\n \"access the server file system at compile time. Use inline HTML and Tailwind utility classes instead.\",\r\n \"maizzle\",\r\n \"validation\",\r\n );\r\n }\r\n\r\n // ── 3. Load peer dependency ──────────────────────────────────────────\r\n let maizzleRender: (\r\n input: string,\r\n options: Record<string, unknown>,\r\n ) => Promise<{ html: string }>;\r\n\r\n try {\r\n const maizzle = await import(\"@maizzle/framework\");\r\n maizzleRender = maizzle.render;\r\n } catch {\r\n throw new CompileError(\r\n 'Maizzle compilation requires \"@maizzle/framework\". Install it:\\n npm install @maizzle/framework',\r\n \"maizzle\",\r\n \"compile\",\r\n );\r\n }\r\n\r\n // ── 4. Compile with timeout ──────────────────────────────────────────\r\n const compilePromise = maizzleRender(source, {\r\n css: {\r\n inline: {\r\n removeInlinedSelectors: true,\r\n applyWidthAttributes: true,\r\n applyHeightAttributes: true,\r\n },\r\n shorthand: true,\r\n sixHex: true,\r\n },\r\n locals: {},\r\n });\r\n\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n const t = setTimeout(() => {\r\n reject(\r\n new CompileError(\r\n `Maizzle compilation timed out after ${COMPILE_TIMEOUT_MS / 1000}s.`,\r\n \"maizzle\",\r\n \"compile\",\r\n ),\r\n );\r\n }, COMPILE_TIMEOUT_MS);\r\n if (typeof t.unref === \"function\") t.unref();\r\n });\r\n\r\n try {\r\n const { html } = await Promise.race([compilePromise, timeoutPromise]);\r\n\r\n if (!html) {\r\n throw new CompileError(\"Maizzle compilation produced empty output.\", \"maizzle\", \"compile\");\r\n }\r\n\r\n return html;\r\n } catch (err: unknown) {\r\n if (err instanceof CompileError) throw err;\r\n const message = err instanceof Error ? err.message : \"Unknown Maizzle compilation error\";\r\n throw new CompileError(`Maizzle compilation failed: ${message}`, \"maizzle\", \"compile\");\r\n }\r\n}\r\n"],"mappings":";;;;;AAGA,IAAM,kBAAkB;AAGxB,IAAM,qBAAqB;AAc3B,IAAM,yBACJ;AAqBF,eAAsB,eAAe,QAAiC;AAEpE,MAAI,CAAC,UAAU,CAAC,OAAO,KAAK,GAAG;AAC7B,UAAM,IAAI,aAAa,qCAAqC,WAAW,YAAY;AAAA,EACrF;AAEA,MAAI,OAAO,SAAS,iBAAiB;AACnC,UAAM,IAAI;AAAA,MACR,0BAA0B,kBAAkB,GAAI;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,uBAAuB,KAAK,MAAM,GAAG;AACvC,UAAM,IAAI;AAAA,MACR;AAAA,MAGA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AAKJ,MAAI;AACF,UAAM,UAAU,MAAM,OAAO,oBAAoB;AACjD,oBAAgB,QAAQ;AAAA,EAC1B,SAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,cAAc,QAAQ;AAAA,IAC3C,KAAK;AAAA,MACH,QAAQ;AAAA,QACN,wBAAwB;AAAA,QACxB,sBAAsB;AAAA,QACtB,uBAAuB;AAAA,MACzB;AAAA,MACA,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,IACA,QAAQ,CAAC;AAAA,EACX,CAAC;AAED,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,UAAM,IAAI,WAAW,MAAM;AACzB;AAAA,QACE,IAAI;AAAA,UACF,uCAAuC,qBAAqB,GAAI;AAAA,UAChE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,kBAAkB;AACrB,QAAI,OAAO,EAAE,UAAU,WAAY,GAAE,MAAM;AAAA,EAC7C,CAAC;AAED,MAAI;AACF,UAAM,EAAE,KAAK,IAAI,MAAM,QAAQ,KAAK,CAAC,gBAAgB,cAAc,CAAC;AAEpE,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,aAAa,8CAA8C,WAAW,SAAS;AAAA,IAC3F;AAEA,WAAO;AAAA,EACT,SAAS,KAAc;AACrB,QAAI,eAAe,aAAc,OAAM;AACvC,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,UAAM,IAAI,aAAa,+BAA+B,OAAO,IAAI,WAAW,SAAS;AAAA,EACvF;AACF;","names":[]}
@@ -1,9 +0,0 @@
1
- import {
2
- compileMaizzle
3
- } from "./chunk-PW6EUG2G.js";
4
- import "./chunk-Z22AD2IU.js";
5
- import "./chunk-2NMEKWO5.js";
6
- export {
7
- compileMaizzle
8
- };
9
- //# sourceMappingURL=maizzle-KKJF7XY7.js.map