@emailens/engine 0.10.1 → 0.10.3

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.
@@ -1,4 +1,4 @@
1
- import { u as InputFormat } from './types-DEAn3IiX.cjs';
1
+ import { u as InputFormat } from './types-BLR3-Fzo.cjs';
2
2
 
3
3
  /**
4
4
  * Unified error class for all email compilation failures.
@@ -1,4 +1,4 @@
1
- import { u as InputFormat } from './types-DEAn3IiX.js';
1
+ import { u as InputFormat } from './types-BLR3-Fzo.js';
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 { j as DeliverabilityReport } from './types-DEAn3IiX.cjs';
2
+ import { j as DeliverabilityReport } from './types-BLR3-Fzo.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 { j as DeliverabilityReport } from './types-DEAn3IiX.js';
2
+ import { j as DeliverabilityReport } from './types-BLR3-Fzo.js';
3
3
 
4
4
  /**
5
5
  * DNS-based email deliverability checker.
@@ -111,11 +111,42 @@ interface EmailClient {
111
111
  deprecated?: string;
112
112
  }
113
113
  type Severity = "error" | "warning" | "info";
114
+ /**
115
+ * Where an issue lives in the analyzed HTML.
116
+ *
117
+ * Lines and columns are 1-based; `offset` is a 0-based character index into
118
+ * the HTML string. Populated only when the analysis ran with `positions: true`
119
+ * — and only for findings that belong to a specific node, so document-level
120
+ * findings (email size, aggregate spam signals) leave it undefined.
121
+ */
122
+ interface SourceLocation {
123
+ /** 1-based line in the original HTML string. */
124
+ line: number;
125
+ /** 1-based column. */
126
+ column: number;
127
+ endLine: number;
128
+ endColumn: number;
129
+ /** 0-based character offset, for consumers that prefer offsets. */
130
+ offset: number;
131
+ length: number;
132
+ }
114
133
  /** Shared shape for every analyzer's issue objects. */
115
134
  interface BaseIssue {
116
135
  rule: string;
117
136
  severity: Severity;
118
137
  message: string;
138
+ /** Position of the first occurrence in the source HTML. Requires `positions: true`. */
139
+ loc?: SourceLocation;
140
+ /**
141
+ * Every occurrence, in document order — `loc` is the first of them.
142
+ *
143
+ * Present on analyzers that report one issue per *kind* of problem rather
144
+ * than one per element (overflow, visual). Analyzers that already emit an
145
+ * issue per element carry `loc` alone. Capped at {@link MAX_WARNING_LOCATIONS}.
146
+ */
147
+ locs?: SourceLocation[];
148
+ /** `locs` hit the cap and does not list every occurrence. */
149
+ locsTruncated?: boolean;
119
150
  }
120
151
  interface CodeFix {
121
152
  before: string;
@@ -133,8 +164,34 @@ interface CSSWarning {
133
164
  fix?: CodeFix;
134
165
  fixIsGenericFallback?: boolean;
135
166
  fixType?: FixType;
167
+ /**
168
+ * @deprecated Use `loc`. Without `positions: true` this is the line within
169
+ * the `<style>` block that declared the property (and is absent for inline
170
+ * styles); with positions on it is `loc.line`, i.e. absolute in the document.
171
+ */
136
172
  line?: number;
137
173
  selector?: string;
174
+ /** Position of the first occurrence in the source HTML. Requires `positions: true`. */
175
+ loc?: SourceLocation;
176
+ /**
177
+ * Every occurrence, in document order — `loc` is the first of them.
178
+ *
179
+ * Warnings are deduplicated per client, property, severity and `selector`,
180
+ * so twelve elements the analyzer describes the same way collapse into one
181
+ * warning — this is how a consumer reaches the other eleven. Elements
182
+ * described differently (`div.card` vs `span`) still produce separate
183
+ * warnings for the same property, so a consumer that wants every place a
184
+ * property breaks should union `locs` across the warnings for that property.
185
+ * Ordered by position, capped at {@link MAX_WARNING_LOCATIONS}.
186
+ */
187
+ locs?: SourceLocation[];
188
+ /**
189
+ * `locs` hit the cap and does not list every occurrence.
190
+ *
191
+ * A consumer that acts on all of them (an editor applying a fix everywhere)
192
+ * needs to know the list is partial rather than infer it from the length.
193
+ */
194
+ locsTruncated?: boolean;
138
195
  }
139
196
  /**
140
197
  * Callback that sends a prompt to an LLM and returns the text response.
@@ -303,4 +360,4 @@ interface DeliverabilityIssue extends BaseIssue {
303
360
  detail?: string;
304
361
  }
305
362
 
306
- 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 TemplateIssue as G, type TokenEstimate as H, type ImageReport as I, type TokenEstimateWithWarnings as J, type VisualIssue as K, type LinkReport as L, estimateAiFixTokens as M, generateFixPrompt as N, type OverflowReport as O, type PreviewResult as P, heuristicTokenCount as Q, type SupportLevel as S, type TransformResult as T, type VisualReport as V, 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 InboxPreview as g, type SizeReport as h, type TemplateReport as i, type DeliverabilityReport as j, type AccessibilityIssue as k, type ClientTruncation as l, type DeliverabilityCheck as m, type DeliverabilityIssue as n, type EstimateOptions as o, type ExportScope as p, type FixType as q, type ImageInfo as r, type ImageIssue as s, type InboxPreviewIssue as t, type InputFormat as u, type LinkIssue as v, type OverflowIssue as w, type Severity as x, type SizeIssue as y, type SpamIssue as z };
363
+ 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 SpamIssue as G, type TemplateIssue as H, type ImageReport as I, type TokenEstimate as J, type TokenEstimateWithWarnings as K, type LinkReport as L, type VisualIssue as M, estimateAiFixTokens as N, type OverflowReport as O, type PreviewResult as P, generateFixPrompt as Q, heuristicTokenCount as R, type SupportLevel as S, type TransformResult as T, type VisualReport as V, 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 InboxPreview as g, type SizeReport as h, type TemplateReport as i, type DeliverabilityReport as j, type AccessibilityIssue as k, type ClientTruncation as l, type DeliverabilityCheck as m, type DeliverabilityIssue as n, type EstimateOptions as o, type ExportScope as p, type FixType as q, type ImageInfo as r, type ImageIssue as s, type InboxPreviewIssue as t, type InputFormat as u, type LinkIssue as v, type OverflowIssue as w, type Severity as x, type SizeIssue as y, type SourceLocation as z };
@@ -111,11 +111,42 @@ interface EmailClient {
111
111
  deprecated?: string;
112
112
  }
113
113
  type Severity = "error" | "warning" | "info";
114
+ /**
115
+ * Where an issue lives in the analyzed HTML.
116
+ *
117
+ * Lines and columns are 1-based; `offset` is a 0-based character index into
118
+ * the HTML string. Populated only when the analysis ran with `positions: true`
119
+ * — and only for findings that belong to a specific node, so document-level
120
+ * findings (email size, aggregate spam signals) leave it undefined.
121
+ */
122
+ interface SourceLocation {
123
+ /** 1-based line in the original HTML string. */
124
+ line: number;
125
+ /** 1-based column. */
126
+ column: number;
127
+ endLine: number;
128
+ endColumn: number;
129
+ /** 0-based character offset, for consumers that prefer offsets. */
130
+ offset: number;
131
+ length: number;
132
+ }
114
133
  /** Shared shape for every analyzer's issue objects. */
115
134
  interface BaseIssue {
116
135
  rule: string;
117
136
  severity: Severity;
118
137
  message: string;
138
+ /** Position of the first occurrence in the source HTML. Requires `positions: true`. */
139
+ loc?: SourceLocation;
140
+ /**
141
+ * Every occurrence, in document order — `loc` is the first of them.
142
+ *
143
+ * Present on analyzers that report one issue per *kind* of problem rather
144
+ * than one per element (overflow, visual). Analyzers that already emit an
145
+ * issue per element carry `loc` alone. Capped at {@link MAX_WARNING_LOCATIONS}.
146
+ */
147
+ locs?: SourceLocation[];
148
+ /** `locs` hit the cap and does not list every occurrence. */
149
+ locsTruncated?: boolean;
119
150
  }
120
151
  interface CodeFix {
121
152
  before: string;
@@ -133,8 +164,34 @@ interface CSSWarning {
133
164
  fix?: CodeFix;
134
165
  fixIsGenericFallback?: boolean;
135
166
  fixType?: FixType;
167
+ /**
168
+ * @deprecated Use `loc`. Without `positions: true` this is the line within
169
+ * the `<style>` block that declared the property (and is absent for inline
170
+ * styles); with positions on it is `loc.line`, i.e. absolute in the document.
171
+ */
136
172
  line?: number;
137
173
  selector?: string;
174
+ /** Position of the first occurrence in the source HTML. Requires `positions: true`. */
175
+ loc?: SourceLocation;
176
+ /**
177
+ * Every occurrence, in document order — `loc` is the first of them.
178
+ *
179
+ * Warnings are deduplicated per client, property, severity and `selector`,
180
+ * so twelve elements the analyzer describes the same way collapse into one
181
+ * warning — this is how a consumer reaches the other eleven. Elements
182
+ * described differently (`div.card` vs `span`) still produce separate
183
+ * warnings for the same property, so a consumer that wants every place a
184
+ * property breaks should union `locs` across the warnings for that property.
185
+ * Ordered by position, capped at {@link MAX_WARNING_LOCATIONS}.
186
+ */
187
+ locs?: SourceLocation[];
188
+ /**
189
+ * `locs` hit the cap and does not list every occurrence.
190
+ *
191
+ * A consumer that acts on all of them (an editor applying a fix everywhere)
192
+ * needs to know the list is partial rather than infer it from the length.
193
+ */
194
+ locsTruncated?: boolean;
138
195
  }
139
196
  /**
140
197
  * Callback that sends a prompt to an LLM and returns the text response.
@@ -303,4 +360,4 @@ interface DeliverabilityIssue extends BaseIssue {
303
360
  detail?: string;
304
361
  }
305
362
 
306
- 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 TemplateIssue as G, type TokenEstimate as H, type ImageReport as I, type TokenEstimateWithWarnings as J, type VisualIssue as K, type LinkReport as L, estimateAiFixTokens as M, generateFixPrompt as N, type OverflowReport as O, type PreviewResult as P, heuristicTokenCount as Q, type SupportLevel as S, type TransformResult as T, type VisualReport as V, 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 InboxPreview as g, type SizeReport as h, type TemplateReport as i, type DeliverabilityReport as j, type AccessibilityIssue as k, type ClientTruncation as l, type DeliverabilityCheck as m, type DeliverabilityIssue as n, type EstimateOptions as o, type ExportScope as p, type FixType as q, type ImageInfo as r, type ImageIssue as s, type InboxPreviewIssue as t, type InputFormat as u, type LinkIssue as v, type OverflowIssue as w, type Severity as x, type SizeIssue as y, type SpamIssue as z };
363
+ 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 SpamIssue as G, type TemplateIssue as H, type ImageReport as I, type TokenEstimate as J, type TokenEstimateWithWarnings as K, type LinkReport as L, type VisualIssue as M, estimateAiFixTokens as N, type OverflowReport as O, type PreviewResult as P, generateFixPrompt as Q, heuristicTokenCount as R, type SupportLevel as S, type TransformResult as T, type VisualReport as V, 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 InboxPreview as g, type SizeReport as h, type TemplateReport as i, type DeliverabilityReport as j, type AccessibilityIssue as k, type ClientTruncation as l, type DeliverabilityCheck as m, type DeliverabilityIssue as n, type EstimateOptions as o, type ExportScope as p, type FixType as q, type ImageInfo as r, type ImageIssue as s, type InboxPreviewIssue as t, type InputFormat as u, type LinkIssue as v, type OverflowIssue as w, type Severity as x, type SizeIssue as y, type SourceLocation as z };
package/package.json CHANGED
@@ -1,123 +1,124 @@
1
- {
2
- "name": "@emailens/engine",
3
- "version": "0.10.1",
4
- "description": "Email compatibility engine — transforms CSS per email client, scores compatibility, simulates dark mode, suggests fixes, and runs spam, accessibility, link, and image quality analysis.",
5
- "type": "module",
6
- "exports": {
7
- ".": {
8
- "types": "./dist/index.d.ts",
9
- "import": "./dist/index.js",
10
- "require": "./dist/index.cjs"
11
- },
12
- "./compile": {
13
- "types": "./dist/compile/index.d.ts",
14
- "import": "./dist/compile/index.js",
15
- "require": "./dist/compile/index.cjs"
16
- },
17
- "./server": {
18
- "types": "./dist/server.d.ts",
19
- "import": "./dist/server.js",
20
- "require": "./dist/server.cjs"
21
- }
22
- },
23
- "types": "./dist/index.d.ts",
24
- "sideEffects": false,
25
- "engines": {
26
- "node": ">=18"
27
- },
28
- "files": [
29
- "dist",
30
- "LICENSE"
31
- ],
32
- "scripts": {
33
- "build": "tsup",
34
- "dev": "tsup --watch",
35
- "typecheck": "tsc --noEmit",
36
- "sync:caniemail": "bun run scripts/sync-caniemail.ts",
37
- "check:freshness": "bun run scripts/check-data-freshness.ts",
38
- "test": "bun test",
39
- "test:render": "RENDER_TESTS=1 bun test src/__tests__/render.e2e.test.ts",
40
- "prepublishOnly": "bun run build"
41
- },
42
- "dependencies": {
43
- "cheerio": "^1.2.0",
44
- "css-tree": "^3.1.0"
45
- },
46
- "peerDependencies": {
47
- "@maizzle/framework": ">=5.0.0",
48
- "@react-email/components": ">=0.0.36",
49
- "@react-email/render": ">=1.0.0",
50
- "isolated-vm": ">=5.0.0",
51
- "mjml": ">=4.0.0",
52
- "quickjs-emscripten": ">=0.29.0",
53
- "react": "^18.0.0 || ^19.0.0",
54
- "sucrase": "^3.35.0"
55
- },
56
- "peerDependenciesMeta": {
57
- "sucrase": {
58
- "optional": true
59
- },
60
- "react": {
61
- "optional": true
62
- },
63
- "@react-email/components": {
64
- "optional": true
65
- },
66
- "@react-email/render": {
67
- "optional": true
68
- },
69
- "mjml": {
70
- "optional": true
71
- },
72
- "@maizzle/framework": {
73
- "optional": true
74
- },
75
- "isolated-vm": {
76
- "optional": true
77
- },
78
- "quickjs-emscripten": {
79
- "optional": true
80
- }
81
- },
82
- "devDependencies": {
83
- "@maizzle/framework": "^5.0.0",
84
- "@react-email/components": "^0.0.36",
85
- "@react-email/render": "^1.0.6",
86
- "@types/bun": "^1.3.9",
87
- "@types/css-tree": "^2.3.11",
88
- "@types/mjml": "^4.7.4",
89
- "@types/node": "^25.3.0",
90
- "@types/react": "^19.2.14",
91
- "bun-types": "^1.3.9",
92
- "mjml": "^4.15.0",
93
- "playwright": "^1.62.0",
94
- "react": "^19.0.0",
95
- "sucrase": "^3.35.0",
96
- "tsup": "^8.4.0",
97
- "typescript": "^5.9.3"
98
- },
99
- "keywords": [
100
- "email",
101
- "html-email",
102
- "css",
103
- "compatibility",
104
- "gmail",
105
- "outlook",
106
- "apple-mail",
107
- "dark-mode",
108
- "email-testing",
109
- "spam-scoring",
110
- "accessibility",
111
- "link-validation",
112
- "image-analysis"
113
- ],
114
- "license": "MIT",
115
- "repository": {
116
- "type": "git",
117
- "url": "git+https://github.com/emailens/engine.git"
118
- },
119
- "homepage": "https://github.com/emailens/engine#readme",
120
- "bugs": {
121
- "url": "https://github.com/emailens/engine/issues"
122
- }
123
- }
1
+ {
2
+ "name": "@emailens/engine",
3
+ "version": "0.10.3",
4
+ "description": "Email compatibility engine — transforms CSS per email client, scores compatibility, simulates dark mode, suggests fixes, and runs spam, accessibility, link, and image quality analysis.",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.cjs"
11
+ },
12
+ "./compile": {
13
+ "types": "./dist/compile/index.d.ts",
14
+ "import": "./dist/compile/index.js",
15
+ "require": "./dist/compile/index.cjs"
16
+ },
17
+ "./server": {
18
+ "types": "./dist/server.d.ts",
19
+ "import": "./dist/server.js",
20
+ "require": "./dist/server.cjs"
21
+ }
22
+ },
23
+ "types": "./dist/index.d.ts",
24
+ "sideEffects": false,
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsup",
34
+ "dev": "tsup --watch",
35
+ "typecheck": "tsc --noEmit",
36
+ "sync:caniemail": "bun run scripts/sync-caniemail.ts",
37
+ "check:freshness": "bun run scripts/check-data-freshness.ts",
38
+ "bench:positions": "bun run scripts/bench-positions.ts",
39
+ "test": "bun test",
40
+ "test:render": "RENDER_TESTS=1 bun test src/__tests__/render.e2e.test.ts",
41
+ "prepublishOnly": "bun run build"
42
+ },
43
+ "dependencies": {
44
+ "cheerio": "^1.2.0",
45
+ "css-tree": "^3.1.0"
46
+ },
47
+ "peerDependencies": {
48
+ "@maizzle/framework": ">=5.0.0 <6.0.0",
49
+ "@react-email/components": ">=0.0.36",
50
+ "@react-email/render": ">=1.0.0",
51
+ "isolated-vm": ">=5.0.0",
52
+ "mjml": ">=4.0.0",
53
+ "quickjs-emscripten": ">=0.29.0",
54
+ "react": "^18.0.0 || ^19.0.0",
55
+ "sucrase": "^3.35.0"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "sucrase": {
59
+ "optional": true
60
+ },
61
+ "react": {
62
+ "optional": true
63
+ },
64
+ "@react-email/components": {
65
+ "optional": true
66
+ },
67
+ "@react-email/render": {
68
+ "optional": true
69
+ },
70
+ "mjml": {
71
+ "optional": true
72
+ },
73
+ "@maizzle/framework": {
74
+ "optional": true
75
+ },
76
+ "isolated-vm": {
77
+ "optional": true
78
+ },
79
+ "quickjs-emscripten": {
80
+ "optional": true
81
+ }
82
+ },
83
+ "devDependencies": {
84
+ "@maizzle/framework": "^5.5.0",
85
+ "@react-email/components": "^1.0.12",
86
+ "@react-email/render": "^2.1.0",
87
+ "@types/bun": "^1.3.9",
88
+ "@types/css-tree": "^2.3.11",
89
+ "@types/mjml": "^5.0.0",
90
+ "@types/node": "^25.3.0",
91
+ "@types/react": "^19.2.14",
92
+ "bun-types": "^1.3.9",
93
+ "mjml": "^5.4.0",
94
+ "playwright": "^1.62.0",
95
+ "react": "^19.0.0",
96
+ "sucrase": "^3.35.0",
97
+ "tsup": "^8.4.0",
98
+ "typescript": "^5.9.3"
99
+ },
100
+ "keywords": [
101
+ "email",
102
+ "html-email",
103
+ "css",
104
+ "compatibility",
105
+ "gmail",
106
+ "outlook",
107
+ "apple-mail",
108
+ "dark-mode",
109
+ "email-testing",
110
+ "spam-scoring",
111
+ "accessibility",
112
+ "link-validation",
113
+ "image-analysis"
114
+ ],
115
+ "license": "MIT",
116
+ "repository": {
117
+ "type": "git",
118
+ "url": "git+https://github.com/emailens/engine.git"
119
+ },
120
+ "homepage": "https://github.com/emailens/engine#readme",
121
+ "bugs": {
122
+ "url": "https://github.com/emailens/engine/issues"
123
+ }
124
+ }