@samva/markup 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +104 -37
- package/README.md +188 -52
- package/dist/assets-C5duwTya.d.ts +40 -0
- package/dist/brand-B-0bN_Ir.d.ts +88 -0
- package/dist/{render-aaJBnsXK.js → cascade-t6kxlgEI.js} +130 -160
- package/dist/channel-edit.d.ts +121 -0
- package/dist/channel-edit.js +609 -0
- package/dist/channel-specs-B6M_HlaV.js +29 -0
- package/dist/channel-specs-C2feJwuP.d.ts +13 -0
- package/dist/compatibility-DbISoFIq.js +589 -0
- package/dist/compiler.d.ts +19 -249
- package/dist/compiler.js +10 -1408
- package/dist/{css-COcFOT1y.d.ts → css-BVQKICKC.d.ts} +30 -4
- package/dist/diagnostic-codes.d.ts +403 -0
- package/dist/diagnostic-codes.js +399 -0
- package/dist/{diagnostics-BMYtBCQk.d.ts → diagnostics-B-Gym34R.d.ts} +8 -4
- package/dist/diagnostics.d.ts +31 -2
- package/dist/diagnostics.js +1 -19
- package/dist/{elements-BzjjnoCS.d.ts → elements-cqldpaJt.d.ts} +3 -3
- package/dist/email/assets.d.ts +2 -0
- package/dist/email/assets.js +63 -0
- package/dist/email/brand-footer.d.ts +34 -0
- package/dist/email/brand-footer.js +63 -0
- package/dist/email/brand.d.ts +2 -0
- package/dist/email/brand.js +148 -0
- package/dist/email/components.d.ts +21 -10
- package/dist/email/components.js +46 -11
- package/dist/email/diagnostics.d.ts +2 -2
- package/dist/email/diagnostics.js +2 -1
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -42
- package/dist/email/html.js +56 -2
- package/dist/email/jsx-dev-runtime.d.ts +2 -2
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/render.d.ts +10 -13
- package/dist/email/render.js +163 -6
- package/dist/email/text.d.ts +1 -1
- package/dist/fmt.d.ts +32 -0
- package/dist/fmt.js +174 -0
- package/dist/html-BJepOwZ4.d.ts +56 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/ir-aaqNE987.d.ts +252 -0
- package/dist/ir.d.ts +2 -0
- package/dist/ir.js +7 -0
- package/dist/preview-Ekdg1dXG.d.ts +100 -0
- package/dist/preview.d.ts +2 -0
- package/dist/preview.js +160 -0
- package/dist/profile-BH-OtdDA.js +3670 -0
- package/dist/render-ir.d.ts +19 -0
- package/dist/render-ir.js +826 -0
- package/dist/sms-segments.d.ts +13 -2
- package/dist/sms.d.ts +16 -0
- package/dist/sms.js +12 -0
- package/dist/{email/source-edit.d.ts → source-edit.d.ts} +55 -6
- package/dist/source-edit.js +343 -0
- package/dist/source-locations-C8wCsiAy.d.ts +23 -0
- package/dist/source-locations.d.ts +2 -2
- package/dist/source-locations.js +3 -89
- package/dist/static.d.ts +57 -0
- package/dist/static.js +69 -0
- package/dist/tailwind-CMYpZf1v.js +614 -0
- package/dist/template-_QE_rQND.d.ts +65 -0
- package/dist/template.d.ts +2 -2
- package/dist/template.js +15 -10
- package/dist/theme-css-hFqcPSar.js +587 -0
- package/dist/theme-css.d.ts +57 -16
- package/dist/theme-css.js +2 -509
- package/dist/theme-imports-lvBw3AD1.js +109 -0
- package/dist/transform-Ct2OMkFN.d.ts +153 -0
- package/dist/unsubscribe-link-CoesnQDU.js +26 -0
- package/dist/whatsapp.d.ts +57 -0
- package/dist/whatsapp.js +22 -0
- package/generated/contract.json +1782 -0
- package/generated/reference.md +353 -0
- package/package.json +56 -154
- package/samva-brand.d.ts +14 -0
- package/skills/sml/SKILL.md +123 -0
- package/dist/ast-BrDtApwS.d.ts +0 -107
- package/dist/ast.d.ts +0 -2
- package/dist/ast.js +0 -124
- package/dist/candidate.d.ts +0 -29
- package/dist/candidate.js +0 -88
- package/dist/catalog-60eaYC7b.d.ts +0 -356
- package/dist/checks-DBweSIPN.js +0 -58954
- package/dist/checks.d.ts +0 -33
- package/dist/checks.js +0 -2
- package/dist/classes.d.ts +0 -27
- package/dist/classes.js +0 -184
- package/dist/compile-sms.d.ts +0 -28
- package/dist/compile-sms.js +0 -44
- package/dist/compile-whatsapp.d.ts +0 -56
- package/dist/compile-whatsapp.js +0 -186
- package/dist/compile.d.ts +0 -18
- package/dist/compile.js +0 -29
- package/dist/components.d.ts +0 -289
- package/dist/components.js +0 -106
- package/dist/conditionals.d.ts +0 -10
- package/dist/conditionals.js +0 -74
- package/dist/corpus-BjYMqOoY.d.ts +0 -106
- package/dist/diagnostics-OcQKQYSY.d.ts +0 -49
- package/dist/email/selection.d.ts +0 -91
- package/dist/email/selection.js +0 -91
- package/dist/email/source-edit.js +0 -185
- package/dist/email/stylesheets.d.ts +0 -15
- package/dist/email/stylesheets.js +0 -45
- package/dist/emit.d.ts +0 -51
- package/dist/emit.js +0 -151
- package/dist/footer.d.ts +0 -66
- package/dist/footer.js +0 -93
- package/dist/interpolate.d.ts +0 -24
- package/dist/interpolate.js +0 -43
- package/dist/jsx-dev-runtime.d.ts +0 -11
- package/dist/jsx-dev-runtime.js +0 -15
- package/dist/jsx-runtime-I-1nCtl2.d.ts +0 -57
- package/dist/jsx-runtime.d.ts +0 -2
- package/dist/jsx-runtime.js +0 -121
- package/dist/lexer.d.ts +0 -60
- package/dist/lexer.js +0 -281
- package/dist/model.d.ts +0 -24
- package/dist/model.js +0 -77
- package/dist/ops-2aiiYO7m.js +0 -630
- package/dist/ops.d.ts +0 -114
- package/dist/ops.js +0 -2
- package/dist/parser-t29cHLVL.d.ts +0 -396
- package/dist/parser.d.ts +0 -2
- package/dist/parser.js +0 -859
- package/dist/predicate-BI6uRRM-.js +0 -549
- package/dist/predicate-M-05Nd7R.d.ts +0 -56
- package/dist/predicate.d.ts +0 -2
- package/dist/predicate.js +0 -2
- package/dist/presets/category-mapping.d.ts +0 -13
- package/dist/presets/category-mapping.js +0 -49
- package/dist/presets/corpus.d.ts +0 -2
- package/dist/presets/corpus.js +0 -194
- package/dist/presets/public-gallery.d.ts +0 -266
- package/dist/presets/public-gallery.js +0 -916
- package/dist/presets/public-handoff.d.ts +0 -164
- package/dist/presets/public-handoff.js +0 -361
- package/dist/presets/public-preview-artifacts.d.ts +0 -43
- package/dist/presets/public-preview-artifacts.js +0 -104
- package/dist/presets/public-preview.d.ts +0 -61
- package/dist/presets/public-preview.js +0 -83
- package/dist/presets/showcase.d.ts +0 -2
- package/dist/presets/showcase.js +0 -627
- package/dist/presets/sources.d.ts +0 -38
- package/dist/presets/sources.js +0 -6083
- package/dist/presets.d.ts +0 -2
- package/dist/presets.js +0 -881
- package/dist/printer.d.ts +0 -6
- package/dist/printer.js +0 -122
- package/dist/registry.d.ts +0 -42
- package/dist/registry.js +0 -646
- package/dist/render-template.d.ts +0 -45
- package/dist/render-template.js +0 -76
- package/dist/showcase-DGZAWn4Z.d.ts +0 -456
- package/dist/sms-segments-y4FpPilJ.d.ts +0 -13
- package/dist/source-locations-DrCM82Ym.d.ts +0 -67
- package/dist/template-DWftqh4x.d.ts +0 -60
- package/dist/theme-6ApjjiBo.d.ts +0 -116
- package/dist/theme.d.ts +0 -2
- package/dist/theme.js +0 -118
- package/dist/tokens.d.ts +0 -6
- package/dist/tokens.js +0 -417
- package/dist/tsx-source-instrumentation.d.ts +0 -30
- package/dist/tsx-source-instrumentation.js +0 -115
- package/dist/tsx-tracer.d.ts +0 -112
- package/dist/tsx-tracer.js +0 -985
- package/dist/variables-J_L3qxRa.d.ts +0 -77
- package/dist/variables.d.ts +0 -2
- package/dist/variables.js +0 -141
- package/dist/version-BITr58kk.js +0 -96
- package/generated/sml-agent-contract.json +0 -709
- package/generated/sml-email-agent-contract.json +0 -615
- package/generated/sml-email-language-reference.md +0 -94
- package/generated/sml-language-reference.md +0 -195
package/dist/checks.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
-
//#region src/checks.d.ts
|
|
3
|
-
type EmailClientDarkBehavior = "honors" | "force-inverts" | "no dark mode";
|
|
4
|
-
interface EmailClientTarget {
|
|
5
|
-
readonly family: string;
|
|
6
|
-
readonly platform: string;
|
|
7
|
-
readonly label: string;
|
|
8
|
-
readonly darkBehavior: EmailClientDarkBehavior;
|
|
9
|
-
}
|
|
10
|
-
interface TargetClientProfile {
|
|
11
|
-
readonly id: string;
|
|
12
|
-
readonly label: string;
|
|
13
|
-
readonly targets: readonly EmailClientTarget[];
|
|
14
|
-
}
|
|
15
|
-
interface EmailCompatibilityInput {
|
|
16
|
-
readonly source: string;
|
|
17
|
-
readonly profile?: TargetClientProfile | undefined;
|
|
18
|
-
readonly declaredVariables?: readonly string[] | undefined;
|
|
19
|
-
}
|
|
20
|
-
declare const DEFAULT_EMAIL_TARGET_CLIENT_PROFILE: TargetClientProfile;
|
|
21
|
-
/**
|
|
22
|
-
* Finds site-relative assets that work in Vite preview but cannot resolve
|
|
23
|
-
* after an email leaves the author's site. Values backed entirely by one
|
|
24
|
-
* variable are excluded because their runtime value is a delivery concern.
|
|
25
|
-
*/
|
|
26
|
-
declare const checkDeliveryAssetDiagnostics: (source: string) => readonly Diagnostic[];
|
|
27
|
-
declare function isBreakingCompatibilityCheck(message: string): boolean;
|
|
28
|
-
declare function collectSmlFeatureSlugs(source: string): readonly string[];
|
|
29
|
-
declare function worstCaseArtifactBytes(html: string): number;
|
|
30
|
-
declare function checkSmlCompatibility(input: EmailCompatibilityInput): readonly string[];
|
|
31
|
-
//#endregion
|
|
32
|
-
export { DEFAULT_EMAIL_TARGET_CLIENT_PROFILE, EmailClientDarkBehavior, EmailClientTarget, EmailCompatibilityInput, TargetClientProfile, checkDeliveryAssetDiagnostics, checkSmlCompatibility, collectSmlFeatureSlugs, isBreakingCompatibilityCheck, worstCaseArtifactBytes };
|
|
33
|
-
//# sourceMappingURL=checks.d.ts.map
|
package/dist/checks.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { a as isBreakingCompatibilityCheck, i as collectSmlFeatureSlugs, n as checkDeliveryAssetDiagnostics, o as worstCaseArtifactBytes, r as checkSmlCompatibility, t as DEFAULT_EMAIL_TARGET_CLIENT_PROFILE } from "./checks-DBweSIPN.js";
|
|
2
|
-
export { DEFAULT_EMAIL_TARGET_CLIENT_PROFILE, checkDeliveryAssetDiagnostics, checkSmlCompatibility, collectSmlFeatureSlugs, isBreakingCompatibilityCheck, worstCaseArtifactBytes };
|
package/dist/classes.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { a as Span, t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
-
import { s as TokenTable } from "./theme-6ApjjiBo.js";
|
|
3
|
-
import { Declaration } from "./registry.js";
|
|
4
|
-
//#region src/classes.d.ts
|
|
5
|
-
type ClassVariant = "base" | "sm" | "dark";
|
|
6
|
-
interface ResolvedClass {
|
|
7
|
-
readonly raw: string;
|
|
8
|
-
readonly span: Span;
|
|
9
|
-
readonly variant: ClassVariant;
|
|
10
|
-
readonly declarations: ReadonlyArray<Declaration>;
|
|
11
|
-
/**
|
|
12
|
-
* Automatic dark-mode counterparts: present only on a base-variant
|
|
13
|
-
* color-family class whose named token has a `colorsDark` entry. Literal
|
|
14
|
-
* values and tokens without a dark pair never get auto-dark; explicit dark:
|
|
15
|
-
* classes win by being emitted after these (CSS last-wins).
|
|
16
|
-
*/
|
|
17
|
-
readonly darkDeclarations?: ReadonlyArray<Declaration> | undefined;
|
|
18
|
-
}
|
|
19
|
-
interface ClassResolution {
|
|
20
|
-
readonly classes: ReadonlyArray<ResolvedClass>;
|
|
21
|
-
readonly errors: ReadonlyArray<Diagnostic>;
|
|
22
|
-
readonly warnings: ReadonlyArray<Diagnostic>;
|
|
23
|
-
}
|
|
24
|
-
declare const resolveClasses: (classAttribute: string, theme: TokenTable, offset: number) => ClassResolution;
|
|
25
|
-
//#endregion
|
|
26
|
-
export { ClassResolution, ClassVariant, ResolvedClass, resolveClasses };
|
|
27
|
-
//# sourceMappingURL=classes.d.ts.map
|
package/dist/classes.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { parseCandidate, splitRoot } from "./candidate.js";
|
|
2
|
-
import { forbiddenUtilities, registryRoots, utilityRegistry } from "./registry.js";
|
|
3
|
-
//#region src/classes.ts
|
|
4
|
-
const KNOWN_ROOT_SUMMARY = "supported utilities: p*/m* spacing, w/max-w/h, text-*, leading-*, tracking-*, font-*, bg-*, bg-gradient-to-* with from-*/to-*, border*, rounded*, uppercase, underline/no-underline, block/inline-block/hidden";
|
|
5
|
-
const VARIANT_ERRORS = {
|
|
6
|
-
hover: "email clients don't apply hover: styles — remove the variant",
|
|
7
|
-
focus: "email clients don't apply focus: styles — remove the variant",
|
|
8
|
-
active: "email clients don't apply active: styles — remove the variant",
|
|
9
|
-
md: "only the sm: breakpoint is supported (progressive enhancement) — use sm:",
|
|
10
|
-
lg: "only the sm: breakpoint is supported (progressive enhancement) — use sm:",
|
|
11
|
-
xl: "only the sm: breakpoint is supported (progressive enhancement) — use sm:",
|
|
12
|
-
"2xl": "only the sm: breakpoint is supported (progressive enhancement) — use sm:"
|
|
13
|
-
};
|
|
14
|
-
const REJECTED_ARBITRARY_FUNCTIONS = [
|
|
15
|
-
["var(", "CSS variables don't exist in compiled email — use a theme token or a literal value"],
|
|
16
|
-
["calc(", "calc() is unsupported in Outlook for Windows — use a literal px value"],
|
|
17
|
-
["oklch(", "oklch() is unsupported in email clients — use a literal hex color"],
|
|
18
|
-
["rgb(", "use a literal hex color — rgb()/rgba() alpha renders solid black in Outlook for Windows"],
|
|
19
|
-
["hsl(", "use a literal hex color — hsl() is unreliable across email clients"]
|
|
20
|
-
];
|
|
21
|
-
const removeClassRepair = (raw, explanation) => ({
|
|
22
|
-
kind: "remove-class",
|
|
23
|
-
raw,
|
|
24
|
-
suggestions: [],
|
|
25
|
-
explanation
|
|
26
|
-
});
|
|
27
|
-
const replaceClassRepair = (raw, suggestions, explanation) => ({
|
|
28
|
-
kind: "replace-class",
|
|
29
|
-
raw,
|
|
30
|
-
suggestions,
|
|
31
|
-
explanation
|
|
32
|
-
});
|
|
33
|
-
const primitiveRepair = (raw, suggestions, explanation) => ({
|
|
34
|
-
kind: "use-primitive",
|
|
35
|
-
raw,
|
|
36
|
-
suggestions,
|
|
37
|
-
explanation
|
|
38
|
-
});
|
|
39
|
-
const variantRepair = (raw, variantName) => variantName === "md" || variantName === "lg" || variantName === "xl" || variantName === "2xl" ? replaceClassRepair(raw, [`sm:${raw.slice(raw.indexOf(":") + 1)}`, raw.slice(raw.indexOf(":") + 1)], "Only sm: exists for responsive email enhancement. Use sm: or remove the variant.") : replaceClassRepair(raw, [raw.slice(raw.indexOf(":") + 1)], "Email clients do not support this interaction/responsive variant. Remove the variant.");
|
|
40
|
-
const forbiddenRepair = (raw) => {
|
|
41
|
-
if (/^(inline-)?(flex|grid)$/.test(raw) || raw.startsWith("gap-")) return primitiveRepair(raw, ["<Row><Column>...</Column></Row>", "<Spacer height={16} />"], "Email layout must use table-backed primitives instead of flex/grid utilities.");
|
|
42
|
-
if (raw.startsWith("items-") || raw.startsWith("justify-")) return primitiveRepair(raw, ["<Row><Column valign=\"middle\">...</Column></Row>", "text-center"], "Use Row/Column alignment or text alignment instead of flexbox alignment utilities.");
|
|
43
|
-
if (raw.startsWith("overflow-") || raw === "truncate" || raw.startsWith("line-clamp-")) return primitiveRepair(raw, ["shorten the copy", "split content into rows/sections"], "Email clients cannot reliably clip or line-clamp content.");
|
|
44
|
-
return removeClassRepair(raw, "This CSS feature is not reliable in email clients.");
|
|
45
|
-
};
|
|
46
|
-
const invalidValueRepair = (raw, root, value) => {
|
|
47
|
-
if (root === "text" && /^\d+(\.\d+)?px$/.test(value)) return replaceClassRepair(raw, [
|
|
48
|
-
"text-[15px]",
|
|
49
|
-
"text-base",
|
|
50
|
-
"text-lg",
|
|
51
|
-
"text-xl",
|
|
52
|
-
"text-2xl"
|
|
53
|
-
], "Arbitrary text sizes must be px values between 8px and 72px, or use a named text scale.");
|
|
54
|
-
if (root.startsWith("rounded")) return replaceClassRepair(raw, [
|
|
55
|
-
`${root}-md`,
|
|
56
|
-
`${root}-lg`,
|
|
57
|
-
`${root}-xl`,
|
|
58
|
-
`${root}-[12px]`
|
|
59
|
-
], "Border radius values must use the supported radius scale, none/full, or a px arbitrary value.");
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* Resolves one class attribute value. `offset` is the absolute source offset
|
|
63
|
-
* of the attribute value's first character, so every class gets its own span.
|
|
64
|
-
* Collects all errors instead of failing fast — agents fix a list at a time.
|
|
65
|
-
*/
|
|
66
|
-
const ZERO_LENGTH = /^0(?:px|rem|em|%)?$/;
|
|
67
|
-
const isZeroValued = (declarations) => declarations.every((declaration) => ZERO_LENGTH.test(declaration.value));
|
|
68
|
-
const resolveClasses = (classAttribute, theme, offset) => {
|
|
69
|
-
const classes = [];
|
|
70
|
-
const errors = [];
|
|
71
|
-
const warnings = [];
|
|
72
|
-
for (const match of classAttribute.matchAll(/\S+/g)) {
|
|
73
|
-
const raw = match[0];
|
|
74
|
-
const span = {
|
|
75
|
-
start: offset + match.index,
|
|
76
|
-
end: offset + match.index + raw.length
|
|
77
|
-
};
|
|
78
|
-
const fail = (code, message, repair) => {
|
|
79
|
-
errors.push(repair === void 0 ? {
|
|
80
|
-
code,
|
|
81
|
-
message,
|
|
82
|
-
span
|
|
83
|
-
} : {
|
|
84
|
-
code,
|
|
85
|
-
message,
|
|
86
|
-
span,
|
|
87
|
-
repair
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
const candidate = parseCandidate(raw);
|
|
91
|
-
if (candidate.important) {
|
|
92
|
-
fail("unsupported-important", `remove the trailing ! from "${raw}" — the compiler manages !important for sm:/dark: rules`, removeClassRepair(raw, "The compiler manages specificity for sm:/dark: rules."));
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (candidate.variants.length > 1) {
|
|
96
|
-
fail("unsupported-variant", `at most one variant per class — split "${raw}" into separate sm:/dark: classes`, replaceClassRepair(raw, [candidate.base], "Use at most one variant per class; duplicate the base utility if both sm: and dark: variants are needed."));
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const variantName = candidate.variants[0];
|
|
100
|
-
if (variantName !== void 0 && variantName !== "sm" && variantName !== "dark") {
|
|
101
|
-
fail("unsupported-variant", `${variantName}: on "${raw}" — ${VARIANT_ERRORS[variantName] ?? "unknown variant — only sm: and dark: are supported"}`, variantRepair(raw, variantName));
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
const variant = variantName ?? "base";
|
|
105
|
-
const forbidden = forbiddenUtilities.find((entry) => entry.match.endsWith("-") ? candidate.base.startsWith(entry.match) : candidate.base === entry.match);
|
|
106
|
-
if (forbidden !== void 0) {
|
|
107
|
-
fail("forbidden-class", `class "${raw}" — ${forbidden.message}`, forbiddenRepair(raw));
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (candidate.modifier !== null) {
|
|
111
|
-
fail("unsupported-modifier", `the /${candidate.modifier} modifier on "${raw}" compiles to alpha colors, which render solid black in Outlook for Windows (Word engine) — use a solid color token`, replaceClassRepair(raw, [candidate.base], "Alpha modifiers are unsafe in Outlook for Windows. Use a solid token or literal hex color."));
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
const split = splitRoot(candidate.base, registryRoots);
|
|
115
|
-
if (split === null) {
|
|
116
|
-
fail("unknown-class", `unknown class "${raw}" — ${KNOWN_ROOT_SUMMARY}`, removeClassRepair(raw, "Use only the closed SML email utility subset."));
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
if (split.value?.kind === "arbitrary") {
|
|
120
|
-
const arbitraryValue = split.value.value;
|
|
121
|
-
const rejection = REJECTED_ARBITRARY_FUNCTIONS.find(([prefix]) => arbitraryValue.includes(prefix));
|
|
122
|
-
if (rejection !== void 0) {
|
|
123
|
-
fail("unsupported-arbitrary-value", `class "${raw}" — ${rejection[1]}`, replaceClassRepair(raw, split.root === "text" || split.root === "bg" || split.root === "border" ? [`${split.root}-[#374151]`] : [], "Use literal px lengths or literal hex colors only; functions and variables are not email-safe."));
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
const families = utilityRegistry.filter((family) => family.root === split.root);
|
|
128
|
-
let resolved = null;
|
|
129
|
-
for (const family of families) {
|
|
130
|
-
let declarations = null;
|
|
131
|
-
if (split.value === null) declarations = family.bare ?? null;
|
|
132
|
-
else if (split.value.kind === "named") declarations = family.named?.(split.value.value, theme) ?? null;
|
|
133
|
-
else declarations = family.arbitrary?.(split.value.value, theme) ?? null;
|
|
134
|
-
if (declarations === null) continue;
|
|
135
|
-
if (family.baseOnly === true && variantName !== void 0) {
|
|
136
|
-
fail("unsupported-variant", `${variantName}: on "${raw}" — gradient utilities are combined per node at compile time and can't ride sm:/dark: head rules; remove the variant`, replaceClassRepair(raw, [candidate.base], "Gradient utilities compile per element, not as variant head rules."));
|
|
137
|
-
resolved = null;
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
if (variant === "dark" && family.colorFamily !== true) {
|
|
141
|
-
fail("dark-variant-non-color", `dark: applies only to color utilities (bg-*, text-{color}, border-{color}) — remove dark: from "${raw}"`, replaceClassRepair(raw, [candidate.base], "Only color utilities can have dark: variants in email."));
|
|
142
|
-
resolved = null;
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
if (family.warn !== void 0 && !isZeroValued(declarations)) warnings.push({
|
|
146
|
-
code: "warn-tier-class",
|
|
147
|
-
message: `class "${raw}" — ${family.warn}`,
|
|
148
|
-
span
|
|
149
|
-
});
|
|
150
|
-
const darkHex = variantName === void 0 && family.colorFamily === true && split.value?.kind === "named" ? theme.colorsDark[split.value.value] : void 0;
|
|
151
|
-
resolved = darkHex === void 0 ? {
|
|
152
|
-
raw,
|
|
153
|
-
span,
|
|
154
|
-
variant,
|
|
155
|
-
declarations
|
|
156
|
-
} : {
|
|
157
|
-
raw,
|
|
158
|
-
span,
|
|
159
|
-
variant,
|
|
160
|
-
declarations,
|
|
161
|
-
darkDeclarations: declarations.map((declaration) => ({
|
|
162
|
-
property: declaration.property,
|
|
163
|
-
value: darkHex
|
|
164
|
-
}))
|
|
165
|
-
};
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
if (resolved !== null) {
|
|
169
|
-
classes.push(resolved);
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
if (errors.length > 0 && errors[errors.length - 1].span === span) continue;
|
|
173
|
-
fail("unknown-class", `unknown class "${raw}" — ${split.value === null ? `"${split.root}" needs a value` : `"${split.value.value}" is not a valid value for ${split.root}-*`}`, split.value === null ? void 0 : invalidValueRepair(raw, split.root, split.value.value));
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
classes,
|
|
177
|
-
errors,
|
|
178
|
-
warnings
|
|
179
|
-
};
|
|
180
|
-
};
|
|
181
|
-
//#endregion
|
|
182
|
-
export { resolveClasses };
|
|
183
|
-
|
|
184
|
-
//# sourceMappingURL=classes.js.map
|
package/dist/compile-sms.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
-
import { f as ElementNode } from "./ast-BrDtApwS.js";
|
|
3
|
-
import { a as SMS_TAG_SPECS } from "./parser-t29cHLVL.js";
|
|
4
|
-
import { t as SmsEncoding } from "./sms-segments-y4FpPilJ.js";
|
|
5
|
-
//#region src/compile-sms.d.ts
|
|
6
|
-
/** Documented worst-case rendered width of one `{{variable}}`. */
|
|
7
|
-
declare const VARIABLE_WORST_CASE_CHARS = 16;
|
|
8
|
-
/** Derived from the grammar's closed category set (mirrors smsCategoryEnum). */
|
|
9
|
-
type SmsCategory = (typeof SMS_TAG_SPECS)["Sms"]["attributes"]["category"]["values"][number];
|
|
10
|
-
interface CompiledSms {
|
|
11
|
-
readonly channel: "sms";
|
|
12
|
-
/** The root tag's authoring-intent category; compliance state stays on variant rows. */
|
|
13
|
-
readonly category?: SmsCategory | undefined;
|
|
14
|
-
/** Template body: text verbatim, `{{vars}}` literal, `<If>` as sml: markers. */
|
|
15
|
-
readonly body: string;
|
|
16
|
-
readonly encoding: SmsEncoding;
|
|
17
|
-
/** Segments of the primary rendering (every <If> true, variables at worst case). */
|
|
18
|
-
readonly estimatedSegments: number;
|
|
19
|
-
/** Worst branch combination; present only when the body has conditionals. */
|
|
20
|
-
readonly maxSegments?: number | undefined;
|
|
21
|
-
readonly warnings: ReadonlyArray<Diagnostic>;
|
|
22
|
-
readonly compilerVersion: string;
|
|
23
|
-
}
|
|
24
|
-
/** Root is a parsed `<Sms>` element; the grammar already validated its shape. */
|
|
25
|
-
declare const compileSmsRoot: (root: ElementNode) => CompiledSms;
|
|
26
|
-
//#endregion
|
|
27
|
-
export { CompiledSms, SmsCategory, VARIABLE_WORST_CASE_CHARS, compileSmsRoot };
|
|
28
|
-
//# sourceMappingURL=compile-sms.d.ts.map
|
package/dist/compile-sms.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { stringAttribute } from "./ast.js";
|
|
2
|
-
import { i as primaryChannelText, n as channelTextVariants, r as flattenChannelText, t as COMPILER_VERSION } from "./version-BITr58kk.js";
|
|
3
|
-
import { hasSmsOptOut, smsSegmentInfo } from "./sms-segments.js";
|
|
4
|
-
//#region src/compile-sms.ts
|
|
5
|
-
/** Documented worst-case rendered width of one `{{variable}}`. */
|
|
6
|
-
const VARIABLE_WORST_CASE_CHARS = 16;
|
|
7
|
-
const WORST_CASE = { worstCaseChars: 16 };
|
|
8
|
-
/** Root is a parsed `<Sms>` element; the grammar already validated its shape. */
|
|
9
|
-
const compileSmsRoot = (root) => {
|
|
10
|
-
const body = flattenChannelText(root.children);
|
|
11
|
-
const category = stringAttribute(root, "category");
|
|
12
|
-
const hasConditionals = root.children.some((child) => child.kind === "element" && child.tag === "If");
|
|
13
|
-
const variantInfo = channelTextVariants(root.children, WORST_CASE).map(smsSegmentInfo);
|
|
14
|
-
const encoding = variantInfo.some((info) => info.encoding === "ucs2") ? "ucs2" : "gsm7";
|
|
15
|
-
const estimatedSegments = smsSegmentInfo(primaryChannelText(root.children, WORST_CASE)).segmentCount;
|
|
16
|
-
const worstSegments = Math.max(estimatedSegments, ...variantInfo.map((info) => info.segmentCount));
|
|
17
|
-
const warnings = [];
|
|
18
|
-
const warn = (code, message) => {
|
|
19
|
-
warnings.push({
|
|
20
|
-
code,
|
|
21
|
-
message,
|
|
22
|
-
span: root.span
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
if (encoding === "ucs2") warn("sms-ucs2", "sms uses non-GSM characters (UCS-2); each segment holds 70 characters instead of 160");
|
|
26
|
-
if (worstSegments > 1) warn("sms-multi-segment", `sms spans ${worstSegments} segments (variables counted at 16 characters); each segment is billed separately`);
|
|
27
|
-
if (worstSegments > 10) warn("sms-segment-limit", "sms exceeds 10 segments and may be rejected by carriers");
|
|
28
|
-
const literalPrimary = primaryChannelText(root.children, "literal");
|
|
29
|
-
if (literalPrimary.trim().length > 0 && !hasSmsOptOut(literalPrimary)) warn("sms-opt-out", "sms should include opt-out instructions (e.g. \"Reply STOP to unsubscribe\")");
|
|
30
|
-
return {
|
|
31
|
-
channel: "sms",
|
|
32
|
-
category,
|
|
33
|
-
body,
|
|
34
|
-
encoding,
|
|
35
|
-
estimatedSegments,
|
|
36
|
-
maxSegments: hasConditionals ? worstSegments : void 0,
|
|
37
|
-
warnings,
|
|
38
|
-
compilerVersion: COMPILER_VERSION
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
//#endregion
|
|
42
|
-
export { VARIABLE_WORST_CASE_CHARS, compileSmsRoot };
|
|
43
|
-
|
|
44
|
-
//# sourceMappingURL=compile-sms.js.map
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { r as SmlCompileError, t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
-
import { f as ElementNode } from "./ast-BrDtApwS.js";
|
|
3
|
-
import { l as WHATSAPP_TAG_SPECS } from "./parser-t29cHLVL.js";
|
|
4
|
-
import { Result } from "better-result";
|
|
5
|
-
//#region src/compile-whatsapp.d.ts
|
|
6
|
-
type WhatsAppSpecs = typeof WHATSAPP_TAG_SPECS;
|
|
7
|
-
/** Mirrors whatsappTemplateCategoryEnum, derived from the grammar's closed set. */
|
|
8
|
-
type WhatsAppTemplateCategory = WhatsAppSpecs["WhatsApp"]["attributes"]["category"]["values"][number];
|
|
9
|
-
/** Header type as authored (`type` attribute; defaults to "text"). */
|
|
10
|
-
type WhatsAppHeaderType = WhatsAppSpecs["Header"]["attributes"]["type"]["values"][number];
|
|
11
|
-
type WhatsAppHeaderMediaType = Exclude<WhatsAppHeaderType, "text">;
|
|
12
|
-
/** Meta-wire button rows, stored as-is in the buttons jsonb column. */
|
|
13
|
-
type WhatsAppButtonPayload = {
|
|
14
|
-
readonly type: "QUICK_REPLY";
|
|
15
|
-
readonly text: string;
|
|
16
|
-
} | {
|
|
17
|
-
readonly type: "URL";
|
|
18
|
-
readonly text: string;
|
|
19
|
-
readonly url: string;
|
|
20
|
-
} | {
|
|
21
|
-
readonly type: "PHONE_NUMBER";
|
|
22
|
-
readonly text: string;
|
|
23
|
-
readonly phone_number: string;
|
|
24
|
-
} | {
|
|
25
|
-
readonly type: "COPY_CODE";
|
|
26
|
-
readonly example: string;
|
|
27
|
-
};
|
|
28
|
-
/** Variable names referenced per slot — the raw material for Meta example payloads. */
|
|
29
|
-
interface WhatsAppExamples {
|
|
30
|
-
readonly header?: ReadonlyArray<string> | undefined;
|
|
31
|
-
readonly body?: ReadonlyArray<string> | undefined;
|
|
32
|
-
readonly footer?: ReadonlyArray<string> | undefined;
|
|
33
|
-
readonly buttons?: ReadonlyArray<string> | undefined;
|
|
34
|
-
}
|
|
35
|
-
interface CompiledWhatsApp {
|
|
36
|
-
readonly channel: "whatsapp";
|
|
37
|
-
/** Authoring-intent metadata; the API layer defaults name from the template slug. */
|
|
38
|
-
readonly name?: string | undefined;
|
|
39
|
-
/** The API layer defaults language from the variant locale ("en_US"). */
|
|
40
|
-
readonly language?: string | undefined;
|
|
41
|
-
readonly category: WhatsAppTemplateCategory;
|
|
42
|
-
readonly headerType?: WhatsAppHeaderType | undefined;
|
|
43
|
-
readonly headerMediaType?: WhatsAppHeaderMediaType | undefined;
|
|
44
|
-
readonly headerContent?: string | undefined;
|
|
45
|
-
readonly bodyContent: string;
|
|
46
|
-
readonly footerContent?: string | undefined;
|
|
47
|
-
readonly buttons: ReadonlyArray<WhatsAppButtonPayload>;
|
|
48
|
-
readonly examples: WhatsAppExamples;
|
|
49
|
-
readonly warnings: ReadonlyArray<Diagnostic>;
|
|
50
|
-
readonly compilerVersion: string;
|
|
51
|
-
}
|
|
52
|
-
/** Root is a parsed `<WhatsApp>` element; the grammar already validated its anatomy. */
|
|
53
|
-
declare const compileWhatsAppRoot: (root: ElementNode) => Result<CompiledWhatsApp, SmlCompileError>;
|
|
54
|
-
//#endregion
|
|
55
|
-
export { CompiledWhatsApp, WhatsAppButtonPayload, WhatsAppExamples, WhatsAppHeaderMediaType, WhatsAppHeaderType, WhatsAppTemplateCategory, compileWhatsAppRoot };
|
|
56
|
-
//# sourceMappingURL=compile-whatsapp.d.ts.map
|
package/dist/compile-whatsapp.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { SmlCompileError } from "./diagnostics.js";
|
|
2
|
-
import { stringAttribute } from "./ast.js";
|
|
3
|
-
import { n as channelTextVariants, r as flattenChannelText, t as COMPILER_VERSION } from "./version-BITr58kk.js";
|
|
4
|
-
import { variableReferences } from "./interpolate.js";
|
|
5
|
-
import { Result } from "better-result";
|
|
6
|
-
//#region src/compile-whatsapp.ts
|
|
7
|
-
const WHATSAPP_BUTTON_LIMITS = {
|
|
8
|
-
URL: 2,
|
|
9
|
-
PHONE_NUMBER: 1,
|
|
10
|
-
QUICK_REPLY: 10,
|
|
11
|
-
total: 10
|
|
12
|
-
};
|
|
13
|
-
const WHATSAPP_HEADER_MAX = 60;
|
|
14
|
-
const WHATSAPP_FOOTER_MAX = 60;
|
|
15
|
-
const WHATSAPP_BODY_MAX = 1024;
|
|
16
|
-
const WHATSAPP_BUTTON_TEXT_MAX = 25;
|
|
17
|
-
const POSITIONAL_PATTERN = /\{\{\s*(\d+)\s*\}\}/;
|
|
18
|
-
const NAMED_PATTERN = /\{\{\s*([A-Za-z_][\w.]*)\s*\}\}/;
|
|
19
|
-
const LITERAL = "literal";
|
|
20
|
-
/** Longest possible send-time rendering of a slot, with literal placeholders. */
|
|
21
|
-
const worstCaseLength = (node) => Math.max(0, ...channelTextVariants(node.children, LITERAL).map((variant) => variant.length));
|
|
22
|
-
const component = (root, tag) => root.children.find((child) => child.kind === "element" && child.tag === tag);
|
|
23
|
-
const slotExamples = (texts) => {
|
|
24
|
-
const names = /* @__PURE__ */ new Set();
|
|
25
|
-
for (const text of texts) for (const name of variableReferences(text)) names.add(name);
|
|
26
|
-
return names.size === 0 ? void 0 : [...names].sort();
|
|
27
|
-
};
|
|
28
|
-
/** Root is a parsed `<WhatsApp>` element; the grammar already validated its anatomy. */
|
|
29
|
-
const compileWhatsAppRoot = (root) => {
|
|
30
|
-
const errors = [];
|
|
31
|
-
const warnings = [];
|
|
32
|
-
const header = component(root, "Header");
|
|
33
|
-
const body = component(root, "Body");
|
|
34
|
-
const footer = component(root, "Footer");
|
|
35
|
-
const buttonsNode = component(root, "Buttons");
|
|
36
|
-
const headerType = header === void 0 ? void 0 : stringAttribute(header, "type") ?? "text";
|
|
37
|
-
const headerContent = header === void 0 ? void 0 : flattenChannelText(header.children);
|
|
38
|
-
const bodyContent = flattenChannelText(body.children);
|
|
39
|
-
const footerContent = footer === void 0 ? void 0 : flattenChannelText(footer.children);
|
|
40
|
-
if (header !== void 0 && headerType === "text" && worstCaseLength(header) > WHATSAPP_HEADER_MAX) warnings.push({
|
|
41
|
-
code: "whatsapp-header-length",
|
|
42
|
-
message: `whatsapp header should stay under ${WHATSAPP_HEADER_MAX} characters`,
|
|
43
|
-
span: header.span
|
|
44
|
-
});
|
|
45
|
-
if (worstCaseLength(body) > WHATSAPP_BODY_MAX) warnings.push({
|
|
46
|
-
code: "whatsapp-body-length",
|
|
47
|
-
message: `whatsapp body should stay under ${WHATSAPP_BODY_MAX} characters`,
|
|
48
|
-
span: body.span
|
|
49
|
-
});
|
|
50
|
-
if (footer !== void 0 && worstCaseLength(footer) > WHATSAPP_FOOTER_MAX) warnings.push({
|
|
51
|
-
code: "whatsapp-footer-length",
|
|
52
|
-
message: `whatsapp footer should stay under ${WHATSAPP_FOOTER_MAX} characters`,
|
|
53
|
-
span: footer.span
|
|
54
|
-
});
|
|
55
|
-
const buttonElements = buttonsNode === void 0 ? [] : buttonsNode.children.filter((child) => child.kind === "element" && child.tag === "Button");
|
|
56
|
-
const buttons = [];
|
|
57
|
-
for (const button of buttonElements) {
|
|
58
|
-
const type = stringAttribute(button, "type");
|
|
59
|
-
const text = flattenChannelText(button.children);
|
|
60
|
-
const url = stringAttribute(button, "url");
|
|
61
|
-
const phone = stringAttribute(button, "phone");
|
|
62
|
-
if (url !== void 0 && type !== "url") {
|
|
63
|
-
errors.push({
|
|
64
|
-
code: "whatsapp-button-url",
|
|
65
|
-
message: `url is only valid on <Button type="url"> — remove it or change the type`,
|
|
66
|
-
span: button.span
|
|
67
|
-
});
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
if (phone !== void 0 && type !== "phone") {
|
|
71
|
-
errors.push({
|
|
72
|
-
code: "whatsapp-button-phone",
|
|
73
|
-
message: `phone is only valid on <Button type="phone"> — remove it or change the type`,
|
|
74
|
-
span: button.span
|
|
75
|
-
});
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (type !== "copy-code" && worstCaseLength(button) > WHATSAPP_BUTTON_TEXT_MAX) warnings.push({
|
|
79
|
-
code: "whatsapp-button-text-length",
|
|
80
|
-
message: `whatsapp button text should stay under ${WHATSAPP_BUTTON_TEXT_MAX} characters`,
|
|
81
|
-
span: button.span
|
|
82
|
-
});
|
|
83
|
-
switch (type) {
|
|
84
|
-
case "quick-reply":
|
|
85
|
-
buttons.push({
|
|
86
|
-
type: "QUICK_REPLY",
|
|
87
|
-
text
|
|
88
|
-
});
|
|
89
|
-
break;
|
|
90
|
-
case "url":
|
|
91
|
-
if (url === void 0) {
|
|
92
|
-
errors.push({
|
|
93
|
-
code: "whatsapp-button-url",
|
|
94
|
-
message: `<Button type="url"> requires a url attribute — add url="https://..."`,
|
|
95
|
-
span: button.span
|
|
96
|
-
});
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
buttons.push({
|
|
100
|
-
type: "URL",
|
|
101
|
-
text,
|
|
102
|
-
url
|
|
103
|
-
});
|
|
104
|
-
break;
|
|
105
|
-
case "phone":
|
|
106
|
-
if (phone === void 0) {
|
|
107
|
-
errors.push({
|
|
108
|
-
code: "whatsapp-button-phone",
|
|
109
|
-
message: `<Button type="phone"> requires a phone attribute — add phone="+15551234567"`,
|
|
110
|
-
span: button.span
|
|
111
|
-
});
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
buttons.push({
|
|
115
|
-
type: "PHONE_NUMBER",
|
|
116
|
-
text,
|
|
117
|
-
phone_number: phone
|
|
118
|
-
});
|
|
119
|
-
break;
|
|
120
|
-
case "copy-code": buttons.push({
|
|
121
|
-
type: "COPY_CODE",
|
|
122
|
-
example: text
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
const buttonsSpan = buttonsNode?.span ?? root.span;
|
|
127
|
-
const countOf = (type) => buttons.filter((button) => button.type === type).length;
|
|
128
|
-
if (countOf("URL") > WHATSAPP_BUTTON_LIMITS.URL) errors.push({
|
|
129
|
-
code: "whatsapp-button-limit",
|
|
130
|
-
message: `whatsapp allows at most ${WHATSAPP_BUTTON_LIMITS.URL} URL buttons`,
|
|
131
|
-
span: buttonsSpan
|
|
132
|
-
});
|
|
133
|
-
if (countOf("PHONE_NUMBER") > WHATSAPP_BUTTON_LIMITS.PHONE_NUMBER) errors.push({
|
|
134
|
-
code: "whatsapp-button-limit",
|
|
135
|
-
message: `whatsapp allows at most ${WHATSAPP_BUTTON_LIMITS.PHONE_NUMBER} phone-number button`,
|
|
136
|
-
span: buttonsSpan
|
|
137
|
-
});
|
|
138
|
-
if (countOf("QUICK_REPLY") > WHATSAPP_BUTTON_LIMITS.QUICK_REPLY) errors.push({
|
|
139
|
-
code: "whatsapp-button-limit",
|
|
140
|
-
message: `whatsapp allows at most ${WHATSAPP_BUTTON_LIMITS.QUICK_REPLY} quick-reply buttons`,
|
|
141
|
-
span: buttonsSpan
|
|
142
|
-
});
|
|
143
|
-
if (buttonElements.length > WHATSAPP_BUTTON_LIMITS.total) errors.push({
|
|
144
|
-
code: "whatsapp-button-limit",
|
|
145
|
-
message: `whatsapp allows at most ${WHATSAPP_BUTTON_LIMITS.total} buttons total`,
|
|
146
|
-
span: buttonsSpan
|
|
147
|
-
});
|
|
148
|
-
const placeholderSources = [
|
|
149
|
-
headerContent ?? "",
|
|
150
|
-
bodyContent,
|
|
151
|
-
footerContent ?? "",
|
|
152
|
-
...buttons.map((button) => button.type === "URL" ? button.url : "")
|
|
153
|
-
];
|
|
154
|
-
const hasPositional = placeholderSources.some((source) => POSITIONAL_PATTERN.test(source));
|
|
155
|
-
const hasNamed = placeholderSources.some((source) => NAMED_PATTERN.test(source));
|
|
156
|
-
if (hasPositional && hasNamed) warnings.push({
|
|
157
|
-
code: "whatsapp-mixed-placeholders",
|
|
158
|
-
message: "whatsapp mixes positional {{1}} and named {{var}} placeholders; Meta requires one style",
|
|
159
|
-
span: root.span
|
|
160
|
-
});
|
|
161
|
-
if (errors.length > 0) return Result.err(new SmlCompileError({ diagnostics: errors }));
|
|
162
|
-
return Result.ok({
|
|
163
|
-
channel: "whatsapp",
|
|
164
|
-
name: stringAttribute(root, "name"),
|
|
165
|
-
language: stringAttribute(root, "language"),
|
|
166
|
-
category: stringAttribute(root, "category"),
|
|
167
|
-
headerType,
|
|
168
|
-
headerMediaType: headerType === void 0 || headerType === "text" ? void 0 : headerType,
|
|
169
|
-
headerContent,
|
|
170
|
-
bodyContent,
|
|
171
|
-
footerContent,
|
|
172
|
-
buttons,
|
|
173
|
-
examples: {
|
|
174
|
-
header: slotExamples([headerContent ?? ""]),
|
|
175
|
-
body: slotExamples([bodyContent]),
|
|
176
|
-
footer: slotExamples([footerContent ?? ""]),
|
|
177
|
-
buttons: slotExamples(buttons.map((button) => button.type === "URL" ? `${button.text} ${button.url}` : button.type === "COPY_CODE" ? button.example : button.text))
|
|
178
|
-
},
|
|
179
|
-
warnings,
|
|
180
|
-
compilerVersion: COMPILER_VERSION
|
|
181
|
-
});
|
|
182
|
-
};
|
|
183
|
-
//#endregion
|
|
184
|
-
export { compileWhatsAppRoot };
|
|
185
|
-
|
|
186
|
-
//# sourceMappingURL=compile-whatsapp.js.map
|
package/dist/compile.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { i as SmlParseError, r as SmlCompileError } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
-
import { b as SmlDocument } from "./ast-BrDtApwS.js";
|
|
3
|
-
import { CompiledSms } from "./compile-sms.js";
|
|
4
|
-
import { CompiledWhatsApp } from "./compile-whatsapp.js";
|
|
5
|
-
import { Result } from "better-result";
|
|
6
|
-
//#region src/version.d.ts
|
|
7
|
-
declare const COMPILER_VERSION = "0.1.0";
|
|
8
|
-
//#endregion
|
|
9
|
-
//#region src/compile.d.ts
|
|
10
|
-
/** Structured channel payloads compiled from recorded SML. */
|
|
11
|
-
type CompiledTemplate = CompiledSms | CompiledWhatsApp;
|
|
12
|
-
/** Compile a structured document; email definitions execute through the email runtime. */
|
|
13
|
-
declare const compileSml: (document: SmlDocument) => Result<CompiledTemplate, SmlCompileError>;
|
|
14
|
-
/** Parse and compile a structured SMS or WhatsApp document. */
|
|
15
|
-
declare const compileSource: (source: string) => Result<CompiledTemplate, SmlParseError | SmlCompileError>;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { COMPILER_VERSION, CompiledTemplate, compileSml, compileSource };
|
|
18
|
-
//# sourceMappingURL=compile.d.ts.map
|
package/dist/compile.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { SmlCompileError } from "./diagnostics.js";
|
|
2
|
-
import { parseSml } from "./parser.js";
|
|
3
|
-
import { t as COMPILER_VERSION } from "./version-BITr58kk.js";
|
|
4
|
-
import { compileSmsRoot } from "./compile-sms.js";
|
|
5
|
-
import { compileWhatsAppRoot } from "./compile-whatsapp.js";
|
|
6
|
-
import { Result } from "better-result";
|
|
7
|
-
//#region src/compile.ts
|
|
8
|
-
/** Compile a structured document; email definitions execute through the email runtime. */
|
|
9
|
-
const compileSml = (document) => {
|
|
10
|
-
switch (document.root.tag) {
|
|
11
|
-
case "Sms": return Result.ok(compileSmsRoot(document.root));
|
|
12
|
-
case "WhatsApp": return compileWhatsAppRoot(document.root);
|
|
13
|
-
default: return Result.err(new SmlCompileError({ diagnostics: [{
|
|
14
|
-
code: "email-requires-object-template",
|
|
15
|
-
message: "Email templates must default-export defineEmail with an input schema and fixtures.",
|
|
16
|
-
span: document.root.span
|
|
17
|
-
}] }));
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
/** Parse and compile a structured SMS or WhatsApp document. */
|
|
21
|
-
const compileSource = (source) => {
|
|
22
|
-
const parsed = parseSml(source);
|
|
23
|
-
if (Result.isError(parsed)) return Result.err(parsed.error);
|
|
24
|
-
return compileSml(parsed.value);
|
|
25
|
-
};
|
|
26
|
-
//#endregion
|
|
27
|
-
export { COMPILER_VERSION, compileSml, compileSource };
|
|
28
|
-
|
|
29
|
-
//# sourceMappingURL=compile.js.map
|