@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.
Files changed (92) hide show
  1. package/AGENTS.md +53 -41
  2. package/CHANGELOG.md +379 -0
  3. package/README.md +6 -6
  4. package/dist/assets-B0yseju_.d.ts +115 -0
  5. package/dist/brand-DTctcDmf.js +202 -0
  6. package/dist/brand-plugin-CHhcei-j.d.ts +32 -0
  7. package/dist/{theme-css.d.ts → brand.d.ts} +15 -4
  8. package/dist/brand.js +4 -0
  9. package/dist/compiler.d.ts +236 -18
  10. package/dist/compiler.js +1315 -13
  11. package/dist/{email/components.js → components-Bl6DT21n.js} +4 -4
  12. package/dist/diagnostic-model-DJtqbETd.js +38 -0
  13. package/dist/diagnostic-model-DxthUZBT.d.ts +31 -0
  14. package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +2 -2
  15. package/dist/diagnostics.d.ts +406 -27
  16. package/dist/diagnostics.js +402 -34
  17. package/dist/edit.d.ts +234 -0
  18. package/dist/{channel-edit.js → edit.js} +341 -3
  19. package/dist/email/jsx-dev-runtime.d.ts +1 -1
  20. package/dist/email/jsx-dev-runtime.js +1 -2
  21. package/dist/email/jsx-runtime.d.ts +1 -1
  22. package/dist/email/jsx-runtime.js +1 -85
  23. package/dist/{email/components.d.ts → email.d.ts} +2 -2
  24. package/dist/email.js +2 -0
  25. package/dist/html-DjPxwjLi.js +1637 -0
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/{cascade-t6kxlgEI.js → ir-De6pTH51.js} +8 -4
  29. package/dist/jsx-runtime-CBlexoeR.js +98 -0
  30. package/dist/{elements-cqldpaJt.d.ts → jsx-runtime-ylIOnaSf.d.ts} +74 -74
  31. package/dist/{profile-BH-OtdDA.js → profile-PUfi3GPH.js} +166 -32
  32. package/dist/{email/render.js → render-D2ht57ZZ.js} +103 -8
  33. package/dist/render-DQKz4Aco.d.ts +548 -0
  34. package/dist/render.d.ts +35 -0
  35. package/dist/render.js +49 -0
  36. package/dist/sms.d.ts +1 -1
  37. package/dist/sms.js +1 -1
  38. package/dist/{template-_QE_rQND.d.ts → template-DMPwxMSq.d.ts} +2 -2
  39. package/dist/{template.js → template-zLUjcwfF.js} +2 -2
  40. package/dist/{theme-css-hFqcPSar.js → theme-css-CEUrDpqq.js} +3 -3
  41. package/dist/whatsapp.d.ts +1 -1
  42. package/dist/whatsapp.js +1 -1
  43. package/generated/contract.json +18 -12
  44. package/generated/reference.md +19 -12
  45. package/package.json +39 -122
  46. package/samva-brand.d.ts +4 -4
  47. package/skills/sml/SKILL.md +2 -2
  48. package/dist/assets-C5duwTya.d.ts +0 -40
  49. package/dist/brand-B-0bN_Ir.d.ts +0 -88
  50. package/dist/channel-edit.d.ts +0 -121
  51. package/dist/channel-specs-B6M_HlaV.js +0 -29
  52. package/dist/compatibility-DbISoFIq.js +0 -589
  53. package/dist/css-BVQKICKC.d.ts +0 -109
  54. package/dist/diagnostic-codes.d.ts +0 -403
  55. package/dist/diagnostic-codes.js +0 -399
  56. package/dist/email/assets.d.ts +0 -2
  57. package/dist/email/assets.js +0 -63
  58. package/dist/email/brand-footer.d.ts +0 -34
  59. package/dist/email/brand-footer.js +0 -63
  60. package/dist/email/brand.d.ts +0 -2
  61. package/dist/email/brand.js +0 -148
  62. package/dist/email/diagnostics.d.ts +0 -2
  63. package/dist/email/elements.d.ts +0 -2
  64. package/dist/email/elements.js +0 -299
  65. package/dist/email/html.d.ts +0 -2
  66. package/dist/email/html.js +0 -321
  67. package/dist/email/render.d.ts +0 -40
  68. package/dist/email/text.d.ts +0 -7
  69. package/dist/email/text.js +0 -100
  70. package/dist/html-BJepOwZ4.d.ts +0 -56
  71. package/dist/ir-aaqNE987.d.ts +0 -252
  72. package/dist/ir.d.ts +0 -2
  73. package/dist/ir.js +0 -7
  74. package/dist/preview-Ekdg1dXG.d.ts +0 -100
  75. package/dist/preview.d.ts +0 -2
  76. package/dist/preview.js +0 -160
  77. package/dist/render-ir.d.ts +0 -19
  78. package/dist/render-ir.js +0 -826
  79. package/dist/sms-segments.d.ts +0 -13
  80. package/dist/sms-segments.js +0 -46
  81. package/dist/source-edit.d.ts +0 -116
  82. package/dist/source-edit.js +0 -343
  83. package/dist/source-locations.d.ts +0 -2
  84. package/dist/source-locations.js +0 -16
  85. package/dist/static.d.ts +0 -57
  86. package/dist/static.js +0 -69
  87. package/dist/tailwind-CMYpZf1v.js +0 -614
  88. package/dist/template.d.ts +0 -2
  89. package/dist/theme-css.js +0 -2
  90. package/dist/theme-imports-lvBw3AD1.js +0 -109
  91. package/dist/transform-Ct2OMkFN.d.ts +0 -153
  92. package/dist/unsubscribe-link-CoesnQDU.js +0 -26
@@ -1,148 +0,0 @@
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,2 +0,0 @@
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 };
@@ -1,2 +0,0 @@
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
- export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
@@ -1,299 +0,0 @@
1
- //#region src/email/elements.ts
2
- /** Attributes every supported element accepts. `class`/`className`/`style` are handled separately. */
3
- const EMAIL_GLOBAL_ATTRIBUTES = {
4
- id: { type: "string" },
5
- title: { type: "string" },
6
- lang: { type: "string" },
7
- dir: {
8
- type: "string",
9
- values: [
10
- "ltr",
11
- "rtl",
12
- "auto"
13
- ]
14
- },
15
- role: { type: "string" }
16
- };
17
- const alignment = {
18
- type: "string",
19
- values: [
20
- "left",
21
- "center",
22
- "right"
23
- ]
24
- };
25
- const verticalAlignment = {
26
- type: "string",
27
- values: [
28
- "top",
29
- "middle",
30
- "bottom"
31
- ]
32
- };
33
- const flowAttributes = { align: alignment };
34
- const cellAttributes = {
35
- align: alignment,
36
- valign: verticalAlignment,
37
- width: { type: "measure" },
38
- height: { type: "measure" },
39
- bgcolor: { type: "string" },
40
- colspan: { type: "number" },
41
- rowspan: { type: "number" }
42
- };
43
- const block = (attributes) => ({
44
- content: "flow",
45
- layout: "block",
46
- attributes
47
- });
48
- const inline = () => ({
49
- content: "flow",
50
- layout: "inline",
51
- attributes: {}
52
- });
53
- /** The complete supported vocabulary. Anything outside it is a compile error with a source location. */
54
- const EMAIL_ELEMENTS = {
55
- html: {
56
- content: "flow",
57
- layout: "document",
58
- attributes: {
59
- xmlns: { type: "string" },
60
- "xmlns:o": { type: "string" },
61
- "xmlns:v": { type: "string" },
62
- "xmlns:w": { type: "string" }
63
- },
64
- childElements: ["head", "body"]
65
- },
66
- head: {
67
- content: "flow",
68
- layout: "metadata",
69
- attributes: {},
70
- childElements: [
71
- "title",
72
- "meta",
73
- "style"
74
- ]
75
- },
76
- title: {
77
- content: "text",
78
- layout: "metadata",
79
- attributes: {}
80
- },
81
- style: {
82
- content: "raw",
83
- layout: "metadata",
84
- attributes: { type: { type: "string" } }
85
- },
86
- meta: {
87
- content: "void",
88
- layout: "metadata",
89
- attributes: {
90
- name: { type: "string" },
91
- content: { type: "string" },
92
- charset: { type: "string" },
93
- "http-equiv": { type: "string" }
94
- }
95
- },
96
- body: {
97
- content: "flow",
98
- layout: "block",
99
- attributes: { bgcolor: { type: "string" } }
100
- },
101
- div: block(flowAttributes),
102
- section: block(flowAttributes),
103
- article: block(flowAttributes),
104
- header: block(flowAttributes),
105
- footer: block(flowAttributes),
106
- main: block(flowAttributes),
107
- center: block({}),
108
- p: block(flowAttributes),
109
- blockquote: block(flowAttributes),
110
- pre: {
111
- content: "flow",
112
- layout: "preformatted",
113
- attributes: {}
114
- },
115
- h1: block(flowAttributes),
116
- h2: block(flowAttributes),
117
- h3: block(flowAttributes),
118
- h4: block(flowAttributes),
119
- h5: block(flowAttributes),
120
- h6: block(flowAttributes),
121
- span: inline(),
122
- strong: inline(),
123
- b: inline(),
124
- em: inline(),
125
- i: inline(),
126
- u: inline(),
127
- s: inline(),
128
- small: inline(),
129
- code: inline(),
130
- a: {
131
- content: "flow",
132
- layout: "link",
133
- attributes: {
134
- href: {
135
- type: "url",
136
- required: true
137
- },
138
- target: { type: "string" },
139
- rel: { type: "string" },
140
- name: { type: "string" }
141
- }
142
- },
143
- img: {
144
- content: "void",
145
- layout: "image",
146
- attributes: {
147
- src: {
148
- type: "url",
149
- required: true
150
- },
151
- alt: {
152
- type: "string",
153
- required: true
154
- },
155
- width: { type: "measure" },
156
- height: { type: "measure" },
157
- border: { type: "measure" },
158
- align: alignment
159
- }
160
- },
161
- table: {
162
- content: "flow",
163
- layout: "table",
164
- attributes: {
165
- width: { type: "measure" },
166
- height: { type: "measure" },
167
- border: { type: "measure" },
168
- cellpadding: { type: "measure" },
169
- cellspacing: { type: "measure" },
170
- align: alignment,
171
- bgcolor: { type: "string" }
172
- },
173
- childElements: [
174
- "caption",
175
- "colgroup",
176
- "thead",
177
- "tbody",
178
- "tfoot",
179
- "tr"
180
- ]
181
- },
182
- caption: {
183
- content: "flow",
184
- layout: "block",
185
- attributes: flowAttributes
186
- },
187
- colgroup: {
188
- content: "flow",
189
- layout: "table-section",
190
- attributes: {
191
- span: { type: "number" },
192
- width: { type: "measure" }
193
- },
194
- childElements: ["col"]
195
- },
196
- col: {
197
- content: "void",
198
- layout: "table-section",
199
- attributes: {
200
- span: { type: "number" },
201
- width: { type: "measure" }
202
- }
203
- },
204
- thead: {
205
- content: "flow",
206
- layout: "table-section",
207
- attributes: {
208
- align: alignment,
209
- valign: verticalAlignment,
210
- bgcolor: { type: "string" }
211
- },
212
- childElements: ["tr"]
213
- },
214
- tbody: {
215
- content: "flow",
216
- layout: "table-section",
217
- attributes: {
218
- align: alignment,
219
- valign: verticalAlignment,
220
- bgcolor: { type: "string" }
221
- },
222
- childElements: ["tr"]
223
- },
224
- tfoot: {
225
- content: "flow",
226
- layout: "table-section",
227
- attributes: {
228
- align: alignment,
229
- valign: verticalAlignment,
230
- bgcolor: { type: "string" }
231
- },
232
- childElements: ["tr"]
233
- },
234
- tr: {
235
- content: "flow",
236
- layout: "row",
237
- attributes: {
238
- align: alignment,
239
- valign: verticalAlignment,
240
- bgcolor: { type: "string" },
241
- height: { type: "measure" }
242
- },
243
- childElements: ["td", "th"]
244
- },
245
- td: {
246
- content: "flow",
247
- layout: "cell",
248
- attributes: cellAttributes
249
- },
250
- th: {
251
- content: "flow",
252
- layout: "cell",
253
- attributes: cellAttributes
254
- },
255
- ul: {
256
- content: "flow",
257
- layout: "list",
258
- attributes: {},
259
- childElements: ["li"]
260
- },
261
- ol: {
262
- content: "flow",
263
- layout: "list",
264
- attributes: {
265
- start: { type: "number" },
266
- type: { type: "string" }
267
- },
268
- childElements: ["li"]
269
- },
270
- li: {
271
- content: "flow",
272
- layout: "list-item",
273
- attributes: {}
274
- },
275
- br: {
276
- content: "void",
277
- layout: "break",
278
- attributes: {}
279
- },
280
- hr: {
281
- content: "void",
282
- layout: "rule",
283
- attributes: {
284
- width: { type: "measure" },
285
- size: { type: "number" },
286
- align: alignment
287
- }
288
- }
289
- };
290
- /** Attributes that must carry a URL; these are checked against the safe-scheme rule. */
291
- const isUrlAttribute = (tag, attribute) => {
292
- return EMAIL_ELEMENTS[tag]?.attributes[attribute]?.type === "url";
293
- };
294
- /** Look up one supported element, or `undefined` when the tag is outside the vocabulary. */
295
- const emailElement = (tag) => Object.hasOwn(EMAIL_ELEMENTS, tag) ? EMAIL_ELEMENTS[tag] : void 0;
296
- //#endregion
297
- export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement, isUrlAttribute };
298
-
299
- //# sourceMappingURL=elements.js.map
@@ -1,2 +0,0 @@
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 };