@samva/markup 0.7.0 → 0.9.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/AGENTS.md +104 -37
- package/README.md +188 -52
- package/dist/assets-C5duwTya.d.ts +40 -0
- package/dist/brand-B-0bN_Ir.d.ts +88 -0
- package/dist/{render-aaJBnsXK.js → cascade-t6kxlgEI.js} +130 -160
- package/dist/channel-edit.d.ts +121 -0
- package/dist/channel-edit.js +609 -0
- package/dist/channel-specs-B6M_HlaV.js +29 -0
- package/dist/channel-specs-C2feJwuP.d.ts +13 -0
- package/dist/compatibility-DbISoFIq.js +589 -0
- package/dist/compiler.d.ts +19 -249
- package/dist/compiler.js +10 -1408
- package/dist/{css-COcFOT1y.d.ts → css-BVQKICKC.d.ts} +30 -4
- package/dist/diagnostic-codes.d.ts +403 -0
- package/dist/diagnostic-codes.js +399 -0
- package/dist/{diagnostics-BMYtBCQk.d.ts → diagnostics-B-Gym34R.d.ts} +8 -4
- package/dist/diagnostics.d.ts +31 -2
- package/dist/diagnostics.js +1 -19
- package/dist/{elements-BzjjnoCS.d.ts → elements-cqldpaJt.d.ts} +3 -3
- package/dist/email/assets.d.ts +2 -0
- package/dist/email/assets.js +63 -0
- package/dist/email/brand-footer.d.ts +34 -0
- package/dist/email/brand-footer.js +63 -0
- package/dist/email/brand.d.ts +2 -0
- package/dist/email/brand.js +148 -0
- package/dist/email/components.d.ts +21 -10
- package/dist/email/components.js +46 -11
- package/dist/email/diagnostics.d.ts +2 -2
- package/dist/email/diagnostics.js +2 -1
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -42
- package/dist/email/html.js +56 -2
- package/dist/email/jsx-dev-runtime.d.ts +2 -2
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/render.d.ts +10 -13
- package/dist/email/render.js +163 -6
- package/dist/email/text.d.ts +1 -1
- package/dist/fmt.d.ts +32 -0
- package/dist/fmt.js +174 -0
- package/dist/html-BJepOwZ4.d.ts +56 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/ir-aaqNE987.d.ts +252 -0
- package/dist/ir.d.ts +2 -0
- package/dist/ir.js +7 -0
- package/dist/preview-Ekdg1dXG.d.ts +100 -0
- package/dist/preview.d.ts +2 -0
- package/dist/preview.js +160 -0
- package/dist/profile-BH-OtdDA.js +3670 -0
- package/dist/render-ir.d.ts +19 -0
- package/dist/render-ir.js +826 -0
- package/dist/sms-segments.d.ts +13 -2
- package/dist/sms.d.ts +16 -0
- package/dist/sms.js +12 -0
- package/dist/{email/source-edit.d.ts → source-edit.d.ts} +55 -6
- package/dist/source-edit.js +343 -0
- package/dist/source-locations-C8wCsiAy.d.ts +23 -0
- package/dist/source-locations.d.ts +2 -2
- package/dist/source-locations.js +3 -89
- package/dist/static.d.ts +57 -0
- package/dist/static.js +69 -0
- package/dist/tailwind-CMYpZf1v.js +614 -0
- package/dist/template-_QE_rQND.d.ts +65 -0
- package/dist/template.d.ts +2 -2
- package/dist/template.js +15 -10
- package/dist/theme-css-hFqcPSar.js +587 -0
- package/dist/theme-css.d.ts +57 -16
- package/dist/theme-css.js +2 -509
- package/dist/theme-imports-lvBw3AD1.js +109 -0
- package/dist/transform-Ct2OMkFN.d.ts +153 -0
- package/dist/unsubscribe-link-CoesnQDU.js +26 -0
- package/dist/whatsapp.d.ts +57 -0
- package/dist/whatsapp.js +22 -0
- package/generated/contract.json +1782 -0
- package/generated/reference.md +353 -0
- package/package.json +56 -154
- package/samva-brand.d.ts +14 -0
- package/skills/sml/SKILL.md +123 -0
- package/dist/ast-BrDtApwS.d.ts +0 -107
- package/dist/ast.d.ts +0 -2
- package/dist/ast.js +0 -124
- package/dist/candidate.d.ts +0 -29
- package/dist/candidate.js +0 -88
- package/dist/catalog-60eaYC7b.d.ts +0 -356
- package/dist/checks-DBweSIPN.js +0 -58954
- package/dist/checks.d.ts +0 -33
- package/dist/checks.js +0 -2
- package/dist/classes.d.ts +0 -27
- package/dist/classes.js +0 -184
- package/dist/compile-sms.d.ts +0 -28
- package/dist/compile-sms.js +0 -44
- package/dist/compile-whatsapp.d.ts +0 -56
- package/dist/compile-whatsapp.js +0 -186
- package/dist/compile.d.ts +0 -18
- package/dist/compile.js +0 -29
- package/dist/components.d.ts +0 -289
- package/dist/components.js +0 -106
- package/dist/conditionals.d.ts +0 -10
- package/dist/conditionals.js +0 -74
- package/dist/corpus-BjYMqOoY.d.ts +0 -106
- package/dist/diagnostics-OcQKQYSY.d.ts +0 -49
- package/dist/email/selection.d.ts +0 -91
- package/dist/email/selection.js +0 -91
- package/dist/email/source-edit.js +0 -185
- package/dist/email/stylesheets.d.ts +0 -15
- package/dist/email/stylesheets.js +0 -45
- package/dist/emit.d.ts +0 -51
- package/dist/emit.js +0 -151
- package/dist/footer.d.ts +0 -66
- package/dist/footer.js +0 -93
- package/dist/interpolate.d.ts +0 -24
- package/dist/interpolate.js +0 -43
- package/dist/jsx-dev-runtime.d.ts +0 -11
- package/dist/jsx-dev-runtime.js +0 -15
- package/dist/jsx-runtime-I-1nCtl2.d.ts +0 -57
- package/dist/jsx-runtime.d.ts +0 -2
- package/dist/jsx-runtime.js +0 -121
- package/dist/lexer.d.ts +0 -60
- package/dist/lexer.js +0 -281
- package/dist/model.d.ts +0 -24
- package/dist/model.js +0 -77
- package/dist/ops-2aiiYO7m.js +0 -630
- package/dist/ops.d.ts +0 -114
- package/dist/ops.js +0 -2
- package/dist/parser-t29cHLVL.d.ts +0 -396
- package/dist/parser.d.ts +0 -2
- package/dist/parser.js +0 -859
- package/dist/predicate-BI6uRRM-.js +0 -549
- package/dist/predicate-M-05Nd7R.d.ts +0 -56
- package/dist/predicate.d.ts +0 -2
- package/dist/predicate.js +0 -2
- package/dist/presets/category-mapping.d.ts +0 -13
- package/dist/presets/category-mapping.js +0 -49
- package/dist/presets/corpus.d.ts +0 -2
- package/dist/presets/corpus.js +0 -194
- package/dist/presets/public-gallery.d.ts +0 -266
- package/dist/presets/public-gallery.js +0 -916
- package/dist/presets/public-handoff.d.ts +0 -164
- package/dist/presets/public-handoff.js +0 -361
- package/dist/presets/public-preview-artifacts.d.ts +0 -43
- package/dist/presets/public-preview-artifacts.js +0 -104
- package/dist/presets/public-preview.d.ts +0 -61
- package/dist/presets/public-preview.js +0 -83
- package/dist/presets/showcase.d.ts +0 -2
- package/dist/presets/showcase.js +0 -627
- package/dist/presets/sources.d.ts +0 -38
- package/dist/presets/sources.js +0 -6083
- package/dist/presets.d.ts +0 -2
- package/dist/presets.js +0 -881
- package/dist/printer.d.ts +0 -6
- package/dist/printer.js +0 -122
- package/dist/registry.d.ts +0 -42
- package/dist/registry.js +0 -646
- package/dist/render-template.d.ts +0 -45
- package/dist/render-template.js +0 -76
- package/dist/showcase-DGZAWn4Z.d.ts +0 -456
- package/dist/sms-segments-y4FpPilJ.d.ts +0 -13
- package/dist/source-locations-DrCM82Ym.d.ts +0 -67
- package/dist/template-DWftqh4x.d.ts +0 -60
- package/dist/theme-6ApjjiBo.d.ts +0 -116
- package/dist/theme.d.ts +0 -2
- package/dist/theme.js +0 -118
- package/dist/tokens.d.ts +0 -6
- package/dist/tokens.js +0 -417
- package/dist/tsx-source-instrumentation.d.ts +0 -30
- package/dist/tsx-source-instrumentation.js +0 -115
- package/dist/tsx-tracer.d.ts +0 -112
- package/dist/tsx-tracer.js +0 -985
- package/dist/variables-J_L3qxRa.d.ts +0 -77
- package/dist/variables.d.ts +0 -2
- package/dist/variables.js +0 -141
- package/dist/version-BITr58kk.js +0 -96
- package/generated/sml-agent-contract.json +0 -709
- package/generated/sml-email-agent-contract.json +0 -615
- package/generated/sml-email-language-reference.md +0 -94
- package/generated/sml-language-reference.md +0 -195
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EmailCompileError } from "./diagnostics.js";
|
|
2
|
+
import { c as parseBrandCss, i as brandTailwindCss } from "../theme-css-hFqcPSar.js";
|
|
3
|
+
import { BRAND_COMPONENT_CLASSES, brandComponents, withoutUnsubscribeRow } from "./brand.js";
|
|
4
|
+
import { t as applyStylesheet } from "../cascade-t6kxlgEI.js";
|
|
5
|
+
import { a as parseStylesheet, t as compileTailwind } from "../tailwind-CMYpZf1v.js";
|
|
6
|
+
import { compileEmail, renderEmailContent } from "./render.js";
|
|
7
|
+
//#region src/email/brand-footer.ts
|
|
8
|
+
/** The brand theme as Tailwind compiles it; a theme outside the grammar is a compile refusal. */
|
|
9
|
+
const brandTheme = (brand) => {
|
|
10
|
+
const parsed = parseBrandCss(brand.css);
|
|
11
|
+
if (parsed.isErr()) throw new EmailCompileError({ diagnostics: parsed.error.map((finding) => ({
|
|
12
|
+
code: finding.code,
|
|
13
|
+
severity: "error",
|
|
14
|
+
message: `samva:brand: ${finding.message}`,
|
|
15
|
+
origins: []
|
|
16
|
+
})) });
|
|
17
|
+
return brandTailwindCss(parsed.value);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Render `BrandFooter` against a brand on its own, for the send path to
|
|
21
|
+
* append to a message whose template renders no footer of its own. It
|
|
22
|
+
* compiles the same component, styled by the same brand theme, a template
|
|
23
|
+
* would get from `samva:brand`. Without `unsubscribe` the unsubscribe row is
|
|
24
|
+
* left out.
|
|
25
|
+
*/
|
|
26
|
+
const renderBrandFooter = async (brand, options) => {
|
|
27
|
+
const tailwind = await compileTailwind(BRAND_COMPONENT_CLASSES, { css: brandTheme(brand) });
|
|
28
|
+
const node = brandComponents(brand).BrandFooter({});
|
|
29
|
+
if (node === null) return {
|
|
30
|
+
html: "",
|
|
31
|
+
text: ""
|
|
32
|
+
};
|
|
33
|
+
const styled = applyStylesheet(node, parseStylesheet(tailwind.css, { origin: "samva:brand" }));
|
|
34
|
+
const compiled = compileEmail(styled.tree);
|
|
35
|
+
const rendered = options.unsubscribe ? compiled : withoutUnsubscribeRow({
|
|
36
|
+
html: compiled.html,
|
|
37
|
+
text: compiled.text
|
|
38
|
+
});
|
|
39
|
+
const text = (rendered.text ?? "").trim();
|
|
40
|
+
return {
|
|
41
|
+
html: rendered.html ?? "",
|
|
42
|
+
text: text === "" ? "" : `\n\n---\n${text}`
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Render content against a brand as a project whose `theme.css` is
|
|
47
|
+
* `@import "samva:brand";` renders it: Tailwind compiles the brand theme for
|
|
48
|
+
* the classes the content names, `BrandLogo` and `BrandFooter` are bound to the
|
|
49
|
+
* brand, and the render inlines the result. A brand preview renders through
|
|
50
|
+
* this, so it shows what a template importing the brand compiles to.
|
|
51
|
+
*/
|
|
52
|
+
const renderBrandSample = async (brand, sample) => {
|
|
53
|
+
const tailwind = await compileTailwind([...BRAND_COMPONENT_CLASSES, ...sample.classes], { css: "@import \"samva:brand\";" }, {
|
|
54
|
+
stylesheets: /* @__PURE__ */ new Map(),
|
|
55
|
+
brandCss: brandTheme(brand)
|
|
56
|
+
});
|
|
57
|
+
const components = brandComponents(brand);
|
|
58
|
+
return renderEmailContent(parseStylesheet(tailwind.css, { origin: "samva:brand" }), () => sample.render(components));
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { renderBrandFooter, renderBrandSample };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=brand-footer.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as EmailBrand, c as EmailBrandFooter, d as RenderedFooterMarkers, f as UNSUBSCRIBE_ROW_ATTRIBUTE, g as UNSUBSCRIBE_URL_PLACEHOLDER, h as withoutUnsubscribeRow, i as BrandLogoProps, l as EmailBrandSocialLink, m as renderedFooterMarkers, n as BrandComponents, o as EmailBrandAddress, p as brandComponents, r as BrandFooterProps, s as EmailBrandAssets, t as BRAND_COMPONENT_CLASSES, u as FOOTER_ATTRIBUTE } from "../brand-B-0bN_Ir.js";
|
|
2
|
+
export { BRAND_COMPONENT_CLASSES, BrandComponents, BrandFooterProps, BrandLogoProps, EmailBrand, EmailBrandAddress, EmailBrandAssets, EmailBrandFooter, EmailBrandSocialLink, FOOTER_ATTRIBUTE, RenderedFooterMarkers, UNSUBSCRIBE_ROW_ATTRIBUTE, UNSUBSCRIBE_URL_PLACEHOLDER, brandComponents, renderedFooterMarkers, withoutUnsubscribeRow };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { i as UNSUBSCRIBE_URL_PLACEHOLDER, r as UNSUBSCRIBE_LINK, t as BRAND_FOOTER_MARKER } from "../unsubscribe-link-CoesnQDU.js";
|
|
2
|
+
import { Fragment, jsx } from "./jsx-runtime.js";
|
|
3
|
+
//#region src/email/brand.ts
|
|
4
|
+
/** Marks the block the send path recognizes as the template's own footer. */
|
|
5
|
+
const FOOTER_ATTRIBUTE = "data-samva-footer";
|
|
6
|
+
/** Marks the footer row that carries the unsubscribe link. */
|
|
7
|
+
const UNSUBSCRIBE_ROW_ATTRIBUTE = "data-samva-unsubscribe";
|
|
8
|
+
/** Every class the brand components use, compiled for any project that imports them. */
|
|
9
|
+
const BRAND_COMPONENT_CLASSES = [
|
|
10
|
+
"dark:hidden!",
|
|
11
|
+
"hidden",
|
|
12
|
+
"dark:block!",
|
|
13
|
+
"text-xs",
|
|
14
|
+
"text-gray-500",
|
|
15
|
+
"text-center",
|
|
16
|
+
"font-semibold",
|
|
17
|
+
"underline"
|
|
18
|
+
];
|
|
19
|
+
const addressLines = (address) => [
|
|
20
|
+
address.street1,
|
|
21
|
+
address.street2,
|
|
22
|
+
[
|
|
23
|
+
address.city,
|
|
24
|
+
address.region,
|
|
25
|
+
address.postalCode
|
|
26
|
+
].filter((part) => part.trim() !== "").join(", "),
|
|
27
|
+
address.country
|
|
28
|
+
].filter((line) => line !== void 0 && line.trim() !== "");
|
|
29
|
+
const classes = (...names) => {
|
|
30
|
+
const joined = names.filter((name) => name !== void 0 && name !== "").join(" ");
|
|
31
|
+
return joined === "" ? void 0 : joined;
|
|
32
|
+
};
|
|
33
|
+
const row = (children, props = {}) => jsx("tr", {
|
|
34
|
+
...props,
|
|
35
|
+
children: jsx("td", {
|
|
36
|
+
style: { padding: "0 0 8px 0" },
|
|
37
|
+
children
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
/** Bind `BrandLogo` and `BrandFooter` to one brand. */
|
|
41
|
+
const brandComponents = (brand) => {
|
|
42
|
+
const assets = brand.assets ?? {};
|
|
43
|
+
const footer = brand.footer ?? {};
|
|
44
|
+
const BrandLogo = ({ width = 120, alt, align, className }) => {
|
|
45
|
+
if (assets.logoUrl === void 0) return null;
|
|
46
|
+
const label = alt ?? footer.companyName ?? "";
|
|
47
|
+
const image = (src, imageClass, imageAlt) => jsx("img", {
|
|
48
|
+
src,
|
|
49
|
+
alt: imageAlt,
|
|
50
|
+
width,
|
|
51
|
+
border: 0,
|
|
52
|
+
...align === void 0 ? {} : { align },
|
|
53
|
+
className: classes(imageClass, className),
|
|
54
|
+
style: {
|
|
55
|
+
display: "block",
|
|
56
|
+
outline: "none",
|
|
57
|
+
border: "none",
|
|
58
|
+
height: "auto"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (assets.logoDarkUrl === void 0) return image(assets.logoUrl, void 0, label);
|
|
62
|
+
return jsx(Fragment, { children: [image(assets.logoUrl, "dark:hidden!", label), jsx("div", {
|
|
63
|
+
className: "hidden dark:block!",
|
|
64
|
+
style: {
|
|
65
|
+
msoHide: "all",
|
|
66
|
+
maxHeight: 0,
|
|
67
|
+
overflow: "hidden"
|
|
68
|
+
},
|
|
69
|
+
children: image(assets.logoDarkUrl, void 0, "")
|
|
70
|
+
})] });
|
|
71
|
+
};
|
|
72
|
+
const BrandFooter = ({ unsubscribeLabel = "Unsubscribe", className }) => {
|
|
73
|
+
const rows = [];
|
|
74
|
+
if (footer.companyName !== void 0 && footer.companyName.trim() !== "") rows.push(row(jsx("span", {
|
|
75
|
+
className: "font-semibold",
|
|
76
|
+
children: footer.companyName
|
|
77
|
+
})));
|
|
78
|
+
if (footer.address !== void 0) {
|
|
79
|
+
const lines = addressLines(footer.address);
|
|
80
|
+
if (lines.length > 0) rows.push(row(lines.flatMap((line, index) => index === 0 ? [line] : [jsx("br", {}), line])));
|
|
81
|
+
}
|
|
82
|
+
const links = footer.socialLinks ?? [];
|
|
83
|
+
if (links.length > 0) rows.push(row(links.flatMap((link, index) => [...index === 0 ? [] : [" · "], jsx("a", {
|
|
84
|
+
href: link.url,
|
|
85
|
+
className: "text-gray-500 underline",
|
|
86
|
+
children: link.label
|
|
87
|
+
})])));
|
|
88
|
+
rows.push(row(unsubscribeLink(unsubscribeLabel), {
|
|
89
|
+
[UNSUBSCRIBE_ROW_ATTRIBUTE]: "",
|
|
90
|
+
[BRAND_FOOTER_MARKER]: true
|
|
91
|
+
}));
|
|
92
|
+
return jsx("table", {
|
|
93
|
+
role: "presentation",
|
|
94
|
+
width: "100%",
|
|
95
|
+
border: 0,
|
|
96
|
+
cellpadding: 0,
|
|
97
|
+
cellspacing: 0,
|
|
98
|
+
[FOOTER_ATTRIBUTE]: "",
|
|
99
|
+
[BRAND_FOOTER_MARKER]: true,
|
|
100
|
+
children: jsx("tbody", { children: jsx("tr", { children: jsx("td", {
|
|
101
|
+
align: "center",
|
|
102
|
+
className: classes("text-xs text-gray-500 text-center", className),
|
|
103
|
+
style: { padding: "32px 16px" },
|
|
104
|
+
children: jsx("table", {
|
|
105
|
+
role: "presentation",
|
|
106
|
+
border: 0,
|
|
107
|
+
cellpadding: 0,
|
|
108
|
+
cellspacing: 0,
|
|
109
|
+
children: jsx("tbody", { children: rows })
|
|
110
|
+
})
|
|
111
|
+
}) }) })
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
BrandLogo,
|
|
116
|
+
BrandFooter
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* The unsubscribe link. Its href is the placeholder, which no author-written
|
|
121
|
+
* link may carry: the serializer accepts it only on this node, and marks it so
|
|
122
|
+
* click tracking never rewrites it.
|
|
123
|
+
*/
|
|
124
|
+
const unsubscribeLink = (label) => jsx("a", {
|
|
125
|
+
href: UNSUBSCRIBE_URL_PLACEHOLDER,
|
|
126
|
+
className: "text-gray-500 underline",
|
|
127
|
+
[UNSUBSCRIBE_LINK]: true,
|
|
128
|
+
children: label
|
|
129
|
+
});
|
|
130
|
+
const UNSUBSCRIBE_ROW = new RegExp(`<tr ${UNSUBSCRIBE_ROW_ATTRIBUTE}=""[^>]*>[\\s\\S]*?</tr>`, "g");
|
|
131
|
+
const UNSUBSCRIBE_HREF = `href="${UNSUBSCRIBE_URL_PLACEHOLDER}"`;
|
|
132
|
+
/** Read the footer markers from rendered HTML. */
|
|
133
|
+
const renderedFooterMarkers = (html) => ({
|
|
134
|
+
footer: html.includes(`${FOOTER_ATTRIBUTE}=""`),
|
|
135
|
+
unsubscribeLink: html.includes(UNSUBSCRIBE_HREF)
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Drop the unsubscribe row from a rendered message, for a send that resolved
|
|
139
|
+
* no unsubscribe group: there is no link to put there, so the row goes.
|
|
140
|
+
*/
|
|
141
|
+
const withoutUnsubscribeRow = (rendered) => ({
|
|
142
|
+
html: rendered.html?.replace(UNSUBSCRIBE_ROW, ""),
|
|
143
|
+
text: rendered.text?.split("\n").filter((line) => !line.includes(UNSUBSCRIBE_URL_PLACEHOLDER)).join("\n")
|
|
144
|
+
});
|
|
145
|
+
//#endregion
|
|
146
|
+
export { BRAND_COMPONENT_CLASSES, FOOTER_ATTRIBUTE, UNSUBSCRIBE_ROW_ATTRIBUTE, UNSUBSCRIBE_URL_PLACEHOLDER, brandComponents, renderedFooterMarkers, withoutUnsubscribeRow };
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=brand.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-
|
|
1
|
+
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-cqldpaJt.js";
|
|
2
2
|
//#region src/email/components.d.ts
|
|
3
3
|
/** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
|
|
4
4
|
declare const PREHEADER_ATTRIBUTE = "data-samva-preheader";
|
|
@@ -9,8 +9,6 @@ interface EmailProps {
|
|
|
9
9
|
readonly dir?: "ltr" | "rtl" | undefined;
|
|
10
10
|
/** Document title; several clients use it as the fallback preview line. */
|
|
11
11
|
readonly title?: string | undefined;
|
|
12
|
-
/** Hidden preview text shown in the inbox list next to the subject. */
|
|
13
|
-
readonly preheader?: string | undefined;
|
|
14
12
|
readonly backgroundColor?: string | undefined;
|
|
15
13
|
/** Applied to the content cell, where Yahoo and AOL keep body styling. */
|
|
16
14
|
readonly style?: EmailStyle | undefined;
|
|
@@ -19,7 +17,7 @@ interface EmailProps {
|
|
|
19
17
|
/** The hidden inbox preview block. Padding characters stop the client borrowing body copy. */
|
|
20
18
|
declare const preheaderNode: (text: string) => EmailNode;
|
|
21
19
|
/** Document shell: the head every target client needs, plus the body content cell. */
|
|
22
|
-
declare const Email: ({ className, lang, dir, title,
|
|
20
|
+
declare const Email: ({ className, lang, dir, title, backgroundColor, style, children }: EmailProps) => EmailNode;
|
|
23
21
|
interface SectionProps {
|
|
24
22
|
/** CSS classes applied to the primitive's content element. */
|
|
25
23
|
readonly className?: string | undefined;
|
|
@@ -33,17 +31,30 @@ interface SectionProps {
|
|
|
33
31
|
}
|
|
34
32
|
/** A full-width band of content, as the single-cell table every client agrees on. */
|
|
35
33
|
declare const Section: ({ className, align, width, bgcolor, style, tableStyle, children }: SectionProps) => EmailNode;
|
|
36
|
-
interface ColumnsProps {
|
|
34
|
+
interface ColumnsProps<Item = never> {
|
|
37
35
|
/** CSS classes applied to the primitive's content element. */
|
|
38
36
|
readonly className?: string | undefined;
|
|
39
37
|
readonly align?: "left" | "center" | "right" | undefined;
|
|
40
38
|
readonly width?: number | string | undefined;
|
|
41
39
|
readonly style?: EmailStyle | undefined;
|
|
42
|
-
/**
|
|
43
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Repeat the cells for each item: `children` is then a function from an item (and its index in
|
|
42
|
+
* the row) to a `Column`. Without `per` all items share one row.
|
|
43
|
+
*/
|
|
44
|
+
readonly each?: readonly Item[] | undefined;
|
|
45
|
+
/** With `each`, the cells in a row; each chunk of items is its own `Columns` table. */
|
|
46
|
+
readonly per?: number | undefined;
|
|
47
|
+
/** `Column` elements, or with `each` a function that returns one. */
|
|
48
|
+
readonly children?: EmailChild | ((item: Item, index: number) => EmailChild);
|
|
44
49
|
}
|
|
45
|
-
/**
|
|
46
|
-
declare const
|
|
50
|
+
/** The equal share of a row that each of `count` cells takes, whole percent rounded down. */
|
|
51
|
+
declare const equalColumnWidth: (count: number) => string;
|
|
52
|
+
/**
|
|
53
|
+
* A row of side-by-side `Column`s. No flex or grid conversion happens here. With `each` it repeats
|
|
54
|
+
* its cells over a list, `per` to a row, and splits the row equally between cells that state no
|
|
55
|
+
* width.
|
|
56
|
+
*/
|
|
57
|
+
declare const Columns: <Item = never>({ className, align, width, style, each, per, children }: ColumnsProps<Item>) => EmailNode;
|
|
47
58
|
interface ColumnProps {
|
|
48
59
|
/** CSS classes applied to the primitive's content element. */
|
|
49
60
|
readonly className?: string | undefined;
|
|
@@ -121,5 +132,5 @@ interface LinkProps {
|
|
|
121
132
|
/** A text link that opens outside the client and cannot reach back at the opener. */
|
|
122
133
|
declare const Link: ({ className, href, target, rel, style, children }: LinkProps) => EmailNode;
|
|
123
134
|
//#endregion
|
|
124
|
-
export { Button, ButtonProps, Column, ColumnProps, Columns, ColumnsProps, Divider, DividerProps, Email, EmailProps, Image, ImageProps, Link, LinkProps, PREHEADER_ATTRIBUTE, Section, SectionProps, Spacer, SpacerProps, preheaderNode };
|
|
135
|
+
export { Button, ButtonProps, Column, ColumnProps, Columns, ColumnsProps, Divider, DividerProps, Email, EmailProps, Image, ImageProps, Link, LinkProps, PREHEADER_ATTRIBUTE, Section, SectionProps, Spacer, SpacerProps, equalColumnWidth, preheaderNode };
|
|
125
136
|
//# sourceMappingURL=components.d.ts.map
|
package/dist/email/components.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx, rawMarkup, reportEmailDiagnostic } from "./jsx-runtime.js";
|
|
1
|
+
import { EmailNode, Fragment, jsx, normalizeChildren, rawMarkup, reportEmailDiagnostic } from "./jsx-runtime.js";
|
|
2
2
|
import { escapeAttribute, escapeText } from "./html.js";
|
|
3
3
|
//#region src/email/components.ts
|
|
4
4
|
/** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
|
|
@@ -34,7 +34,7 @@ const preheaderNode = (text) => jsx("div", {
|
|
|
34
34
|
})]
|
|
35
35
|
});
|
|
36
36
|
/** Document shell: the head every target client needs, plus the body content cell. */
|
|
37
|
-
const Email = ({ className, lang = "en", dir = "ltr", title,
|
|
37
|
+
const Email = ({ className, lang = "en", dir = "ltr", title, backgroundColor, style, children }) => jsx("html", {
|
|
38
38
|
lang,
|
|
39
39
|
dir,
|
|
40
40
|
xmlns: "http://www.w3.org/1999/xhtml",
|
|
@@ -66,7 +66,7 @@ const Email = ({ className, lang = "en", dir = "ltr", title, preheader, backgrou
|
|
|
66
66
|
padding: 0,
|
|
67
67
|
...backgroundColor === void 0 ? {} : { backgroundColor }
|
|
68
68
|
},
|
|
69
|
-
children: [
|
|
69
|
+
children: [presentation({
|
|
70
70
|
align: "center",
|
|
71
71
|
width: "100%",
|
|
72
72
|
...backgroundColor === void 0 ? {} : { bgcolor: backgroundColor }
|
|
@@ -88,13 +88,48 @@ const Section = ({ className, align = "center", width = "100%", bgcolor, style,
|
|
|
88
88
|
...style === void 0 ? {} : { style },
|
|
89
89
|
children
|
|
90
90
|
}));
|
|
91
|
-
/**
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
width
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
/** The equal share of a row that each of `count` cells takes, whole percent rounded down. */
|
|
92
|
+
const equalColumnWidth = (count) => `${Math.floor(100 / count)}%`;
|
|
93
|
+
/** Give a `Column` that states no width its equal share, keeping the primitive's attribute order. */
|
|
94
|
+
const withColumnWidth = (node, width) => {
|
|
95
|
+
if (node.type === "Fragment") return EmailNode.Fragment({ children: node.children.map((child) => withColumnWidth(child, width)) });
|
|
96
|
+
if (node.type !== "Element" || node.tag !== "td" || node.props.width !== void 0) return node;
|
|
97
|
+
const props = {};
|
|
98
|
+
for (const [key, value] of Object.entries(node.props)) {
|
|
99
|
+
if (key === "style") props.width = width;
|
|
100
|
+
props[key] = value;
|
|
101
|
+
}
|
|
102
|
+
if (props.width === void 0) props.width = width;
|
|
103
|
+
return EmailNode.Element({
|
|
104
|
+
...node,
|
|
105
|
+
props
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* A row of side-by-side `Column`s. No flex or grid conversion happens here. With `each` it repeats
|
|
110
|
+
* its cells over a list, `per` to a row, and splits the row equally between cells that state no
|
|
111
|
+
* width.
|
|
112
|
+
*/
|
|
113
|
+
const Columns = ({ className, align = "center", width = "100%", style, each, per, children }) => {
|
|
114
|
+
const table = {
|
|
115
|
+
className,
|
|
116
|
+
align,
|
|
117
|
+
width,
|
|
118
|
+
...style === void 0 ? {} : { style }
|
|
119
|
+
};
|
|
120
|
+
if (each === void 0 || typeof children !== "function") return presentation(table, children, { style: { width: "100%" } });
|
|
121
|
+
if (per !== void 0 && (!Number.isInteger(per) || per < 1)) reportEmailDiagnostic({
|
|
122
|
+
code: "invalid-columns-per",
|
|
123
|
+
severity: "error",
|
|
124
|
+
message: "<Columns per> must be a positive integer."
|
|
125
|
+
});
|
|
126
|
+
const size = per !== void 0 && Number.isInteger(per) && per >= 1 ? per : void 0;
|
|
127
|
+
const chunks = [];
|
|
128
|
+
if (size === void 0) chunks.push(each);
|
|
129
|
+
else for (let at = 0; at < each.length; at += size) chunks.push(each.slice(at, at + size));
|
|
130
|
+
const share = equalColumnWidth(size ?? Math.max(each.length, 1));
|
|
131
|
+
return jsx(Fragment, { children: chunks.map((chunk) => presentation(table, chunk.flatMap((item, index) => normalizeChildren(children(item, index)).map((cell) => withColumnWidth(cell, share))), { style: { width: "100%" } })) });
|
|
132
|
+
};
|
|
98
133
|
/** One cell of a `Columns` row. */
|
|
99
134
|
const Column = ({ className, align, valign, width, style, children }) => jsx("td", {
|
|
100
135
|
className,
|
|
@@ -235,6 +270,6 @@ const Link = ({ className, href, target = "_blank", rel = "noopener noreferrer",
|
|
|
235
270
|
children
|
|
236
271
|
});
|
|
237
272
|
//#endregion
|
|
238
|
-
export { Button, Column, Columns, Divider, Email, Image, Link, PREHEADER_ATTRIBUTE, Section, Spacer, preheaderNode };
|
|
273
|
+
export { Button, Column, Columns, Divider, Email, Image, Link, PREHEADER_ATTRIBUTE, Section, Spacer, equalColumnWidth, preheaderNode };
|
|
239
274
|
|
|
240
275
|
//# sourceMappingURL=components.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
1
|
+
import { a as TemplateDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as formatEmailDiagnostic, r as EmailDiagnostic, s as hasBlockingDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-B-Gym34R.js";
|
|
2
|
+
export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, TemplateDiagnostic, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
@@ -11,7 +11,8 @@ var EmailCompileError = class extends TaggedError("EmailCompileError") {
|
|
|
11
11
|
/** `emails/welcome.tsx:12:3 unsupported-element: …` — the shape agents iterate on. */
|
|
12
12
|
const formatEmailDiagnostic = (diagnostic) => {
|
|
13
13
|
const origin = diagnostic.origins[0];
|
|
14
|
-
|
|
14
|
+
const head = `${origin === void 0 ? "<unknown source>" : `${origin.fileName}:${origin.lineNumber}:${origin.columnNumber}`} ${diagnostic.code}: ${diagnostic.message}`;
|
|
15
|
+
return diagnostic.fix === void 0 ? head : `${head}\n Fix: ${diagnostic.fix}`;
|
|
15
16
|
};
|
|
16
17
|
/** True when a set of findings must stop the compile or refuse a publication. */
|
|
17
18
|
const hasBlockingDiagnostic = (diagnostics) => diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
package/dist/email/elements.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-
|
|
1
|
+
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-cqldpaJt.js";
|
|
2
2
|
export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
|
package/dist/email/html.d.ts
CHANGED
|
@@ -1,42 +1,2 @@
|
|
|
1
|
-
import { r as
|
|
2
|
-
|
|
3
|
-
import { EmittedPosition } from "./selection.js";
|
|
4
|
-
//#region src/email/html.d.ts
|
|
5
|
-
/** Escape a value for element content. */
|
|
6
|
-
declare const escapeText: (value: string) => string;
|
|
7
|
-
/** Escape a value for a double-quoted attribute. */
|
|
8
|
-
declare const escapeAttribute: (value: string) => string;
|
|
9
|
-
/** camelCase to kebab-case; already-kebab names pass through unchanged. */
|
|
10
|
-
declare const kebab: (property: string) => string;
|
|
11
|
-
/** A bare number is pixels for every property that takes a length. */
|
|
12
|
-
declare const declarationValue: (property: string, value: string | number) => string;
|
|
13
|
-
interface EmailHtmlOutput {
|
|
14
|
-
readonly html: string;
|
|
15
|
-
readonly diagnostics: readonly EmailDiagnostic[];
|
|
16
|
-
/**
|
|
17
|
-
* Each emitted element's offset range and origins. A compatibility finding
|
|
18
|
-
* carries a position in the emitted document, and this is what turns that
|
|
19
|
-
* back into the authoring element the author can edit.
|
|
20
|
-
*/
|
|
21
|
-
readonly positions: readonly EmittedPosition[];
|
|
22
|
-
}
|
|
23
|
-
/** How this document will be consumed. Delivery is the default; export is opt-in. */
|
|
24
|
-
interface SerializeEmailOptions {
|
|
25
|
-
/**
|
|
26
|
-
* Accept relative references. A local export serves assets from a relative
|
|
27
|
-
* base beside the file; a delivered message has no directory to resolve one
|
|
28
|
-
* against, so this stays off for anything that will be sent.
|
|
29
|
-
*/
|
|
30
|
-
readonly relativeUrls?: boolean | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* Stamp every element with its instance path, so an editor preview can
|
|
33
|
-
* resolve a click in the rendered document to exactly one rendered element.
|
|
34
|
-
* A delivered message never carries it.
|
|
35
|
-
*/
|
|
36
|
-
readonly instancePaths?: boolean | undefined;
|
|
37
|
-
}
|
|
38
|
-
/** Lower the derived tree to email HTML, reporting every unsupported construct with its origin. */
|
|
39
|
-
declare const serializeEmailHtml: (node: EmailNode, options?: SerializeEmailOptions) => EmailHtmlOutput;
|
|
40
|
-
//#endregion
|
|
41
|
-
export { EmailHtmlOutput, SerializeEmailOptions, declarationValue, escapeAttribute, escapeText, kebab, serializeEmailHtml };
|
|
42
|
-
//# sourceMappingURL=html.d.ts.map
|
|
1
|
+
import { a as escapeAttribute, c as serializeEmailHtml, i as declarationValue, l as serializeStyle, n as SerializeEmailOptions, o as escapeText, r as checkAttribute, s as kebab, t as EmailHtmlOutput } from "../html-BJepOwZ4.js";
|
|
2
|
+
export { EmailHtmlOutput, SerializeEmailOptions, checkAttribute, declarationValue, escapeAttribute, escapeText, kebab, serializeEmailHtml, serializeStyle };
|
package/dist/email/html.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { n as isObject } from "../guards-eV1qLbf2.js";
|
|
2
|
+
import { i as UNSUBSCRIBE_URL_PLACEHOLDER, n as RESERVED_FOOTER_ATTRIBUTES, r as UNSUBSCRIBE_LINK, t as BRAND_FOOTER_MARKER } from "../unsubscribe-link-CoesnQDU.js";
|
|
2
3
|
import { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement } from "./elements.js";
|
|
3
|
-
import { INSTANCE_PATH_ATTRIBUTE } from "
|
|
4
|
+
import { INSTANCE_PATH_ATTRIBUTE } from "../preview.js";
|
|
4
5
|
//#region src/email/html.ts
|
|
5
6
|
/** Escape a value for element content. */
|
|
6
7
|
const escapeText = (value) => value.replace(/[&<>]/g, (character) => ({
|
|
@@ -117,9 +118,15 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
117
118
|
const emitted = [];
|
|
118
119
|
const present = /* @__PURE__ */ new Set();
|
|
119
120
|
let classes;
|
|
121
|
+
const unsubscribeLink = tag === "a" && props[UNSUBSCRIBE_LINK] === true;
|
|
120
122
|
for (const [key, value] of Object.entries(props)) {
|
|
121
123
|
if (key === "key") continue;
|
|
122
124
|
const name = key === "className" ? "class" : key;
|
|
125
|
+
if (unsubscribeLink && name === "href" && value === "%samva:unsubscribe-url%") {
|
|
126
|
+
present.add(name);
|
|
127
|
+
emitted.push(` href="${UNSUBSCRIBE_URL_PLACEHOLDER}" ses:no-track`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
123
130
|
if (name === "class") {
|
|
124
131
|
if (value === void 0 || value === null) continue;
|
|
125
132
|
if (typeof value !== "string") {
|
|
@@ -148,6 +155,10 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
148
155
|
report(sink, "event-handler", `<${tag} ${name}> is an event handler; email clients strip scripting and Samva refuses it.`, origins);
|
|
149
156
|
continue;
|
|
150
157
|
}
|
|
158
|
+
if (RESERVED_FOOTER_ATTRIBUTES.has(name) && props[BRAND_FOOTER_MARKER] !== true) {
|
|
159
|
+
report(sink, "reserved-attribute", `<${tag} ${name}> is written only by BrandFooter from samva:brand; render BrandFooter instead of marking an element as the footer.`, origins);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
151
162
|
if (/^(data|aria)-[a-z0-9-]+$/.test(name)) {
|
|
152
163
|
const text = attributeValue(sink, tag, name, { type: "string" }, value, origins);
|
|
153
164
|
if (text !== void 0) emitted.push(` ${name}="${escapeAttribute(text)}"`);
|
|
@@ -261,7 +272,50 @@ const serializeEmailHtml = (node, options = {}) => {
|
|
|
261
272
|
positions: sink.positions
|
|
262
273
|
};
|
|
263
274
|
};
|
|
275
|
+
/** An authored style object as a declaration list, checked by the same rules as a serialized tree. */
|
|
276
|
+
const serializeStyle = (style, origins) => {
|
|
277
|
+
const sink = {
|
|
278
|
+
diagnostics: [],
|
|
279
|
+
positions: [],
|
|
280
|
+
written: 0,
|
|
281
|
+
relativeUrls: false,
|
|
282
|
+
instancePaths: false
|
|
283
|
+
};
|
|
284
|
+
return {
|
|
285
|
+
css: declarations(sink, style, origins),
|
|
286
|
+
diagnostics: sink.diagnostics
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Check one static attribute value against its element's spec, as serialization does. Returns
|
|
291
|
+
* the text that would be emitted, or `undefined` when the attribute is dropped or invalid.
|
|
292
|
+
*/
|
|
293
|
+
const checkAttribute = (tag, name, value, origins) => {
|
|
294
|
+
const sink = {
|
|
295
|
+
diagnostics: [],
|
|
296
|
+
positions: [],
|
|
297
|
+
written: 0,
|
|
298
|
+
relativeUrls: false,
|
|
299
|
+
instancePaths: false
|
|
300
|
+
};
|
|
301
|
+
const element = emailElement(tag);
|
|
302
|
+
const globals = EMAIL_GLOBAL_ATTRIBUTES;
|
|
303
|
+
const attributeSpec = () => {
|
|
304
|
+
if (/^(data|aria)-[a-z0-9-]+$/.test(name)) return { type: "string" };
|
|
305
|
+
if (Object.hasOwn(globals, name)) return globals[name];
|
|
306
|
+
if (element !== void 0 && Object.hasOwn(element.attributes, name)) return element.attributes[name];
|
|
307
|
+
};
|
|
308
|
+
const spec = attributeSpec();
|
|
309
|
+
if (spec === void 0) return {
|
|
310
|
+
text: void 0,
|
|
311
|
+
diagnostics: sink.diagnostics
|
|
312
|
+
};
|
|
313
|
+
return {
|
|
314
|
+
text: attributeValue(sink, tag, name, spec, value, origins),
|
|
315
|
+
diagnostics: sink.diagnostics
|
|
316
|
+
};
|
|
317
|
+
};
|
|
264
318
|
//#endregion
|
|
265
|
-
export { declarationValue, escapeAttribute, escapeText, kebab, serializeEmailHtml };
|
|
319
|
+
export { checkAttribute, declarationValue, escapeAttribute, escapeText, kebab, serializeEmailHtml, serializeStyle };
|
|
266
320
|
|
|
267
321
|
//# sourceMappingURL=html.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as JSX, h as Fragment, m as EmailNode, p as EmailComponent } from "../elements-
|
|
1
|
+
import { n as JsxSource } from "../source-locations-C8wCsiAy.js";
|
|
2
|
+
import { g as JSX, h as Fragment, m as EmailNode, p as EmailComponent } from "../elements-cqldpaJt.js";
|
|
3
3
|
//#region src/email/jsx-dev-runtime.d.ts
|
|
4
4
|
/** Development JSX retains compiler-provided origins directly on the semantic tree. */
|
|
5
5
|
declare const jsxDEV: (type: string | EmailComponent<Record<string, unknown>> | typeof Fragment, props: Record<string, unknown> | null, _key?: unknown, _staticChildren?: boolean, source?: JsxSource) => EmailNode;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as reportEmailDiagnostic, S as rawMarkup, _ as currentEmailOrigins, b as jsxs, f as EmailChild, g as JSX, h as Fragment, m as EmailNode, p as EmailComponent, v as drainEmailDiagnostics, x as normalizeChildren, y as jsx } from "../elements-
|
|
1
|
+
import { C as reportEmailDiagnostic, S as rawMarkup, _ as currentEmailOrigins, b as jsxs, f as EmailChild, g as JSX, h as Fragment, m as EmailNode, p as EmailComponent, v as drainEmailDiagnostics, x as normalizeChildren, y as jsx } from "../elements-cqldpaJt.js";
|
|
2
2
|
export { EmailChild, EmailComponent, EmailNode, Fragment, JSX, currentEmailOrigins, drainEmailDiagnostics, jsx, jsxs, normalizeChildren, rawMarkup, reportEmailDiagnostic };
|
package/dist/email/render.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "../diagnostics-
|
|
2
|
-
import { m as EmailNode } from "../elements-
|
|
3
|
-
import { EmittedPosition } from "
|
|
4
|
-
import { SerializeEmailOptions } from "
|
|
5
|
-
import {
|
|
6
|
-
import { i as Stylesheet } from "../css-
|
|
1
|
+
import { r as EmailDiagnostic } from "../diagnostics-B-Gym34R.js";
|
|
2
|
+
import { m as EmailNode } from "../elements-cqldpaJt.js";
|
|
3
|
+
import { n as EmittedPosition } from "../preview-Ekdg1dXG.js";
|
|
4
|
+
import { n as SerializeEmailOptions } from "../html-BJepOwZ4.js";
|
|
5
|
+
import { n as EmailContent } from "../template-_QE_rQND.js";
|
|
6
|
+
import { i as Stylesheet } from "../css-BVQKICKC.js";
|
|
7
7
|
//#region src/email/render.d.ts
|
|
8
8
|
/** Classic Outlook lays a document out correctly only under a transitional doctype. */
|
|
9
9
|
declare const EMAIL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
|
|
@@ -30,14 +30,11 @@ interface RenderedEmail {
|
|
|
30
30
|
readonly diagnostics: readonly EmailDiagnostic[];
|
|
31
31
|
readonly positions: readonly EmittedPosition[];
|
|
32
32
|
}
|
|
33
|
-
/** Render one validated input through the template's only content function. Host isolation is required for untrusted source. */
|
|
34
|
-
declare const renderEmail: <Input>(template: TemplateDefinition<Input>, data: unknown, options?: SerializeEmailOptions) => RenderedEmail;
|
|
35
33
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* loaded into the same process cannot restyle an entry that is rendered again.
|
|
34
|
+
* Render authored content against a stylesheet: inline what a client honors,
|
|
35
|
+
* keep the rest for `<head>`, and lower to HTML and text.
|
|
39
36
|
*/
|
|
40
|
-
declare const
|
|
37
|
+
declare const renderEmailContent: (stylesheet: Stylesheet | undefined, render: () => EmailContent, options?: SerializeEmailOptions) => RenderedEmail;
|
|
41
38
|
//#endregion
|
|
42
|
-
export { EMAIL_DOCTYPE, EmailCompileOutput, RenderedEmail,
|
|
39
|
+
export { EMAIL_DOCTYPE, EmailCompileOutput, RenderedEmail, compileEmail, renderEmailContent };
|
|
43
40
|
//# sourceMappingURL=render.d.ts.map
|