@emailens/engine 0.5.2 → 0.6.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/dist/index.cjs CHANGED
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  auditEmail: () => auditEmail,
73
73
  checkAccessibility: () => checkAccessibility,
74
74
  contrastRatio: () => contrastRatio,
75
+ createSession: () => createSession,
75
76
  diffResults: () => diffResults,
76
77
  errorWarnings: () => errorWarnings,
77
78
  estimateAiFixTokens: () => estimateAiFixTokens,
@@ -2836,6 +2837,14 @@ var GENERIC_LINK_TEXT = /* @__PURE__ */ new Set([
2836
2837
  "tap here",
2837
2838
  "this"
2838
2839
  ]);
2840
+ var EMPTY_SPAM = { score: 100, level: "low", issues: [] };
2841
+ var EMPTY_LINKS = {
2842
+ totalLinks: 0,
2843
+ issues: [],
2844
+ breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
2845
+ };
2846
+ var EMPTY_ACCESSIBILITY = { score: 100, issues: [] };
2847
+ var EMPTY_IMAGES = { total: 0, totalDataUriBytes: 0, issues: [], images: [] };
2839
2848
 
2840
2849
  // src/transform.ts
2841
2850
  function inlineStyles($) {
@@ -3344,15 +3353,8 @@ function transformForAllClients(html, framework) {
3344
3353
  // src/analyze.ts
3345
3354
  var cheerio2 = __toESM(require("cheerio"), 1);
3346
3355
  var csstree2 = __toESM(require("css-tree"), 1);
3347
- function analyzeEmail(html, framework) {
3356
+ function analyzeEmailFromDom($, framework) {
3348
3357
  var _a, _b, _c, _d, _e, _f, _g;
3349
- if (!html || !html.trim()) {
3350
- return [];
3351
- }
3352
- if (html.length > MAX_HTML_SIZE) {
3353
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
3354
- }
3355
- const $ = cheerio2.load(html);
3356
3358
  const warnings = [];
3357
3359
  const seenWarnings = /* @__PURE__ */ new Set();
3358
3360
  function addWarning(w) {
@@ -3597,6 +3599,16 @@ function analyzeEmail(html, framework) {
3597
3599
  warnings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
3598
3600
  return warnings;
3599
3601
  }
3602
+ function analyzeEmail(html, framework) {
3603
+ if (!html || !html.trim()) {
3604
+ return [];
3605
+ }
3606
+ if (html.length > MAX_HTML_SIZE) {
3607
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
3608
+ }
3609
+ const $ = cheerio2.load(html);
3610
+ return analyzeEmailFromDom($, framework);
3611
+ }
3600
3612
  function getFixType(prop) {
3601
3613
  return STRUCTURAL_FIX_PROPERTIES.has(prop) ? "structural" : "css";
3602
3614
  }
@@ -4723,14 +4735,7 @@ function checkAllCapsTitle($) {
4723
4735
  }
4724
4736
  return null;
4725
4737
  }
4726
- function analyzeSpam(html, options) {
4727
- if (!html || !html.trim()) {
4728
- return { score: 100, level: "low", issues: [] };
4729
- }
4730
- if (html.length > MAX_HTML_SIZE) {
4731
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
4732
- }
4733
- const $ = cheerio4.load(html);
4738
+ function analyzeSpamFromDom($, options) {
4734
4739
  const text = extractVisibleText($);
4735
4740
  const issues = [];
4736
4741
  const capsIssue = checkCapsRatio(text);
@@ -4768,6 +4773,16 @@ function analyzeSpam(html, options) {
4768
4773
  const level = score >= 70 ? "low" : score >= 40 ? "medium" : "high";
4769
4774
  return { score, level, issues };
4770
4775
  }
4776
+ function analyzeSpam(html, options) {
4777
+ if (!html || !html.trim()) {
4778
+ return { score: 100, level: "low", issues: [] };
4779
+ }
4780
+ if (html.length > MAX_HTML_SIZE) {
4781
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
4782
+ }
4783
+ const $ = cheerio4.load(html);
4784
+ return analyzeSpamFromDom($, options);
4785
+ }
4771
4786
 
4772
4787
  // src/link-validator.ts
4773
4788
  var cheerio5 = __toESM(require("cheerio"), 1);
@@ -4787,18 +4802,7 @@ function isPlaceholderHref(href) {
4787
4802
  const h = href.trim().toLowerCase();
4788
4803
  return h === "#" || h === "" || h === "javascript:void(0)" || h === "javascript:;";
4789
4804
  }
4790
- function validateLinks(html) {
4791
- if (!html || !html.trim()) {
4792
- return {
4793
- totalLinks: 0,
4794
- issues: [],
4795
- breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
4796
- };
4797
- }
4798
- if (html.length > MAX_HTML_SIZE) {
4799
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
4800
- }
4801
- const $ = cheerio5.load(html);
4805
+ function validateLinksFromDom($) {
4802
4806
  const issues = [];
4803
4807
  const breakdown = { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 };
4804
4808
  const links = $("a");
@@ -4949,6 +4953,20 @@ function validateLinks(html) {
4949
4953
  }
4950
4954
  return { totalLinks, issues, breakdown };
4951
4955
  }
4956
+ function validateLinks(html) {
4957
+ if (!html || !html.trim()) {
4958
+ return {
4959
+ totalLinks: 0,
4960
+ issues: [],
4961
+ breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
4962
+ };
4963
+ }
4964
+ if (html.length > MAX_HTML_SIZE) {
4965
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
4966
+ }
4967
+ const $ = cheerio5.load(html);
4968
+ return validateLinksFromDom($);
4969
+ }
4952
4970
 
4953
4971
  // src/accessibility-checker.ts
4954
4972
  var cheerio6 = __toESM(require("cheerio"), 1);
@@ -5197,14 +5215,7 @@ function checkSemanticStructure($) {
5197
5215
  }
5198
5216
  return issues;
5199
5217
  }
5200
- function checkAccessibility(html) {
5201
- if (!html || !html.trim()) {
5202
- return { score: 100, issues: [] };
5203
- }
5204
- if (html.length > MAX_HTML_SIZE) {
5205
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
5206
- }
5207
- const $ = cheerio6.load(html);
5218
+ function checkAccessibilityFromDom($) {
5208
5219
  const issues = [];
5209
5220
  const langIssue = checkLangAttribute($);
5210
5221
  if (langIssue) issues.push(langIssue);
@@ -5237,6 +5248,16 @@ function checkAccessibility(html) {
5237
5248
  const score = Math.max(0, 100 - penalty);
5238
5249
  return { score, issues };
5239
5250
  }
5251
+ function checkAccessibility(html) {
5252
+ if (!html || !html.trim()) {
5253
+ return { score: 100, issues: [] };
5254
+ }
5255
+ if (html.length > MAX_HTML_SIZE) {
5256
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
5257
+ }
5258
+ const $ = cheerio6.load(html);
5259
+ return checkAccessibilityFromDom($);
5260
+ }
5240
5261
 
5241
5262
  // src/image-analyzer.ts
5242
5263
  var cheerio7 = __toESM(require("cheerio"), 1);
@@ -5270,14 +5291,7 @@ function truncateSrc(src, max = 60) {
5270
5291
  }
5271
5292
  return src.length > max ? src.slice(0, max - 3) + "..." : src;
5272
5293
  }
5273
- function analyzeImages(html) {
5274
- if (!html || !html.trim()) {
5275
- return { total: 0, totalDataUriBytes: 0, issues: [], images: [] };
5276
- }
5277
- if (html.length > MAX_HTML_SIZE) {
5278
- throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
5279
- }
5280
- const $ = cheerio7.load(html);
5294
+ function analyzeImagesFromDom($) {
5281
5295
  const issues = [];
5282
5296
  const images = [];
5283
5297
  let totalDataUriBytes = 0;
@@ -5403,16 +5417,19 @@ function analyzeImages(html) {
5403
5417
  }
5404
5418
  return { total: images.length, totalDataUriBytes, issues, images };
5405
5419
  }
5420
+ function analyzeImages(html) {
5421
+ if (!html || !html.trim()) {
5422
+ return { total: 0, totalDataUriBytes: 0, issues: [], images: [] };
5423
+ }
5424
+ if (html.length > MAX_HTML_SIZE) {
5425
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
5426
+ }
5427
+ const $ = cheerio7.load(html);
5428
+ return analyzeImagesFromDom($);
5429
+ }
5406
5430
 
5407
5431
  // src/audit.ts
5408
- var EMPTY_SPAM = { score: 100, level: "low", issues: [] };
5409
- var EMPTY_LINKS = {
5410
- totalLinks: 0,
5411
- issues: [],
5412
- breakdown: { https: 0, http: 0, mailto: 0, tel: 0, anchor: 0, javascript: 0, protocolRelative: 0, other: 0 }
5413
- };
5414
- var EMPTY_ACCESSIBILITY = { score: 100, issues: [] };
5415
- var EMPTY_IMAGES = { total: 0, totalDataUriBytes: 0, issues: [], images: [] };
5432
+ var cheerio8 = __toESM(require("cheerio"), 1);
5416
5433
  function auditEmail(html, options) {
5417
5434
  var _a;
5418
5435
  if (!html || !html.trim()) {
@@ -5429,15 +5446,92 @@ function auditEmail(html, options) {
5429
5446
  }
5430
5447
  const framework = options == null ? void 0 : options.framework;
5431
5448
  const skip = new Set((_a = options == null ? void 0 : options.skip) != null ? _a : []);
5432
- const warnings = skip.has("compatibility") ? [] : analyzeEmail(html, framework);
5449
+ const $ = cheerio8.load(html);
5450
+ const warnings = skip.has("compatibility") ? [] : analyzeEmailFromDom($, framework);
5433
5451
  const scores = skip.has("compatibility") ? {} : generateCompatibilityScore(warnings);
5434
- const spam = skip.has("spam") ? EMPTY_SPAM : analyzeSpam(html, options == null ? void 0 : options.spam);
5435
- const links = skip.has("links") ? EMPTY_LINKS : validateLinks(html);
5436
- const accessibility = skip.has("accessibility") ? EMPTY_ACCESSIBILITY : checkAccessibility(html);
5437
- const images = skip.has("images") ? EMPTY_IMAGES : analyzeImages(html);
5452
+ const spam = skip.has("spam") ? EMPTY_SPAM : analyzeSpamFromDom($, options == null ? void 0 : options.spam);
5453
+ const links = skip.has("links") ? EMPTY_LINKS : validateLinksFromDom($);
5454
+ const accessibility = skip.has("accessibility") ? EMPTY_ACCESSIBILITY : checkAccessibilityFromDom($);
5455
+ const images = skip.has("images") ? EMPTY_IMAGES : analyzeImagesFromDom($);
5438
5456
  return { compatibility: { warnings, scores }, spam, links, accessibility, images };
5439
5457
  }
5440
5458
 
5459
+ // src/session.ts
5460
+ var cheerio9 = __toESM(require("cheerio"), 1);
5461
+ function createSession(html, options) {
5462
+ if (!html || !html.trim()) {
5463
+ const fw = options == null ? void 0 : options.framework;
5464
+ return {
5465
+ html: html || "",
5466
+ framework: fw,
5467
+ audit: () => ({
5468
+ compatibility: { warnings: [], scores: {} },
5469
+ spam: EMPTY_SPAM,
5470
+ links: EMPTY_LINKS,
5471
+ accessibility: EMPTY_ACCESSIBILITY,
5472
+ images: EMPTY_IMAGES
5473
+ }),
5474
+ analyze: () => [],
5475
+ score: () => ({}),
5476
+ analyzeSpam: () => EMPTY_SPAM,
5477
+ validateLinks: () => EMPTY_LINKS,
5478
+ checkAccessibility: () => EMPTY_ACCESSIBILITY,
5479
+ analyzeImages: () => EMPTY_IMAGES,
5480
+ transformForClient: (clientId) => ({ clientId, html: html || "", warnings: [] }),
5481
+ transformForAllClients: () => [],
5482
+ simulateDarkMode: (clientId) => ({ html: html || "", warnings: [] })
5483
+ };
5484
+ }
5485
+ if (html.length > MAX_HTML_SIZE) {
5486
+ throw new Error(`HTML input exceeds ${MAX_HTML_SIZE / 1024}KB limit.`);
5487
+ }
5488
+ const $ = cheerio9.load(html);
5489
+ const framework = options == null ? void 0 : options.framework;
5490
+ return {
5491
+ html,
5492
+ framework,
5493
+ audit(opts) {
5494
+ var _a;
5495
+ const skip = new Set((_a = opts == null ? void 0 : opts.skip) != null ? _a : []);
5496
+ const warnings = skip.has("compatibility") ? [] : analyzeEmailFromDom($, framework);
5497
+ const scores = skip.has("compatibility") ? {} : generateCompatibilityScore(warnings);
5498
+ const spam = skip.has("spam") ? EMPTY_SPAM : analyzeSpamFromDom($, opts == null ? void 0 : opts.spam);
5499
+ const links = skip.has("links") ? EMPTY_LINKS : validateLinksFromDom($);
5500
+ const accessibility = skip.has("accessibility") ? EMPTY_ACCESSIBILITY : checkAccessibilityFromDom($);
5501
+ const images = skip.has("images") ? EMPTY_IMAGES : analyzeImagesFromDom($);
5502
+ return { compatibility: { warnings, scores }, spam, links, accessibility, images };
5503
+ },
5504
+ analyze() {
5505
+ return analyzeEmailFromDom($, framework);
5506
+ },
5507
+ score(warnings) {
5508
+ return generateCompatibilityScore(warnings);
5509
+ },
5510
+ analyzeSpam(opts) {
5511
+ return analyzeSpamFromDom($, opts);
5512
+ },
5513
+ validateLinks() {
5514
+ return validateLinksFromDom($);
5515
+ },
5516
+ checkAccessibility() {
5517
+ return checkAccessibilityFromDom($);
5518
+ },
5519
+ analyzeImages() {
5520
+ return analyzeImagesFromDom($);
5521
+ },
5522
+ // Transforms create isolated copies since they mutate the DOM
5523
+ transformForClient(clientId) {
5524
+ return transformForClient(html, clientId, framework);
5525
+ },
5526
+ transformForAllClients() {
5527
+ return transformForAllClients(html, framework);
5528
+ },
5529
+ simulateDarkMode(clientId) {
5530
+ return simulateDarkMode(html, clientId);
5531
+ }
5532
+ };
5533
+ }
5534
+
5441
5535
  // src/compile/errors.ts
5442
5536
  var CompileError = class extends Error {
5443
5537
  constructor(message, format, phase) {
@@ -5462,6 +5556,7 @@ var CompileError = class extends Error {
5462
5556
  auditEmail,
5463
5557
  checkAccessibility,
5464
5558
  contrastRatio,
5559
+ createSession,
5465
5560
  diffResults,
5466
5561
  errorWarnings,
5467
5562
  estimateAiFixTokens,