@samva/markup 0.12.0 → 0.13.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/CHANGELOG.md +20 -0
- package/dist/{brand-DTctcDmf.js → brand-C45QBKX9.js} +1 -1
- package/dist/brand.js +2 -2
- package/dist/compiler.d.ts +1 -1
- package/dist/compiler.js +6 -6
- package/dist/{components-Bl6DT21n.js → components-DycSEKva.js} +1 -1
- package/dist/{diagnostic-codes-BduqCv_h.js → diagnostic-codes-DdZ4tka5.js} +10 -0
- package/dist/diagnostics.d.ts +6 -0
- package/dist/diagnostics.js +1 -1
- package/dist/edit.d.ts +2 -3
- package/dist/edit.js +5 -8
- package/dist/email.js +1 -1
- package/dist/{html-DjPxwjLi.js → html-eOZfDwVf.js} +0 -1
- package/dist/{ir-De6pTH51.js → ir-C-ubz6N3.js} +1 -1
- package/dist/{profile-CWZ2kkt-.js → profile-CXnkfEMi.js} +19 -15
- package/dist/{render-C28ucTh8.d.ts → render-C6OTH8BQ.d.ts} +0 -2
- package/dist/{render-BVW-ESn-.js → render-Cja448i0.js} +3 -3
- package/dist/render.d.ts +1 -1
- package/dist/render.js +3 -3
- package/dist/whatsapp.d.ts +0 -1
- package/generated/contract.json +8 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## @samva/markup@0.13.1
|
|
2
|
+
|
|
3
|
+
### The authoring reference omits channel-only upgrade recipes
|
|
4
|
+
|
|
5
|
+
`generated/reference.md` lists upgrade recipes only for diagnostics that apply to every template,
|
|
6
|
+
matching its diagnostics table and `contract.json`. The `whatsapp-template-name` recipe stays in the
|
|
7
|
+
diagnostic codes, where an agent migrating a WhatsApp template reads it.
|
|
8
|
+
|
|
9
|
+
## @samva/markup@0.13.0
|
|
10
|
+
|
|
11
|
+
### Meta's WhatsApp template name comes from the template's handle
|
|
12
|
+
|
|
13
|
+
`<WhatsApp>` no longer takes `name`. Samva registers each WhatsApp template with Meta under its
|
|
14
|
+
handle, so an authored name could only disagree with it. A template that still sets `name` fails
|
|
15
|
+
with `whatsapp-template-name`, which carries an upgrade recipe: remove the attribute.
|
|
16
|
+
|
|
17
|
+
`WhatsAppProps`, `IrWhatsApp`, `RenderedIrWhatsApp`, `WhatsAppChannelForm` and the editor host's
|
|
18
|
+
`WhatsAppRender` drop `name`. A `WhatsAppEdit` attribute edit names only `language` or `category`,
|
|
19
|
+
with a string value. The WhatsApp workspace no longer shows a Template name field.
|
|
20
|
+
|
|
1
21
|
## @samva/markup@0.11.4
|
|
2
22
|
|
|
3
23
|
### Diagnostics carry their upgrade recipe
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as samvaBrandPlugin, O as BRAND_FOOTER_MARKER, k as UNSUBSCRIBE_LINK, r as escapeAttribute } from "./html-
|
|
1
|
+
import { D as samvaBrandPlugin, O as BRAND_FOOTER_MARKER, k as UNSUBSCRIBE_LINK, r as escapeAttribute } from "./html-eOZfDwVf.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. */
|
package/dist/brand.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as samvaBrandPlugin } from "./html-
|
|
1
|
+
import { D as samvaBrandPlugin } from "./html-eOZfDwVf.js";
|
|
2
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-
|
|
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-C45QBKX9.js";
|
|
4
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
|
@@ -2,7 +2,7 @@ import { n as parseBrandSpecifier, t as BrandPlugin } from "./brand-plugin-CHhce
|
|
|
2
2
|
import { a as TemplateDiagnostic, r as EmailDiagnostic } from "./diagnostics-CUYlQ_6x.js";
|
|
3
3
|
import { r as EmailNode } from "./jsx-runtime-DC7xG0aA.js";
|
|
4
4
|
import { n as AssetEntry, p as EmailBrand, u as BrandComponents } from "./assets-DCULM6QD.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-
|
|
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-C6OTH8BQ.js";
|
|
6
6
|
import { a as TEMPLATE_NAME_PATTERN, n as EmailContent } from "./template-B-UDXK8a.js";
|
|
7
7
|
import { caniemail } from "caniemail";
|
|
8
8
|
//#region src/email/compatibility.d.ts
|
package/dist/compiler.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as isObject } from "./guards-eV1qLbf2.js";
|
|
2
2
|
import { n as TEMPLATE_NAME_PATTERN } from "./template-zLUjcwfF.js";
|
|
3
|
-
import { D as samvaBrandPlugin, T as parseBrandSpecifier, _ as renderIr, w as brandSpecifierPattern } from "./html-
|
|
3
|
+
import { D as samvaBrandPlugin, T as parseBrandSpecifier, _ as renderIr, w as brandSpecifierPattern } from "./html-eOZfDwVf.js";
|
|
4
4
|
import { c as parseBrandCss, d as formatColor, f as parseColor, i as brandTailwindCss, u as downlevelColors } from "./theme-css-CEUrDpqq.js";
|
|
5
|
-
import { a as downlevelMediaQuery, c as renderHeadCss, i as matchesSelector, l as resolveVariables, n as applyStylesheet, o as finalizeValue, r as classListOf, s as foldCalc, u as unquote } from "./ir-
|
|
6
|
-
import { i as buildLineMap, s as lineColumn } from "./diagnostic-codes-
|
|
7
|
-
import { a as lowerProject, d as resolveFromDirectory, f as resolveThemeImports, i as completed, l as Findings, n as introducedProfileErrors, r as loadProject, t as checkStaticProfile, u as projectDirectory } from "./profile-
|
|
8
|
-
import { c as checkAssetBase, i as withoutUnsubscribeRow, l as isAssetPath, n as brandComponents, o as assetEntry, s as assetUrl, t as BRAND_COMPONENT_CLASSES } from "./brand-
|
|
5
|
+
import { a as downlevelMediaQuery, c as renderHeadCss, i as matchesSelector, l as resolveVariables, n as applyStylesheet, o as finalizeValue, r as classListOf, s as foldCalc, u as unquote } from "./ir-C-ubz6N3.js";
|
|
6
|
+
import { i as buildLineMap, s as lineColumn } from "./diagnostic-codes-DdZ4tka5.js";
|
|
7
|
+
import { a as lowerProject, d as resolveFromDirectory, f as resolveThemeImports, i as completed, l as Findings, n as introducedProfileErrors, r as loadProject, t as checkStaticProfile, u as projectDirectory } from "./profile-CXnkfEMi.js";
|
|
8
|
+
import { c as checkAssetBase, i as withoutUnsubscribeRow, l as isAssetPath, n as brandComponents, o as assetEntry, s as assetUrl, t as BRAND_COMPONENT_CLASSES } from "./brand-C45QBKX9.js";
|
|
9
9
|
import { t as EmailCompileError } from "./diagnostics-C0Tr8-eQ.js";
|
|
10
|
-
import { n as compileEmail, r as renderEmailContent } from "./render-
|
|
10
|
+
import { n as compileEmail, r as renderEmailContent } from "./render-Cja448i0.js";
|
|
11
11
|
import { caniemail, parseHtml, rawData } from "caniemail";
|
|
12
12
|
import { generate, ident, parse, walk } from "css-tree";
|
|
13
13
|
import { parse as parse$1 } from "@babel/parser";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as escapeText, r as escapeAttribute } from "./html-
|
|
1
|
+
import { i as escapeText, r as escapeAttribute } from "./html-eOZfDwVf.js";
|
|
2
2
|
import { a as jsx, c as rawMarkup, l as reportEmailDiagnostic, n as Fragment, s as normalizeChildren, t as EmailNode } from "./jsx-runtime-CBlexoeR.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. */
|
|
@@ -385,6 +385,16 @@ const DIAGNOSTIC_CODES = codes({
|
|
|
385
385
|
fix: "Write text and bindings, with a newline for a line break.",
|
|
386
386
|
channelOnly: true
|
|
387
387
|
},
|
|
388
|
+
"whatsapp-template-name": {
|
|
389
|
+
summary: "A <WhatsApp> names its Meta template; the name comes from the template's handle.",
|
|
390
|
+
fix: "Remove `name` from <WhatsApp>.",
|
|
391
|
+
upgrade: [
|
|
392
|
+
"Remove the `name` attribute from every <WhatsApp> element in the project, templates and partials alike. Samva registers each WhatsApp template with Meta under its handle, with hyphens as underscores, so the attribute has no replacement. Change nothing else.",
|
|
393
|
+
"If an authored name differs from the name the handle produces and the template is already registered with Meta under it, tell the user: keeping that Meta name means renaming the template's handle, which you do not do yourself.",
|
|
394
|
+
"Compile each entry and render every declared fixture to confirm the WhatsApp output is otherwise unchanged. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish."
|
|
395
|
+
].join("\n\n"),
|
|
396
|
+
channelOnly: true
|
|
397
|
+
},
|
|
388
398
|
"whatsapp-structure": {
|
|
389
399
|
summary: "WhatsApp content sits outside Header, Body, Footer or Buttons.",
|
|
390
400
|
fix: "Move it into <WhatsApp.Body>.",
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -354,6 +354,12 @@ declare const DIAGNOSTIC_CODES: {
|
|
|
354
354
|
readonly fix: "Write text and bindings, with a newline for a line break.";
|
|
355
355
|
readonly channelOnly: true;
|
|
356
356
|
};
|
|
357
|
+
readonly "whatsapp-template-name": {
|
|
358
|
+
readonly summary: "A <WhatsApp> names its Meta template; the name comes from the template's handle.";
|
|
359
|
+
readonly fix: "Remove `name` from <WhatsApp>.";
|
|
360
|
+
readonly upgrade: string;
|
|
361
|
+
readonly channelOnly: true;
|
|
362
|
+
};
|
|
357
363
|
readonly "whatsapp-structure": {
|
|
358
364
|
readonly summary: "WhatsApp content sits outside Header, Body, Footer or Buttons.";
|
|
359
365
|
readonly fix: "Move it into <WhatsApp.Body>.";
|
package/dist/diagnostics.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as createDiagnosticFormatter, i as buildLineMap, n as DIAGNOSTIC_CODE_FAMILIES, o as formatDiagnostic, r as hasUpgradeRecipe, s as lineColumn, t as DIAGNOSTIC_CODES } from "./diagnostic-codes-
|
|
1
|
+
import { a as createDiagnosticFormatter, i as buildLineMap, n as DIAGNOSTIC_CODE_FAMILIES, o as formatDiagnostic, r as hasUpgradeRecipe, s as lineColumn, t as DIAGNOSTIC_CODES } from "./diagnostic-codes-DdZ4tka5.js";
|
|
2
2
|
import { n as formatEmailDiagnostic, r as hasBlockingDiagnostic, t as EmailCompileError } from "./diagnostics-C0Tr8-eQ.js";
|
|
3
3
|
export { DIAGNOSTIC_CODES, DIAGNOSTIC_CODE_FAMILIES, EmailCompileError, buildLineMap, createDiagnosticFormatter, formatDiagnostic, formatEmailDiagnostic, hasBlockingDiagnostic, hasUpgradeRecipe, lineColumn };
|
package/dist/edit.d.ts
CHANGED
|
@@ -161,7 +161,6 @@ type WhatsAppButtonRow = {
|
|
|
161
161
|
readonly summary: string;
|
|
162
162
|
};
|
|
163
163
|
interface WhatsAppChannelForm {
|
|
164
|
-
readonly name: AttributeState;
|
|
165
164
|
readonly language: AttributeState;
|
|
166
165
|
readonly category: AttributeState;
|
|
167
166
|
/** Null when the template has no header. */
|
|
@@ -191,8 +190,8 @@ type SmsEdit = {
|
|
|
191
190
|
type WhatsAppPart = "header" | "body" | "footer";
|
|
192
191
|
type WhatsAppEdit = {
|
|
193
192
|
readonly kind: "attribute";
|
|
194
|
-
readonly name: "
|
|
195
|
-
readonly value: string
|
|
193
|
+
readonly name: "language" | "category";
|
|
194
|
+
readonly value: string;
|
|
196
195
|
} | {
|
|
197
196
|
readonly kind: "headerType";
|
|
198
197
|
readonly value: WhatsAppHeaderType;
|
package/dist/edit.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as isObject } from "./guards-eV1qLbf2.js";
|
|
2
2
|
import { d as completeJsxSourceLocation, u as JSX_SOURCE_LOCATION_PROP } from "./jsx-runtime-CBlexoeR.js";
|
|
3
|
-
import { i as buildLineMap } from "./diagnostic-codes-
|
|
4
|
-
import { c as WHATSAPP_HEADER_TYPES, n as introducedProfileErrors, o as SMS_CATEGORIES, s as WHATSAPP_CATEGORIES, t as checkStaticProfile } from "./profile-
|
|
3
|
+
import { i as buildLineMap } from "./diagnostic-codes-DdZ4tka5.js";
|
|
4
|
+
import { c as WHATSAPP_HEADER_TYPES, n as introducedProfileErrors, o as SMS_CATEGORIES, s as WHATSAPP_CATEGORIES, t as checkStaticProfile } from "./profile-CXnkfEMi.js";
|
|
5
5
|
import { parse } from "@babel/parser";
|
|
6
6
|
//#region src/source-edit.ts
|
|
7
7
|
const node = (value) => isObject(value) && "type" in value && typeof value.type === "string" && "start" in value && typeof value.start === "number" && "end" in value && typeof value.end === "number";
|
|
@@ -806,7 +806,6 @@ const readWhatsAppChannel = (source) => {
|
|
|
806
806
|
if (channel === null || channel.body === null) return null;
|
|
807
807
|
const { root } = channel;
|
|
808
808
|
return {
|
|
809
|
-
name: attributeState(source, root, "name"),
|
|
810
809
|
language: attributeState(source, root, "language"),
|
|
811
810
|
category: attributeState(source, root, "category"),
|
|
812
811
|
header: channel.header === null ? null : segmentsOf(source, channel.header),
|
|
@@ -856,14 +855,12 @@ const editWhatsAppChannel = (source, edit) => {
|
|
|
856
855
|
};
|
|
857
856
|
const { root, local } = channel;
|
|
858
857
|
switch (edit.kind) {
|
|
859
|
-
case "attribute":
|
|
860
|
-
if (edit.name === "category" && !WHATSAPP_CATEGORIES.includes(edit.value
|
|
858
|
+
case "attribute":
|
|
859
|
+
if (edit.name === "category" && !WHATSAPP_CATEGORIES.includes(edit.value)) return {
|
|
861
860
|
ok: false,
|
|
862
861
|
reason: "Choose a WhatsApp category."
|
|
863
862
|
};
|
|
864
|
-
|
|
865
|
-
return setAttribute(source, root, edit.name, value);
|
|
866
|
-
}
|
|
863
|
+
return setAttribute(source, root, edit.name, edit.value);
|
|
867
864
|
case "headerType":
|
|
868
865
|
if (channel.header === null) return {
|
|
869
866
|
ok: false,
|
package/dist/email.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Email, c as PREHEADER_ATTRIBUTE, d as equalColumnWidth, f as preheaderNode, i as Divider, l as Section, n as Column, o as Image, r as Columns, s as Link, t as Button, u as Spacer } from "./components-
|
|
1
|
+
import { a as Email, c as PREHEADER_ATTRIBUTE, d as equalColumnWidth, f as preheaderNode, i as Divider, l as Section, n as Column, o as Image, r as Columns, s as Link, t as Button, u as Spacer } from "./components-DycSEKva.js";
|
|
2
2
|
export { Button, Column, Columns, Divider, Email, Image, Link, PREHEADER_ATTRIBUTE, Section, Spacer, equalColumnWidth, preheaderNode };
|
|
@@ -1157,7 +1157,6 @@ const renderIrWhatsApp = (ir, input, options = {}) => {
|
|
|
1157
1157
|
resolveButtons(ctx, whatsapp.buttons ?? [], buttons, 0);
|
|
1158
1158
|
settle(ctx);
|
|
1159
1159
|
return {
|
|
1160
|
-
...whatsapp.name === void 0 ? {} : { name: whatsapp.name },
|
|
1161
1160
|
language: whatsapp.language,
|
|
1162
1161
|
category: whatsapp.category,
|
|
1163
1162
|
...header === void 0 ? {} : { header },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as isObject } from "./guards-eV1qLbf2.js";
|
|
2
|
-
import { a as kebab, n as declarationValue, r as escapeAttribute } from "./html-
|
|
2
|
+
import { a as kebab, n as declarationValue, r as escapeAttribute } from "./html-eOZfDwVf.js";
|
|
3
3
|
import { t as EmailNode } from "./jsx-runtime-CBlexoeR.js";
|
|
4
4
|
//#region src/email/font-stacks.ts
|
|
5
5
|
/** Generic families every email client understands as the last resort in a stack. */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as isObject } from "./guards-eV1qLbf2.js";
|
|
2
2
|
import { n as inputSchema, r as jsonSchema } from "./input-schema-zjkgrXn2.js";
|
|
3
3
|
import { n as TEMPLATE_NAME_PATTERN, t as TEMPLATE_ID_PATTERN } from "./template-zLUjcwfF.js";
|
|
4
|
-
import { D as samvaBrandPlugin, E as reservedBrandAttributes, O as BRAND_FOOTER_MARKER, S as emailElement, T as parseBrandSpecifier, b as EMAIL_ELEMENTS, s as serializeStyle, t as checkAttribute } from "./html-
|
|
4
|
+
import { D as samvaBrandPlugin, E as reservedBrandAttributes, O as BRAND_FOOTER_MARKER, S as emailElement, T as parseBrandSpecifier, b as EMAIL_ELEMENTS, s as serializeStyle, t as checkAttribute } from "./html-eOZfDwVf.js";
|
|
5
5
|
import { FORMATTER_NAMES } from "./fmt.js";
|
|
6
6
|
import { i as drainEmailDiagnostics, t as EmailNode } from "./jsx-runtime-CBlexoeR.js";
|
|
7
|
-
import { a as Email, d as equalColumnWidth, i as Divider, l as Section, n as Column, o as Image, r as Columns, s as Link, t as Button, u as Spacer } from "./components-
|
|
8
|
-
import { n as applyStylesheet } from "./ir-
|
|
9
|
-
import { i as buildLineMap, s as lineColumn, t as DIAGNOSTIC_CODES } from "./diagnostic-codes-
|
|
10
|
-
import { l as isAssetPath, n as brandComponents } from "./brand-
|
|
7
|
+
import { a as Email, d as equalColumnWidth, i as Divider, l as Section, n as Column, o as Image, r as Columns, s as Link, t as Button, u as Spacer } from "./components-DycSEKva.js";
|
|
8
|
+
import { n as applyStylesheet } from "./ir-C-ubz6N3.js";
|
|
9
|
+
import { i as buildLineMap, s as lineColumn, t as DIAGNOSTIC_CODES } from "./diagnostic-codes-DdZ4tka5.js";
|
|
10
|
+
import { l as isAssetPath, n as brandComponents } from "./brand-C45QBKX9.js";
|
|
11
11
|
import { parse } from "css-tree";
|
|
12
12
|
import { parse as parse$1 } from "@babel/parser";
|
|
13
13
|
//#region src/email/theme-imports.ts
|
|
@@ -284,11 +284,7 @@ const WHATSAPP_HEADER_TYPES = [
|
|
|
284
284
|
/** The attributes `<Sms>` accepts. */
|
|
285
285
|
const SMS_ATTRIBUTES = ["category"];
|
|
286
286
|
/** The attributes `<WhatsApp>` accepts. */
|
|
287
|
-
const WHATSAPP_ATTRIBUTES = [
|
|
288
|
-
"name",
|
|
289
|
-
"language",
|
|
290
|
-
"category"
|
|
291
|
-
];
|
|
287
|
+
const WHATSAPP_ATTRIBUTES = ["language", "category"];
|
|
292
288
|
//#endregion
|
|
293
289
|
//#region src/whatsapp-template.ts
|
|
294
290
|
const isConcat = (value) => typeof value === "object" && value !== null && "concat" in value;
|
|
@@ -2545,8 +2541,13 @@ const readRoot = (input, field, imported, specifier) => {
|
|
|
2545
2541
|
local: tag
|
|
2546
2542
|
};
|
|
2547
2543
|
};
|
|
2548
|
-
/**
|
|
2549
|
-
const
|
|
2544
|
+
/** Meta's template name is not authored: Samva registers the template under its handle. */
|
|
2545
|
+
const WHATSAPP_REFUSED = { name: {
|
|
2546
|
+
code: "whatsapp-template-name",
|
|
2547
|
+
message: "Meta's name for a WhatsApp template comes from the template's handle, not from <WhatsApp>.",
|
|
2548
|
+
fix: "Remove `name`; rename the template's handle to change its Meta name."
|
|
2549
|
+
} };
|
|
2550
|
+
const readAttributes = (input, root, allowed, refused = {}) => {
|
|
2550
2551
|
const values = /* @__PURE__ */ new Map();
|
|
2551
2552
|
for (const attribute of attributesOf(root.node)) {
|
|
2552
2553
|
if (attribute.type === "JSXSpreadAttribute") {
|
|
@@ -2556,6 +2557,11 @@ const readAttributes = (input, root, allowed) => {
|
|
|
2556
2557
|
const nameNode = child(attribute, "name");
|
|
2557
2558
|
const name = nameNode === void 0 ? "" : jsxName(nameNode);
|
|
2558
2559
|
if (name === "key") continue;
|
|
2560
|
+
const refusal = Object.hasOwn(refused, name) ? refused[name] : void 0;
|
|
2561
|
+
if (refusal !== void 0) {
|
|
2562
|
+
input.lowerer.error(root.ctx, attribute, refusal.code, refusal.message, refusal.fix);
|
|
2563
|
+
continue;
|
|
2564
|
+
}
|
|
2559
2565
|
if (!allowed.includes(name)) {
|
|
2560
2566
|
input.lowerer.error(root.ctx, attribute, "unknown-attribute", `\`${name}\` is not an attribute of this component.`, `The attributes are ${allowed.join(", ")}.`);
|
|
2561
2567
|
continue;
|
|
@@ -2658,7 +2664,7 @@ const whatsappChannel = (input, field) => {
|
|
|
2658
2664
|
if (root === void 0) return void 0;
|
|
2659
2665
|
const { lowerer } = input;
|
|
2660
2666
|
const { ctx } = root;
|
|
2661
|
-
const attributes = readAttributes(input, root, WHATSAPP_ATTRIBUTES);
|
|
2667
|
+
const attributes = readAttributes(input, root, WHATSAPP_ATTRIBUTES, WHATSAPP_REFUSED);
|
|
2662
2668
|
for (const required of ["category", "language"]) if (!attributes.has(required)) lowerer.error(ctx, root.node, "missing-attribute", `<WhatsApp> needs \`${required}\`.`, required === "category" ? `Write category="utility" (${WHATSAPP_CATEGORIES.join(", ")}).` : "Write language=\"en_US\".");
|
|
2663
2669
|
const category = attributes.get("category");
|
|
2664
2670
|
const categoryNode = attributesOf(root.node).find((attribute) => text(child(attribute, "name") ?? attribute, "name") === "category");
|
|
@@ -2749,9 +2755,7 @@ const whatsappChannel = (input, field) => {
|
|
|
2749
2755
|
}
|
|
2750
2756
|
if (input.schema !== void 0) input.checks.push(...checkBindings(input.schema, roots, []));
|
|
2751
2757
|
if (category === void 0 || !attributes.has("language")) return void 0;
|
|
2752
|
-
const name = attributes.get("name");
|
|
2753
2758
|
return {
|
|
2754
|
-
...name === void 0 ? {} : { name },
|
|
2755
2759
|
category,
|
|
2756
2760
|
language: attributes.get("language"),
|
|
2757
2761
|
...header === void 0 ? {} : { header },
|
|
@@ -176,7 +176,6 @@ type IrWhatsAppButtonNode = IrWhatsAppButton | {
|
|
|
176
176
|
readonly src?: IrSource;
|
|
177
177
|
};
|
|
178
178
|
interface IrWhatsApp {
|
|
179
|
-
readonly name?: string;
|
|
180
179
|
readonly category: string;
|
|
181
180
|
readonly language: string;
|
|
182
181
|
/** For a media header, `content` is the media URL. */
|
|
@@ -247,7 +246,6 @@ type RenderedWhatsAppButton = {
|
|
|
247
246
|
};
|
|
248
247
|
/** A WhatsApp message with every text rendered and every conditional button resolved. */
|
|
249
248
|
interface RenderedIrWhatsApp {
|
|
250
|
-
readonly name?: string;
|
|
251
249
|
readonly language: string;
|
|
252
250
|
readonly category: string;
|
|
253
251
|
/** For a media header, `text` is the media URL. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { S as emailElement, o as serializeEmailHtml } from "./html-
|
|
1
|
+
import { S as emailElement, o as serializeEmailHtml } from "./html-eOZfDwVf.js";
|
|
2
2
|
import { i as drainEmailDiagnostics, t as EmailNode } from "./jsx-runtime-CBlexoeR.js";
|
|
3
|
-
import { f as preheaderNode } from "./components-
|
|
4
|
-
import { n as applyStylesheet } from "./ir-
|
|
3
|
+
import { f as preheaderNode } from "./components-DycSEKva.js";
|
|
4
|
+
import { n as applyStylesheet } from "./ir-C-ubz6N3.js";
|
|
5
5
|
import { r as hasBlockingDiagnostic, t as EmailCompileError } from "./diagnostics-C0Tr8-eQ.js";
|
|
6
6
|
//#region src/email/text.ts
|
|
7
7
|
const PARAGRAPH = "\n\n";
|
package/dist/render.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as isUrlAttribute, S as emailElement, _ as EmailGlobalProps, b as EmailStyle, g as EmailElementSpec, h as EmailAttributeSpec, m as EMAIL_GLOBAL_ATTRIBUTES, p as EMAIL_ELEMENTS, r as EmailNode, v as EmailIntrinsicElements, x as EmailTag, y as EmailLayout } from "./jsx-runtime-DC7xG0aA.js";
|
|
2
|
-
import { $ as IrWhatsApp, A as emailAuthoringTarget, B as IrElement, D as EmittedPosition, E as EmailElementSelection, F as emailSelections, G as IrPredicate, H as IrFormatter, I as renderIrPreview, J as IrRawPart, K as IrPreheader, L as IrArithmetic, M as emailSelectionAncestry, N as emailSelectionIndex, O as INSTANCE_PATH_ATTRIBUTE, P as emailSelectionSiblings, Q as IrValue, R as IrComparison, U as IrIf, V as IrEmail, W as IrNode, X as IrSource, Y as IrSms, Z as IrStyle, a as renderEmailContent, at as RenderedPosition, c as checkAttribute, ct as TemplateIr, d as escapeText, et as IrWhatsAppButton, f as kebab, i as compileEmail, it as RenderedIrWhatsApp, j as emailDefinitionInstances, k as IrPreview, l as declarationValue, m as serializeStyle, n as EmailCompileOutput, nt as RenderOptions, o as EmailHtmlOutput, ot as RenderedWhatsAppButton, p as serializeEmailHtml, q as IrRaw, r as RenderedEmail, rt as RenderedIrEmail, s as SerializeEmailOptions, st as SML_IR_VERSION, t as EMAIL_DOCTYPE, tt as IrWhatsAppButtonNode, u as escapeAttribute, z as IrEach } from "./render-
|
|
2
|
+
import { $ as IrWhatsApp, A as emailAuthoringTarget, B as IrElement, D as EmittedPosition, E as EmailElementSelection, F as emailSelections, G as IrPredicate, H as IrFormatter, I as renderIrPreview, J as IrRawPart, K as IrPreheader, L as IrArithmetic, M as emailSelectionAncestry, N as emailSelectionIndex, O as INSTANCE_PATH_ATTRIBUTE, P as emailSelectionSiblings, Q as IrValue, R as IrComparison, U as IrIf, V as IrEmail, W as IrNode, X as IrSource, Y as IrSms, Z as IrStyle, a as renderEmailContent, at as RenderedPosition, c as checkAttribute, ct as TemplateIr, d as escapeText, et as IrWhatsAppButton, f as kebab, i as compileEmail, it as RenderedIrWhatsApp, j as emailDefinitionInstances, k as IrPreview, l as declarationValue, m as serializeStyle, n as EmailCompileOutput, nt as RenderOptions, o as EmailHtmlOutput, ot as RenderedWhatsAppButton, p as serializeEmailHtml, q as IrRaw, r as RenderedEmail, rt as RenderedIrEmail, s as SerializeEmailOptions, st as SML_IR_VERSION, t as EMAIL_DOCTYPE, tt as IrWhatsAppButtonNode, u as escapeAttribute, z as IrEach } from "./render-C6OTH8BQ.js";
|
|
3
3
|
//#region src/render-ir.d.ts
|
|
4
4
|
interface IrRenderDiagnostic {
|
|
5
5
|
readonly code: string;
|
package/dist/render.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as isUrlAttribute, S as emailElement, _ as renderIr, a as kebab, b as EMAIL_ELEMENTS, c as INSTANCE_PATH_ATTRIBUTE, d as emailSelectionAncestry, f as emailSelectionIndex, g as IrRenderError, h as renderIrPreview, i as escapeText, l as emailAuthoringTarget, m as emailSelections, n as declarationValue, o as serializeEmailHtml, p as emailSelectionSiblings, r as escapeAttribute, s as serializeStyle, t as checkAttribute, u as emailDefinitionInstances, v as renderIrSms, x as EMAIL_GLOBAL_ATTRIBUTES, y as renderIrWhatsApp } from "./html-
|
|
2
|
-
import { t as SML_IR_VERSION } from "./ir-
|
|
3
|
-
import { i as deriveEmailText, n as compileEmail, r as renderEmailContent, t as EMAIL_DOCTYPE } from "./render-
|
|
1
|
+
import { C as isUrlAttribute, S as emailElement, _ as renderIr, a as kebab, b as EMAIL_ELEMENTS, c as INSTANCE_PATH_ATTRIBUTE, d as emailSelectionAncestry, f as emailSelectionIndex, g as IrRenderError, h as renderIrPreview, i as escapeText, l as emailAuthoringTarget, m as emailSelections, n as declarationValue, o as serializeEmailHtml, p as emailSelectionSiblings, r as escapeAttribute, s as serializeStyle, t as checkAttribute, u as emailDefinitionInstances, v as renderIrSms, x as EMAIL_GLOBAL_ATTRIBUTES, y as renderIrWhatsApp } from "./html-eOZfDwVf.js";
|
|
2
|
+
import { t as SML_IR_VERSION } from "./ir-C-ubz6N3.js";
|
|
3
|
+
import { i as deriveEmailText, n as compileEmail, r as renderEmailContent, t as EMAIL_DOCTYPE } from "./render-Cja448i0.js";
|
|
4
4
|
//#region src/sms-segments.ts
|
|
5
5
|
const GSM7_EXTENDED = /* @__PURE__ */ new Set([
|
|
6
6
|
"[",
|
package/dist/whatsapp.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { r as EmailNode, t as EmailChild } from "./jsx-runtime-DC7xG0aA.js";
|
|
|
2
2
|
import { n as WhatsAppCategory, r as WhatsAppHeaderType } from "./channel-specs-C2feJwuP.js";
|
|
3
3
|
//#region src/whatsapp.d.ts
|
|
4
4
|
interface WhatsAppProps {
|
|
5
|
-
readonly name?: string | undefined;
|
|
6
5
|
/** The Meta language code, for example `en_US`. */
|
|
7
6
|
readonly language: string;
|
|
8
7
|
readonly category: WhatsAppCategory;
|
package/generated/contract.json
CHANGED
|
@@ -575,11 +575,6 @@
|
|
|
575
575
|
"name": "WhatsApp",
|
|
576
576
|
"import": "@samva/markup/whatsapp",
|
|
577
577
|
"props": [
|
|
578
|
-
{
|
|
579
|
-
"name": "name",
|
|
580
|
-
"type": "string",
|
|
581
|
-
"optional": true
|
|
582
|
-
},
|
|
583
578
|
{
|
|
584
579
|
"name": "language",
|
|
585
580
|
"type": "string",
|
|
@@ -1292,7 +1287,7 @@
|
|
|
1292
1287
|
},
|
|
1293
1288
|
"whatsapp": {
|
|
1294
1289
|
"categories": ["marketing", "utility", "authentication"],
|
|
1295
|
-
"attributes": ["
|
|
1290
|
+
"attributes": ["language", "category"],
|
|
1296
1291
|
"headerTypes": ["text", "image", "video", "document"]
|
|
1297
1292
|
}
|
|
1298
1293
|
},
|
|
@@ -1765,6 +1760,13 @@
|
|
|
1765
1760
|
"fix": "Move it into <WhatsApp.Body>.",
|
|
1766
1761
|
"channelOnly": true
|
|
1767
1762
|
},
|
|
1763
|
+
{
|
|
1764
|
+
"code": "whatsapp-template-name",
|
|
1765
|
+
"summary": "A <WhatsApp> names its Meta template; the name comes from the template's handle.",
|
|
1766
|
+
"fix": "Remove `name` from <WhatsApp>.",
|
|
1767
|
+
"upgrade": "Remove the `name` attribute from every <WhatsApp> element in the project, templates and partials alike. Samva registers each WhatsApp template with Meta under its handle, with hyphens as underscores, so the attribute has no replacement. Change nothing else.\n\nIf an authored name differs from the name the handle produces and the template is already registered with Meta under it, tell the user: keeping that Meta name means renaming the template's handle, which you do not do yourself.\n\nCompile each entry and render every declared fixture to confirm the WhatsApp output is otherwise unchanged. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish.",
|
|
1768
|
+
"channelOnly": true
|
|
1769
|
+
},
|
|
1768
1770
|
{
|
|
1769
1771
|
"code": "wrong-channel",
|
|
1770
1772
|
"summary": "A channel body does not return its own channel component.",
|