@samva/markup 0.9.0 → 0.11.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 +53 -41
- package/CHANGELOG.md +379 -0
- package/README.md +6 -6
- package/dist/assets-B0yseju_.d.ts +115 -0
- package/dist/brand-DTctcDmf.js +202 -0
- package/dist/brand-plugin-CHhcei-j.d.ts +32 -0
- package/dist/{theme-css.d.ts → brand.d.ts} +15 -4
- package/dist/brand.js +4 -0
- package/dist/compiler.d.ts +236 -18
- package/dist/compiler.js +1315 -13
- package/dist/{email/components.js → components-Bl6DT21n.js} +4 -4
- package/dist/diagnostic-model-DJtqbETd.js +38 -0
- package/dist/diagnostic-model-DxthUZBT.d.ts +31 -0
- package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +2 -2
- package/dist/diagnostics.d.ts +406 -27
- package/dist/diagnostics.js +402 -34
- package/dist/edit.d.ts +234 -0
- package/dist/{channel-edit.js → edit.js} +341 -3
- package/dist/email/jsx-dev-runtime.d.ts +1 -1
- package/dist/email/jsx-dev-runtime.js +1 -2
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/jsx-runtime.js +1 -85
- package/dist/{email/components.d.ts → email.d.ts} +2 -2
- package/dist/email.js +2 -0
- package/dist/html-DjPxwjLi.js +1637 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{cascade-t6kxlgEI.js → ir-De6pTH51.js} +8 -4
- package/dist/jsx-runtime-CBlexoeR.js +98 -0
- package/dist/{elements-cqldpaJt.d.ts → jsx-runtime-ylIOnaSf.d.ts} +74 -74
- package/dist/{profile-BH-OtdDA.js → profile-PUfi3GPH.js} +166 -32
- package/dist/{email/render.js → render-D2ht57ZZ.js} +103 -8
- package/dist/render-DQKz4Aco.d.ts +548 -0
- package/dist/render.d.ts +35 -0
- package/dist/render.js +49 -0
- package/dist/sms.d.ts +1 -1
- package/dist/sms.js +1 -1
- package/dist/{template-_QE_rQND.d.ts → template-DMPwxMSq.d.ts} +2 -2
- package/dist/{template.js → template-zLUjcwfF.js} +2 -2
- package/dist/{theme-css-hFqcPSar.js → theme-css-CEUrDpqq.js} +3 -3
- package/dist/whatsapp.d.ts +1 -1
- package/dist/whatsapp.js +1 -1
- package/generated/contract.json +18 -12
- package/generated/reference.md +19 -12
- package/package.json +39 -122
- package/samva-brand.d.ts +4 -4
- package/skills/sml/SKILL.md +2 -2
- package/dist/assets-C5duwTya.d.ts +0 -40
- package/dist/brand-B-0bN_Ir.d.ts +0 -88
- package/dist/channel-edit.d.ts +0 -121
- package/dist/channel-specs-B6M_HlaV.js +0 -29
- package/dist/compatibility-DbISoFIq.js +0 -589
- package/dist/css-BVQKICKC.d.ts +0 -109
- package/dist/diagnostic-codes.d.ts +0 -403
- package/dist/diagnostic-codes.js +0 -399
- package/dist/email/assets.d.ts +0 -2
- package/dist/email/assets.js +0 -63
- package/dist/email/brand-footer.d.ts +0 -34
- package/dist/email/brand-footer.js +0 -63
- package/dist/email/brand.d.ts +0 -2
- package/dist/email/brand.js +0 -148
- package/dist/email/diagnostics.d.ts +0 -2
- package/dist/email/elements.d.ts +0 -2
- package/dist/email/elements.js +0 -299
- package/dist/email/html.d.ts +0 -2
- package/dist/email/html.js +0 -321
- package/dist/email/render.d.ts +0 -40
- package/dist/email/text.d.ts +0 -7
- package/dist/email/text.js +0 -100
- package/dist/html-BJepOwZ4.d.ts +0 -56
- package/dist/ir-aaqNE987.d.ts +0 -252
- package/dist/ir.d.ts +0 -2
- package/dist/ir.js +0 -7
- package/dist/preview-Ekdg1dXG.d.ts +0 -100
- package/dist/preview.d.ts +0 -2
- package/dist/preview.js +0 -160
- package/dist/render-ir.d.ts +0 -19
- package/dist/render-ir.js +0 -826
- package/dist/sms-segments.d.ts +0 -13
- package/dist/sms-segments.js +0 -46
- package/dist/source-edit.d.ts +0 -116
- package/dist/source-edit.js +0 -343
- package/dist/source-locations.d.ts +0 -2
- package/dist/source-locations.js +0 -16
- package/dist/static.d.ts +0 -57
- package/dist/static.js +0 -69
- package/dist/tailwind-CMYpZf1v.js +0 -614
- package/dist/template.d.ts +0 -2
- package/dist/theme-css.js +0 -2
- package/dist/theme-imports-lvBw3AD1.js +0 -109
- package/dist/transform-Ct2OMkFN.d.ts +0 -153
- package/dist/unsubscribe-link-CoesnQDU.js +0 -26
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { t as BrandPlugin } from "./brand-plugin-CHhcei-j.js";
|
|
2
|
+
import { r as EmailDiagnostic } from "./diagnostics-B-Gym34R.js";
|
|
3
|
+
import { r as EmailNode } from "./jsx-runtime-ylIOnaSf.js";
|
|
4
|
+
//#region src/email/brand.d.ts
|
|
5
|
+
interface EmailBrandAddress {
|
|
6
|
+
readonly street1: string;
|
|
7
|
+
readonly street2?: string | undefined;
|
|
8
|
+
readonly city: string;
|
|
9
|
+
readonly region: string;
|
|
10
|
+
readonly postalCode: string;
|
|
11
|
+
readonly country: string;
|
|
12
|
+
}
|
|
13
|
+
interface EmailBrandSocialLink {
|
|
14
|
+
readonly label: string;
|
|
15
|
+
readonly url: string;
|
|
16
|
+
}
|
|
17
|
+
interface EmailBrandAssets {
|
|
18
|
+
readonly logoUrl?: string | undefined;
|
|
19
|
+
readonly logoDarkUrl?: string | undefined;
|
|
20
|
+
readonly iconUrl?: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
interface EmailBrandFooter {
|
|
23
|
+
readonly companyName?: string | undefined;
|
|
24
|
+
readonly address?: EmailBrandAddress | undefined;
|
|
25
|
+
readonly socialLinks?: readonly EmailBrandSocialLink[] | undefined;
|
|
26
|
+
}
|
|
27
|
+
interface EmailBrand {
|
|
28
|
+
/** The brand's slug; a `<specifier>/<slug>` brand import must name it. */
|
|
29
|
+
readonly slug: string;
|
|
30
|
+
/** Brand theme CSS in the closed grammar `parseBrandCss` accepts. */
|
|
31
|
+
readonly css: string;
|
|
32
|
+
readonly assets?: EmailBrandAssets | undefined;
|
|
33
|
+
readonly footer?: EmailBrandFooter | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** Every class the brand components use, compiled for any project that imports them. */
|
|
36
|
+
declare const BRAND_COMPONENT_CLASSES: readonly ["dark:hidden!", "hidden", "dark:block!", "text-xs", "text-gray-500", "text-center", "font-semibold", "underline"];
|
|
37
|
+
interface BrandLogoProps {
|
|
38
|
+
/** Rendered width in pixels; the height follows the image. */
|
|
39
|
+
readonly width?: number | undefined;
|
|
40
|
+
/** Defaults to the brand footer's company name. */
|
|
41
|
+
readonly alt?: string | undefined;
|
|
42
|
+
readonly align?: "left" | "center" | "right" | undefined;
|
|
43
|
+
readonly className?: string | undefined;
|
|
44
|
+
}
|
|
45
|
+
interface BrandFooterProps {
|
|
46
|
+
/** Text of the unsubscribe link. */
|
|
47
|
+
readonly unsubscribeLabel?: string | undefined;
|
|
48
|
+
readonly className?: string | undefined;
|
|
49
|
+
}
|
|
50
|
+
interface BrandComponents {
|
|
51
|
+
readonly BrandLogo: (props: BrandLogoProps) => EmailNode | null;
|
|
52
|
+
readonly BrandFooter: (props: BrandFooterProps) => EmailNode | null;
|
|
53
|
+
}
|
|
54
|
+
/** Bind `BrandLogo` and `BrandFooter` to one brand, marked as the plugin names. */
|
|
55
|
+
declare const brandComponents: (brand: EmailBrand, plugin?: BrandPlugin) => BrandComponents;
|
|
56
|
+
/** What a rendered message says about the footer it carries. */
|
|
57
|
+
interface RenderedFooterMarkers {
|
|
58
|
+
/** The message renders `BrandFooter` (or claims to, with the marker). */
|
|
59
|
+
readonly footer: boolean;
|
|
60
|
+
/** The message carries the unsubscribe placeholder link only `BrandFooter` can write. */
|
|
61
|
+
readonly unsubscribeLink: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** Read the plugin's footer markers from rendered HTML. */
|
|
64
|
+
declare const renderedFooterMarkers: (html: string, plugin?: BrandPlugin) => RenderedFooterMarkers;
|
|
65
|
+
/**
|
|
66
|
+
* Drop the unsubscribe row from a rendered message, for a send that resolved
|
|
67
|
+
* no unsubscribe group: there is no link to put there, so the row goes.
|
|
68
|
+
*/
|
|
69
|
+
declare const withoutUnsubscribeRow: (rendered: {
|
|
70
|
+
readonly html?: string | undefined;
|
|
71
|
+
readonly text?: string | undefined;
|
|
72
|
+
}, plugin?: BrandPlugin) => {
|
|
73
|
+
readonly html: string | undefined;
|
|
74
|
+
readonly text: string | undefined;
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/email/assets.d.ts
|
|
78
|
+
/** Files a template may import, and what they are served as. */
|
|
79
|
+
declare const ASSET_CONTENT_TYPES: Readonly<Record<string, string>>;
|
|
80
|
+
interface AssetEntry {
|
|
81
|
+
/** Project-relative path the template imported. */
|
|
82
|
+
readonly path: string;
|
|
83
|
+
/** SHA-256 of the exact bytes, lowercase hex. */
|
|
84
|
+
readonly digest: string;
|
|
85
|
+
readonly bytes: number;
|
|
86
|
+
readonly contentType: string;
|
|
87
|
+
/** `<digest><ext>` — the name the asset has under any base. */
|
|
88
|
+
readonly fileName: string;
|
|
89
|
+
}
|
|
90
|
+
interface AssetManifest {
|
|
91
|
+
/** Where these assets are served from in this build. */
|
|
92
|
+
readonly base: string;
|
|
93
|
+
readonly assets: readonly AssetEntry[];
|
|
94
|
+
}
|
|
95
|
+
/** True when the compiler turns this import into a content-addressed asset. */
|
|
96
|
+
declare const isAssetPath: (path: string) => boolean;
|
|
97
|
+
/** Address one file by its content. */
|
|
98
|
+
declare const assetEntry: (path: string, bytes: Uint8Array) => Promise<AssetEntry>;
|
|
99
|
+
/**
|
|
100
|
+
* The URL an asset has under a base. The base is a build input: publication
|
|
101
|
+
* passes its hosted origin, and a local export passes whatever it will serve
|
|
102
|
+
* the exported files from.
|
|
103
|
+
*/
|
|
104
|
+
declare const assetUrl: (entry: AssetEntry, base: string) => string;
|
|
105
|
+
/** Record, but never fetch, a URL the template points at. */
|
|
106
|
+
declare const isExternalAsset: (reference: string) => boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Reject an asset base that would produce URLs a client will not load. The
|
|
109
|
+
* relative forms are the ones a page on disk resolves against its own
|
|
110
|
+
* directory, which is what a local export writes.
|
|
111
|
+
*/
|
|
112
|
+
declare const checkAssetBase: (base: string) => readonly EmailDiagnostic[];
|
|
113
|
+
//#endregion
|
|
114
|
+
export { EmailBrandSocialLink as _, assetUrl as a, renderedFooterMarkers as b, isExternalAsset as c, BrandFooterProps as d, BrandLogoProps as f, EmailBrandFooter as g, EmailBrandAssets as h, assetEntry as i, BRAND_COMPONENT_CLASSES as l, EmailBrandAddress as m, AssetEntry as n, checkAssetBase as o, EmailBrand as p, AssetManifest as r, isAssetPath as s, ASSET_CONTENT_TYPES as t, BrandComponents as u, RenderedFooterMarkers as v, withoutUnsubscribeRow as x, brandComponents as y };
|
|
115
|
+
//# sourceMappingURL=assets-B0yseju_.d.ts.map
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { D as samvaBrandPlugin, O as BRAND_FOOTER_MARKER, k as UNSUBSCRIBE_LINK, r as escapeAttribute } from "./html-DjPxwjLi.js";
|
|
2
|
+
import { a as jsx, n as Fragment } from "./jsx-runtime-CBlexoeR.js";
|
|
3
|
+
//#region src/email/assets.ts
|
|
4
|
+
/** Files a template may import, and what they are served as. */
|
|
5
|
+
const ASSET_CONTENT_TYPES = {
|
|
6
|
+
".png": "image/png",
|
|
7
|
+
".jpg": "image/jpeg",
|
|
8
|
+
".jpeg": "image/jpeg",
|
|
9
|
+
".gif": "image/gif",
|
|
10
|
+
".webp": "image/webp",
|
|
11
|
+
".avif": "image/avif",
|
|
12
|
+
".svg": "image/svg+xml",
|
|
13
|
+
".ico": "image/x-icon",
|
|
14
|
+
".woff": "font/woff",
|
|
15
|
+
".woff2": "font/woff2",
|
|
16
|
+
".ttf": "font/ttf",
|
|
17
|
+
".otf": "font/otf",
|
|
18
|
+
".pdf": "application/pdf",
|
|
19
|
+
".txt": "text/plain"
|
|
20
|
+
};
|
|
21
|
+
const extensionOf = (path) => {
|
|
22
|
+
const dot = path.lastIndexOf(".");
|
|
23
|
+
return dot < 0 ? "" : path.slice(dot).toLowerCase();
|
|
24
|
+
};
|
|
25
|
+
/** True when the compiler turns this import into a content-addressed asset. */
|
|
26
|
+
const isAssetPath = (path) => Object.hasOwn(ASSET_CONTENT_TYPES, extensionOf(path));
|
|
27
|
+
const hex = (buffer) => Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
28
|
+
/** Address one file by its content. */
|
|
29
|
+
const assetEntry = async (path, bytes) => {
|
|
30
|
+
const extension = extensionOf(path);
|
|
31
|
+
const view = new Uint8Array(bytes.byteLength);
|
|
32
|
+
view.set(bytes);
|
|
33
|
+
const digest = hex(await crypto.subtle.digest("SHA-256", view));
|
|
34
|
+
return {
|
|
35
|
+
path,
|
|
36
|
+
digest,
|
|
37
|
+
bytes: bytes.byteLength,
|
|
38
|
+
contentType: ASSET_CONTENT_TYPES[extension] ?? "application/octet-stream",
|
|
39
|
+
fileName: `${digest}${extension}`
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The URL an asset has under a base. The base is a build input: publication
|
|
44
|
+
* passes its hosted origin, and a local export passes whatever it will serve
|
|
45
|
+
* the exported files from.
|
|
46
|
+
*/
|
|
47
|
+
const assetUrl = (entry, base) => `${base.replace(/\/+$/, "")}/${entry.fileName}`;
|
|
48
|
+
const EXTERNAL_IMAGE = /^https:\/\//i;
|
|
49
|
+
/** Record, but never fetch, a URL the template points at. */
|
|
50
|
+
const isExternalAsset = (reference) => EXTERNAL_IMAGE.test(reference);
|
|
51
|
+
/**
|
|
52
|
+
* Reject an asset base that would produce URLs a client will not load. The
|
|
53
|
+
* relative forms are the ones a page on disk resolves against its own
|
|
54
|
+
* directory, which is what a local export writes.
|
|
55
|
+
*/
|
|
56
|
+
const checkAssetBase = (base) => /^(https:\/\/|\.{1,2}\/|\/)/i.test(base) ? [] : [{
|
|
57
|
+
code: "invalid-asset-base",
|
|
58
|
+
severity: "error",
|
|
59
|
+
message: `Asset base ${JSON.stringify(base)} must be an https URL, an absolute path, or a relative path for a local export.`,
|
|
60
|
+
origins: []
|
|
61
|
+
}];
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/email/brand.ts
|
|
64
|
+
/** Every class the brand components use, compiled for any project that imports them. */
|
|
65
|
+
const BRAND_COMPONENT_CLASSES = [
|
|
66
|
+
"dark:hidden!",
|
|
67
|
+
"hidden",
|
|
68
|
+
"dark:block!",
|
|
69
|
+
"text-xs",
|
|
70
|
+
"text-gray-500",
|
|
71
|
+
"text-center",
|
|
72
|
+
"font-semibold",
|
|
73
|
+
"underline"
|
|
74
|
+
];
|
|
75
|
+
const addressLines = (address) => [
|
|
76
|
+
address.street1,
|
|
77
|
+
address.street2,
|
|
78
|
+
[
|
|
79
|
+
address.city,
|
|
80
|
+
address.region,
|
|
81
|
+
address.postalCode
|
|
82
|
+
].filter((part) => part.trim() !== "").join(", "),
|
|
83
|
+
address.country
|
|
84
|
+
].filter((line) => line !== void 0 && line.trim() !== "");
|
|
85
|
+
const classes = (...names) => {
|
|
86
|
+
const joined = names.filter((name) => name !== void 0 && name !== "").join(" ");
|
|
87
|
+
return joined === "" ? void 0 : joined;
|
|
88
|
+
};
|
|
89
|
+
const row = (children, props = {}) => jsx("tr", {
|
|
90
|
+
...props,
|
|
91
|
+
children: jsx("td", {
|
|
92
|
+
style: { padding: "0 0 8px 0" },
|
|
93
|
+
children
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
/** Bind `BrandLogo` and `BrandFooter` to one brand, marked as the plugin names. */
|
|
97
|
+
const brandComponents = (brand, plugin = samvaBrandPlugin) => {
|
|
98
|
+
const assets = brand.assets ?? {};
|
|
99
|
+
const footer = brand.footer ?? {};
|
|
100
|
+
const BrandLogo = ({ width = 120, alt, align, className }) => {
|
|
101
|
+
if (assets.logoUrl === void 0) return null;
|
|
102
|
+
const label = alt ?? footer.companyName ?? "";
|
|
103
|
+
const image = (src, imageClass, imageAlt) => jsx("img", {
|
|
104
|
+
src,
|
|
105
|
+
alt: imageAlt,
|
|
106
|
+
width,
|
|
107
|
+
border: 0,
|
|
108
|
+
...align === void 0 ? {} : { align },
|
|
109
|
+
className: classes(imageClass, className),
|
|
110
|
+
style: {
|
|
111
|
+
display: "block",
|
|
112
|
+
outline: "none",
|
|
113
|
+
border: "none",
|
|
114
|
+
height: "auto"
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
if (assets.logoDarkUrl === void 0) return image(assets.logoUrl, void 0, label);
|
|
118
|
+
return jsx(Fragment, { children: [image(assets.logoUrl, "dark:hidden!", label), jsx("div", {
|
|
119
|
+
className: "hidden dark:block!",
|
|
120
|
+
style: {
|
|
121
|
+
msoHide: "all",
|
|
122
|
+
maxHeight: 0,
|
|
123
|
+
overflow: "hidden"
|
|
124
|
+
},
|
|
125
|
+
children: image(assets.logoDarkUrl, void 0, "")
|
|
126
|
+
})] });
|
|
127
|
+
};
|
|
128
|
+
const BrandFooter = ({ unsubscribeLabel = "Unsubscribe", className }) => {
|
|
129
|
+
const rows = [];
|
|
130
|
+
if (footer.companyName !== void 0 && footer.companyName.trim() !== "") rows.push(row(jsx("span", {
|
|
131
|
+
className: "font-semibold",
|
|
132
|
+
children: footer.companyName
|
|
133
|
+
})));
|
|
134
|
+
if (footer.address !== void 0) {
|
|
135
|
+
const lines = addressLines(footer.address);
|
|
136
|
+
if (lines.length > 0) rows.push(row(lines.flatMap((line, index) => index === 0 ? [line] : [jsx("br", {}), line])));
|
|
137
|
+
}
|
|
138
|
+
const links = footer.socialLinks ?? [];
|
|
139
|
+
if (links.length > 0) rows.push(row(links.flatMap((link, index) => [...index === 0 ? [] : [" · "], jsx("a", {
|
|
140
|
+
href: link.url,
|
|
141
|
+
className: "text-gray-500 underline",
|
|
142
|
+
children: link.label
|
|
143
|
+
})])));
|
|
144
|
+
rows.push(row(unsubscribeLink(unsubscribeLabel, plugin), {
|
|
145
|
+
[plugin.unsubscribeRowAttribute]: "",
|
|
146
|
+
[BRAND_FOOTER_MARKER]: true
|
|
147
|
+
}));
|
|
148
|
+
return jsx("table", {
|
|
149
|
+
role: "presentation",
|
|
150
|
+
width: "100%",
|
|
151
|
+
border: 0,
|
|
152
|
+
cellpadding: 0,
|
|
153
|
+
cellspacing: 0,
|
|
154
|
+
[plugin.footerAttribute]: "",
|
|
155
|
+
[BRAND_FOOTER_MARKER]: true,
|
|
156
|
+
children: jsx("tbody", { children: jsx("tr", { children: jsx("td", {
|
|
157
|
+
align: "center",
|
|
158
|
+
className: classes("text-xs text-gray-500 text-center", className),
|
|
159
|
+
style: { padding: "32px 16px" },
|
|
160
|
+
children: jsx("table", {
|
|
161
|
+
role: "presentation",
|
|
162
|
+
border: 0,
|
|
163
|
+
cellpadding: 0,
|
|
164
|
+
cellspacing: 0,
|
|
165
|
+
children: jsx("tbody", { children: rows })
|
|
166
|
+
})
|
|
167
|
+
}) }) })
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
return {
|
|
171
|
+
BrandLogo,
|
|
172
|
+
BrandFooter
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* The unsubscribe link. Its href is the placeholder, which no author-written
|
|
177
|
+
* link may carry: the serializer accepts it only on this node, and writes the
|
|
178
|
+
* plugin's no-track marker on it so click tracking never rewrites it.
|
|
179
|
+
*/
|
|
180
|
+
const unsubscribeLink = (label, plugin) => jsx("a", {
|
|
181
|
+
href: plugin.unsubscribeUrlPlaceholder,
|
|
182
|
+
className: "text-gray-500 underline",
|
|
183
|
+
[UNSUBSCRIBE_LINK]: true,
|
|
184
|
+
children: label
|
|
185
|
+
});
|
|
186
|
+
/** Read the plugin's footer markers from rendered HTML. */
|
|
187
|
+
const renderedFooterMarkers = (html, plugin = samvaBrandPlugin) => ({
|
|
188
|
+
footer: html.includes(`${plugin.footerAttribute}=""`),
|
|
189
|
+
unsubscribeLink: html.includes(`href="${escapeAttribute(plugin.unsubscribeUrlPlaceholder)}"`)
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* Drop the unsubscribe row from a rendered message, for a send that resolved
|
|
193
|
+
* no unsubscribe group: there is no link to put there, so the row goes.
|
|
194
|
+
*/
|
|
195
|
+
const withoutUnsubscribeRow = (rendered, plugin = samvaBrandPlugin) => ({
|
|
196
|
+
html: rendered.html?.replace(new RegExp(`<tr ${plugin.unsubscribeRowAttribute}=""[^>]*>[\\s\\S]*?</tr>`, "g"), ""),
|
|
197
|
+
text: rendered.text?.split("\n").filter((line) => !line.includes(plugin.unsubscribeUrlPlaceholder)).join("\n")
|
|
198
|
+
});
|
|
199
|
+
//#endregion
|
|
200
|
+
export { ASSET_CONTENT_TYPES as a, checkAssetBase as c, withoutUnsubscribeRow as i, isAssetPath as l, brandComponents as n, assetEntry as o, renderedFooterMarkers as r, assetUrl as s, BRAND_COMPONENT_CLASSES as t, isExternalAsset as u };
|
|
201
|
+
|
|
202
|
+
//# sourceMappingURL=brand-DTctcDmf.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/email/brand-plugin.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* How a template reaches its brand and how the footer `BrandFooter` renders is
|
|
4
|
+
* marked for the send path that delivers it. The compiler and the IR renderer
|
|
5
|
+
* read every brand import, footer marker and unsubscribe link from the plugin
|
|
6
|
+
* a build passes; `samvaBrandPlugin` is the default.
|
|
7
|
+
*/
|
|
8
|
+
interface BrandPlugin {
|
|
9
|
+
/**
|
|
10
|
+
* The module and stylesheet specifier a template imports its brand from.
|
|
11
|
+
* `<specifier>/<slug>` names one brand; the bare specifier names the default.
|
|
12
|
+
*/
|
|
13
|
+
readonly specifier: string;
|
|
14
|
+
/** Marks the block `BrandFooter` renders, so the send path finds a template's own footer. */
|
|
15
|
+
readonly footerAttribute: `data-${string}`;
|
|
16
|
+
/** Marks the footer row that carries the unsubscribe link, so a send can drop it. */
|
|
17
|
+
readonly unsubscribeRowAttribute: `data-${string}`;
|
|
18
|
+
/** The unsubscribe link's href; the send path substitutes each delivery's URL for it. */
|
|
19
|
+
readonly unsubscribeUrlPlaceholder: string;
|
|
20
|
+
/**
|
|
21
|
+
* Written on the unsubscribe link, so the send path delivers it without
|
|
22
|
+
* click tracking: a rewritten link would carry another recipient's token.
|
|
23
|
+
*/
|
|
24
|
+
readonly noTrackAttribute: `data-${string}`;
|
|
25
|
+
}
|
|
26
|
+
/** The brand a specifier names: `undefined` slug means the default brand; `undefined` when it names none. */
|
|
27
|
+
declare const parseBrandSpecifier: (specifier: string, plugin?: BrandPlugin) => {
|
|
28
|
+
readonly slug: string | undefined;
|
|
29
|
+
} | undefined;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { parseBrandSpecifier as n, BrandPlugin as t };
|
|
32
|
+
//# sourceMappingURL=brand-plugin-CHhcei-j.d.ts.map
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as BrandPlugin } from "./brand-plugin-CHhcei-j.js";
|
|
2
|
+
import { _ as EmailBrandSocialLink, a as assetUrl, b as renderedFooterMarkers, c as isExternalAsset, d as BrandFooterProps, f as BrandLogoProps, g as EmailBrandFooter, h as EmailBrandAssets, i as assetEntry, l as BRAND_COMPONENT_CLASSES, m as EmailBrandAddress, n as AssetEntry, o as checkAssetBase, p as EmailBrand, r as AssetManifest, s as isAssetPath, t as ASSET_CONTENT_TYPES, u as BrandComponents, v as RenderedFooterMarkers, x as withoutUnsubscribeRow, y as brandComponents } from "./assets-B0yseju_.js";
|
|
3
|
+
import { t as Diagnostic } from "./diagnostic-model-DxthUZBT.js";
|
|
2
4
|
import { Result } from "better-result";
|
|
5
|
+
//#region src/email/samva-brand-plugin.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Samva's brand plugin, the compiler's default. A template imports its
|
|
8
|
+
* organization's brand from `samva:brand`, and Samva's send path fills
|
|
9
|
+
* `%samva:unsubscribe-url%` per delivery and turns `data-samva-no-track` into
|
|
10
|
+
* its email provider's own no-track marker.
|
|
11
|
+
*/
|
|
12
|
+
declare const samvaBrandPlugin: BrandPlugin;
|
|
13
|
+
//#endregion
|
|
3
14
|
//#region src/theme-css.d.ts
|
|
4
15
|
/** One `@font-face` a brand declares. `src` is the declaration value as authored. */
|
|
5
16
|
interface BrandFontFace {
|
|
@@ -58,8 +69,8 @@ declare const brandForegroundDefaults: (brand: BrandCss) => {
|
|
|
58
69
|
* build compiles the same default and the stored CSS never carries it.
|
|
59
70
|
*/
|
|
60
71
|
declare const brandThemeVariables: (brand: BrandCss) => Readonly<Record<string, string>>;
|
|
61
|
-
/** The stylesheet Tailwind compiles for
|
|
72
|
+
/** The stylesheet Tailwind compiles for the theme's brand import: `brandThemeVariables` and the font faces. */
|
|
62
73
|
declare const brandTailwindCss: (brand: BrandCss) => string;
|
|
63
74
|
//#endregion
|
|
64
|
-
export { BRAND_COLOR_VARIABLE, BRAND_FOREGROUND_VARIABLE, BrandCss, BrandFontFace, brandForegroundDefaults, brandTailwindCss, brandThemeVariables, contrastForeground, darkVariableName, parseBrandCss, printBrandCss };
|
|
65
|
-
//# sourceMappingURL=
|
|
75
|
+
export { ASSET_CONTENT_TYPES, AssetEntry, AssetManifest, BRAND_COLOR_VARIABLE, BRAND_COMPONENT_CLASSES, BRAND_FOREGROUND_VARIABLE, BrandComponents, BrandCss, BrandFontFace, BrandFooterProps, BrandLogoProps, type BrandPlugin, EmailBrand, EmailBrandAddress, EmailBrandAssets, EmailBrandFooter, EmailBrandSocialLink, RenderedFooterMarkers, assetEntry, assetUrl, brandComponents, brandForegroundDefaults, brandTailwindCss, brandThemeVariables, checkAssetBase, contrastForeground, darkVariableName, isAssetPath, isExternalAsset, parseBrandCss, printBrandCss, renderedFooterMarkers, samvaBrandPlugin, withoutUnsubscribeRow };
|
|
76
|
+
//# sourceMappingURL=brand.d.ts.map
|
package/dist/brand.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { D as samvaBrandPlugin } from "./html-DjPxwjLi.js";
|
|
2
|
+
import { a as brandThemeVariables, c as parseBrandCss, i as brandTailwindCss, l as printBrandCss, n as BRAND_FOREGROUND_VARIABLE, o as contrastForeground, r as brandForegroundDefaults, s as darkVariableName, t as BRAND_COLOR_VARIABLE } from "./theme-css-CEUrDpqq.js";
|
|
3
|
+
import { a as ASSET_CONTENT_TYPES, c as checkAssetBase, i as withoutUnsubscribeRow, l as isAssetPath, n as brandComponents, o as assetEntry, r as renderedFooterMarkers, s as assetUrl, t as BRAND_COMPONENT_CLASSES, u as isExternalAsset } from "./brand-DTctcDmf.js";
|
|
4
|
+
export { ASSET_CONTENT_TYPES, BRAND_COLOR_VARIABLE, BRAND_COMPONENT_CLASSES, BRAND_FOREGROUND_VARIABLE, assetEntry, assetUrl, brandComponents, brandForegroundDefaults, brandTailwindCss, brandThemeVariables, checkAssetBase, contrastForeground, darkVariableName, isAssetPath, isExternalAsset, parseBrandCss, printBrandCss, renderedFooterMarkers, samvaBrandPlugin, withoutUnsubscribeRow };
|
package/dist/compiler.d.ts
CHANGED
|
@@ -1,13 +1,68 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { n as parseBrandSpecifier, t as BrandPlugin } from "./brand-plugin-CHhcei-j.js";
|
|
2
|
+
import { a as TemplateDiagnostic, r as EmailDiagnostic } from "./diagnostics-B-Gym34R.js";
|
|
3
|
+
import { r as EmailNode } from "./jsx-runtime-ylIOnaSf.js";
|
|
4
|
+
import { n as AssetEntry, p as EmailBrand, u as BrandComponents } from "./assets-B0yseju_.js";
|
|
5
|
+
import { C as Compound, D as EmittedPosition, S as CompiledSelector, T as matchesSelector, _ as Specificity, b as parseStylesheet, ct as TemplateIr, g as CssRule, h as CssDeclaration, r as RenderedEmail, v as Stylesheet, w as classListOf, x as Ancestry, y as compileSelector } from "./render-DQKz4Aco.js";
|
|
6
|
+
import { a as TEMPLATE_NAME_PATTERN, n as EmailContent } from "./template-DMPwxMSq.js";
|
|
7
|
+
import { caniemail } from "caniemail";
|
|
8
|
+
//#region src/email/compatibility.d.ts
|
|
9
|
+
type CaniemailClient = Parameters<typeof caniemail>[0]["clients"][number];
|
|
10
|
+
/** One client this compiler makes claims about. */
|
|
11
|
+
interface EmailClientTarget {
|
|
12
|
+
readonly id: CaniemailClient;
|
|
13
|
+
readonly label: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The pinned matrix. Every finding is reported per client, and a client absent
|
|
17
|
+
* from this list is a client Samva makes no claim about.
|
|
18
|
+
*/
|
|
19
|
+
declare const EMAIL_CLIENT_MATRIX: readonly EmailClientTarget[];
|
|
20
|
+
interface CompatibilityProvenance {
|
|
21
|
+
/** The exact rules package a finding came from. */
|
|
22
|
+
readonly rules: string;
|
|
23
|
+
readonly apiVersion: string;
|
|
24
|
+
/** The day caniemail last changed the data this build was checked against. */
|
|
25
|
+
readonly lastUpdate: string;
|
|
26
|
+
}
|
|
27
|
+
declare const COMPATIBILITY_PROVENANCE: CompatibilityProvenance;
|
|
28
|
+
/**
|
|
29
|
+
* The constructs whose loss actually breaks a message: the recipient reads
|
|
30
|
+
* something different, in a different order, follows a link that does not work,
|
|
31
|
+
* or sees a layout that has collapsed. A target client dropping one of these
|
|
32
|
+
* blocks publication.
|
|
33
|
+
*
|
|
34
|
+
* The list is deliberately short and enumerated, because the contract is to
|
|
35
|
+
* block *known* failures. Nonessential differences require an assessment of
|
|
36
|
+
* emitted values: a concrete risk warns, expected differences and unverified
|
|
37
|
+
* behavior remain compatibility observations.
|
|
38
|
+
*/
|
|
39
|
+
declare const ESSENTIAL_CONSTRUCTS: ReadonlySet<string>;
|
|
40
|
+
interface CompatibilityInput {
|
|
41
|
+
/** The document the recipient receives. */
|
|
42
|
+
readonly html: string;
|
|
43
|
+
/** The declared fixture checked by this invocation. */
|
|
44
|
+
readonly fixture?: string | undefined;
|
|
45
|
+
/** Retained head rules, when they are not already inside the HTML. */
|
|
46
|
+
readonly css?: string | undefined;
|
|
47
|
+
/** Emitted-offset ranges with the origins of the node that produced them. */
|
|
48
|
+
readonly positions?: readonly EmittedPosition[] | undefined;
|
|
49
|
+
readonly clients?: readonly EmailClientTarget[] | undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check the emitted document against the pinned matrix.
|
|
53
|
+
*
|
|
54
|
+
* Findings are grouped by construct rather than repeated per client, so one
|
|
55
|
+
* unsupported property is one diagnostic naming every client that drops it.
|
|
56
|
+
*/
|
|
57
|
+
declare const checkEmailCompatibility: (input: CompatibilityInput) => readonly EmailDiagnostic[];
|
|
58
|
+
/**
|
|
59
|
+
* Constructs the pinned data says nothing about for a target client. These are
|
|
60
|
+
* reported so "we did not check that" is never mistaken for "that works".
|
|
61
|
+
*/
|
|
62
|
+
declare const unknownCoverage: (titles: Iterable<string>) => readonly EmailDiagnostic[];
|
|
63
|
+
/** A publication carrying one of these is refused; the message would arrive broken. */
|
|
64
|
+
declare const hasBlockingCompatibility: (findings: readonly EmailDiagnostic[]) => boolean;
|
|
65
|
+
//#endregion
|
|
11
66
|
//#region src/email/css-values.d.ts
|
|
12
67
|
/**
|
|
13
68
|
* Expand `var(--x, fallback)` against the collected custom properties.
|
|
@@ -64,13 +119,176 @@ declare const applyStylesheet: (root: EmailNode, sheet: Stylesheet, options?: {
|
|
|
64
119
|
/** The exact Tailwind release the compiler runs, recorded in every build manifest. */
|
|
65
120
|
declare const TAILWIND_VERSION = "4.3.3";
|
|
66
121
|
//#endregion
|
|
67
|
-
//#region src/email/
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
//#region src/email/tailwind.d.ts
|
|
123
|
+
interface TailwindOptions {
|
|
124
|
+
/**
|
|
125
|
+
* Project CSS appended to the compiled entry: `@theme` overrides, `@utility`
|
|
126
|
+
* definitions and ordinary rules. This is the project's pinned configuration.
|
|
127
|
+
*/
|
|
128
|
+
readonly css?: string | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* The project path `css` was read from (`theme.css` by default). Its
|
|
131
|
+
* relative `@import`s resolve from this file's directory.
|
|
132
|
+
*/
|
|
133
|
+
readonly cssPath?: string | undefined;
|
|
134
|
+
/** Classes the compiler cannot discover, declared by the project on purpose. */
|
|
135
|
+
readonly safelist?: readonly string[] | undefined;
|
|
136
|
+
/** Tailwind's browser reset is off by default; email clients do not want it. */
|
|
137
|
+
readonly preflight?: boolean | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Bounds on what the compiler may generate. Class discovery reads authored
|
|
140
|
+
* source, so a project can hand it an unbounded candidate set and get an
|
|
141
|
+
* unbounded stylesheet back — inside a build that has a wall clock and a
|
|
142
|
+
* bundle a Worker then has to load. A host that publishes supplies these.
|
|
143
|
+
*/
|
|
144
|
+
readonly limits?: TailwindLimits | undefined;
|
|
145
|
+
}
|
|
146
|
+
interface TailwindLimits {
|
|
147
|
+
/** Distinct classes handed to the compiler. */
|
|
148
|
+
readonly candidates: number;
|
|
149
|
+
/** Bytes of generated CSS. */
|
|
150
|
+
readonly cssBytes: number;
|
|
151
|
+
}
|
|
152
|
+
interface TailwindOutput {
|
|
153
|
+
readonly css: string;
|
|
154
|
+
readonly version: string;
|
|
155
|
+
/** Every candidate handed to the compiler, sorted, for the build manifest. */
|
|
156
|
+
readonly candidates: readonly string[];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* What the project theme's `@import`s resolve to, already checked by
|
|
160
|
+
* `resolveThemeImports`: project stylesheets by path, and the brand theme the
|
|
161
|
+
* brand plugin's specifier stands for.
|
|
162
|
+
*/
|
|
163
|
+
interface TailwindImports {
|
|
164
|
+
readonly stylesheets: ReadonlyMap<string, string>;
|
|
165
|
+
readonly brandCss?: string | undefined;
|
|
166
|
+
/** Names the brand import; `samvaBrandPlugin` when omitted. */
|
|
167
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
168
|
+
}
|
|
169
|
+
/** Compile the discovered class set into CSS with the pinned Tailwind release. */
|
|
170
|
+
declare const compileTailwind: (candidates: Iterable<string>, options?: TailwindOptions, imports?: TailwindImports) => Promise<TailwindOutput>;
|
|
171
|
+
interface ClassDiscovery {
|
|
172
|
+
readonly candidates: readonly string[];
|
|
173
|
+
readonly diagnostics: readonly EmailDiagnostic[];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Collect the class names one module states literally, and report the positions
|
|
177
|
+
* where a class is assembled from values the compiler cannot see.
|
|
178
|
+
*/
|
|
179
|
+
declare const discoverClassCandidates: (source: string, fileName: string) => ClassDiscovery;
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/email/transform.d.ts
|
|
182
|
+
/** Where this build serves assets from, and how Tailwind is configured. */
|
|
183
|
+
interface TransformOptions {
|
|
184
|
+
readonly assetBase: string;
|
|
185
|
+
/** `false` compiles no Tailwind at all. */
|
|
186
|
+
readonly tailwind?: TailwindOptions | false | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* The brand the brand import resolves to, supplied by the host. A project
|
|
189
|
+
* that imports a brand with no brand here fails to compile.
|
|
190
|
+
*/
|
|
191
|
+
readonly brand?: EmailBrand | undefined;
|
|
192
|
+
/** Names the brand import and marks the footer `BrandFooter` renders; `samvaBrandPlugin` when omitted. */
|
|
193
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
194
|
+
}
|
|
195
|
+
interface ProjectTransform {
|
|
196
|
+
readonly assets: readonly AssetEntry[];
|
|
197
|
+
/** The compiled Tailwind sheet, when the project used any utility class. */
|
|
198
|
+
readonly tailwindSheet: Stylesheet | undefined;
|
|
199
|
+
/** Every project stylesheet, parsed, by path. */
|
|
200
|
+
readonly stylesheets: ReadonlyMap<string, Stylesheet>;
|
|
201
|
+
readonly diagnostics: readonly EmailDiagnostic[];
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The brand specifier a project imports — from its theme's `@import`s or its
|
|
205
|
+
* TSX — so a host can fetch that brand before it compiles. `undefined` when
|
|
206
|
+
* the project imports no brand. A project that names two brands gets the
|
|
207
|
+
* first here and a refusal from the compile.
|
|
208
|
+
*/
|
|
209
|
+
declare const projectBrandSpecifier: (files: Readonly<Record<string, string | Uint8Array>>, themePath?: string, brandPlugin?: BrandPlugin) => string | undefined;
|
|
210
|
+
/** Read a whole project, then compile the classes its scripts used. */
|
|
211
|
+
declare const transformProject: (files: Readonly<Record<string, string | Uint8Array>>, options: TransformOptions) => Promise<ProjectTransform>;
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/email/brand-footer.d.ts
|
|
214
|
+
/** A footer block for the send path to append, and its plain-text tail. */
|
|
215
|
+
interface RenderedBrandFooter {
|
|
216
|
+
readonly html: string;
|
|
217
|
+
readonly text: string;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Render `BrandFooter` against a brand on its own, for the send path to
|
|
221
|
+
* append to a message whose template renders no footer of its own. It
|
|
222
|
+
* compiles the same component, styled by the same brand theme, a template
|
|
223
|
+
* would get from its brand import. Without `unsubscribe` the unsubscribe row is
|
|
224
|
+
* left out.
|
|
225
|
+
*/
|
|
226
|
+
declare const renderBrandFooter: (brand: EmailBrand, options: {
|
|
227
|
+
readonly unsubscribe: boolean;
|
|
228
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
229
|
+
}) => Promise<RenderedBrandFooter>;
|
|
230
|
+
/**
|
|
231
|
+
* Render content against a brand as a project whose `theme.css` imports only
|
|
232
|
+
* the brand renders it: Tailwind compiles the brand theme for
|
|
233
|
+
* the classes the content names, `BrandLogo` and `BrandFooter` are bound to the
|
|
234
|
+
* brand, and the render inlines the result. A brand preview renders through
|
|
235
|
+
* this, so it shows what a template importing the brand compiles to.
|
|
236
|
+
*/
|
|
237
|
+
declare const renderBrandSample: (brand: EmailBrand, sample: {
|
|
238
|
+
/** Every class the content names; nothing is discovered from source here. */
|
|
239
|
+
readonly classes: readonly string[];
|
|
240
|
+
readonly render: (components: BrandComponents) => EmailContent;
|
|
241
|
+
}, brandPlugin?: BrandPlugin) => Promise<RenderedEmail>;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/sml/lower-project.d.ts
|
|
244
|
+
interface CompiledTemplate {
|
|
245
|
+
/** The IR, or `undefined` when a finding blocks it. */
|
|
246
|
+
readonly ir: TemplateIr | undefined;
|
|
247
|
+
/** The fixtures read from the entry, with imported assets resolved to their URLs. */
|
|
248
|
+
readonly fixtures: Readonly<Record<string, unknown>>;
|
|
249
|
+
readonly assets: readonly AssetEntry[];
|
|
250
|
+
/** Errors block the IR; warnings ride along. */
|
|
251
|
+
readonly diagnostics: readonly TemplateDiagnostic[];
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/sml/compile.d.ts
|
|
255
|
+
interface CompileTemplateOptions extends TransformOptions {
|
|
256
|
+
/** The project's files by path. Binary files are addressed as assets. */
|
|
257
|
+
readonly files: Readonly<Record<string, string | Uint8Array>>;
|
|
258
|
+
/** The entry: a `.tsx` file that default-exports `defineTemplate({ ... })`. */
|
|
259
|
+
readonly entry: string;
|
|
260
|
+
/**
|
|
261
|
+
* The portable JSON Schema, for an entry whose `schema` is not a literal `jsonSchema(...)`
|
|
262
|
+
* (a Zod or Effect schema needs a library to become JSON Schema). A host that has evaluated the
|
|
263
|
+
* schema passes its conversion here; a literal schema is read from source and this is ignored.
|
|
264
|
+
*/
|
|
265
|
+
readonly schema?: Readonly<Record<string, unknown>> | undefined;
|
|
266
|
+
}
|
|
267
|
+
/** Compile a project's entry template to IR without evaluating any of it. */
|
|
268
|
+
declare const compileTemplate: (options: CompileTemplateOptions) => Promise<CompiledTemplate>;
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/sml/compatibility.d.ts
|
|
271
|
+
/**
|
|
272
|
+
* Check what each declared fixture delivers against the pinned client matrix. The rules run on the
|
|
273
|
+
* rendered document, because what a client drops is what the compiler produced, and every finding
|
|
274
|
+
* is located at the source of the element that produced it.
|
|
275
|
+
*/
|
|
276
|
+
declare const checkTemplateCompatibility: (ir: TemplateIr, fixtures: Readonly<Record<string, unknown>>, options?: {
|
|
277
|
+
readonly clients?: readonly EmailClientTarget[] | undefined;
|
|
278
|
+
}) => readonly EmailDiagnostic[];
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/sml/profile.d.ts
|
|
281
|
+
/**
|
|
282
|
+
* Check an entry against the static profile. Pass the entry's source alone, or the project's files
|
|
283
|
+
* and the entry's path. Imports of files that are absent are trusted to exist, and the brand,
|
|
284
|
+
* Tailwind and theme are not resolved, so the result holds only findings the source itself owns.
|
|
285
|
+
*/
|
|
286
|
+
declare const checkStaticProfile: (files: string | Readonly<Record<string, string | Uint8Array>>, entry?: string, brandPlugin?: BrandPlugin) => readonly TemplateDiagnostic[];
|
|
287
|
+
/**
|
|
288
|
+
* The errors in `after` that `before` did not already have, compared by code and message so a
|
|
289
|
+
* finding that only moved does not count as new.
|
|
290
|
+
*/
|
|
291
|
+
declare const introducedProfileErrors: (before: readonly TemplateDiagnostic[], after: readonly TemplateDiagnostic[]) => readonly TemplateDiagnostic[];
|
|
74
292
|
//#endregion
|
|
75
|
-
export {
|
|
293
|
+
export { type Ancestry, type AppliedStyles, COMPATIBILITY_PROVENANCE, type ClassDiscovery, type CompatibilityInput, type CompatibilityProvenance, type CompileTemplateOptions, type CompiledSelector, type CompiledTemplate, type Compound, type CssDeclaration, type CssRule, EMAIL_CLIENT_MATRIX, ESSENTIAL_CONSTRUCTS, type EmailClientTarget, type EmailContent, type ProjectTransform, type RenderedBrandFooter, type Specificity, type Stylesheet, TAILWIND_VERSION, TEMPLATE_NAME_PATTERN, type TailwindLimits, type TailwindOptions, type TailwindOutput, type TransformOptions, applyStylesheet, checkEmailCompatibility, checkStaticProfile, checkTemplateCompatibility, classListOf, compileSelector, compileTailwind, compileTemplate, discoverClassCandidates, downlevelColors, downlevelMediaQuery, finalizeValue, foldCalc, formatColor, hasBlockingCompatibility, introducedProfileErrors, matchesSelector, parseBrandSpecifier, parseColor, parseStylesheet, projectBrandSpecifier, renderBrandFooter, renderBrandSample, renderHeadCss, resolveVariables, transformProject, unknownCoverage };
|
|
76
294
|
//# sourceMappingURL=compiler.d.ts.map
|