@emailens/engine 0.3.1 → 0.5.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/README.md +255 -246
- package/dist/chunk-LW2IMTBA.js +326 -0
- package/dist/chunk-LW2IMTBA.js.map +1 -0
- package/dist/chunk-PFONR3YC.js +56 -0
- package/dist/chunk-PFONR3YC.js.map +1 -0
- package/dist/chunk-SZ5O5PDZ.js +78 -0
- package/dist/chunk-SZ5O5PDZ.js.map +1 -0
- package/dist/chunk-W4SPWESS.js +64 -0
- package/dist/chunk-W4SPWESS.js.map +1 -0
- package/dist/compile/index.cjs +585 -0
- package/dist/compile/index.cjs.map +1 -0
- package/dist/compile/index.d.cts +47 -0
- package/dist/compile/index.d.ts +47 -0
- package/dist/compile/index.js +59 -0
- package/dist/compile/index.js.map +1 -0
- package/dist/index.cjs +5485 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +273 -0
- package/dist/index.d.ts +84 -231
- package/dist/index.js +1455 -927
- package/dist/index.js.map +1 -1
- package/dist/maizzle-YDSYDVSM.js +8 -0
- package/dist/maizzle-YDSYDVSM.js.map +1 -0
- package/dist/mjml-IYGC6AOM.js +8 -0
- package/dist/mjml-IYGC6AOM.js.map +1 -0
- package/dist/react-email-AN62KVVF.js +8 -0
- package/dist/react-email-AN62KVVF.js.map +1 -0
- package/dist/react-email-BQljgXbo.d.cts +289 -0
- package/dist/react-email-BQljgXbo.d.ts +289 -0
- package/package.json +97 -60
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
type ExportScope = "all" | "current";
|
|
2
|
+
interface ExportPromptOptions {
|
|
3
|
+
originalHtml: string;
|
|
4
|
+
warnings: CSSWarning[];
|
|
5
|
+
scores: Record<string, {
|
|
6
|
+
score: number;
|
|
7
|
+
errors: number;
|
|
8
|
+
warnings: number;
|
|
9
|
+
info: number;
|
|
10
|
+
}>;
|
|
11
|
+
scope: ExportScope;
|
|
12
|
+
selectedClientId?: string;
|
|
13
|
+
format?: "html" | "jsx" | "mjml" | "maizzle";
|
|
14
|
+
}
|
|
15
|
+
declare function generateFixPrompt(options: ExportPromptOptions): string;
|
|
16
|
+
|
|
17
|
+
interface TokenEstimate {
|
|
18
|
+
/** Estimated input tokens (prompt + system prompt) */
|
|
19
|
+
inputTokens: number;
|
|
20
|
+
/** Estimated output tokens (fixed code response) */
|
|
21
|
+
estimatedOutputTokens: number;
|
|
22
|
+
/** Raw character count of the prompt */
|
|
23
|
+
promptCharacters: number;
|
|
24
|
+
/** Character count of just the HTML being fixed */
|
|
25
|
+
htmlCharacters: number;
|
|
26
|
+
/** Total warnings included in the prompt */
|
|
27
|
+
warningCount: number;
|
|
28
|
+
/** How many warnings are structural (need HTML changes) */
|
|
29
|
+
structuralCount: number;
|
|
30
|
+
/** Whether warnings were truncated to fit within limits */
|
|
31
|
+
truncated: boolean;
|
|
32
|
+
/** Number of warnings removed during truncation */
|
|
33
|
+
warningsRemoved: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extended return type from `estimateAiFixTokens()` that includes both the
|
|
37
|
+
* token metrics AND the (potentially truncated) warnings list. The `warnings`
|
|
38
|
+
* field is used internally by `generateAiFix()` to build the prompt with the
|
|
39
|
+
* truncated set, but is NOT exposed in `AiFixResult.tokenEstimate` to keep
|
|
40
|
+
* the public API clean.
|
|
41
|
+
*/
|
|
42
|
+
interface TokenEstimateWithWarnings extends TokenEstimate {
|
|
43
|
+
/** The warnings after smart truncation (may be shorter than the input list) */
|
|
44
|
+
warnings: CSSWarning[];
|
|
45
|
+
}
|
|
46
|
+
interface EstimateOptions extends Omit<ExportPromptOptions, "warnings"> {
|
|
47
|
+
warnings: CSSWarning[];
|
|
48
|
+
/**
|
|
49
|
+
* Maximum input tokens to target. If the estimated prompt exceeds
|
|
50
|
+
* this, warnings will be truncated (info first, then duplicates).
|
|
51
|
+
* Defaults to 16000 (~56KB of prompt text).
|
|
52
|
+
*/
|
|
53
|
+
maxInputTokens?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Optional precise token counter. If provided, it will be called
|
|
56
|
+
* with the final prompt text for an exact count. Consumers can wire
|
|
57
|
+
* this to `anthropic.messages.countTokens()`.
|
|
58
|
+
*/
|
|
59
|
+
tokenCounter?: (text: string) => Promise<number> | number;
|
|
60
|
+
/**
|
|
61
|
+
* Token count for the system prompt. Added to the input token estimate
|
|
62
|
+
* since the system prompt counts against the context window. Defaults
|
|
63
|
+
* to 250 (matching the built-in AI_FIX_SYSTEM_PROMPT). Set to 0 if
|
|
64
|
+
* not using a system prompt, or override for custom system prompts.
|
|
65
|
+
*/
|
|
66
|
+
systemPromptTokens?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Estimate tokens for an AI fix prompt BEFORE making the API call.
|
|
70
|
+
* Use this to show cost estimates, check limits, and decide whether
|
|
71
|
+
* to proceed.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const estimate = await estimateAiFixTokens({
|
|
76
|
+
* originalHtml: html,
|
|
77
|
+
* warnings,
|
|
78
|
+
* scores,
|
|
79
|
+
* scope: "all",
|
|
80
|
+
* format: "jsx",
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* console.log(`~${estimate.inputTokens} input tokens`);
|
|
84
|
+
* console.log(`~${estimate.estimatedOutputTokens} output tokens`);
|
|
85
|
+
* console.log(`Truncated: ${estimate.truncated}`);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function estimateAiFixTokens(options: EstimateOptions): Promise<TokenEstimateWithWarnings>;
|
|
89
|
+
/**
|
|
90
|
+
* Quick synchronous heuristic token count. No deps, no API calls.
|
|
91
|
+
* Accuracy: within ~10-15% of real Claude tokenizer for code/HTML.
|
|
92
|
+
*/
|
|
93
|
+
declare function heuristicTokenCount(text: string): number;
|
|
94
|
+
|
|
95
|
+
type SupportLevel = "supported" | "partial" | "unsupported" | "unknown";
|
|
96
|
+
type Framework = "jsx" | "mjml" | "maizzle";
|
|
97
|
+
type InputFormat = "html" | Framework;
|
|
98
|
+
interface EmailClient {
|
|
99
|
+
id: string;
|
|
100
|
+
name: string;
|
|
101
|
+
category: "webmail" | "desktop" | "mobile";
|
|
102
|
+
engine: string;
|
|
103
|
+
darkModeSupport: boolean;
|
|
104
|
+
icon: string;
|
|
105
|
+
}
|
|
106
|
+
interface CodeFix {
|
|
107
|
+
before: string;
|
|
108
|
+
after: string;
|
|
109
|
+
language: "html" | "css" | "jsx" | "mjml" | "maizzle";
|
|
110
|
+
description: string;
|
|
111
|
+
}
|
|
112
|
+
type FixType = "css" | "structural";
|
|
113
|
+
interface CSSWarning {
|
|
114
|
+
severity: "error" | "warning" | "info";
|
|
115
|
+
client: string;
|
|
116
|
+
property: string;
|
|
117
|
+
message: string;
|
|
118
|
+
suggestion?: string;
|
|
119
|
+
fix?: CodeFix;
|
|
120
|
+
fixIsGenericFallback?: boolean;
|
|
121
|
+
fixType?: FixType;
|
|
122
|
+
line?: number;
|
|
123
|
+
selector?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Callback that sends a prompt to an LLM and returns the text response.
|
|
127
|
+
* Consumers bring their own AI provider (Anthropic SDK, Vercel AI, etc.).
|
|
128
|
+
*/
|
|
129
|
+
type AiProvider = (prompt: string) => Promise<string>;
|
|
130
|
+
interface AiFixResult {
|
|
131
|
+
/** The fixed email code returned by the AI */
|
|
132
|
+
code: string;
|
|
133
|
+
/** The raw prompt that was sent to the AI */
|
|
134
|
+
prompt: string;
|
|
135
|
+
/** Number of warnings the fix was targeting */
|
|
136
|
+
targetedWarnings: number;
|
|
137
|
+
/** How many of those had fixType: "structural" */
|
|
138
|
+
structuralCount: number;
|
|
139
|
+
/** Token estimate for the AI call */
|
|
140
|
+
tokenEstimate: TokenEstimate;
|
|
141
|
+
}
|
|
142
|
+
interface TransformResult {
|
|
143
|
+
clientId: string;
|
|
144
|
+
html: string;
|
|
145
|
+
warnings: CSSWarning[];
|
|
146
|
+
}
|
|
147
|
+
interface PreviewResult {
|
|
148
|
+
id: string;
|
|
149
|
+
originalHtml: string;
|
|
150
|
+
transforms: TransformResult[];
|
|
151
|
+
cssReport: CSSWarning[];
|
|
152
|
+
createdAt: string;
|
|
153
|
+
}
|
|
154
|
+
interface DiffResult {
|
|
155
|
+
clientId: string;
|
|
156
|
+
scoreBefore: number;
|
|
157
|
+
scoreAfter: number;
|
|
158
|
+
scoreDelta: number;
|
|
159
|
+
fixed: CSSWarning[];
|
|
160
|
+
introduced: CSSWarning[];
|
|
161
|
+
unchanged: CSSWarning[];
|
|
162
|
+
}
|
|
163
|
+
interface SpamIssue {
|
|
164
|
+
rule: string;
|
|
165
|
+
severity: "error" | "warning" | "info";
|
|
166
|
+
message: string;
|
|
167
|
+
detail?: string;
|
|
168
|
+
}
|
|
169
|
+
interface SpamReport {
|
|
170
|
+
score: number;
|
|
171
|
+
level: "low" | "medium" | "high";
|
|
172
|
+
issues: SpamIssue[];
|
|
173
|
+
}
|
|
174
|
+
interface SpamAnalysisOptions {
|
|
175
|
+
/** Value of the List-Unsubscribe header, if present */
|
|
176
|
+
listUnsubscribeHeader?: string;
|
|
177
|
+
/** Type of email — transactional emails are exempt from unsubscribe requirements */
|
|
178
|
+
emailType?: "marketing" | "transactional";
|
|
179
|
+
}
|
|
180
|
+
interface LinkIssue {
|
|
181
|
+
severity: "error" | "warning" | "info";
|
|
182
|
+
rule: string;
|
|
183
|
+
message: string;
|
|
184
|
+
href?: string;
|
|
185
|
+
text?: string;
|
|
186
|
+
}
|
|
187
|
+
interface LinkReport {
|
|
188
|
+
totalLinks: number;
|
|
189
|
+
issues: LinkIssue[];
|
|
190
|
+
breakdown: {
|
|
191
|
+
https: number;
|
|
192
|
+
http: number;
|
|
193
|
+
mailto: number;
|
|
194
|
+
tel: number;
|
|
195
|
+
anchor: number;
|
|
196
|
+
javascript: number;
|
|
197
|
+
protocolRelative: number;
|
|
198
|
+
other: number;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
interface AccessibilityIssue {
|
|
202
|
+
severity: "error" | "warning" | "info";
|
|
203
|
+
rule: string;
|
|
204
|
+
message: string;
|
|
205
|
+
element?: string;
|
|
206
|
+
details?: string;
|
|
207
|
+
}
|
|
208
|
+
interface AccessibilityReport {
|
|
209
|
+
score: number;
|
|
210
|
+
issues: AccessibilityIssue[];
|
|
211
|
+
}
|
|
212
|
+
interface ImageIssue {
|
|
213
|
+
rule: string;
|
|
214
|
+
severity: "error" | "warning" | "info";
|
|
215
|
+
message: string;
|
|
216
|
+
src?: string;
|
|
217
|
+
}
|
|
218
|
+
interface ImageInfo {
|
|
219
|
+
src: string;
|
|
220
|
+
alt: string | null;
|
|
221
|
+
width: string | null;
|
|
222
|
+
height: string | null;
|
|
223
|
+
isTrackingPixel: boolean;
|
|
224
|
+
dataUriBytes: number;
|
|
225
|
+
issues: string[];
|
|
226
|
+
}
|
|
227
|
+
interface ImageReport {
|
|
228
|
+
total: number;
|
|
229
|
+
totalDataUriBytes: number;
|
|
230
|
+
issues: ImageIssue[];
|
|
231
|
+
images: ImageInfo[];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Unified error class for all email compilation failures.
|
|
236
|
+
*
|
|
237
|
+
* Replaces the per-format error classes (ReactEmailCompileError,
|
|
238
|
+
* MjmlCompileError, MaizzleCompileError) with a single class that
|
|
239
|
+
* carries the source format and failure phase.
|
|
240
|
+
*/
|
|
241
|
+
declare class CompileError extends Error {
|
|
242
|
+
name: string;
|
|
243
|
+
readonly format: Exclude<InputFormat, "html">;
|
|
244
|
+
readonly phase: "validation" | "transpile" | "execution" | "render" | "compile";
|
|
245
|
+
constructor(message: string, format: CompileError["format"], phase: CompileError["phase"]);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Sandbox strategy for JSX execution.
|
|
250
|
+
*
|
|
251
|
+
* - `"vm"` — `node:vm` with hardened globals. Fast, zero-dependency,
|
|
252
|
+
* but NOT a true security boundary (prototype-chain escapes are possible).
|
|
253
|
+
* Suitable for CLI / local use where users run their own code.
|
|
254
|
+
*
|
|
255
|
+
* - `"isolated-vm"` (default) — Separate V8 isolate via the `isolated-vm`
|
|
256
|
+
* npm package. True heap isolation; escapes require a V8 engine bug.
|
|
257
|
+
* Requires `isolated-vm` to be installed (native addon).
|
|
258
|
+
*
|
|
259
|
+
* - `"quickjs"` — Validates code structure in a QuickJS WASM sandbox, then
|
|
260
|
+
* executes in `node:vm` for React rendering. Security is equivalent to
|
|
261
|
+
* `node:vm` — the QuickJS phase validates import restrictions only.
|
|
262
|
+
* No native addons needed, but only supports ES2020 and is slower.
|
|
263
|
+
* For true isolation on servers, use `isolated-vm`.
|
|
264
|
+
*/
|
|
265
|
+
type SandboxStrategy = "vm" | "isolated-vm" | "quickjs";
|
|
266
|
+
interface CompileReactEmailOptions {
|
|
267
|
+
/**
|
|
268
|
+
* Sandbox strategy to use for executing user JSX code.
|
|
269
|
+
* @default "isolated-vm"
|
|
270
|
+
*/
|
|
271
|
+
sandbox?: SandboxStrategy;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Compile a React Email JSX/TSX source string into an HTML email string.
|
|
275
|
+
*
|
|
276
|
+
* Pipeline:
|
|
277
|
+
* 1. Validate input (size, basic checks)
|
|
278
|
+
* 2. Transpile JSX/TSX → CommonJS JS using sucrase
|
|
279
|
+
* 3. Execute inside a sandbox (configurable strategy)
|
|
280
|
+
* 4. Render the exported component to a full HTML email string
|
|
281
|
+
*
|
|
282
|
+
* Requires peer dependencies: sucrase, react, @react-email/components,
|
|
283
|
+
* @react-email/render. Additionally:
|
|
284
|
+
* - sandbox "isolated-vm" requires `isolated-vm`
|
|
285
|
+
* - sandbox "quickjs" requires `quickjs-emscripten`
|
|
286
|
+
*/
|
|
287
|
+
declare function compileReactEmail(source: string, options?: CompileReactEmailOptions): Promise<string>;
|
|
288
|
+
|
|
289
|
+
export { type AiProvider as A, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, type ImageReport as I, type LinkReport as L, type PreviewResult as P, type SpamAnalysisOptions as S, type TransformResult as T, type CodeFix as a, type ExportPromptOptions as b, type AiFixResult as c, type SpamReport as d, type AccessibilityReport as e, type AccessibilityIssue as f, CompileError as g, type CompileReactEmailOptions as h, type EstimateOptions as i, type ExportScope as j, type FixType as k, type ImageInfo as l, type ImageIssue as m, type InputFormat as n, type LinkIssue as o, type SandboxStrategy as p, type SpamIssue as q, type SupportLevel as r, type TokenEstimate as s, type TokenEstimateWithWarnings as t, estimateAiFixTokens as u, generateFixPrompt as v, heuristicTokenCount as w, compileReactEmail as x };
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
type ExportScope = "all" | "current";
|
|
2
|
+
interface ExportPromptOptions {
|
|
3
|
+
originalHtml: string;
|
|
4
|
+
warnings: CSSWarning[];
|
|
5
|
+
scores: Record<string, {
|
|
6
|
+
score: number;
|
|
7
|
+
errors: number;
|
|
8
|
+
warnings: number;
|
|
9
|
+
info: number;
|
|
10
|
+
}>;
|
|
11
|
+
scope: ExportScope;
|
|
12
|
+
selectedClientId?: string;
|
|
13
|
+
format?: "html" | "jsx" | "mjml" | "maizzle";
|
|
14
|
+
}
|
|
15
|
+
declare function generateFixPrompt(options: ExportPromptOptions): string;
|
|
16
|
+
|
|
17
|
+
interface TokenEstimate {
|
|
18
|
+
/** Estimated input tokens (prompt + system prompt) */
|
|
19
|
+
inputTokens: number;
|
|
20
|
+
/** Estimated output tokens (fixed code response) */
|
|
21
|
+
estimatedOutputTokens: number;
|
|
22
|
+
/** Raw character count of the prompt */
|
|
23
|
+
promptCharacters: number;
|
|
24
|
+
/** Character count of just the HTML being fixed */
|
|
25
|
+
htmlCharacters: number;
|
|
26
|
+
/** Total warnings included in the prompt */
|
|
27
|
+
warningCount: number;
|
|
28
|
+
/** How many warnings are structural (need HTML changes) */
|
|
29
|
+
structuralCount: number;
|
|
30
|
+
/** Whether warnings were truncated to fit within limits */
|
|
31
|
+
truncated: boolean;
|
|
32
|
+
/** Number of warnings removed during truncation */
|
|
33
|
+
warningsRemoved: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extended return type from `estimateAiFixTokens()` that includes both the
|
|
37
|
+
* token metrics AND the (potentially truncated) warnings list. The `warnings`
|
|
38
|
+
* field is used internally by `generateAiFix()` to build the prompt with the
|
|
39
|
+
* truncated set, but is NOT exposed in `AiFixResult.tokenEstimate` to keep
|
|
40
|
+
* the public API clean.
|
|
41
|
+
*/
|
|
42
|
+
interface TokenEstimateWithWarnings extends TokenEstimate {
|
|
43
|
+
/** The warnings after smart truncation (may be shorter than the input list) */
|
|
44
|
+
warnings: CSSWarning[];
|
|
45
|
+
}
|
|
46
|
+
interface EstimateOptions extends Omit<ExportPromptOptions, "warnings"> {
|
|
47
|
+
warnings: CSSWarning[];
|
|
48
|
+
/**
|
|
49
|
+
* Maximum input tokens to target. If the estimated prompt exceeds
|
|
50
|
+
* this, warnings will be truncated (info first, then duplicates).
|
|
51
|
+
* Defaults to 16000 (~56KB of prompt text).
|
|
52
|
+
*/
|
|
53
|
+
maxInputTokens?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Optional precise token counter. If provided, it will be called
|
|
56
|
+
* with the final prompt text for an exact count. Consumers can wire
|
|
57
|
+
* this to `anthropic.messages.countTokens()`.
|
|
58
|
+
*/
|
|
59
|
+
tokenCounter?: (text: string) => Promise<number> | number;
|
|
60
|
+
/**
|
|
61
|
+
* Token count for the system prompt. Added to the input token estimate
|
|
62
|
+
* since the system prompt counts against the context window. Defaults
|
|
63
|
+
* to 250 (matching the built-in AI_FIX_SYSTEM_PROMPT). Set to 0 if
|
|
64
|
+
* not using a system prompt, or override for custom system prompts.
|
|
65
|
+
*/
|
|
66
|
+
systemPromptTokens?: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Estimate tokens for an AI fix prompt BEFORE making the API call.
|
|
70
|
+
* Use this to show cost estimates, check limits, and decide whether
|
|
71
|
+
* to proceed.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const estimate = await estimateAiFixTokens({
|
|
76
|
+
* originalHtml: html,
|
|
77
|
+
* warnings,
|
|
78
|
+
* scores,
|
|
79
|
+
* scope: "all",
|
|
80
|
+
* format: "jsx",
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* console.log(`~${estimate.inputTokens} input tokens`);
|
|
84
|
+
* console.log(`~${estimate.estimatedOutputTokens} output tokens`);
|
|
85
|
+
* console.log(`Truncated: ${estimate.truncated}`);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function estimateAiFixTokens(options: EstimateOptions): Promise<TokenEstimateWithWarnings>;
|
|
89
|
+
/**
|
|
90
|
+
* Quick synchronous heuristic token count. No deps, no API calls.
|
|
91
|
+
* Accuracy: within ~10-15% of real Claude tokenizer for code/HTML.
|
|
92
|
+
*/
|
|
93
|
+
declare function heuristicTokenCount(text: string): number;
|
|
94
|
+
|
|
95
|
+
type SupportLevel = "supported" | "partial" | "unsupported" | "unknown";
|
|
96
|
+
type Framework = "jsx" | "mjml" | "maizzle";
|
|
97
|
+
type InputFormat = "html" | Framework;
|
|
98
|
+
interface EmailClient {
|
|
99
|
+
id: string;
|
|
100
|
+
name: string;
|
|
101
|
+
category: "webmail" | "desktop" | "mobile";
|
|
102
|
+
engine: string;
|
|
103
|
+
darkModeSupport: boolean;
|
|
104
|
+
icon: string;
|
|
105
|
+
}
|
|
106
|
+
interface CodeFix {
|
|
107
|
+
before: string;
|
|
108
|
+
after: string;
|
|
109
|
+
language: "html" | "css" | "jsx" | "mjml" | "maizzle";
|
|
110
|
+
description: string;
|
|
111
|
+
}
|
|
112
|
+
type FixType = "css" | "structural";
|
|
113
|
+
interface CSSWarning {
|
|
114
|
+
severity: "error" | "warning" | "info";
|
|
115
|
+
client: string;
|
|
116
|
+
property: string;
|
|
117
|
+
message: string;
|
|
118
|
+
suggestion?: string;
|
|
119
|
+
fix?: CodeFix;
|
|
120
|
+
fixIsGenericFallback?: boolean;
|
|
121
|
+
fixType?: FixType;
|
|
122
|
+
line?: number;
|
|
123
|
+
selector?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Callback that sends a prompt to an LLM and returns the text response.
|
|
127
|
+
* Consumers bring their own AI provider (Anthropic SDK, Vercel AI, etc.).
|
|
128
|
+
*/
|
|
129
|
+
type AiProvider = (prompt: string) => Promise<string>;
|
|
130
|
+
interface AiFixResult {
|
|
131
|
+
/** The fixed email code returned by the AI */
|
|
132
|
+
code: string;
|
|
133
|
+
/** The raw prompt that was sent to the AI */
|
|
134
|
+
prompt: string;
|
|
135
|
+
/** Number of warnings the fix was targeting */
|
|
136
|
+
targetedWarnings: number;
|
|
137
|
+
/** How many of those had fixType: "structural" */
|
|
138
|
+
structuralCount: number;
|
|
139
|
+
/** Token estimate for the AI call */
|
|
140
|
+
tokenEstimate: TokenEstimate;
|
|
141
|
+
}
|
|
142
|
+
interface TransformResult {
|
|
143
|
+
clientId: string;
|
|
144
|
+
html: string;
|
|
145
|
+
warnings: CSSWarning[];
|
|
146
|
+
}
|
|
147
|
+
interface PreviewResult {
|
|
148
|
+
id: string;
|
|
149
|
+
originalHtml: string;
|
|
150
|
+
transforms: TransformResult[];
|
|
151
|
+
cssReport: CSSWarning[];
|
|
152
|
+
createdAt: string;
|
|
153
|
+
}
|
|
154
|
+
interface DiffResult {
|
|
155
|
+
clientId: string;
|
|
156
|
+
scoreBefore: number;
|
|
157
|
+
scoreAfter: number;
|
|
158
|
+
scoreDelta: number;
|
|
159
|
+
fixed: CSSWarning[];
|
|
160
|
+
introduced: CSSWarning[];
|
|
161
|
+
unchanged: CSSWarning[];
|
|
162
|
+
}
|
|
163
|
+
interface SpamIssue {
|
|
164
|
+
rule: string;
|
|
165
|
+
severity: "error" | "warning" | "info";
|
|
166
|
+
message: string;
|
|
167
|
+
detail?: string;
|
|
168
|
+
}
|
|
169
|
+
interface SpamReport {
|
|
170
|
+
score: number;
|
|
171
|
+
level: "low" | "medium" | "high";
|
|
172
|
+
issues: SpamIssue[];
|
|
173
|
+
}
|
|
174
|
+
interface SpamAnalysisOptions {
|
|
175
|
+
/** Value of the List-Unsubscribe header, if present */
|
|
176
|
+
listUnsubscribeHeader?: string;
|
|
177
|
+
/** Type of email — transactional emails are exempt from unsubscribe requirements */
|
|
178
|
+
emailType?: "marketing" | "transactional";
|
|
179
|
+
}
|
|
180
|
+
interface LinkIssue {
|
|
181
|
+
severity: "error" | "warning" | "info";
|
|
182
|
+
rule: string;
|
|
183
|
+
message: string;
|
|
184
|
+
href?: string;
|
|
185
|
+
text?: string;
|
|
186
|
+
}
|
|
187
|
+
interface LinkReport {
|
|
188
|
+
totalLinks: number;
|
|
189
|
+
issues: LinkIssue[];
|
|
190
|
+
breakdown: {
|
|
191
|
+
https: number;
|
|
192
|
+
http: number;
|
|
193
|
+
mailto: number;
|
|
194
|
+
tel: number;
|
|
195
|
+
anchor: number;
|
|
196
|
+
javascript: number;
|
|
197
|
+
protocolRelative: number;
|
|
198
|
+
other: number;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
interface AccessibilityIssue {
|
|
202
|
+
severity: "error" | "warning" | "info";
|
|
203
|
+
rule: string;
|
|
204
|
+
message: string;
|
|
205
|
+
element?: string;
|
|
206
|
+
details?: string;
|
|
207
|
+
}
|
|
208
|
+
interface AccessibilityReport {
|
|
209
|
+
score: number;
|
|
210
|
+
issues: AccessibilityIssue[];
|
|
211
|
+
}
|
|
212
|
+
interface ImageIssue {
|
|
213
|
+
rule: string;
|
|
214
|
+
severity: "error" | "warning" | "info";
|
|
215
|
+
message: string;
|
|
216
|
+
src?: string;
|
|
217
|
+
}
|
|
218
|
+
interface ImageInfo {
|
|
219
|
+
src: string;
|
|
220
|
+
alt: string | null;
|
|
221
|
+
width: string | null;
|
|
222
|
+
height: string | null;
|
|
223
|
+
isTrackingPixel: boolean;
|
|
224
|
+
dataUriBytes: number;
|
|
225
|
+
issues: string[];
|
|
226
|
+
}
|
|
227
|
+
interface ImageReport {
|
|
228
|
+
total: number;
|
|
229
|
+
totalDataUriBytes: number;
|
|
230
|
+
issues: ImageIssue[];
|
|
231
|
+
images: ImageInfo[];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Unified error class for all email compilation failures.
|
|
236
|
+
*
|
|
237
|
+
* Replaces the per-format error classes (ReactEmailCompileError,
|
|
238
|
+
* MjmlCompileError, MaizzleCompileError) with a single class that
|
|
239
|
+
* carries the source format and failure phase.
|
|
240
|
+
*/
|
|
241
|
+
declare class CompileError extends Error {
|
|
242
|
+
name: string;
|
|
243
|
+
readonly format: Exclude<InputFormat, "html">;
|
|
244
|
+
readonly phase: "validation" | "transpile" | "execution" | "render" | "compile";
|
|
245
|
+
constructor(message: string, format: CompileError["format"], phase: CompileError["phase"]);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Sandbox strategy for JSX execution.
|
|
250
|
+
*
|
|
251
|
+
* - `"vm"` — `node:vm` with hardened globals. Fast, zero-dependency,
|
|
252
|
+
* but NOT a true security boundary (prototype-chain escapes are possible).
|
|
253
|
+
* Suitable for CLI / local use where users run their own code.
|
|
254
|
+
*
|
|
255
|
+
* - `"isolated-vm"` (default) — Separate V8 isolate via the `isolated-vm`
|
|
256
|
+
* npm package. True heap isolation; escapes require a V8 engine bug.
|
|
257
|
+
* Requires `isolated-vm` to be installed (native addon).
|
|
258
|
+
*
|
|
259
|
+
* - `"quickjs"` — Validates code structure in a QuickJS WASM sandbox, then
|
|
260
|
+
* executes in `node:vm` for React rendering. Security is equivalent to
|
|
261
|
+
* `node:vm` — the QuickJS phase validates import restrictions only.
|
|
262
|
+
* No native addons needed, but only supports ES2020 and is slower.
|
|
263
|
+
* For true isolation on servers, use `isolated-vm`.
|
|
264
|
+
*/
|
|
265
|
+
type SandboxStrategy = "vm" | "isolated-vm" | "quickjs";
|
|
266
|
+
interface CompileReactEmailOptions {
|
|
267
|
+
/**
|
|
268
|
+
* Sandbox strategy to use for executing user JSX code.
|
|
269
|
+
* @default "isolated-vm"
|
|
270
|
+
*/
|
|
271
|
+
sandbox?: SandboxStrategy;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Compile a React Email JSX/TSX source string into an HTML email string.
|
|
275
|
+
*
|
|
276
|
+
* Pipeline:
|
|
277
|
+
* 1. Validate input (size, basic checks)
|
|
278
|
+
* 2. Transpile JSX/TSX → CommonJS JS using sucrase
|
|
279
|
+
* 3. Execute inside a sandbox (configurable strategy)
|
|
280
|
+
* 4. Render the exported component to a full HTML email string
|
|
281
|
+
*
|
|
282
|
+
* Requires peer dependencies: sucrase, react, @react-email/components,
|
|
283
|
+
* @react-email/render. Additionally:
|
|
284
|
+
* - sandbox "isolated-vm" requires `isolated-vm`
|
|
285
|
+
* - sandbox "quickjs" requires `quickjs-emscripten`
|
|
286
|
+
*/
|
|
287
|
+
declare function compileReactEmail(source: string, options?: CompileReactEmailOptions): Promise<string>;
|
|
288
|
+
|
|
289
|
+
export { type AiProvider as A, type CSSWarning as C, type DiffResult as D, type EmailClient as E, type Framework as F, type ImageReport as I, type LinkReport as L, type PreviewResult as P, type SpamAnalysisOptions as S, type TransformResult as T, type CodeFix as a, type ExportPromptOptions as b, type AiFixResult as c, type SpamReport as d, type AccessibilityReport as e, type AccessibilityIssue as f, CompileError as g, type CompileReactEmailOptions as h, type EstimateOptions as i, type ExportScope as j, type FixType as k, type ImageInfo as l, type ImageIssue as m, type InputFormat as n, type LinkIssue as o, type SandboxStrategy as p, type SpamIssue as q, type SupportLevel as r, type TokenEstimate as s, type TokenEstimateWithWarnings as t, estimateAiFixTokens as u, generateFixPrompt as v, heuristicTokenCount as w, compileReactEmail as x };
|