@emailens/engine 0.9.5 → 0.9.6

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/index.d.cts CHANGED
@@ -1,6 +1,6 @@
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, g as InboxPreview, h as SizeReport, i as TemplateReport, j as DeliverabilityReport } from './types-p9e1n-G_.cjs';
2
- export { k as AccessibilityIssue, l as ClientTruncation, m as DeliverabilityCheck, n as DeliverabilityIssue, o as EstimateOptions, p as ExportScope, q as FixType, r as ImageInfo, s as ImageIssue, t as InboxPreviewIssue, u as InputFormat, v as LinkIssue, P as PreviewResult, w as SizeIssue, x as SpamIssue, y as TemplateIssue, z as TokenEstimate, B as TokenEstimateWithWarnings, G as estimateAiFixTokens, H as generateFixPrompt, J as heuristicTokenCount } from './types-p9e1n-G_.cjs';
3
- export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-WFdbEleP.cjs';
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, g as InboxPreview, h as SizeReport, i as TemplateReport, j as DeliverabilityReport } from './types-WvVf2OXX.cjs';
2
+ export { k as AccessibilityIssue, B as BaseIssue, l as ClientTruncation, m as DeliverabilityCheck, n as DeliverabilityIssue, o as EstimateOptions, p as ExportScope, q as FixType, r as ImageInfo, s as ImageIssue, t as InboxPreviewIssue, u as InputFormat, v as LinkIssue, P as PreviewResult, w as Severity, x as SizeIssue, y as SpamIssue, z as TemplateIssue, G as TokenEstimate, H as TokenEstimateWithWarnings, J as estimateAiFixTokens, K as generateFixPrompt, M as heuristicTokenCount } from './types-WvVf2OXX.cjs';
3
+ export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-M23kFFxl.cjs';
4
4
 
5
5
  declare const EMAIL_CLIENTS: EmailClient[];
6
6
  declare function getClient(id: string): EmailClient | undefined;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
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, g as InboxPreview, h as SizeReport, i as TemplateReport, j as DeliverabilityReport } from './types-p9e1n-G_.js';
2
- export { k as AccessibilityIssue, l as ClientTruncation, m as DeliverabilityCheck, n as DeliverabilityIssue, o as EstimateOptions, p as ExportScope, q as FixType, r as ImageInfo, s as ImageIssue, t as InboxPreviewIssue, u as InputFormat, v as LinkIssue, P as PreviewResult, w as SizeIssue, x as SpamIssue, y as TemplateIssue, z as TokenEstimate, B as TokenEstimateWithWarnings, G as estimateAiFixTokens, H as generateFixPrompt, J as heuristicTokenCount } from './types-p9e1n-G_.js';
3
- export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-CkBByvBK.js';
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, g as InboxPreview, h as SizeReport, i as TemplateReport, j as DeliverabilityReport } from './types-WvVf2OXX.js';
2
+ export { k as AccessibilityIssue, B as BaseIssue, l as ClientTruncation, m as DeliverabilityCheck, n as DeliverabilityIssue, o as EstimateOptions, p as ExportScope, q as FixType, r as ImageInfo, s as ImageIssue, t as InboxPreviewIssue, u as InputFormat, v as LinkIssue, P as PreviewResult, w as Severity, x as SizeIssue, y as SpamIssue, z as TemplateIssue, G as TokenEstimate, H as TokenEstimateWithWarnings, J as estimateAiFixTokens, K as generateFixPrompt, M as heuristicTokenCount } from './types-WvVf2OXX.js';
3
+ export { C as CompileError, a as CompileReactEmailOptions, S as SandboxStrategy } from './react-email-TJF6usIm.js';
4
4
 
5
5
  declare const EMAIL_CLIENTS: EmailClient[];
6
6
  declare function getClient(id: string): EmailClient | undefined;
package/dist/index.js CHANGED
@@ -8575,8 +8575,17 @@ function extractCode(response) {
8575
8575
  return response.trim();
8576
8576
  }
8577
8577
 
8578
- // src/spam-scorer.ts
8578
+ // src/parse-html.ts
8579
8579
  import * as cheerio5 from "cheerio";
8580
+ function fromHtml(html, empty, fn) {
8581
+ if (!html || !html.trim()) return empty;
8582
+ if (html.length > MAX_HTML_SIZE) {
8583
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
8584
+ }
8585
+ return fn(cheerio5.load(html), html);
8586
+ }
8587
+
8588
+ // src/spam-scorer.ts
8580
8589
  var SPAM_TRIGGER_PHRASES = [
8581
8590
  "act now",
8582
8591
  "limited time",
@@ -9006,18 +9015,10 @@ function analyzeSpamFromDom($, options) {
9006
9015
  return { score, level, issues };
9007
9016
  }
9008
9017
  function analyzeSpam(html, options) {
9009
- if (!html || !html.trim()) {
9010
- return { score: 100, level: "low", issues: [] };
9011
- }
9012
- if (html.length > MAX_HTML_SIZE) {
9013
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9014
- }
9015
- const $ = cheerio5.load(html);
9016
- return analyzeSpamFromDom($, options);
9018
+ return fromHtml(html, EMPTY_SPAM, ($) => analyzeSpamFromDom($, options));
9017
9019
  }
9018
9020
 
9019
9021
  // src/link-validator.ts
9020
- import * as cheerio6 from "cheerio";
9021
9022
  function classifyHref(href) {
9022
9023
  if (!href || !href.trim()) return "empty";
9023
9024
  const h = href.trim().toLowerCase();
@@ -9203,22 +9204,10 @@ function validateLinksFromDom($) {
9203
9204
  return { totalLinks, issues, breakdown };
9204
9205
  }
9205
9206
  function validateLinks(html) {
9206
- if (!html || !html.trim()) {
9207
- return {
9208
- totalLinks: 0,
9209
- issues: [],
9210
- breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
9211
- };
9212
- }
9213
- if (html.length > MAX_HTML_SIZE) {
9214
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9215
- }
9216
- const $ = cheerio6.load(html);
9217
- return validateLinksFromDom($);
9207
+ return fromHtml(html, EMPTY_LINKS, validateLinksFromDom);
9218
9208
  }
9219
9209
 
9220
9210
  // src/accessibility-checker.ts
9221
- import * as cheerio7 from "cheerio";
9222
9211
  var RULE_PENALTY_CAPS = {
9223
9212
  "img-missing-alt": 3,
9224
9213
  "link-generic-text": 3,
@@ -9515,18 +9504,10 @@ function checkAccessibilityFromDom($) {
9515
9504
  return { score, issues };
9516
9505
  }
9517
9506
  function checkAccessibility(html) {
9518
- if (!html || !html.trim()) {
9519
- return { score: 100, issues: [] };
9520
- }
9521
- if (html.length > MAX_HTML_SIZE) {
9522
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9523
- }
9524
- const $ = cheerio7.load(html);
9525
- return checkAccessibilityFromDom($);
9507
+ return fromHtml(html, EMPTY_ACCESSIBILITY, checkAccessibilityFromDom);
9526
9508
  }
9527
9509
 
9528
9510
  // src/image-analyzer.ts
9529
- import * as cheerio8 from "cheerio";
9530
9511
  var DATA_URI_WARN_BYTES = 100 * 1024;
9531
9512
  var TOTAL_DATA_URI_WARN_BYTES = 500 * 1024;
9532
9513
  var HIGH_IMAGE_COUNT = 10;
@@ -9684,39 +9665,24 @@ function analyzeImagesFromDom($) {
9684
9665
  return { total: images.length, totalDataUriBytes, issues, images };
9685
9666
  }
9686
9667
  function analyzeImages(html) {
9687
- if (!html || !html.trim()) {
9688
- return { total: 0, totalDataUriBytes: 0, issues: [], images: [] };
9689
- }
9690
- if (html.length > MAX_HTML_SIZE) {
9691
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9692
- }
9693
- const $ = cheerio8.load(html);
9694
- return analyzeImagesFromDom($);
9668
+ return fromHtml(html, EMPTY_IMAGES, analyzeImagesFromDom);
9695
9669
  }
9696
9670
 
9697
9671
  // src/inbox-preview.ts
9698
- import * as cheerio9 from "cheerio";
9699
9672
  var MAX_SUBJECT_LENGTH = 60;
9700
9673
  var MAX_PREHEADER_LENGTH = 100;
9701
9674
  var MIN_PREHEADER_LENGTH = 30;
9702
9675
  var EMOJI_PATTERN = /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F1E0}-\u{1F1FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2B50}-\u{2B55}\u{FE00}-\u{FE0F}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{200D}\u{20E3}\u{E0020}-\u{E007F}]/u;
9703
9676
  var ZWNJ_PADDING_PATTERN = /(\u200C\s*( |\u00A0)\s*){2,}|(‌\s* \s*){2,}/;
9704
9677
  function extractInboxPreview(html) {
9705
- if (!html || !html.trim()) {
9706
- return {
9707
- subject: null,
9708
- preheader: null,
9709
- subjectLength: 0,
9710
- preheaderLength: 0,
9711
- truncation: [],
9712
- issues: [{ rule: "missing-subject", severity: "warning", message: "No <title> tag found. Most email clients use this as the subject line." }]
9713
- };
9714
- }
9715
- if (html.length > MAX_HTML_SIZE) {
9716
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9717
- }
9718
- const $ = cheerio9.load(html);
9719
- return extractInboxPreviewFromDom($);
9678
+ return fromHtml(html, {
9679
+ subject: null,
9680
+ preheader: null,
9681
+ subjectLength: 0,
9682
+ preheaderLength: 0,
9683
+ truncation: [],
9684
+ issues: [{ rule: "missing-subject", severity: "warning", message: "No <title> tag found. Most email clients use this as the subject line." }]
9685
+ }, extractInboxPreviewFromDom);
9720
9686
  }
9721
9687
  function extractInboxPreviewFromDom($) {
9722
9688
  var _a, _b;
@@ -9883,7 +9849,6 @@ function getFirstVisibleText($, body) {
9883
9849
  }
9884
9850
 
9885
9851
  // src/size-checker.ts
9886
- import * as cheerio10 from "cheerio";
9887
9852
  function humanizeBytes(bytes) {
9888
9853
  if (bytes < 1024) return `${bytes} B`;
9889
9854
  const kb = bytes / 1024;
@@ -9915,18 +9880,10 @@ function checkSizeFromDom(_$, html) {
9915
9880
  return { htmlBytes, humanSize, clipped, issues };
9916
9881
  }
9917
9882
  function checkSize(html) {
9918
- if (!html || !html.trim()) {
9919
- return { htmlBytes: 0, humanSize: "0 B", clipped: false, issues: [] };
9920
- }
9921
- if (html.length > MAX_HTML_SIZE) {
9922
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9923
- }
9924
- const $ = cheerio10.load(html);
9925
- return checkSizeFromDom($, html);
9883
+ return fromHtml(html, EMPTY_SIZE, checkSizeFromDom);
9926
9884
  }
9927
9885
 
9928
9886
  // src/template-checker.ts
9929
- import * as cheerio11 from "cheerio";
9930
9887
  function checkTemplateVariablesFromDom($) {
9931
9888
  const issues = [];
9932
9889
  const seen = /* @__PURE__ */ new Set();
@@ -9983,38 +9940,23 @@ function extractTextContent($) {
9983
9940
  return clone.text();
9984
9941
  }
9985
9942
  function checkTemplateVariables(html) {
9986
- if (!html || !html.trim()) {
9987
- return { unresolvedCount: 0, issues: [] };
9988
- }
9989
- if (html.length > MAX_HTML_SIZE) {
9990
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
9991
- }
9992
- const $ = cheerio11.load(html);
9993
- return checkTemplateVariablesFromDom($);
9943
+ return fromHtml(html, EMPTY_TEMPLATE, checkTemplateVariablesFromDom);
9994
9944
  }
9995
9945
 
9996
9946
  // src/audit.ts
9997
- import * as cheerio12 from "cheerio";
9998
- function auditEmail(html, options) {
9947
+ var EMPTY_AUDIT = {
9948
+ compatibility: { warnings: [], scores: {} },
9949
+ spam: EMPTY_SPAM,
9950
+ links: EMPTY_LINKS,
9951
+ accessibility: EMPTY_ACCESSIBILITY,
9952
+ images: EMPTY_IMAGES,
9953
+ inboxPreview: EMPTY_INBOX_PREVIEW,
9954
+ size: EMPTY_SIZE,
9955
+ templateVariables: EMPTY_TEMPLATE
9956
+ };
9957
+ function runAudit($, html, framework, options) {
9999
9958
  var _a;
10000
- if (!html || !html.trim()) {
10001
- return {
10002
- compatibility: { warnings: [], scores: {} },
10003
- spam: EMPTY_SPAM,
10004
- links: EMPTY_LINKS,
10005
- accessibility: EMPTY_ACCESSIBILITY,
10006
- images: EMPTY_IMAGES,
10007
- inboxPreview: EMPTY_INBOX_PREVIEW,
10008
- size: EMPTY_SIZE,
10009
- templateVariables: EMPTY_TEMPLATE
10010
- };
10011
- }
10012
- if (html.length > MAX_HTML_SIZE) {
10013
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
10014
- }
10015
- const framework = options == null ? void 0 : options.framework;
10016
9959
  const skip = new Set((_a = options == null ? void 0 : options.skip) != null ? _a : []);
10017
- const $ = cheerio12.load(html);
10018
9960
  const warnings = skip.has("compatibility") ? [] : analyzeEmailFromDom($, framework);
10019
9961
  const scores = skip.has("compatibility") ? {} : generateCompatibilityScore(warnings);
10020
9962
  const spam = skip.has("spam") ? EMPTY_SPAM : analyzeSpamFromDom($, options == null ? void 0 : options.spam);
@@ -10026,11 +9968,14 @@ function auditEmail(html, options) {
10026
9968
  const templateVariables = skip.has("templateVariables") ? EMPTY_TEMPLATE : checkTemplateVariablesFromDom($);
10027
9969
  return { compatibility: { warnings, scores }, spam, links, accessibility, images, inboxPreview, size, templateVariables };
10028
9970
  }
9971
+ function auditEmail(html, options) {
9972
+ return fromHtml(html, EMPTY_AUDIT, ($, h) => runAudit($, h, options == null ? void 0 : options.framework, options));
9973
+ }
10029
9974
 
10030
9975
  // src/plain-text.ts
10031
- import * as cheerio13 from "cheerio";
9976
+ import * as cheerio6 from "cheerio";
10032
9977
  function toPlainText(html) {
10033
- const $ = cheerio13.load(html);
9978
+ const $ = cheerio6.load(html);
10034
9979
  $("style, script, head").remove();
10035
9980
  $("[data-skip-in-text='true']").remove();
10036
9981
  const lines = [];
@@ -10132,23 +10077,14 @@ function toPlainText(html) {
10132
10077
  }
10133
10078
 
10134
10079
  // src/session.ts
10135
- import * as cheerio14 from "cheerio";
10080
+ import * as cheerio7 from "cheerio";
10136
10081
  function createSession(html, options) {
10137
10082
  if (!html || !html.trim()) {
10138
10083
  const fw = options == null ? void 0 : options.framework;
10139
10084
  return {
10140
10085
  html: html || "",
10141
10086
  framework: fw,
10142
- audit: () => ({
10143
- compatibility: { warnings: [], scores: {} },
10144
- spam: EMPTY_SPAM,
10145
- links: EMPTY_LINKS,
10146
- accessibility: EMPTY_ACCESSIBILITY,
10147
- images: EMPTY_IMAGES,
10148
- inboxPreview: EMPTY_INBOX_PREVIEW,
10149
- size: EMPTY_SIZE,
10150
- templateVariables: EMPTY_TEMPLATE
10151
- }),
10087
+ audit: () => EMPTY_AUDIT,
10152
10088
  analyze: () => [],
10153
10089
  score: () => ({}),
10154
10090
  analyzeSpam: () => EMPTY_SPAM,
@@ -10166,24 +10102,13 @@ function createSession(html, options) {
10166
10102
  if (html.length > MAX_HTML_SIZE) {
10167
10103
  throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
10168
10104
  }
10169
- const $ = cheerio14.load(html);
10105
+ const $ = cheerio7.load(html);
10170
10106
  const framework = options == null ? void 0 : options.framework;
10171
10107
  return {
10172
10108
  html,
10173
10109
  framework,
10174
10110
  audit(opts) {
10175
- var _a;
10176
- const skip = new Set((_a = opts == null ? void 0 : opts.skip) != null ? _a : []);
10177
- const warnings = skip.has("compatibility") ? [] : analyzeEmailFromDom($, framework);
10178
- const scores = skip.has("compatibility") ? {} : generateCompatibilityScore(warnings);
10179
- const spam = skip.has("spam") ? EMPTY_SPAM : analyzeSpamFromDom($, opts == null ? void 0 : opts.spam);
10180
- const links = skip.has("links") ? EMPTY_LINKS : validateLinksFromDom($);
10181
- const accessibility = skip.has("accessibility") ? EMPTY_ACCESSIBILITY : checkAccessibilityFromDom($);
10182
- const images = skip.has("images") ? EMPTY_IMAGES : analyzeImagesFromDom($);
10183
- const inboxPreview = skip.has("inboxPreview") ? EMPTY_INBOX_PREVIEW : extractInboxPreviewFromDom($);
10184
- const size = skip.has("size") ? EMPTY_SIZE : checkSizeFromDom($, html);
10185
- const templateVariables = skip.has("templateVariables") ? EMPTY_TEMPLATE : checkTemplateVariablesFromDom($);
10186
- return { compatibility: { warnings, scores }, spam, links, accessibility, images, inboxPreview, size, templateVariables };
10111
+ return runAudit($, html, framework, opts);
10187
10112
  },
10188
10113
  analyze() {
10189
10114
  return analyzeEmailFromDom($, framework);