@samva/markup 0.4.0 → 0.6.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 +19 -0
- package/dist/{ast-63I-VLQx.d.ts → ast-BrDtApwS.d.ts} +34 -60
- package/dist/ast.d.ts +2 -2
- package/dist/ast.js +4 -52
- package/dist/{catalog-Ck1tAGwO.d.ts → catalog-60eaYC7b.d.ts} +2 -2
- package/dist/{checks-DXuERO4B.js → checks-DBweSIPN.js} +18 -20
- package/dist/checks.d.ts +1 -1
- package/dist/checks.js +1 -1
- package/dist/classes.d.ts +1 -1
- package/dist/compile-sms.d.ts +3 -3
- package/dist/compile-whatsapp.d.ts +5 -5
- package/dist/compile-whatsapp.js +3 -3
- package/dist/compile.d.ts +5 -5
- package/dist/compile.js +5 -5
- package/dist/compiler.d.ts +8 -5
- package/dist/compiler.js +45 -45
- package/dist/components.d.ts +4 -4
- package/dist/conditionals.js +56 -24
- package/dist/corpus-BjYMqOoY.d.ts +106 -0
- package/dist/{css-ar2lU3NC.d.ts → css-COcFOT1y.d.ts} +4 -5
- package/dist/diagnostics-BMYtBCQk.d.ts +46 -0
- package/dist/diagnostics-OcQKQYSY.d.ts +49 -0
- package/dist/diagnostics.d.ts +2 -2
- package/dist/diagnostics.js +24 -33
- package/dist/{elements-DtwKlFVH.d.ts → elements-BzjjnoCS.d.ts} +40 -161
- package/dist/email/components.d.ts +1 -1
- package/dist/email/components.js +40 -10
- package/dist/email/diagnostics.d.ts +1 -1
- package/dist/email/diagnostics.js +8 -43
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -2
- package/dist/email/html.js +11 -10
- package/dist/email/jsx-dev-runtime.d.ts +3 -21
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/jsx-runtime.js +29 -3
- package/dist/email/render.d.ts +4 -4
- package/dist/email/render.js +1 -1
- package/dist/email/selection.d.ts +20 -31
- package/dist/email/selection.js +1 -53
- package/dist/email/source-edit.d.ts +1 -1
- package/dist/email/source-edit.js +2 -2
- package/dist/email/stylesheets.d.ts +1 -1
- package/dist/email/text.d.ts +1 -1
- package/dist/email/text.js +3 -3
- package/dist/emit.d.ts +2 -2
- package/dist/emit.js +5 -5
- package/dist/footer.js +7 -4
- package/dist/guards-eV1qLbf2.js +9 -0
- package/dist/{input-schema-BIfzI63B.d.ts → input-schema-7dPFVvNE.d.ts} +2 -2
- package/dist/input-schema-zjkgrXn2.js +455 -0
- package/dist/input-schema.d.ts +1 -1
- package/dist/input-schema.js +1 -169
- package/dist/interpolate.d.ts +9 -12
- package/dist/interpolate.js +1 -19
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/{jsx-runtime-C5k_Zq0A.d.ts → jsx-runtime-I-1nCtl2.d.ts} +3 -3
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/lexer.js +17 -5
- package/dist/model.d.ts +18 -33
- package/dist/model.js +4 -17
- package/dist/ops-2aiiYO7m.js +630 -0
- package/dist/ops.d.ts +78 -172
- package/dist/ops.js +2 -546
- package/dist/{parser-CGBS73Gz.d.ts → parser-CQcASEyy.d.ts} +5 -5
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +8 -8
- package/dist/{predicate-CvkzT-a2.js → predicate-BI6uRRM-.js} +24 -14
- package/dist/{predicate-G2SeSvoN.d.ts → predicate-M-05Nd7R.d.ts} +4 -4
- package/dist/predicate.d.ts +1 -1
- package/dist/predicate.js +1 -1
- package/dist/presets/category-mapping.d.ts +1 -1
- package/dist/presets/corpus.d.ts +1 -1
- package/dist/presets/corpus.js +74 -117
- package/dist/presets/public-gallery.d.ts +2 -2
- package/dist/presets/public-gallery.js +17 -9
- package/dist/presets/public-handoff.d.ts +4 -4
- package/dist/presets/public-handoff.js +10 -9
- package/dist/presets/public-preview-artifacts.d.ts +7 -5
- package/dist/presets/public-preview-artifacts.js +10 -9
- package/dist/presets/showcase.d.ts +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/printer.d.ts +1 -1
- package/dist/{render-ykQhtMs_.js → render-aaJBnsXK.js} +44 -27
- package/dist/render-template.d.ts +7 -7
- package/dist/render-template.js +6 -6
- package/dist/{showcase-C_xgl6hz.d.ts → showcase-DGZAWn4Z.d.ts} +2 -2
- package/dist/{source-locations-BCJQnIfU.d.ts → source-locations-DrCM82Ym.d.ts} +4 -26
- package/dist/source-locations.d.ts +2 -2
- package/dist/source-locations.js +3 -26
- package/dist/{template-Dy5yOPyp.d.ts → template-DWftqh4x.d.ts} +4 -4
- package/dist/template.d.ts +1 -1
- package/dist/template.js +3 -3
- package/dist/theme-css.d.ts +3 -3
- package/dist/theme-css.js +3 -3
- package/dist/theme.js +25 -2
- package/dist/tsx-source-instrumentation.d.ts +1 -3
- package/dist/tsx-source-instrumentation.js +6 -6
- package/dist/tsx-tracer.d.ts +7 -11
- package/dist/tsx-tracer.js +165 -165
- package/dist/{variables-if1VrV34.d.ts → variables-J_L3qxRa.d.ts} +2 -2
- package/dist/variables.d.ts +1 -1
- package/dist/variables.js +4 -4
- package/package.json +4 -3
- package/dist/corpus-U2EeALvS.d.ts +0 -234
- package/dist/diagnostics-Djd9ckLg.d.ts +0 -90
- package/dist/diagnostics-oveE-laV.d.ts +0 -79
|
@@ -1,169 +1,48 @@
|
|
|
1
|
-
import { i as JsxSourceLocation } from "./source-locations-
|
|
2
|
-
import { r as EmailDiagnostic } from "./diagnostics-
|
|
3
|
-
import { Data } from "effect";
|
|
1
|
+
import { i as JsxSourceLocation } from "./source-locations-DrCM82Ym.js";
|
|
2
|
+
import { r as EmailDiagnostic } from "./diagnostics-BMYtBCQk.js";
|
|
4
3
|
//#region src/email/jsx-runtime.d.ts
|
|
5
4
|
/** Derived authoring tree; source stays canonical. Origins run from inner element to component call sites. */
|
|
6
|
-
type EmailNode =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* True when this element is written at `origins[0]`; false when a compiler
|
|
17
|
-
* primitive generated it and `origins[0]` is the call site that asked for
|
|
18
|
-
* it. Both point at the same authoring target, but only an authored element
|
|
19
|
-
* can have its own props edited there.
|
|
20
|
-
*/
|
|
21
|
-
readonly authored: boolean;
|
|
22
|
-
};
|
|
23
|
-
Fragment: {
|
|
24
|
-
readonly children: readonly EmailNode[];
|
|
25
|
-
};
|
|
5
|
+
type EmailNode = {
|
|
6
|
+
readonly type: "Text";
|
|
7
|
+
readonly value: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly type: "Element";
|
|
10
|
+
readonly tag: string;
|
|
11
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
12
|
+
readonly children: readonly EmailNode[];
|
|
13
|
+
readonly origins: readonly JsxSourceLocation[];
|
|
26
14
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
15
|
+
* True when this element is written at `origins[0]`; false when a compiler
|
|
16
|
+
* primitive generated it and `origins[0]` is the call site that asked for
|
|
17
|
+
* it. Both point at the same authoring target, but only an authored element
|
|
18
|
+
* can have its own props edited there.
|
|
30
19
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
readonly authored: boolean;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: "Fragment";
|
|
23
|
+
readonly children: readonly EmailNode[];
|
|
24
|
+
} |
|
|
25
|
+
/**
|
|
26
|
+
* Compatibility markup a compiler primitive emits verbatim — conditional
|
|
27
|
+
* comments and VML. Only the primitives in `./components` construct it;
|
|
28
|
+
* nothing an author passes as a string reaches this node.
|
|
29
|
+
*/
|
|
30
|
+
{
|
|
31
|
+
readonly type: "Raw";
|
|
32
|
+
readonly html: string;
|
|
33
|
+
readonly text: string;
|
|
34
|
+
readonly origins: readonly JsxSourceLocation[];
|
|
35
|
+
};
|
|
36
|
+
type EmailNodeOf<Type extends EmailNode["type"]> = Extract<EmailNode, {
|
|
37
|
+
readonly type: Type;
|
|
36
38
|
}>;
|
|
39
|
+
type EmailNodeFields<Type extends EmailNode["type"]> = Omit<EmailNodeOf<Type>, "type">;
|
|
40
|
+
/** Constructors for the authoring tree. The tree is data; nothing here validates it. */
|
|
37
41
|
declare const EmailNode: {
|
|
38
|
-
readonly
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
readonly children: readonly EmailNode[];
|
|
43
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
44
|
-
readonly authored: boolean;
|
|
45
|
-
}, {
|
|
46
|
-
readonly _tag: Tag;
|
|
47
|
-
}> | Extract<{
|
|
48
|
-
readonly _tag: "Fragment";
|
|
49
|
-
readonly children: readonly EmailNode[];
|
|
50
|
-
}, {
|
|
51
|
-
readonly _tag: Tag;
|
|
52
|
-
}> | Extract<{
|
|
53
|
-
readonly _tag: "Raw";
|
|
54
|
-
readonly html: string;
|
|
55
|
-
readonly text: string;
|
|
56
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
57
|
-
}, {
|
|
58
|
-
readonly _tag: Tag;
|
|
59
|
-
}> | Extract<{
|
|
60
|
-
readonly _tag: "Text";
|
|
61
|
-
readonly value: string;
|
|
62
|
-
}, {
|
|
63
|
-
readonly _tag: Tag;
|
|
64
|
-
}>;
|
|
65
|
-
readonly $match: {
|
|
66
|
-
<Cases extends { readonly [Tag in "Element" | "Fragment" | "Raw" | "Text"]: (args: Extract<{
|
|
67
|
-
readonly _tag: "Element";
|
|
68
|
-
readonly tag: string;
|
|
69
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
70
|
-
readonly children: readonly EmailNode[];
|
|
71
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
72
|
-
readonly authored: boolean;
|
|
73
|
-
} | {
|
|
74
|
-
readonly _tag: "Fragment";
|
|
75
|
-
readonly children: readonly EmailNode[];
|
|
76
|
-
} | {
|
|
77
|
-
readonly _tag: "Raw";
|
|
78
|
-
readonly html: string;
|
|
79
|
-
readonly text: string;
|
|
80
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
81
|
-
} | {
|
|
82
|
-
readonly _tag: "Text";
|
|
83
|
-
readonly value: string;
|
|
84
|
-
}, {
|
|
85
|
-
readonly _tag: Tag;
|
|
86
|
-
}>) => any; }>(cases: Cases): (value: {
|
|
87
|
-
readonly _tag: "Element";
|
|
88
|
-
readonly tag: string;
|
|
89
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
90
|
-
readonly children: readonly EmailNode[];
|
|
91
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
92
|
-
readonly authored: boolean;
|
|
93
|
-
} | {
|
|
94
|
-
readonly _tag: "Fragment";
|
|
95
|
-
readonly children: readonly EmailNode[];
|
|
96
|
-
} | {
|
|
97
|
-
readonly _tag: "Raw";
|
|
98
|
-
readonly html: string;
|
|
99
|
-
readonly text: string;
|
|
100
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
101
|
-
} | {
|
|
102
|
-
readonly _tag: "Text";
|
|
103
|
-
readonly value: string;
|
|
104
|
-
}) => import("effect/Unify").Unify<ReturnType<Cases["Element" | "Fragment" | "Raw" | "Text"]>>;
|
|
105
|
-
<Cases extends { readonly [Tag in "Element" | "Fragment" | "Raw" | "Text"]: (args: Extract<{
|
|
106
|
-
readonly _tag: "Element";
|
|
107
|
-
readonly tag: string;
|
|
108
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
109
|
-
readonly children: readonly EmailNode[];
|
|
110
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
111
|
-
readonly authored: boolean;
|
|
112
|
-
} | {
|
|
113
|
-
readonly _tag: "Fragment";
|
|
114
|
-
readonly children: readonly EmailNode[];
|
|
115
|
-
} | {
|
|
116
|
-
readonly _tag: "Raw";
|
|
117
|
-
readonly html: string;
|
|
118
|
-
readonly text: string;
|
|
119
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
120
|
-
} | {
|
|
121
|
-
readonly _tag: "Text";
|
|
122
|
-
readonly value: string;
|
|
123
|
-
}, {
|
|
124
|
-
readonly _tag: Tag;
|
|
125
|
-
}>) => any; }>(value: {
|
|
126
|
-
readonly _tag: "Element";
|
|
127
|
-
readonly tag: string;
|
|
128
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
129
|
-
readonly children: readonly EmailNode[];
|
|
130
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
131
|
-
readonly authored: boolean;
|
|
132
|
-
} | {
|
|
133
|
-
readonly _tag: "Fragment";
|
|
134
|
-
readonly children: readonly EmailNode[];
|
|
135
|
-
} | {
|
|
136
|
-
readonly _tag: "Raw";
|
|
137
|
-
readonly html: string;
|
|
138
|
-
readonly text: string;
|
|
139
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
140
|
-
} | {
|
|
141
|
-
readonly _tag: "Text";
|
|
142
|
-
readonly value: string;
|
|
143
|
-
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Element" | "Fragment" | "Raw" | "Text"]>>;
|
|
144
|
-
};
|
|
145
|
-
readonly Element: Data.TaggedEnum.ConstructorFrom<{
|
|
146
|
-
readonly _tag: "Element";
|
|
147
|
-
readonly tag: string;
|
|
148
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
149
|
-
readonly children: readonly EmailNode[];
|
|
150
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
151
|
-
readonly authored: boolean;
|
|
152
|
-
}, "_tag">;
|
|
153
|
-
readonly Fragment: Data.TaggedEnum.ConstructorFrom<{
|
|
154
|
-
readonly _tag: "Fragment";
|
|
155
|
-
readonly children: readonly EmailNode[];
|
|
156
|
-
}, "_tag">;
|
|
157
|
-
readonly Raw: Data.TaggedEnum.ConstructorFrom<{
|
|
158
|
-
readonly _tag: "Raw";
|
|
159
|
-
readonly html: string;
|
|
160
|
-
readonly text: string;
|
|
161
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
162
|
-
}, "_tag">;
|
|
163
|
-
readonly Text: Data.TaggedEnum.ConstructorFrom<{
|
|
164
|
-
readonly _tag: "Text";
|
|
165
|
-
readonly value: string;
|
|
166
|
-
}, "_tag">;
|
|
42
|
+
readonly Text: (fields: EmailNodeFields<"Text">) => EmailNodeOf<"Text">;
|
|
43
|
+
readonly Element: (fields: EmailNodeFields<"Element">) => EmailNodeOf<"Element">;
|
|
44
|
+
readonly Fragment: (fields: EmailNodeFields<"Fragment">) => EmailNodeOf<"Fragment">;
|
|
45
|
+
readonly Raw: (fields: EmailNodeFields<"Raw">) => EmailNodeOf<"Raw">;
|
|
167
46
|
};
|
|
168
47
|
type EmailChild = EmailNode | string | number | boolean | null | undefined | readonly EmailChild[];
|
|
169
48
|
type EmailComponent<P = never> = (props: P) => EmailChild;
|
|
@@ -817,4 +696,4 @@ type ChildrenProp<Content extends EmailElementSpec["content"]> = Content extends
|
|
|
817
696
|
type EmailIntrinsicElements = { readonly [Tag in EmailTag]: EmailGlobalProps & AttributeProps<typeof EMAIL_GLOBAL_ATTRIBUTES> & AttributeProps<(typeof EMAIL_ELEMENTS)[Tag]["attributes"]> & ChildrenProp<(typeof EMAIL_ELEMENTS)[Tag]["content"]>; };
|
|
818
697
|
//#endregion
|
|
819
698
|
export { reportEmailDiagnostic as C, rawMarkup as S, currentEmailOrigins as _, EmailGlobalProps as a, jsxs as b, EmailStyle as c, isUrlAttribute as d, EmailChild as f, JSX as g, Fragment as h, EmailElementSpec as i, EmailTag as l, EmailNode as m, EMAIL_GLOBAL_ATTRIBUTES as n, EmailIntrinsicElements as o, EmailComponent as p, EmailAttributeSpec as r, EmailLayout as s, EMAIL_ELEMENTS as t, emailElement as u, drainEmailDiagnostics as v, normalizeChildren as x, jsx as y };
|
|
820
|
-
//# sourceMappingURL=elements-
|
|
699
|
+
//# sourceMappingURL=elements-BzjjnoCS.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-
|
|
1
|
+
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-BzjjnoCS.js";
|
|
2
2
|
//#region src/email/components.d.ts
|
|
3
3
|
/** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
|
|
4
4
|
declare const PREHEADER_ATTRIBUTE = "data-samva-preheader";
|
package/dist/email/components.js
CHANGED
|
@@ -107,24 +107,54 @@ const Column = ({ className, align, valign, width, style, children }) => jsx("td
|
|
|
107
107
|
const DEFAULT_BUTTON_FONT = "Helvetica, Arial, sans-serif";
|
|
108
108
|
/** Average advance of a bold sans-serif glyph, as a fraction of the font size. */
|
|
109
109
|
const BOLD_GLYPH_ADVANCE = .6;
|
|
110
|
+
const invalidButtonNumber = (name) => reportEmailDiagnostic({
|
|
111
|
+
code: "invalid-button-number",
|
|
112
|
+
severity: "error",
|
|
113
|
+
message: `<Button ${name}> must be a finite number.`
|
|
114
|
+
});
|
|
115
|
+
const buttonNumber = (name, value, fallback) => {
|
|
116
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
117
|
+
invalidButtonNumber(name);
|
|
118
|
+
return fallback;
|
|
119
|
+
};
|
|
120
|
+
const optionalButtonNumber = (name, value) => {
|
|
121
|
+
if (value === void 0) return void 0;
|
|
122
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
123
|
+
invalidButtonNumber(name);
|
|
124
|
+
};
|
|
125
|
+
const optionalPositiveButtonNumber = (name, value) => {
|
|
126
|
+
if (value === void 0) return void 0;
|
|
127
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
128
|
+
reportEmailDiagnostic({
|
|
129
|
+
code: "invalid-button-number",
|
|
130
|
+
severity: "error",
|
|
131
|
+
message: `<Button ${name}> must be a positive finite number.`
|
|
132
|
+
});
|
|
133
|
+
};
|
|
110
134
|
/** A link styled as a button, with a VML fallback so classic Outlook draws the shape. */
|
|
111
135
|
const Button = ({ className, href, width, height, paddingX = 16, backgroundColor = "#000000", color = "#ffffff", borderRadius = 0, borderColor, borderWidth = 0, fontSize = 16, fontFamily = DEFAULT_BUTTON_FONT, align = "left", style, children }) => {
|
|
136
|
+
const safeWidth = optionalButtonNumber("width", width);
|
|
137
|
+
const safeHeight = optionalPositiveButtonNumber("height", height);
|
|
138
|
+
const safePaddingX = buttonNumber("paddingX", paddingX, 16);
|
|
139
|
+
const safeBorderRadius = buttonNumber("borderRadius", borderRadius, 0);
|
|
140
|
+
const safeBorderWidth = buttonNumber("borderWidth", borderWidth, 0);
|
|
141
|
+
const safeFontSize = buttonNumber("fontSize", fontSize, 16);
|
|
112
142
|
const label = typeof children === "string" ? children : void 0;
|
|
113
|
-
const fallback =
|
|
143
|
+
const fallback = safeHeight !== void 0 && label !== void 0;
|
|
114
144
|
if (!fallback) reportEmailDiagnostic({
|
|
115
145
|
code: "button-outlook-fallback",
|
|
116
146
|
severity: "warning",
|
|
117
147
|
message: "<Button> draws its classic Outlook shape from VML, which needs a height and a plain string label. Without both, classic Windows Outlook shows an unstyled link.",
|
|
118
148
|
clients: ["outlook-windows"]
|
|
119
149
|
});
|
|
120
|
-
const arcsize =
|
|
121
|
-
const fallbackWidth =
|
|
150
|
+
const arcsize = safeHeight === void 0 ? 0 : Math.round(safeBorderRadius / safeHeight * 100);
|
|
151
|
+
const fallbackWidth = safeWidth ?? Math.ceil((label?.length ?? 0) * safeFontSize * BOLD_GLYPH_ADVANCE) + 2 * safePaddingX;
|
|
122
152
|
return presentation({
|
|
123
153
|
width: "100%",
|
|
124
154
|
style: { borderCollapse: "collapse" }
|
|
125
155
|
}, jsx("td", {
|
|
126
156
|
align,
|
|
127
|
-
children: [fallback ? rawMarkup(`<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${escapeAttribute(href)}" style="height:${
|
|
157
|
+
children: [fallback ? rawMarkup(`<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${escapeAttribute(href)}" style="height:${safeHeight}px;v-text-anchor:middle;width:${fallbackWidth}px;" arcsize="${arcsize}%" ${borderColor === void 0 ? "stroke=\"false\"" : `strokecolor="${escapeAttribute(borderColor)}" strokeweight="${safeBorderWidth}px"`} fillcolor="${escapeAttribute(backgroundColor)}"><w:anchorlock/><center style="color:${escapeAttribute(color)};font-family:${escapeAttribute(fontFamily)};font-size:${safeFontSize}px;font-weight:bold;">${escapeText(label)}</center></v:roundrect><![endif]-->`) : null, jsx("a", {
|
|
128
158
|
className,
|
|
129
159
|
href,
|
|
130
160
|
target: "_blank",
|
|
@@ -132,19 +162,19 @@ const Button = ({ className, href, width, height, paddingX = 16, backgroundColor
|
|
|
132
162
|
style: {
|
|
133
163
|
backgroundColor,
|
|
134
164
|
color,
|
|
135
|
-
borderRadius: `${
|
|
165
|
+
borderRadius: `${safeBorderRadius}px`,
|
|
136
166
|
display: "inline-block",
|
|
137
167
|
fontFamily,
|
|
138
|
-
fontSize: `${
|
|
168
|
+
fontSize: `${safeFontSize}px`,
|
|
139
169
|
fontWeight: "bold",
|
|
140
|
-
lineHeight:
|
|
170
|
+
lineHeight: safeHeight === void 0 ? "120%" : `${safeHeight - 2 * safeBorderWidth}px`,
|
|
141
171
|
textAlign: "center",
|
|
142
172
|
textDecoration: "none",
|
|
143
|
-
...
|
|
144
|
-
width: `${
|
|
173
|
+
...safeWidth === void 0 ? { padding: `0 ${safePaddingX}px` } : {
|
|
174
|
+
width: `${safeWidth}px`,
|
|
145
175
|
maxWidth: "100%"
|
|
146
176
|
},
|
|
147
|
-
...borderColor === void 0 ? {} : { border: `${
|
|
177
|
+
...borderColor === void 0 ? {} : { border: `${safeBorderWidth}px solid ${borderColor}` },
|
|
148
178
|
...fallback ? { msoHide: "all" } : {},
|
|
149
179
|
...style
|
|
150
180
|
},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-
|
|
1
|
+
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-BMYtBCQk.js";
|
|
2
2
|
export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
@@ -1,46 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Schema } from "effect";
|
|
1
|
+
import { TaggedError } from "better-result";
|
|
3
2
|
//#region src/email/diagnostics.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const EmailCompatibilityAssessment = Schema.Struct({
|
|
11
|
-
assessment: Schema.Literals([
|
|
12
|
-
"risk",
|
|
13
|
-
"degradation",
|
|
14
|
-
"unverified",
|
|
15
|
-
"not-applicable"
|
|
16
|
-
]),
|
|
17
|
-
/** A short description of the consequence or the remaining verification. */
|
|
18
|
-
title: Schema.String
|
|
19
|
-
});
|
|
20
|
-
const EmailDiagnostic = Schema.Struct({
|
|
21
|
-
/** Stable identifier, e.g. `unsupported-element` or `caniemail/css-border-radius`. */
|
|
22
|
-
code: Schema.String,
|
|
23
|
-
severity: EmailDiagnosticSeverity,
|
|
24
|
-
/** States what is wrong and what to write instead. */
|
|
25
|
-
message: Schema.String,
|
|
26
|
-
/** Innermost authoring element first, then each enclosing component call site. */
|
|
27
|
-
origins: Schema.Array(JsxSourceLocation),
|
|
28
|
-
/** Target clients a compatibility finding applies to. */
|
|
29
|
-
clients: Schema.optional(Schema.Array(Schema.String)),
|
|
30
|
-
/** Partial-support notes and other caveats a client matrix carries. */
|
|
31
|
-
notes: Schema.optional(Schema.String),
|
|
32
|
-
/** Which pinned rule data produced the finding. */
|
|
33
|
-
provenance: Schema.optional(Schema.String),
|
|
34
|
-
/** Declared fixtures whose rendered output produced this finding. */
|
|
35
|
-
fixtures: Schema.optional(Schema.Array(Schema.String)),
|
|
36
|
-
/** Source chains for every located emitted occurrence; origins identifies the first. */
|
|
37
|
-
occurrences: Schema.optional(Schema.Array(Schema.Array(JsxSourceLocation))),
|
|
38
|
-
/** Compatibility observations are not automatically defects or proof of client rendering. */
|
|
39
|
-
compatibility: Schema.optional(EmailCompatibilityAssessment)
|
|
40
|
-
});
|
|
41
|
-
var EmailCompileError = class extends Schema.TaggedError()("EmailCompileError", { diagnostics: Schema.Array(EmailDiagnostic) }) {
|
|
42
|
-
get message() {
|
|
43
|
-
return this.diagnostics.map(formatEmailDiagnostic).join("\n");
|
|
3
|
+
var EmailCompileError = class extends TaggedError("EmailCompileError") {
|
|
4
|
+
constructor(args) {
|
|
5
|
+
super({
|
|
6
|
+
diagnostics: args.diagnostics,
|
|
7
|
+
message: args.diagnostics.map(formatEmailDiagnostic).join("\n")
|
|
8
|
+
});
|
|
44
9
|
}
|
|
45
10
|
};
|
|
46
11
|
/** `emails/welcome.tsx:12:3 unsupported-element: …` — the shape agents iterate on. */
|
|
@@ -51,6 +16,6 @@ const formatEmailDiagnostic = (diagnostic) => {
|
|
|
51
16
|
/** True when a set of findings must stop the compile or refuse a publication. */
|
|
52
17
|
const hasBlockingDiagnostic = (diagnostics) => diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
53
18
|
//#endregion
|
|
54
|
-
export {
|
|
19
|
+
export { EmailCompileError, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
55
20
|
|
|
56
21
|
//# sourceMappingURL=diagnostics.js.map
|
package/dist/email/elements.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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-BzjjnoCS.js";
|
|
2
2
|
export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
|
package/dist/email/html.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "../diagnostics-
|
|
2
|
-
import { m as EmailNode } from "../elements-
|
|
1
|
+
import { r as EmailDiagnostic } from "../diagnostics-BMYtBCQk.js";
|
|
2
|
+
import { m as EmailNode } from "../elements-BzjjnoCS.js";
|
|
3
3
|
import { EmittedPosition } from "./selection.js";
|
|
4
4
|
//#region src/email/html.d.ts
|
|
5
5
|
/** Escape a value for element content. */
|
package/dist/email/html.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { n as isObject } from "../guards-eV1qLbf2.js";
|
|
1
2
|
import { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement } from "./elements.js";
|
|
2
3
|
import { INSTANCE_PATH_ATTRIBUTE } from "./selection.js";
|
|
3
|
-
import { Predicate } from "effect";
|
|
4
4
|
//#region src/email/html.ts
|
|
5
5
|
/** Escape a value for element content. */
|
|
6
6
|
const escapeText = (value) => value.replace(/[&<>]/g, (character) => ({
|
|
@@ -136,7 +136,7 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
136
136
|
}
|
|
137
137
|
if (name === "style") {
|
|
138
138
|
if (value === void 0 || value === null) continue;
|
|
139
|
-
if (!
|
|
139
|
+
if (!isObject(value) || Array.isArray(value)) {
|
|
140
140
|
report(sink, "invalid-style", `<${tag} style> must be a property object, for example style={{ backgroundColor: "#fff" }}.`, origins);
|
|
141
141
|
continue;
|
|
142
142
|
}
|
|
@@ -153,7 +153,8 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
153
153
|
if (text !== void 0) emitted.push(` ${name}="${escapeAttribute(text)}"`);
|
|
154
154
|
continue;
|
|
155
155
|
}
|
|
156
|
-
const
|
|
156
|
+
const globalAttributes = EMAIL_GLOBAL_ATTRIBUTES;
|
|
157
|
+
const attribute = Object.hasOwn(globalAttributes, name) ? globalAttributes[name] : Object.hasOwn(spec.attributes, name) ? spec.attributes[name] : void 0;
|
|
157
158
|
if (attribute === void 0) {
|
|
158
159
|
const supported = [
|
|
159
160
|
...Object.keys(EMAIL_GLOBAL_ATTRIBUTES),
|
|
@@ -172,24 +173,24 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
172
173
|
return emitted.join("");
|
|
173
174
|
};
|
|
174
175
|
/** Fragments are transparent to a content model; raw compatibility markup is not content. */
|
|
175
|
-
const contentChildren = (children) => children.flatMap((child) => child.
|
|
176
|
+
const contentChildren = (children) => children.flatMap((child) => child.type === "Fragment" ? contentChildren(child.children) : [child]);
|
|
176
177
|
const checkContentModel = (sink, tag, spec, children, origins) => {
|
|
177
178
|
if (spec.content === "void") {
|
|
178
179
|
if (contentChildren(children).length > 0) report(sink, "void-element-children", `<${tag}> cannot have children.`, origins);
|
|
179
180
|
return;
|
|
180
181
|
}
|
|
181
182
|
if (spec.content === "text" || spec.content === "raw") {
|
|
182
|
-
for (const child of contentChildren(children)) if (child.
|
|
183
|
+
for (const child of contentChildren(children)) if (child.type !== "Text") report(sink, "invalid-content", `<${tag}> accepts text only.`, child.type === "Element" ? child.origins : origins);
|
|
183
184
|
return;
|
|
184
185
|
}
|
|
185
186
|
if (spec.childElements === void 0) return;
|
|
186
187
|
for (const child of contentChildren(children)) {
|
|
187
|
-
if (child.
|
|
188
|
-
if (child.
|
|
188
|
+
if (child.type === "Raw") continue;
|
|
189
|
+
if (child.type === "Text") {
|
|
189
190
|
if (child.value.trim() !== "") report(sink, "invalid-content", `<${tag}> cannot contain text directly; put it inside <${spec.childElements[0]}>.`, origins);
|
|
190
191
|
continue;
|
|
191
192
|
}
|
|
192
|
-
if (child.
|
|
193
|
+
if (child.type === "Element" && !spec.childElements.includes(child.tag)) report(sink, "invalid-content", `<${tag}> accepts only ${spec.childElements.map((name) => `<${name}>`).join(", ")}; found <${child.tag}>.`, child.origins);
|
|
193
194
|
}
|
|
194
195
|
};
|
|
195
196
|
/** Every write goes through here so `sink.written` stays the emitted offset. */
|
|
@@ -198,7 +199,7 @@ const emit = (sink, text) => {
|
|
|
198
199
|
return text;
|
|
199
200
|
};
|
|
200
201
|
const serialize = (sink, node, parentPath, counter) => {
|
|
201
|
-
switch (node.
|
|
202
|
+
switch (node.type) {
|
|
202
203
|
case "Text": return emit(sink, escapeText(node.value));
|
|
203
204
|
case "Raw": return emit(sink, node.html);
|
|
204
205
|
case "Fragment": return node.children.map((child) => serialize(sink, child, parentPath, counter)).join("");
|
|
@@ -215,7 +216,7 @@ const serialize = (sink, node, parentPath, counter) => {
|
|
|
215
216
|
}
|
|
216
217
|
checkContentModel(sink, node.tag, spec, node.children, node.origins);
|
|
217
218
|
if (spec.content === "raw") {
|
|
218
|
-
const css = node.children.map((child) => child.
|
|
219
|
+
const css = node.children.map((child) => child.type === "Text" ? child.value : "").join("");
|
|
219
220
|
if (/<\/|<!--/i.test(css)) {
|
|
220
221
|
report(sink, "unsafe-raw-text", `<${node.tag}> content cannot contain markup.`, node.origins);
|
|
221
222
|
return "";
|
|
@@ -1,26 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as JSX, h as Fragment, m as EmailNode, p as EmailComponent } from "../elements-
|
|
1
|
+
import { r as JsxSource } from "../source-locations-DrCM82Ym.js";
|
|
2
|
+
import { g as JSX, h as Fragment, m as EmailNode, p as EmailComponent } from "../elements-BzjjnoCS.js";
|
|
3
3
|
//#region src/email/jsx-dev-runtime.d.ts
|
|
4
4
|
/** Development JSX retains compiler-provided origins directly on the semantic tree. */
|
|
5
|
-
declare const jsxDEV: (type: string | EmailComponent<Record<string, unknown>> | typeof Fragment, props: Record<string, unknown> | null, _key?: unknown, _staticChildren?: boolean, source?: JsxSource) =>
|
|
6
|
-
readonly _tag: "Element";
|
|
7
|
-
readonly tag: string;
|
|
8
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
9
|
-
readonly children: readonly EmailNode[];
|
|
10
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
11
|
-
readonly authored: boolean;
|
|
12
|
-
} | {
|
|
13
|
-
readonly _tag: "Fragment";
|
|
14
|
-
readonly children: readonly EmailNode[];
|
|
15
|
-
} | {
|
|
16
|
-
readonly _tag: "Raw";
|
|
17
|
-
readonly html: string;
|
|
18
|
-
readonly text: string;
|
|
19
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
20
|
-
} | {
|
|
21
|
-
readonly _tag: "Text";
|
|
22
|
-
readonly value: string;
|
|
23
|
-
};
|
|
5
|
+
declare const jsxDEV: (type: string | EmailComponent<Record<string, unknown>> | typeof Fragment, props: Record<string, unknown> | null, _key?: unknown, _staticChildren?: boolean, source?: JsxSource) => EmailNode;
|
|
24
6
|
//#endregion
|
|
25
7
|
export { Fragment, type JSX, jsxDEV };
|
|
26
8
|
//# sourceMappingURL=jsx-dev-runtime.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as reportEmailDiagnostic, S as rawMarkup, _ as currentEmailOrigins, b as jsxs, f as EmailChild, g as JSX, h as Fragment, m as EmailNode, p as EmailComponent, v as drainEmailDiagnostics, x as normalizeChildren, y as jsx } from "../elements-
|
|
1
|
+
import { C as reportEmailDiagnostic, S as rawMarkup, _ as currentEmailOrigins, b as jsxs, f as EmailChild, g as JSX, h as Fragment, m as EmailNode, p as EmailComponent, v as drainEmailDiagnostics, x as normalizeChildren, y as jsx } from "../elements-BzjjnoCS.js";
|
|
2
2
|
export { EmailChild, EmailComponent, EmailNode, Fragment, JSX, currentEmailOrigins, drainEmailDiagnostics, jsx, jsxs, normalizeChildren, rawMarkup, reportEmailDiagnostic };
|
|
@@ -1,7 +1,33 @@
|
|
|
1
|
+
import { t as hasProperty } from "../guards-eV1qLbf2.js";
|
|
1
2
|
import { JSX_SOURCE_LOCATION_PROP, completeJsxSourceLocation } from "../source-locations.js";
|
|
2
|
-
import { Data, Predicate } from "effect";
|
|
3
3
|
//#region src/email/jsx-runtime.ts
|
|
4
|
-
|
|
4
|
+
/** Constructors for the authoring tree. The tree is data; nothing here validates it. */
|
|
5
|
+
const EmailNode = {
|
|
6
|
+
Text: (fields) => ({
|
|
7
|
+
type: "Text",
|
|
8
|
+
...fields
|
|
9
|
+
}),
|
|
10
|
+
Element: (fields) => ({
|
|
11
|
+
type: "Element",
|
|
12
|
+
...fields
|
|
13
|
+
}),
|
|
14
|
+
Fragment: (fields) => ({
|
|
15
|
+
type: "Fragment",
|
|
16
|
+
...fields
|
|
17
|
+
}),
|
|
18
|
+
Raw: (fields) => ({
|
|
19
|
+
type: "Raw",
|
|
20
|
+
...fields
|
|
21
|
+
})
|
|
22
|
+
};
|
|
23
|
+
const EMAIL_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
24
|
+
"Text",
|
|
25
|
+
"Element",
|
|
26
|
+
"Fragment",
|
|
27
|
+
"Raw"
|
|
28
|
+
]);
|
|
29
|
+
/** True for a node this runtime built; anything else is not a child it can place. */
|
|
30
|
+
const isEmailNode = (input) => hasProperty(input, "type") && typeof input.type === "string" && EMAIL_NODE_TYPES.has(input.type);
|
|
5
31
|
const Fragment = Symbol.for("@samva/markup/email/Fragment");
|
|
6
32
|
const callSites = [];
|
|
7
33
|
/** Call sites enclosing the element being built, innermost first. */
|
|
@@ -22,7 +48,7 @@ const normalizeChildren = (input) => {
|
|
|
22
48
|
if (typeof input === "string") return [EmailNode.Text({ value: input })];
|
|
23
49
|
if (typeof input === "number" && Number.isFinite(input)) return [EmailNode.Text({ value: String(input) })];
|
|
24
50
|
if (Array.isArray(input)) return input.flatMap(normalizeChildren);
|
|
25
|
-
if (
|
|
51
|
+
if (isEmailNode(input)) return [input];
|
|
26
52
|
throw new TypeError("Email children must be synchronous text, finite numbers, elements, or arrays");
|
|
27
53
|
};
|
|
28
54
|
/** Compatibility markup emitted by a compiler primitive, with the text it stands for. */
|
package/dist/email/render.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "../diagnostics-
|
|
2
|
-
import { m as EmailNode } from "../elements-
|
|
1
|
+
import { r as EmailDiagnostic } from "../diagnostics-BMYtBCQk.js";
|
|
2
|
+
import { m as EmailNode } from "../elements-BzjjnoCS.js";
|
|
3
3
|
import { EmittedPosition } from "./selection.js";
|
|
4
4
|
import { SerializeEmailOptions } from "./html.js";
|
|
5
|
-
import { r as TemplateDefinition } from "../template-
|
|
6
|
-
import { i as Stylesheet } from "../css-
|
|
5
|
+
import { r as TemplateDefinition } from "../template-DWftqh4x.js";
|
|
6
|
+
import { i as Stylesheet } from "../css-COcFOT1y.js";
|
|
7
7
|
//#region src/email/render.d.ts
|
|
8
8
|
/** Classic Outlook lays a document out correctly only under a transitional doctype. */
|
|
9
9
|
declare const EMAIL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
|
package/dist/email/render.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as renderEmail, n as bindStylesheets, r as compileEmail, t as EMAIL_DOCTYPE } from "../render-
|
|
1
|
+
import { i as renderEmail, n as bindStylesheets, r as compileEmail, t as EMAIL_DOCTYPE } from "../render-aaJBnsXK.js";
|
|
2
2
|
import "./html.js";
|
|
3
3
|
import "./diagnostics.js";
|
|
4
4
|
import "./stylesheets.js";
|