@samva/markup 0.10.0 → 0.11.1
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 +5 -1
- package/CHANGELOG.md +34 -0
- package/README.md +11 -0
- package/dist/{assets-BIsyMQ92.d.ts → assets-B0yseju_.d.ts} +9 -12
- package/dist/{brand-C0MKTwmX.js → brand-DTctcDmf.js} +19 -25
- package/dist/brand-plugin-CHhcei-j.d.ts +32 -0
- package/dist/brand.d.ts +10 -8
- package/dist/brand.js +4 -4
- package/dist/compiler.d.ts +22 -24
- package/dist/compiler.js +43 -40
- package/dist/components-Bl6DT21n.js +275 -0
- package/dist/diagnostics.d.ts +3 -3
- package/dist/diagnostics.js +3 -3
- package/dist/edit.js +1 -1
- package/dist/email.js +1 -1
- package/dist/{components-BZCqegS8.js → html-DjPxwjLi.js} +89 -316
- package/dist/{ir-CLhlklKV.js → ir-De6pTH51.js} +2 -2
- package/dist/{profile-pWGtWZXF.js → profile-PUfi3GPH.js} +34 -33
- package/dist/{render-BQmfh94k.js → render-D2ht57ZZ.js} +4 -3
- package/dist/{render-BPonDpCl.d.ts → render-DQKz4Aco.d.ts} +10 -1
- package/dist/render.d.ts +1 -1
- package/dist/render.js +3 -3
- package/dist/{theme-css-JtRCm1fb.js → theme-css-CEUrDpqq.js} +2 -2
- package/generated/contract.json +3 -3
- package/generated/reference.md +3 -3
- package/package.json +4 -4
- package/dist/unsubscribe-link-CoesnQDU.js +0 -26
package/AGENTS.md
CHANGED
|
@@ -30,7 +30,11 @@ Authoring entries are what a template file imports:
|
|
|
30
30
|
mode) and `BrandFooter` (company, postal address, social links and the unsubscribe row the send
|
|
31
31
|
path fills). The compiler binds them to the brand the build resolves; add
|
|
32
32
|
`"types": ["@samva/markup/samva-brand"]` to the project's tsconfig for `tsc`. In `theme.css`,
|
|
33
|
-
`@import "samva:brand";` layers the brand theme; `samva:brand/<slug>` names one brand.
|
|
33
|
+
`@import "samva:brand";` layers the brand theme; `samva:brand/<slug>` names one brand. These are
|
|
34
|
+
Samva's brand plugin (`samvaBrandPlugin` from `@samva/markup/brand`), the default; a host that
|
|
35
|
+
delivers mail itself passes its own `BrandPlugin` as `brandPlugin` to `compileTemplate`,
|
|
36
|
+
`renderIr` and `renderBrandFooter` to rename the brand import, the footer markers, the
|
|
37
|
+
unsubscribe placeholder and the unsubscribe link's no-track marker.
|
|
34
38
|
|
|
35
39
|
Tooling entries are what a host (Vite, the CLI, the editor, the API, the template agent) imports:
|
|
36
40
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,37 @@
|
|
|
1
|
+
## @samva/markup@0.11.0
|
|
2
|
+
|
|
3
|
+
### Breaking: `@samva/markup` reads brand and footer names from a brand plugin
|
|
4
|
+
|
|
5
|
+
Templates do not change: `samva:brand`, `BrandLogo`, `BrandFooter` and the unsubscribe row work as
|
|
6
|
+
before, because Samva's brand plugin is the default.
|
|
7
|
+
|
|
8
|
+
A host that compiles or renders templates can pass its own `BrandPlugin` as `brandPlugin` to
|
|
9
|
+
`compileTemplate`, `transformProject`, `projectBrandSpecifier`, `parseBrandSpecifier`,
|
|
10
|
+
`checkStaticProfile`, `renderIr`, `compileEmail`, `renderBrandFooter`, `renderBrandSample`,
|
|
11
|
+
`brandComponents`, `renderedFooterMarkers` and `withoutUnsubscribeRow`. The plugin names the brand
|
|
12
|
+
import, the attributes that mark the footer and its unsubscribe row, the unsubscribe link's URL
|
|
13
|
+
placeholder, and the attribute that marks that link as untracked.
|
|
14
|
+
|
|
15
|
+
`BrandFooter`'s unsubscribe link now carries `data-samva-no-track` instead of SES's
|
|
16
|
+
`ses:no-track`. A host that delivers mail through SES turns the marker into `ses:no-track` before it
|
|
17
|
+
sends.
|
|
18
|
+
|
|
19
|
+
`@samva/markup/brand` exports `samvaBrandPlugin` and the `BrandPlugin` type in place of
|
|
20
|
+
`FOOTER_ATTRIBUTE`, `UNSUBSCRIBE_ROW_ATTRIBUTE` and `UNSUBSCRIBE_URL_PLACEHOLDER`; read
|
|
21
|
+
`samvaBrandPlugin.footerAttribute`, `.unsubscribeRowAttribute` and `.unsubscribeUrlPlaceholder`.
|
|
22
|
+
`@samva/markup/compiler` no longer exports `BRAND_SPECIFIER`; read `samvaBrandPlugin.specifier`.
|
|
23
|
+
|
|
24
|
+
### Breaking: supply brand resolution to the authoring toolchain
|
|
25
|
+
|
|
26
|
+
`@samva/vite` accepts `brandResolver` and `brandPlugin` on the editor plugin and its dev, project,
|
|
27
|
+
build, render and export APIs. A brand import without a resolver fails with `brand-unavailable`.
|
|
28
|
+
Standalone callers supply a resolver; the package does not read Samva credentials, invoke the
|
|
29
|
+
Samva CLI or load Samva brand snapshots. The `offline` option and Samva snapshot helpers move to
|
|
30
|
+
the CLI.
|
|
31
|
+
|
|
32
|
+
`samva templates dev`, `check`, `build`, `render`, `snapshot` and `export` supply the Samva resolver
|
|
33
|
+
and brand plugin, preserving live lookup, cached snapshots and brand diagnostics.
|
|
34
|
+
|
|
1
35
|
## @samva/markup@0.10.0
|
|
2
36
|
|
|
3
37
|
### Breaking: `@samva/markup` publishes 17 entries in two tiers
|
package/README.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
Type-safe authoring and compilation primitives for Samva email, SMS, and WhatsApp templates. Use it
|
|
4
4
|
directly for TSX templates or together with `@samva/vite` for the visual editor and project build.
|
|
5
5
|
|
|
6
|
+
## For coding agents
|
|
7
|
+
|
|
8
|
+
- **SML** is the name of this toolkit, not a second syntax. An email is a TSX file that
|
|
9
|
+
default-exports `defineTemplate`, written in the static profile (ordinary JSX, HTML, and Tailwind
|
|
10
|
+
classes read without running). Compiling it produces the **IR**, the JSON description that
|
|
11
|
+
previews and sends render.
|
|
12
|
+
- The package ships the `sml` skill at `skills/sml/SKILL.md`; it routes you through write, check,
|
|
13
|
+
render, look, and repair. `AGENTS.md` and `contract.json` ship alongside it.
|
|
14
|
+
- Run `samva templates check --json` after every edit for diagnostics with `file:line:column` and a
|
|
15
|
+
fix for each.
|
|
16
|
+
|
|
6
17
|
## Install
|
|
7
18
|
|
|
8
19
|
```sh
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as BrandPlugin } from "./brand-plugin-CHhcei-j.js";
|
|
1
2
|
import { r as EmailDiagnostic } from "./diagnostics-B-Gym34R.js";
|
|
2
3
|
import { r as EmailNode } from "./jsx-runtime-ylIOnaSf.js";
|
|
3
4
|
//#region src/email/brand.d.ts
|
|
@@ -24,17 +25,13 @@ interface EmailBrandFooter {
|
|
|
24
25
|
readonly socialLinks?: readonly EmailBrandSocialLink[] | undefined;
|
|
25
26
|
}
|
|
26
27
|
interface EmailBrand {
|
|
27
|
-
/** The brand's slug;
|
|
28
|
+
/** The brand's slug; a `<specifier>/<slug>` brand import must name it. */
|
|
28
29
|
readonly slug: string;
|
|
29
30
|
/** Brand theme CSS in the closed grammar `parseBrandCss` accepts. */
|
|
30
31
|
readonly css: string;
|
|
31
32
|
readonly assets?: EmailBrandAssets | undefined;
|
|
32
33
|
readonly footer?: EmailBrandFooter | undefined;
|
|
33
34
|
}
|
|
34
|
-
/** Marks the block the send path recognizes as the template's own footer. */
|
|
35
|
-
declare const FOOTER_ATTRIBUTE = "data-samva-footer";
|
|
36
|
-
/** Marks the footer row that carries the unsubscribe link. */
|
|
37
|
-
declare const UNSUBSCRIBE_ROW_ATTRIBUTE = "data-samva-unsubscribe";
|
|
38
35
|
/** Every class the brand components use, compiled for any project that imports them. */
|
|
39
36
|
declare const BRAND_COMPONENT_CLASSES: readonly ["dark:hidden!", "hidden", "dark:block!", "text-xs", "text-gray-500", "text-center", "font-semibold", "underline"];
|
|
40
37
|
interface BrandLogoProps {
|
|
@@ -54,8 +51,8 @@ interface BrandComponents {
|
|
|
54
51
|
readonly BrandLogo: (props: BrandLogoProps) => EmailNode | null;
|
|
55
52
|
readonly BrandFooter: (props: BrandFooterProps) => EmailNode | null;
|
|
56
53
|
}
|
|
57
|
-
/** Bind `BrandLogo` and `BrandFooter` to one brand. */
|
|
58
|
-
declare const brandComponents: (brand: EmailBrand) => BrandComponents;
|
|
54
|
+
/** Bind `BrandLogo` and `BrandFooter` to one brand, marked as the plugin names. */
|
|
55
|
+
declare const brandComponents: (brand: EmailBrand, plugin?: BrandPlugin) => BrandComponents;
|
|
59
56
|
/** What a rendered message says about the footer it carries. */
|
|
60
57
|
interface RenderedFooterMarkers {
|
|
61
58
|
/** The message renders `BrandFooter` (or claims to, with the marker). */
|
|
@@ -63,8 +60,8 @@ interface RenderedFooterMarkers {
|
|
|
63
60
|
/** The message carries the unsubscribe placeholder link only `BrandFooter` can write. */
|
|
64
61
|
readonly unsubscribeLink: boolean;
|
|
65
62
|
}
|
|
66
|
-
/** Read the footer markers from rendered HTML. */
|
|
67
|
-
declare const renderedFooterMarkers: (html: string) => RenderedFooterMarkers;
|
|
63
|
+
/** Read the plugin's footer markers from rendered HTML. */
|
|
64
|
+
declare const renderedFooterMarkers: (html: string, plugin?: BrandPlugin) => RenderedFooterMarkers;
|
|
68
65
|
/**
|
|
69
66
|
* Drop the unsubscribe row from a rendered message, for a send that resolved
|
|
70
67
|
* no unsubscribe group: there is no link to put there, so the row goes.
|
|
@@ -72,7 +69,7 @@ declare const renderedFooterMarkers: (html: string) => RenderedFooterMarkers;
|
|
|
72
69
|
declare const withoutUnsubscribeRow: (rendered: {
|
|
73
70
|
readonly html?: string | undefined;
|
|
74
71
|
readonly text?: string | undefined;
|
|
75
|
-
}) => {
|
|
72
|
+
}, plugin?: BrandPlugin) => {
|
|
76
73
|
readonly html: string | undefined;
|
|
77
74
|
readonly text: string | undefined;
|
|
78
75
|
};
|
|
@@ -114,5 +111,5 @@ declare const isExternalAsset: (reference: string) => boolean;
|
|
|
114
111
|
*/
|
|
115
112
|
declare const checkAssetBase: (base: string) => readonly EmailDiagnostic[];
|
|
116
113
|
//#endregion
|
|
117
|
-
export {
|
|
118
|
-
//# sourceMappingURL=assets-
|
|
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as samvaBrandPlugin, O as BRAND_FOOTER_MARKER, k as UNSUBSCRIBE_LINK, r as escapeAttribute } from "./html-DjPxwjLi.js";
|
|
2
2
|
import { a as jsx, n as Fragment } from "./jsx-runtime-CBlexoeR.js";
|
|
3
3
|
//#region src/email/assets.ts
|
|
4
4
|
/** Files a template may import, and what they are served as. */
|
|
@@ -61,10 +61,6 @@ const checkAssetBase = (base) => /^(https:\/\/|\.{1,2}\/|\/)/i.test(base) ? [] :
|
|
|
61
61
|
}];
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/email/brand.ts
|
|
64
|
-
/** Marks the block the send path recognizes as the template's own footer. */
|
|
65
|
-
const FOOTER_ATTRIBUTE = "data-samva-footer";
|
|
66
|
-
/** Marks the footer row that carries the unsubscribe link. */
|
|
67
|
-
const UNSUBSCRIBE_ROW_ATTRIBUTE = "data-samva-unsubscribe";
|
|
68
64
|
/** Every class the brand components use, compiled for any project that imports them. */
|
|
69
65
|
const BRAND_COMPONENT_CLASSES = [
|
|
70
66
|
"dark:hidden!",
|
|
@@ -97,8 +93,8 @@ const row = (children, props = {}) => jsx("tr", {
|
|
|
97
93
|
children
|
|
98
94
|
})
|
|
99
95
|
});
|
|
100
|
-
/** Bind `BrandLogo` and `BrandFooter` to one brand. */
|
|
101
|
-
const brandComponents = (brand) => {
|
|
96
|
+
/** Bind `BrandLogo` and `BrandFooter` to one brand, marked as the plugin names. */
|
|
97
|
+
const brandComponents = (brand, plugin = samvaBrandPlugin) => {
|
|
102
98
|
const assets = brand.assets ?? {};
|
|
103
99
|
const footer = brand.footer ?? {};
|
|
104
100
|
const BrandLogo = ({ width = 120, alt, align, className }) => {
|
|
@@ -145,8 +141,8 @@ const brandComponents = (brand) => {
|
|
|
145
141
|
className: "text-gray-500 underline",
|
|
146
142
|
children: link.label
|
|
147
143
|
})])));
|
|
148
|
-
rows.push(row(unsubscribeLink(unsubscribeLabel), {
|
|
149
|
-
[
|
|
144
|
+
rows.push(row(unsubscribeLink(unsubscribeLabel, plugin), {
|
|
145
|
+
[plugin.unsubscribeRowAttribute]: "",
|
|
150
146
|
[BRAND_FOOTER_MARKER]: true
|
|
151
147
|
}));
|
|
152
148
|
return jsx("table", {
|
|
@@ -155,7 +151,7 @@ const brandComponents = (brand) => {
|
|
|
155
151
|
border: 0,
|
|
156
152
|
cellpadding: 0,
|
|
157
153
|
cellspacing: 0,
|
|
158
|
-
[
|
|
154
|
+
[plugin.footerAttribute]: "",
|
|
159
155
|
[BRAND_FOOTER_MARKER]: true,
|
|
160
156
|
children: jsx("tbody", { children: jsx("tr", { children: jsx("td", {
|
|
161
157
|
align: "center",
|
|
@@ -178,31 +174,29 @@ const brandComponents = (brand) => {
|
|
|
178
174
|
};
|
|
179
175
|
/**
|
|
180
176
|
* The unsubscribe link. Its href is the placeholder, which no author-written
|
|
181
|
-
* link may carry: the serializer accepts it only on this node, and
|
|
182
|
-
* click tracking never rewrites it.
|
|
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.
|
|
183
179
|
*/
|
|
184
|
-
const unsubscribeLink = (label) => jsx("a", {
|
|
185
|
-
href:
|
|
180
|
+
const unsubscribeLink = (label, plugin) => jsx("a", {
|
|
181
|
+
href: plugin.unsubscribeUrlPlaceholder,
|
|
186
182
|
className: "text-gray-500 underline",
|
|
187
183
|
[UNSUBSCRIBE_LINK]: true,
|
|
188
184
|
children: label
|
|
189
185
|
});
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
footer: html.includes(`${FOOTER_ATTRIBUTE}=""`),
|
|
195
|
-
unsubscribeLink: html.includes(UNSUBSCRIBE_HREF)
|
|
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)}"`)
|
|
196
190
|
});
|
|
197
191
|
/**
|
|
198
192
|
* Drop the unsubscribe row from a rendered message, for a send that resolved
|
|
199
193
|
* no unsubscribe group: there is no link to put there, so the row goes.
|
|
200
194
|
*/
|
|
201
|
-
const withoutUnsubscribeRow = (rendered) => ({
|
|
202
|
-
html: rendered.html?.replace(
|
|
203
|
-
text: rendered.text?.split("\n").filter((line) => !line.includes(
|
|
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")
|
|
204
198
|
});
|
|
205
199
|
//#endregion
|
|
206
|
-
export {
|
|
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 };
|
|
207
201
|
|
|
208
|
-
//# sourceMappingURL=brand-
|
|
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
|
package/dist/brand.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
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";
|
|
2
3
|
import { t as Diagnostic } from "./diagnostic-model-DxthUZBT.js";
|
|
3
4
|
import { Result } from "better-result";
|
|
4
|
-
//#region src/
|
|
5
|
+
//#region src/email/samva-brand-plugin.d.ts
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* unsubscribe
|
|
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.
|
|
9
11
|
*/
|
|
10
|
-
declare const
|
|
12
|
+
declare const samvaBrandPlugin: BrandPlugin;
|
|
11
13
|
//#endregion
|
|
12
14
|
//#region src/theme-css.d.ts
|
|
13
15
|
/** One `@font-face` a brand declares. `src` is the declaration value as authored. */
|
|
@@ -67,8 +69,8 @@ declare const brandForegroundDefaults: (brand: BrandCss) => {
|
|
|
67
69
|
* build compiles the same default and the stored CSS never carries it.
|
|
68
70
|
*/
|
|
69
71
|
declare const brandThemeVariables: (brand: BrandCss) => Readonly<Record<string, string>>;
|
|
70
|
-
/** The stylesheet Tailwind compiles for
|
|
72
|
+
/** The stylesheet Tailwind compiles for the theme's brand import: `brandThemeVariables` and the font faces. */
|
|
71
73
|
declare const brandTailwindCss: (brand: BrandCss) => string;
|
|
72
74
|
//#endregion
|
|
73
|
-
export { ASSET_CONTENT_TYPES, AssetEntry, AssetManifest, BRAND_COLOR_VARIABLE, BRAND_COMPONENT_CLASSES, BRAND_FOREGROUND_VARIABLE, BrandComponents, BrandCss, BrandFontFace, BrandFooterProps, BrandLogoProps, EmailBrand, EmailBrandAddress, EmailBrandAssets, EmailBrandFooter, EmailBrandSocialLink,
|
|
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 };
|
|
74
76
|
//# sourceMappingURL=brand.d.ts.map
|
package/dist/brand.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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-
|
|
3
|
-
import { a as
|
|
4
|
-
export { ASSET_CONTENT_TYPES, BRAND_COLOR_VARIABLE, BRAND_COMPONENT_CLASSES, BRAND_FOREGROUND_VARIABLE,
|
|
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,7 +1,8 @@
|
|
|
1
|
+
import { n as parseBrandSpecifier, t as BrandPlugin } from "./brand-plugin-CHhcei-j.js";
|
|
1
2
|
import { a as TemplateDiagnostic, r as EmailDiagnostic } from "./diagnostics-B-Gym34R.js";
|
|
2
3
|
import { r as EmailNode } from "./jsx-runtime-ylIOnaSf.js";
|
|
3
|
-
import { n as AssetEntry, p as EmailBrand, u as BrandComponents } from "./assets-
|
|
4
|
-
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-
|
|
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";
|
|
5
6
|
import { a as TEMPLATE_NAME_PATTERN, n as EmailContent } from "./template-DMPwxMSq.js";
|
|
6
7
|
import { caniemail } from "caniemail";
|
|
7
8
|
//#region src/email/compatibility.d.ts
|
|
@@ -156,12 +157,14 @@ interface TailwindOutput {
|
|
|
156
157
|
}
|
|
157
158
|
/**
|
|
158
159
|
* What the project theme's `@import`s resolve to, already checked by
|
|
159
|
-
* `resolveThemeImports`: project stylesheets by path, and the brand theme
|
|
160
|
-
*
|
|
160
|
+
* `resolveThemeImports`: project stylesheets by path, and the brand theme the
|
|
161
|
+
* brand plugin's specifier stands for.
|
|
161
162
|
*/
|
|
162
163
|
interface TailwindImports {
|
|
163
164
|
readonly stylesheets: ReadonlyMap<string, string>;
|
|
164
165
|
readonly brandCss?: string | undefined;
|
|
166
|
+
/** Names the brand import; `samvaBrandPlugin` when omitted. */
|
|
167
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
165
168
|
}
|
|
166
169
|
/** Compile the discovered class set into CSS with the pinned Tailwind release. */
|
|
167
170
|
declare const compileTailwind: (candidates: Iterable<string>, options?: TailwindOptions, imports?: TailwindImports) => Promise<TailwindOutput>;
|
|
@@ -182,10 +185,12 @@ interface TransformOptions {
|
|
|
182
185
|
/** `false` compiles no Tailwind at all. */
|
|
183
186
|
readonly tailwind?: TailwindOptions | false | undefined;
|
|
184
187
|
/**
|
|
185
|
-
* The brand
|
|
186
|
-
* imports
|
|
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.
|
|
187
190
|
*/
|
|
188
191
|
readonly brand?: EmailBrand | undefined;
|
|
192
|
+
/** Names the brand import and marks the footer `BrandFooter` renders; `samvaBrandPlugin` when omitted. */
|
|
193
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
189
194
|
}
|
|
190
195
|
interface ProjectTransform {
|
|
191
196
|
readonly assets: readonly AssetEntry[];
|
|
@@ -196,23 +201,15 @@ interface ProjectTransform {
|
|
|
196
201
|
readonly diagnostics: readonly EmailDiagnostic[];
|
|
197
202
|
}
|
|
198
203
|
/**
|
|
199
|
-
* The
|
|
200
|
-
*
|
|
201
|
-
*
|
|
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
|
|
202
207
|
* first here and a refusal from the compile.
|
|
203
208
|
*/
|
|
204
|
-
declare const projectBrandSpecifier: (files: Readonly<Record<string, string | Uint8Array>>, themePath?: string) => string | undefined;
|
|
209
|
+
declare const projectBrandSpecifier: (files: Readonly<Record<string, string | Uint8Array>>, themePath?: string, brandPlugin?: BrandPlugin) => string | undefined;
|
|
205
210
|
/** Read a whole project, then compile the classes its scripts used. */
|
|
206
211
|
declare const transformProject: (files: Readonly<Record<string, string | Uint8Array>>, options: TransformOptions) => Promise<ProjectTransform>;
|
|
207
212
|
//#endregion
|
|
208
|
-
//#region src/email/theme-imports.d.ts
|
|
209
|
-
/** The CSS and TSX specifier a template uses to reach its organization's brand. */
|
|
210
|
-
declare const BRAND_SPECIFIER = "samva:brand";
|
|
211
|
-
/** The brand a `samva:brand` specifier names: `undefined` slug means the default brand. */
|
|
212
|
-
declare const parseBrandSpecifier: (specifier: string) => {
|
|
213
|
-
readonly slug: string | undefined;
|
|
214
|
-
} | undefined;
|
|
215
|
-
//#endregion
|
|
216
213
|
//#region src/email/brand-footer.d.ts
|
|
217
214
|
/** A footer block for the send path to append, and its plain-text tail. */
|
|
218
215
|
interface RenderedBrandFooter {
|
|
@@ -223,15 +220,16 @@ interface RenderedBrandFooter {
|
|
|
223
220
|
* Render `BrandFooter` against a brand on its own, for the send path to
|
|
224
221
|
* append to a message whose template renders no footer of its own. It
|
|
225
222
|
* compiles the same component, styled by the same brand theme, a template
|
|
226
|
-
* would get from
|
|
223
|
+
* would get from its brand import. Without `unsubscribe` the unsubscribe row is
|
|
227
224
|
* left out.
|
|
228
225
|
*/
|
|
229
226
|
declare const renderBrandFooter: (brand: EmailBrand, options: {
|
|
230
227
|
readonly unsubscribe: boolean;
|
|
228
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
231
229
|
}) => Promise<RenderedBrandFooter>;
|
|
232
230
|
/**
|
|
233
|
-
* Render content against a brand as a project whose `theme.css`
|
|
234
|
-
*
|
|
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
|
|
235
233
|
* the classes the content names, `BrandLogo` and `BrandFooter` are bound to the
|
|
236
234
|
* brand, and the render inlines the result. A brand preview renders through
|
|
237
235
|
* this, so it shows what a template importing the brand compiles to.
|
|
@@ -240,7 +238,7 @@ declare const renderBrandSample: (brand: EmailBrand, sample: {
|
|
|
240
238
|
/** Every class the content names; nothing is discovered from source here. */
|
|
241
239
|
readonly classes: readonly string[];
|
|
242
240
|
readonly render: (components: BrandComponents) => EmailContent;
|
|
243
|
-
}) => Promise<RenderedEmail>;
|
|
241
|
+
}, brandPlugin?: BrandPlugin) => Promise<RenderedEmail>;
|
|
244
242
|
//#endregion
|
|
245
243
|
//#region src/sml/lower-project.d.ts
|
|
246
244
|
interface CompiledTemplate {
|
|
@@ -285,12 +283,12 @@ declare const checkTemplateCompatibility: (ir: TemplateIr, fixtures: Readonly<Re
|
|
|
285
283
|
* and the entry's path. Imports of files that are absent are trusted to exist, and the brand,
|
|
286
284
|
* Tailwind and theme are not resolved, so the result holds only findings the source itself owns.
|
|
287
285
|
*/
|
|
288
|
-
declare const checkStaticProfile: (files: string | Readonly<Record<string, string | Uint8Array>>, entry?: string) => readonly TemplateDiagnostic[];
|
|
286
|
+
declare const checkStaticProfile: (files: string | Readonly<Record<string, string | Uint8Array>>, entry?: string, brandPlugin?: BrandPlugin) => readonly TemplateDiagnostic[];
|
|
289
287
|
/**
|
|
290
288
|
* The errors in `after` that `before` did not already have, compared by code and message so a
|
|
291
289
|
* finding that only moved does not count as new.
|
|
292
290
|
*/
|
|
293
291
|
declare const introducedProfileErrors: (before: readonly TemplateDiagnostic[], after: readonly TemplateDiagnostic[]) => readonly TemplateDiagnostic[];
|
|
294
292
|
//#endregion
|
|
295
|
-
export { type Ancestry, type AppliedStyles,
|
|
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 };
|
|
296
294
|
//# sourceMappingURL=compiler.d.ts.map
|