@emailens/engine 0.11.7 → 0.11.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile/index.d.cts +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/index.cjs +54 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -9
- package/dist/index.d.ts +29 -9
- package/dist/index.js +54 -5
- package/dist/index.js.map +1 -1
- package/dist/{react-email-BROBcC8u.d.ts → react-email-B82A1R_K.d.ts} +1 -1
- package/dist/{react-email-DuZAgJtw.d.cts → react-email-DRkmpgX-.d.cts} +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/{types-bvGDId6f.d.cts → types-DiseE-UH.d.cts} +26 -1
- package/dist/{types-bvGDId6f.d.ts → types-DiseE-UH.d.ts} +26 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +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, g as AccessibilityIssue, I as ImageReport, h as InboxPreview, i as SizeReport, j as TemplateReport, O as OverflowReport, V as VmlReport, k as VisualReport, l as DesignReport, m as DeliverabilityReport } from './types-
|
|
2
|
-
export { B as BaseIssue, n as ClientTruncation, o as DeliverabilityCheck, p as DeliverabilityIssue, q as DesignIssue, r as EstimateOptions, s as ExportScope, t as FixType, u as ImageInfo, v as ImageIssue, w as InboxPreviewIssue, x as InputFormat, y as
|
|
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 VmlReport, k as VisualReport, l as DesignReport, m as DeliverabilityReport } from './types-DiseE-UH.cjs';
|
|
2
|
+
export { B as BaseIssue, n as ClientTruncation, o as DeliverabilityCheck, p as DeliverabilityIssue, q as DesignIssue, r as EstimateOptions, s as ExportScope, t as FixType, u as ImageInfo, v as ImageIssue, w as InboxPreviewIssue, x as InputFormat, y as LinkInfo, z as LinkIssue, G as OverflowIssue, P as PreviewResult, H as Severity, J as SizeIssue, K as SourceLocation, M as SpamIssue, N as TemplateIssue, Q as TokenEstimate, R as TokenEstimateWithWarnings, U as VisualIssue, W as VmlIssue, X as estimateAiFixTokens, Y as generateFixPrompt, Z as heuristicTokenCount } from './types-DiseE-UH.cjs';
|
|
3
3
|
import * as cheerio from 'cheerio';
|
|
4
|
-
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-
|
|
4
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-DRkmpgX-.cjs';
|
|
5
5
|
|
|
6
6
|
declare const EMAIL_CLIENTS: EmailClient[];
|
|
7
7
|
declare function getClient(id: string): EmailClient | undefined;
|
|
@@ -410,12 +410,32 @@ declare function checkVml(html: string, options?: {
|
|
|
410
410
|
* `roundrect` and `rect` are the whole surface. Anything else is left alone
|
|
411
411
|
* rather than approximated.
|
|
412
412
|
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
413
|
+
* How Word *mis*-renders a nested shape is emulated, but only the parts with
|
|
414
|
+
* evidence behind them. This note used to say the failure was not emulated at
|
|
415
|
+
* all, on the grounds that reproducing it meant perturbing Chromium into a
|
|
416
|
+
* picture wrong in a third way. That argument does not survive contact with
|
|
417
|
+
* the specific effects:
|
|
418
|
+
*
|
|
419
|
+
* - the container's fill and geometry disappear -> drop the box. Exact.
|
|
420
|
+
* - VML shapes further down stop drawing text -> blank their labels.
|
|
421
|
+
* Exact, and scoped to
|
|
422
|
+
* shapes we created.
|
|
423
|
+
* - the table structure terminates early, so later
|
|
424
|
+
* content escapes the frame -> WITHDRAWN. It had no
|
|
425
|
+
* methodology, and the
|
|
426
|
+
* fixture built to
|
|
427
|
+
* measure it contradicts
|
|
428
|
+
* it.
|
|
429
|
+
*
|
|
430
|
+
* Two of the three needed no distortion at all; the third turned out not to be
|
|
431
|
+
* a rendering problem but an evidence problem. Refusing to draw any of it
|
|
432
|
+
* meant the preview showed a tidy box with a button in it, a picture no Word
|
|
433
|
+
* engine produces, sitting beside a finding that said the region was
|
|
434
|
+
* destroyed. Between a warning and a screenshot, people believe the
|
|
435
|
+
* screenshot.
|
|
436
|
+
*
|
|
437
|
+
* Affected regions carry `data-vml-outlook` so a surface can label them, since
|
|
438
|
+
* a blank button should read as "Outlook does this" and not as our bug.
|
|
419
439
|
*/
|
|
420
440
|
/**
|
|
421
441
|
* `arcsize` is a VgFraction: a proportion of *half the shape's shorter side*,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +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, g as AccessibilityIssue, I as ImageReport, h as InboxPreview, i as SizeReport, j as TemplateReport, O as OverflowReport, V as VmlReport, k as VisualReport, l as DesignReport, m as DeliverabilityReport } from './types-
|
|
2
|
-
export { B as BaseIssue, n as ClientTruncation, o as DeliverabilityCheck, p as DeliverabilityIssue, q as DesignIssue, r as EstimateOptions, s as ExportScope, t as FixType, u as ImageInfo, v as ImageIssue, w as InboxPreviewIssue, x as InputFormat, y as
|
|
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 VmlReport, k as VisualReport, l as DesignReport, m as DeliverabilityReport } from './types-DiseE-UH.js';
|
|
2
|
+
export { B as BaseIssue, n as ClientTruncation, o as DeliverabilityCheck, p as DeliverabilityIssue, q as DesignIssue, r as EstimateOptions, s as ExportScope, t as FixType, u as ImageInfo, v as ImageIssue, w as InboxPreviewIssue, x as InputFormat, y as LinkInfo, z as LinkIssue, G as OverflowIssue, P as PreviewResult, H as Severity, J as SizeIssue, K as SourceLocation, M as SpamIssue, N as TemplateIssue, Q as TokenEstimate, R as TokenEstimateWithWarnings, U as VisualIssue, W as VmlIssue, X as estimateAiFixTokens, Y as generateFixPrompt, Z as heuristicTokenCount } from './types-DiseE-UH.js';
|
|
3
3
|
import * as cheerio from 'cheerio';
|
|
4
|
-
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-
|
|
4
|
+
export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-B82A1R_K.js';
|
|
5
5
|
|
|
6
6
|
declare const EMAIL_CLIENTS: EmailClient[];
|
|
7
7
|
declare function getClient(id: string): EmailClient | undefined;
|
|
@@ -410,12 +410,32 @@ declare function checkVml(html: string, options?: {
|
|
|
410
410
|
* `roundrect` and `rect` are the whole surface. Anything else is left alone
|
|
411
411
|
* rather than approximated.
|
|
412
412
|
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
413
|
+
* How Word *mis*-renders a nested shape is emulated, but only the parts with
|
|
414
|
+
* evidence behind them. This note used to say the failure was not emulated at
|
|
415
|
+
* all, on the grounds that reproducing it meant perturbing Chromium into a
|
|
416
|
+
* picture wrong in a third way. That argument does not survive contact with
|
|
417
|
+
* the specific effects:
|
|
418
|
+
*
|
|
419
|
+
* - the container's fill and geometry disappear -> drop the box. Exact.
|
|
420
|
+
* - VML shapes further down stop drawing text -> blank their labels.
|
|
421
|
+
* Exact, and scoped to
|
|
422
|
+
* shapes we created.
|
|
423
|
+
* - the table structure terminates early, so later
|
|
424
|
+
* content escapes the frame -> WITHDRAWN. It had no
|
|
425
|
+
* methodology, and the
|
|
426
|
+
* fixture built to
|
|
427
|
+
* measure it contradicts
|
|
428
|
+
* it.
|
|
429
|
+
*
|
|
430
|
+
* Two of the three needed no distortion at all; the third turned out not to be
|
|
431
|
+
* a rendering problem but an evidence problem. Refusing to draw any of it
|
|
432
|
+
* meant the preview showed a tidy box with a button in it, a picture no Word
|
|
433
|
+
* engine produces, sitting beside a finding that said the region was
|
|
434
|
+
* destroyed. Between a warning and a screenshot, people believe the
|
|
435
|
+
* screenshot.
|
|
436
|
+
*
|
|
437
|
+
* Affected regions carry `data-vml-outlook` so a surface can label them, since
|
|
438
|
+
* a blank button should read as "Outlook does this" and not as our bug.
|
|
419
439
|
*/
|
|
420
440
|
/**
|
|
421
441
|
* `arcsize` is a VgFraction: a proportion of *half the shape's shorter side*,
|
package/dist/index.js
CHANGED
|
@@ -9840,10 +9840,23 @@ function vmlToCss(html) {
|
|
|
9840
9840
|
solid ? `background-color:${solid}` : "",
|
|
9841
9841
|
`padding:${padding}`
|
|
9842
9842
|
].filter(Boolean).join(";");
|
|
9843
|
+
if (/data-vml="/.test(content)) {
|
|
9844
|
+
return `<div data-vml="rect" data-vml-outlook="container-dropped">${content}</div>`;
|
|
9845
|
+
}
|
|
9843
9846
|
return `<div data-vml="rect" style="${background}${box}">${content}</div>`;
|
|
9844
9847
|
}
|
|
9845
9848
|
);
|
|
9846
|
-
|
|
9849
|
+
out = out.replace(/<\/?v:(?:fill|textbox|stroke|shadow|imagedata|path|formulas|handles)[^>]*?\/?>/gi, "");
|
|
9850
|
+
return blankLabelsAfterNestedShape(out);
|
|
9851
|
+
}
|
|
9852
|
+
function blankLabelsAfterNestedShape(html) {
|
|
9853
|
+
const at = html.indexOf('data-vml-outlook="container-dropped"');
|
|
9854
|
+
if (at === -1) return html;
|
|
9855
|
+
const tail = html.slice(at).replace(
|
|
9856
|
+
/(<div data-vml="roundrect")([^>]*>)([\s\S]*?)(<\/div>)/gi,
|
|
9857
|
+
(whole, open, rest, label, close) => label.trim() ? `${open}${rest.slice(0, -1)} data-vml-outlook="label-dropped">${close}` : whole
|
|
9858
|
+
);
|
|
9859
|
+
return html.slice(0, at) + tail;
|
|
9847
9860
|
}
|
|
9848
9861
|
function renderOutlookBranch(html) {
|
|
9849
9862
|
if (!/<!--\[if/i.test(html)) return html;
|
|
@@ -9895,6 +9908,7 @@ var EMPTY_SPAM = { score: 100, level: "low", issues: [] };
|
|
|
9895
9908
|
var EMPTY_LINKS = {
|
|
9896
9909
|
totalLinks: 0,
|
|
9897
9910
|
issues: [],
|
|
9911
|
+
links: [],
|
|
9898
9912
|
breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
|
|
9899
9913
|
};
|
|
9900
9914
|
var EMPTY_ACCESSIBILITY = { score: 100, issues: [] };
|
|
@@ -12995,6 +13009,7 @@ function isPlaceholderHref(href) {
|
|
|
12995
13009
|
}
|
|
12996
13010
|
function validateLinksFromDom($) {
|
|
12997
13011
|
const issues = [];
|
|
13012
|
+
const inventory = [];
|
|
12998
13013
|
const breakdown = { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 };
|
|
12999
13014
|
const links = $("a");
|
|
13000
13015
|
const totalLinks = links.length;
|
|
@@ -13004,13 +13019,22 @@ function validateLinksFromDom($) {
|
|
|
13004
13019
|
rule: "no-links",
|
|
13005
13020
|
message: "Email contains no links"
|
|
13006
13021
|
});
|
|
13007
|
-
return { totalLinks: 0, issues, breakdown };
|
|
13022
|
+
return { totalLinks: 0, issues, breakdown, links: [] };
|
|
13008
13023
|
}
|
|
13009
13024
|
const hrefCounts = /* @__PURE__ */ new Map();
|
|
13010
13025
|
links.each((_, el) => {
|
|
13011
13026
|
const href = $(el).attr("href") || "";
|
|
13012
13027
|
const text = $(el).text().trim();
|
|
13013
13028
|
const category = classifyHref(href);
|
|
13029
|
+
const entry = {
|
|
13030
|
+
href,
|
|
13031
|
+
text: text.slice(0, 80),
|
|
13032
|
+
scheme: category,
|
|
13033
|
+
isPlaceholder: isPlaceholderHref(href),
|
|
13034
|
+
issues: []
|
|
13035
|
+
};
|
|
13036
|
+
inventory.push(entry);
|
|
13037
|
+
const flag = (rule) => entry.issues.push(rule);
|
|
13014
13038
|
const elLoc = locOfElement(el);
|
|
13015
13039
|
const hrefLoc = href ? locOfAttr(el, "href") : elLoc;
|
|
13016
13040
|
switch (category) {
|
|
@@ -13043,6 +13067,7 @@ function validateLinksFromDom($) {
|
|
|
13043
13067
|
hrefCounts.set(href, (hrefCounts.get(href) || 0) + 1);
|
|
13044
13068
|
}
|
|
13045
13069
|
if (!href || !href.trim()) {
|
|
13070
|
+
flag("empty-href");
|
|
13046
13071
|
issues.push(__spreadValues({
|
|
13047
13072
|
severity: "error",
|
|
13048
13073
|
rule: "empty-href",
|
|
@@ -13052,6 +13077,7 @@ function validateLinksFromDom($) {
|
|
|
13052
13077
|
return;
|
|
13053
13078
|
}
|
|
13054
13079
|
if (category === "javascript" && !isPlaceholderHref(href)) {
|
|
13080
|
+
flag("javascript-href");
|
|
13055
13081
|
issues.push(__spreadValues({
|
|
13056
13082
|
severity: "error",
|
|
13057
13083
|
rule: "javascript-href",
|
|
@@ -13062,6 +13088,7 @@ function validateLinksFromDom($) {
|
|
|
13062
13088
|
return;
|
|
13063
13089
|
}
|
|
13064
13090
|
if (isPlaceholderHref(href)) {
|
|
13091
|
+
flag("placeholder-href");
|
|
13065
13092
|
issues.push(__spreadValues({
|
|
13066
13093
|
severity: "warning",
|
|
13067
13094
|
rule: "placeholder-href",
|
|
@@ -13072,6 +13099,7 @@ function validateLinksFromDom($) {
|
|
|
13072
13099
|
return;
|
|
13073
13100
|
}
|
|
13074
13101
|
if (category === "http") {
|
|
13102
|
+
flag("insecure-link");
|
|
13075
13103
|
issues.push(__spreadValues({
|
|
13076
13104
|
severity: "warning",
|
|
13077
13105
|
rule: "insecure-link",
|
|
@@ -13081,6 +13109,7 @@ function validateLinksFromDom($) {
|
|
|
13081
13109
|
}, hrefLoc ? { loc: hrefLoc } : {}));
|
|
13082
13110
|
}
|
|
13083
13111
|
if (category === "protocol-relative") {
|
|
13112
|
+
flag("protocol-relative");
|
|
13084
13113
|
issues.push(__spreadValues({
|
|
13085
13114
|
severity: "warning",
|
|
13086
13115
|
rule: "protocol-relative",
|
|
@@ -13090,6 +13119,7 @@ function validateLinksFromDom($) {
|
|
|
13090
13119
|
}, hrefLoc ? { loc: hrefLoc } : {}));
|
|
13091
13120
|
}
|
|
13092
13121
|
if (text && GENERIC_LINK_TEXT.has(text.toLowerCase())) {
|
|
13122
|
+
flag("generic-link-text");
|
|
13093
13123
|
issues.push(__spreadValues({
|
|
13094
13124
|
severity: "warning",
|
|
13095
13125
|
rule: "generic-link-text",
|
|
@@ -13099,6 +13129,7 @@ function validateLinksFromDom($) {
|
|
|
13099
13129
|
}, elLoc ? { loc: elLoc } : {}));
|
|
13100
13130
|
}
|
|
13101
13131
|
if (!text && !$(el).attr("aria-label") && !$(el).find("img[alt]").length) {
|
|
13132
|
+
flag("empty-link-text");
|
|
13102
13133
|
issues.push(__spreadValues({
|
|
13103
13134
|
severity: "error",
|
|
13104
13135
|
rule: "empty-link-text",
|
|
@@ -13107,6 +13138,7 @@ function validateLinksFromDom($) {
|
|
|
13107
13138
|
}, elLoc ? { loc: elLoc } : {}));
|
|
13108
13139
|
}
|
|
13109
13140
|
if (category === "mailto" && href.trim().toLowerCase() === "mailto:") {
|
|
13141
|
+
flag("empty-mailto");
|
|
13110
13142
|
issues.push(__spreadValues({
|
|
13111
13143
|
severity: "error",
|
|
13112
13144
|
rule: "empty-mailto",
|
|
@@ -13116,6 +13148,7 @@ function validateLinksFromDom($) {
|
|
|
13116
13148
|
}, hrefLoc ? { loc: hrefLoc } : {}));
|
|
13117
13149
|
}
|
|
13118
13150
|
if (category === "tel" && href.trim().toLowerCase() === "tel:") {
|
|
13151
|
+
flag("empty-tel");
|
|
13119
13152
|
issues.push(__spreadValues({
|
|
13120
13153
|
severity: "error",
|
|
13121
13154
|
rule: "empty-tel",
|
|
@@ -13125,6 +13158,7 @@ function validateLinksFromDom($) {
|
|
|
13125
13158
|
}, hrefLoc ? { loc: hrefLoc } : {}));
|
|
13126
13159
|
}
|
|
13127
13160
|
if (href.length > 2e3) {
|
|
13161
|
+
flag("long-url");
|
|
13128
13162
|
issues.push(__spreadValues({
|
|
13129
13163
|
severity: "info",
|
|
13130
13164
|
rule: "long-url",
|
|
@@ -13134,7 +13168,8 @@ function validateLinksFromDom($) {
|
|
|
13134
13168
|
}, hrefLoc ? { loc: hrefLoc } : {}));
|
|
13135
13169
|
}
|
|
13136
13170
|
});
|
|
13137
|
-
links.each((
|
|
13171
|
+
links.each((i, el) => {
|
|
13172
|
+
var _a;
|
|
13138
13173
|
const href = $(el).attr("href") || "";
|
|
13139
13174
|
const trimmed = href.trim();
|
|
13140
13175
|
if (trimmed.startsWith("#") && trimmed.length > 1) {
|
|
@@ -13142,6 +13177,7 @@ function validateLinksFromDom($) {
|
|
|
13142
13177
|
const target = $(`[id="${targetId}"]`);
|
|
13143
13178
|
const anchorLoc = locOfAttr(el, "href");
|
|
13144
13179
|
if (target.length === 0) {
|
|
13180
|
+
(_a = inventory[i]) == null ? void 0 : _a.issues.push("broken-anchor");
|
|
13145
13181
|
issues.push(__spreadValues({
|
|
13146
13182
|
severity: "error",
|
|
13147
13183
|
rule: "broken-anchor",
|
|
@@ -13162,7 +13198,7 @@ function validateLinksFromDom($) {
|
|
|
13162
13198
|
});
|
|
13163
13199
|
}
|
|
13164
13200
|
}
|
|
13165
|
-
return { totalLinks, issues, breakdown };
|
|
13201
|
+
return { totalLinks, issues, breakdown, links: inventory };
|
|
13166
13202
|
}
|
|
13167
13203
|
function validateLinks(html, options) {
|
|
13168
13204
|
return fromHtml(html, EMPTY_LINKS, validateLinksFromDom, options);
|
|
@@ -14701,7 +14737,20 @@ function checkVml(html, options) {
|
|
|
14701
14737
|
rule: "vml-nested-shape",
|
|
14702
14738
|
severity: "error",
|
|
14703
14739
|
message: `<v:${name}> is nested inside <v:${parent.name}>. Outlook does not support nesting one VML shape inside another.`,
|
|
14704
|
-
|
|
14740
|
+
// Two effects, not the three this used to claim. The withdrawn one
|
|
14741
|
+
// said the table structure terminates early so content after the
|
|
14742
|
+
// shape falls outside the email frame. It had no methodology behind
|
|
14743
|
+
// it, and `T1c-blast-radius.html`, the fixture built to measure
|
|
14744
|
+
// exactly this, contradicts it: the block after the nested shape
|
|
14745
|
+
// rendered in place inside the same table with its background and
|
|
14746
|
+
// borders intact, and only the VML labels were missing. The likely
|
|
14747
|
+
// origin is over-reading "layout breaks after it" from a run where a
|
|
14748
|
+
// 600px hero band vanished and everything below shifted up.
|
|
14749
|
+
//
|
|
14750
|
+
// Kept as a warning to whoever edits this next: the probe sentence
|
|
14751
|
+
// below covers the downstream text suppression only. Do not let it
|
|
14752
|
+
// lend its authority to a neighbouring clause again.
|
|
14753
|
+
detail: `Verified in Outlook Classic, and the damage is not local. Two things happen: the containing <v:${parent.name}> does not render at all (its fill and everything inside it disappear, leaving the inner shape stranded); and every VML shape further down the email stops drawing its text, so buttons and headings after this point ship as blank coloured blocks. That second effect was confirmed with byte-identical probes either side of one nested shape: the one before it renders its labels, the one after it does not. Every other client renders the HTML fallback correctly, which is why none of this is visible outside the Word engine. Fix: lift the inner shape out of <v:${parent.name}>, or drop the container shape and keep the inner one (a framed background can degrade to a solid fill colour on the <td> instead).`
|
|
14705
14754
|
}, loc));
|
|
14706
14755
|
}
|
|
14707
14756
|
if (!tag.selfClosing) openShapes.push(tag);
|