@endora-commerce/email-components 0.100.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/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/components/email-branding-preview-context.d.ts +7 -0
- package/dist/components/email-branding-preview-context.d.ts.map +1 -0
- package/dist/components/email-branding-preview-context.js +8 -0
- package/dist/components/email-branding-preview-context.js.map +1 -0
- package/dist/components/email-embeds-context.d.ts +11 -0
- package/dist/components/email-embeds-context.d.ts.map +1 -0
- package/dist/components/email-embeds-context.js +15 -0
- package/dist/components/email-embeds-context.js.map +1 -0
- package/dist/config.d.ts +333 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +900 -0
- package/dist/config.js.map +1 -0
- package/dist/defaults/default-footer.d.ts +13 -0
- package/dist/defaults/default-footer.d.ts.map +1 -0
- package/dist/defaults/default-footer.js +42 -0
- package/dist/defaults/default-footer.js.map +1 -0
- package/dist/defaults/default-header.d.ts +5 -0
- package/dist/defaults/default-header.d.ts.map +1 -0
- package/dist/defaults/default-header.js +34 -0
- package/dist/defaults/default-header.js.map +1 -0
- package/dist/defaults/simple-email-body.d.ts +20 -0
- package/dist/defaults/simple-email-body.d.ts.map +1 -0
- package/dist/defaults/simple-email-body.js +41 -0
- package/dist/defaults/simple-email-body.js.map +1 -0
- package/dist/directives/directive-engine.d.ts +7 -0
- package/dist/directives/directive-engine.d.ts.map +1 -0
- package/dist/directives/directive-engine.js +144 -0
- package/dist/directives/directive-engine.js.map +1 -0
- package/dist/editor/email-row-layout-presets.d.ts +33 -0
- package/dist/editor/email-row-layout-presets.d.ts.map +1 -0
- package/dist/editor/email-row-layout-presets.js +145 -0
- package/dist/editor/email-row-layout-presets.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/render/escape-html.d.ts +4 -0
- package/dist/render/escape-html.d.ts.map +1 -0
- package/dist/render/escape-html.js +21 -0
- package/dist/render/escape-html.js.map +1 -0
- package/dist/render/order-labels.d.ts +23 -0
- package/dist/render/order-labels.d.ts.map +1 -0
- package/dist/render/order-labels.js +46 -0
- package/dist/render/order-labels.js.map +1 -0
- package/dist/render/render-email-html.d.ts +18 -0
- package/dist/render/render-email-html.d.ts.map +1 -0
- package/dist/render/render-email-html.js +659 -0
- package/dist/render/render-email-html.js.map +1 -0
- package/dist/render/render-email-text.d.ts +11 -0
- package/dist/render/render-email-text.d.ts.map +1 -0
- package/dist/render/render-email-text.js +167 -0
- package/dist/render/render-email-text.js.map +1 -0
- package/dist/render/sample-variables.d.ts +15 -0
- package/dist/render/sample-variables.d.ts.map +1 -0
- package/dist/render/sample-variables.js +43 -0
- package/dist/render/sample-variables.js.map +1 -0
- package/dist/render/sanitize-email-html.d.ts +9 -0
- package/dist/render/sanitize-email-html.d.ts.map +1 -0
- package/dist/render/sanitize-email-html.js +122 -0
- package/dist/render/sanitize-email-html.js.map +1 -0
- package/dist/render/social-icon-svg.d.ts +6 -0
- package/dist/render/social-icon-svg.d.ts.map +1 -0
- package/dist/render/social-icon-svg.js +41 -0
- package/dist/render/social-icon-svg.js.map +1 -0
- package/dist/schema/component-types.d.ts +269 -0
- package/dist/schema/component-types.d.ts.map +1 -0
- package/dist/schema/component-types.js +105 -0
- package/dist/schema/component-types.js.map +1 -0
- package/dist/schema/envelope.d.ts +21 -0
- package/dist/schema/envelope.d.ts.map +1 -0
- package/dist/schema/envelope.js +8 -0
- package/dist/schema/envelope.js.map +1 -0
- package/dist/tree/walk-embeds.d.ts +7 -0
- package/dist/tree/walk-embeds.d.ts.map +1 -0
- package/dist/tree/walk-embeds.js +115 -0
- package/dist/tree/walk-embeds.js.map +1 -0
- package/package.json +71 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
export type EmailHeadingLevel = 'h1' | 'h2' | 'h3';
|
|
2
|
+
export type EmailAlign = 'left' | 'center' | 'right';
|
|
3
|
+
export interface EmailHeadingProps {
|
|
4
|
+
level: EmailHeadingLevel;
|
|
5
|
+
text: string;
|
|
6
|
+
align: EmailAlign;
|
|
7
|
+
}
|
|
8
|
+
export interface EmailTextProps {
|
|
9
|
+
/** Plain text; newlines become <br>. May contain {{var ...}} directives. */
|
|
10
|
+
text: string;
|
|
11
|
+
align: EmailAlign;
|
|
12
|
+
}
|
|
13
|
+
export interface EmailButtonProps {
|
|
14
|
+
label: string;
|
|
15
|
+
href: string;
|
|
16
|
+
align: EmailAlign;
|
|
17
|
+
backgroundColor: string;
|
|
18
|
+
textColor: string;
|
|
19
|
+
}
|
|
20
|
+
export interface EmailImageProps {
|
|
21
|
+
/** `url` = freeform `src`; `library` = assets library `assetId` (src synced to absolute URL in admin). */
|
|
22
|
+
imageSource?: 'url' | 'library';
|
|
23
|
+
src: string;
|
|
24
|
+
assetId?: string;
|
|
25
|
+
alt: string;
|
|
26
|
+
href: string;
|
|
27
|
+
width: number;
|
|
28
|
+
align: EmailAlign;
|
|
29
|
+
}
|
|
30
|
+
export interface EmailDividerProps {
|
|
31
|
+
/** Line thickness in px (1–8). */
|
|
32
|
+
thickness: number;
|
|
33
|
+
color: string;
|
|
34
|
+
}
|
|
35
|
+
export interface EmailSpacerProps {
|
|
36
|
+
height: number;
|
|
37
|
+
}
|
|
38
|
+
export interface EmailTableHeader {
|
|
39
|
+
label: string;
|
|
40
|
+
}
|
|
41
|
+
export interface EmailTableCell {
|
|
42
|
+
value: string;
|
|
43
|
+
}
|
|
44
|
+
export interface EmailTableRow {
|
|
45
|
+
cells: EmailTableCell[];
|
|
46
|
+
}
|
|
47
|
+
export interface EmailTableProps {
|
|
48
|
+
columns: EmailTableHeader[];
|
|
49
|
+
tableRows: EmailTableRow[];
|
|
50
|
+
striped: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface EmailInsertBlockProps {
|
|
53
|
+
code: string;
|
|
54
|
+
}
|
|
55
|
+
export interface EmailInsertTemplateProps {
|
|
56
|
+
code: string;
|
|
57
|
+
}
|
|
58
|
+
export interface EmailSectionProps {
|
|
59
|
+
backgroundColor: string;
|
|
60
|
+
paddingY: number;
|
|
61
|
+
paddingX: number;
|
|
62
|
+
/** Puck slot — nested email-safe nodes (also resolved from zones). */
|
|
63
|
+
content?: unknown;
|
|
64
|
+
}
|
|
65
|
+
export type EmailVerticalAlign = 'top' | 'middle' | 'bottom';
|
|
66
|
+
/**
|
|
67
|
+
* Multi-column row for email — rendered as a fixed table (not responsive).
|
|
68
|
+
* Children must be {@link EmailColumn} nodes (Puck slot `allow`).
|
|
69
|
+
*/
|
|
70
|
+
export interface EmailRowProps {
|
|
71
|
+
/** Horizontal gap between columns (px); applied as cell padding in HTML. */
|
|
72
|
+
gap: number;
|
|
73
|
+
verticalAlign: EmailVerticalAlign;
|
|
74
|
+
content?: unknown;
|
|
75
|
+
}
|
|
76
|
+
/** A single column inside {@link EmailRow}; holds nested email-safe blocks. */
|
|
77
|
+
export interface EmailColumnProps {
|
|
78
|
+
/** Width on a 12-column grid (canvas + HTML %). */
|
|
79
|
+
span: number;
|
|
80
|
+
content?: unknown;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Brand logo block. `src` is always the branding directive at send time;
|
|
84
|
+
* the admin canvas resolves the live logo URL from branding settings.
|
|
85
|
+
*/
|
|
86
|
+
export interface EmailLogoProps {
|
|
87
|
+
/** Persist as `{{var branding.logoUrl}}` — not author-edited. */
|
|
88
|
+
src: string;
|
|
89
|
+
alt: string;
|
|
90
|
+
href: string;
|
|
91
|
+
width: number;
|
|
92
|
+
align: EmailAlign;
|
|
93
|
+
}
|
|
94
|
+
export interface EmailRichTextProps {
|
|
95
|
+
/** TipTap JSON (editor round-trip). */
|
|
96
|
+
content: unknown;
|
|
97
|
+
/** Sanitized email-safe HTML; may contain {{var}} markers in text. */
|
|
98
|
+
html: string;
|
|
99
|
+
align: EmailAlign;
|
|
100
|
+
}
|
|
101
|
+
export interface EmailProductCardProps {
|
|
102
|
+
/** Catalog product slug (authoring picker). */
|
|
103
|
+
productSlug: string;
|
|
104
|
+
productId: string;
|
|
105
|
+
imageSrc: string;
|
|
106
|
+
title: string;
|
|
107
|
+
sku: string;
|
|
108
|
+
price: string;
|
|
109
|
+
href: string;
|
|
110
|
+
ctaLabel: string;
|
|
111
|
+
showImage: boolean;
|
|
112
|
+
showPrice: boolean;
|
|
113
|
+
showSku: boolean;
|
|
114
|
+
align: EmailAlign;
|
|
115
|
+
}
|
|
116
|
+
export interface EmailProductGridItem {
|
|
117
|
+
productId: string;
|
|
118
|
+
productSlug: string;
|
|
119
|
+
title: string;
|
|
120
|
+
sku: string;
|
|
121
|
+
price: string;
|
|
122
|
+
href: string;
|
|
123
|
+
imageSrc: string;
|
|
124
|
+
}
|
|
125
|
+
/** Multi-product table grid (email-safe; baked item snapshots at authoring time). */
|
|
126
|
+
export interface EmailProductGridProps {
|
|
127
|
+
productSlugs: string[];
|
|
128
|
+
columns: number;
|
|
129
|
+
gap: number;
|
|
130
|
+
showImage: boolean;
|
|
131
|
+
showPrice: boolean;
|
|
132
|
+
showSku: boolean;
|
|
133
|
+
ctaLabel: string;
|
|
134
|
+
items: EmailProductGridItem[];
|
|
135
|
+
}
|
|
136
|
+
export interface EmailCategoryGridItem {
|
|
137
|
+
categoryId: string;
|
|
138
|
+
categorySlug: string;
|
|
139
|
+
title: string;
|
|
140
|
+
href: string;
|
|
141
|
+
imageSrc: string;
|
|
142
|
+
}
|
|
143
|
+
/** Multi-category table grid (email-safe; baked item snapshots at authoring time). */
|
|
144
|
+
export interface EmailCategoryGridProps {
|
|
145
|
+
categorySlugs: string[];
|
|
146
|
+
columns: number;
|
|
147
|
+
gap: number;
|
|
148
|
+
showImage: boolean;
|
|
149
|
+
items: EmailCategoryGridItem[];
|
|
150
|
+
}
|
|
151
|
+
export interface EmailOrderSummaryProps {
|
|
152
|
+
/** Heading above the line items. */
|
|
153
|
+
title: string;
|
|
154
|
+
showSku: boolean;
|
|
155
|
+
showName: boolean;
|
|
156
|
+
showQuantity: boolean;
|
|
157
|
+
showPrice: boolean;
|
|
158
|
+
showTotals: boolean;
|
|
159
|
+
/** Outer spacing above the block (px). */
|
|
160
|
+
marginTop: number;
|
|
161
|
+
/** Outer spacing below the block (px). */
|
|
162
|
+
marginBottom: number;
|
|
163
|
+
/**
|
|
164
|
+
* @deprecated Prefer column toggles; kept for legacy trees.
|
|
165
|
+
* When set and no column flags are used, rendered as plain body.
|
|
166
|
+
*/
|
|
167
|
+
body?: string;
|
|
168
|
+
}
|
|
169
|
+
/** Shared props for labeled order detail blocks (address, totals, methods, …). */
|
|
170
|
+
export interface EmailOrderLabeledVarProps {
|
|
171
|
+
title: string;
|
|
172
|
+
/** Outer spacing above the block (px). */
|
|
173
|
+
marginTop: number;
|
|
174
|
+
/** Outer spacing below the block (px). */
|
|
175
|
+
marginBottom: number;
|
|
176
|
+
}
|
|
177
|
+
/** Default vertical rhythm for order detail blocks in the canvas / send HTML. */
|
|
178
|
+
export declare const EMAIL_ORDER_BLOCK_MARGIN_DEFAULT = 12;
|
|
179
|
+
/**
|
|
180
|
+
* Order-confirmation detail blocks → template variable they emit.
|
|
181
|
+
* Palette-gated via {@link EMAIL_COMPONENT_REQUIRED_VARIABLES}.
|
|
182
|
+
*/
|
|
183
|
+
export declare const EMAIL_ORDER_LABELED_FIELDS: {
|
|
184
|
+
readonly 'orders.EmailOrderId': {
|
|
185
|
+
readonly label: "Order ID";
|
|
186
|
+
readonly defaultTitle: "Order";
|
|
187
|
+
readonly varKey: "order.businessId";
|
|
188
|
+
readonly previewHint: "ORD-1042";
|
|
189
|
+
};
|
|
190
|
+
readonly 'orders.EmailBillingAddress': {
|
|
191
|
+
readonly label: "Billing address";
|
|
192
|
+
readonly defaultTitle: "Billing address";
|
|
193
|
+
readonly varKey: "order.billingAddressText";
|
|
194
|
+
readonly previewHint: "Acme Sp. z o.o.\nul. Główna 1";
|
|
195
|
+
};
|
|
196
|
+
readonly 'orders.EmailShippingAddress': {
|
|
197
|
+
readonly label: "Shipping address";
|
|
198
|
+
readonly defaultTitle: "Shipping address";
|
|
199
|
+
readonly varKey: "order.shippingAddressText";
|
|
200
|
+
readonly previewHint: "Anna Nowak\nul. Główna 1";
|
|
201
|
+
};
|
|
202
|
+
readonly 'orders.EmailOrderTotals': {
|
|
203
|
+
readonly label: "Summary";
|
|
204
|
+
readonly defaultTitle: "Summary";
|
|
205
|
+
readonly varKey: "order.summaryText";
|
|
206
|
+
readonly previewHint: "Suma częściowa: …\nVAT: …\nRazem: …";
|
|
207
|
+
};
|
|
208
|
+
readonly 'orders.EmailAppliedDiscounts': {
|
|
209
|
+
readonly label: "Applied discounts";
|
|
210
|
+
readonly defaultTitle: "Applied discounts";
|
|
211
|
+
readonly varKey: "order.discountsText";
|
|
212
|
+
readonly previewHint: "SUMMER10: -50,00 PLN";
|
|
213
|
+
};
|
|
214
|
+
readonly 'orders.EmailDeliveryMethod': {
|
|
215
|
+
readonly label: "Delivery method";
|
|
216
|
+
readonly defaultTitle: "Delivery method";
|
|
217
|
+
readonly varKey: "order.shippingLine";
|
|
218
|
+
readonly previewHint: "Courier — 15,00 PLN";
|
|
219
|
+
};
|
|
220
|
+
readonly 'orders.EmailPaymentMethod': {
|
|
221
|
+
readonly label: "Payment method";
|
|
222
|
+
readonly defaultTitle: "Payment method";
|
|
223
|
+
readonly varKey: "order.paymentLine";
|
|
224
|
+
readonly previewHint: "Card (+5,00 PLN)";
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
export type EmailOrderLabeledFieldName = keyof typeof EMAIL_ORDER_LABELED_FIELDS;
|
|
228
|
+
export type EmailSocialNetwork = 'facebook' | 'instagram' | 'linkedin' | 'x' | 'youtube' | 'tiktok' | 'other';
|
|
229
|
+
export interface EmailSocialLink {
|
|
230
|
+
network: EmailSocialNetwork;
|
|
231
|
+
href: string;
|
|
232
|
+
label?: string;
|
|
233
|
+
/** When false, the link is hidden. Default true. */
|
|
234
|
+
enabled?: boolean;
|
|
235
|
+
}
|
|
236
|
+
export interface EmailSocialProps {
|
|
237
|
+
links: EmailSocialLink[];
|
|
238
|
+
align: EmailAlign;
|
|
239
|
+
showIcons: boolean;
|
|
240
|
+
showLabels: boolean;
|
|
241
|
+
iconSize: number;
|
|
242
|
+
useBrandColors: boolean;
|
|
243
|
+
/** Used when useBrandColors is false. */
|
|
244
|
+
color: string;
|
|
245
|
+
}
|
|
246
|
+
export interface EmailCalloutProps {
|
|
247
|
+
text: string;
|
|
248
|
+
backgroundColor: string;
|
|
249
|
+
borderColor: string;
|
|
250
|
+
textColor: string;
|
|
251
|
+
align: EmailAlign;
|
|
252
|
+
}
|
|
253
|
+
export interface EmailFooterLegalProps {
|
|
254
|
+
text: string;
|
|
255
|
+
align: EmailAlign;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Canonical set of component names the email editor exposes and the renderer
|
|
259
|
+
* understands. Used by the admin palette and by backend save-time validation.
|
|
260
|
+
*/
|
|
261
|
+
export declare const EMAIL_SAFE_COMPONENT_NAMES: readonly ["transactional_emails.EmailHeading", "transactional_emails.EmailText", "transactional_emails.EmailButton", "transactional_emails.EmailImage", "transactional_emails.EmailDivider", "transactional_emails.EmailSpacer", "transactional_emails.EmailTable", "transactional_emails.EmailInsertBlock", "transactional_emails.EmailSection", "transactional_emails.EmailRow", "transactional_emails.EmailColumn", "transactional_emails.EmailLogo", "transactional_emails.EmailRichText", "catalog.EmailProductCard", "catalog.EmailProductGrid", "catalog.EmailCategoryGrid", "orders.EmailOrderSummary", "orders.EmailOrderId", "orders.EmailBillingAddress", "orders.EmailShippingAddress", "orders.EmailOrderTotals", "orders.EmailAppliedDiscounts", "orders.EmailDeliveryMethod", "orders.EmailPaymentMethod", "transactional_emails.EmailSocial", "transactional_emails.EmailCallout", "transactional_emails.EmailFooterLegal"];
|
|
262
|
+
/**
|
|
263
|
+
* Palette components that only make sense when the email declares these variables.
|
|
264
|
+
* Used by the admin editor to hide commerce blocks outside their owning templates.
|
|
265
|
+
*/
|
|
266
|
+
export declare const EMAIL_COMPONENT_REQUIRED_VARIABLES: Readonly<Record<string, readonly string[]>>;
|
|
267
|
+
export type EmailComponentName = (typeof EMAIL_SAFE_COMPONENT_NAMES)[number];
|
|
268
|
+
export declare function isEmailSafeComponentName(name: string): name is EmailComponentName;
|
|
269
|
+
//# sourceMappingURL=component-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-types.d.ts","sourceRoot":"","sources":["../../src/schema/component-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Email-safe component prop shapes (feature 047 + email builder expansion).
|
|
2
|
+
// Kept React-free so the pure backend renderer and the admin Puck editor share
|
|
3
|
+
// one source of truth. Every component renders to table-based, inline-styled
|
|
4
|
+
// HTML (no flexbox/grid/script).
|
|
5
|
+
/** Default vertical rhythm for order detail blocks in the canvas / send HTML. */
|
|
6
|
+
export const EMAIL_ORDER_BLOCK_MARGIN_DEFAULT = 12;
|
|
7
|
+
/**
|
|
8
|
+
* Order-confirmation detail blocks → template variable they emit.
|
|
9
|
+
* Palette-gated via {@link EMAIL_COMPONENT_REQUIRED_VARIABLES}.
|
|
10
|
+
*/
|
|
11
|
+
export const EMAIL_ORDER_LABELED_FIELDS = {
|
|
12
|
+
'orders.EmailOrderId': {
|
|
13
|
+
label: 'Order ID',
|
|
14
|
+
defaultTitle: 'Order',
|
|
15
|
+
varKey: 'order.businessId',
|
|
16
|
+
previewHint: 'ORD-1042',
|
|
17
|
+
},
|
|
18
|
+
'orders.EmailBillingAddress': {
|
|
19
|
+
label: 'Billing address',
|
|
20
|
+
defaultTitle: 'Billing address',
|
|
21
|
+
varKey: 'order.billingAddressText',
|
|
22
|
+
previewHint: 'Acme Sp. z o.o.\nul. Główna 1',
|
|
23
|
+
},
|
|
24
|
+
'orders.EmailShippingAddress': {
|
|
25
|
+
label: 'Shipping address',
|
|
26
|
+
defaultTitle: 'Shipping address',
|
|
27
|
+
varKey: 'order.shippingAddressText',
|
|
28
|
+
previewHint: 'Anna Nowak\nul. Główna 1',
|
|
29
|
+
},
|
|
30
|
+
'orders.EmailOrderTotals': {
|
|
31
|
+
label: 'Summary',
|
|
32
|
+
defaultTitle: 'Summary',
|
|
33
|
+
varKey: 'order.summaryText',
|
|
34
|
+
previewHint: 'Suma częściowa: …\nVAT: …\nRazem: …',
|
|
35
|
+
},
|
|
36
|
+
'orders.EmailAppliedDiscounts': {
|
|
37
|
+
label: 'Applied discounts',
|
|
38
|
+
defaultTitle: 'Applied discounts',
|
|
39
|
+
varKey: 'order.discountsText',
|
|
40
|
+
previewHint: 'SUMMER10: -50,00 PLN',
|
|
41
|
+
},
|
|
42
|
+
'orders.EmailDeliveryMethod': {
|
|
43
|
+
label: 'Delivery method',
|
|
44
|
+
defaultTitle: 'Delivery method',
|
|
45
|
+
varKey: 'order.shippingLine',
|
|
46
|
+
previewHint: 'Courier — 15,00 PLN',
|
|
47
|
+
},
|
|
48
|
+
'orders.EmailPaymentMethod': {
|
|
49
|
+
label: 'Payment method',
|
|
50
|
+
defaultTitle: 'Payment method',
|
|
51
|
+
varKey: 'order.paymentLine',
|
|
52
|
+
previewHint: 'Card (+5,00 PLN)',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Canonical set of component names the email editor exposes and the renderer
|
|
57
|
+
* understands. Used by the admin palette and by backend save-time validation.
|
|
58
|
+
*/
|
|
59
|
+
export const EMAIL_SAFE_COMPONENT_NAMES = [
|
|
60
|
+
'transactional_emails.EmailHeading',
|
|
61
|
+
'transactional_emails.EmailText',
|
|
62
|
+
'transactional_emails.EmailButton',
|
|
63
|
+
'transactional_emails.EmailImage',
|
|
64
|
+
'transactional_emails.EmailDivider',
|
|
65
|
+
'transactional_emails.EmailSpacer',
|
|
66
|
+
'transactional_emails.EmailTable',
|
|
67
|
+
'transactional_emails.EmailInsertBlock',
|
|
68
|
+
'transactional_emails.EmailSection',
|
|
69
|
+
'transactional_emails.EmailRow',
|
|
70
|
+
'transactional_emails.EmailColumn',
|
|
71
|
+
'transactional_emails.EmailLogo',
|
|
72
|
+
'transactional_emails.EmailRichText',
|
|
73
|
+
'catalog.EmailProductCard',
|
|
74
|
+
'catalog.EmailProductGrid',
|
|
75
|
+
'catalog.EmailCategoryGrid',
|
|
76
|
+
'orders.EmailOrderSummary',
|
|
77
|
+
'orders.EmailOrderId',
|
|
78
|
+
'orders.EmailBillingAddress',
|
|
79
|
+
'orders.EmailShippingAddress',
|
|
80
|
+
'orders.EmailOrderTotals',
|
|
81
|
+
'orders.EmailAppliedDiscounts',
|
|
82
|
+
'orders.EmailDeliveryMethod',
|
|
83
|
+
'orders.EmailPaymentMethod',
|
|
84
|
+
'transactional_emails.EmailSocial',
|
|
85
|
+
'transactional_emails.EmailCallout',
|
|
86
|
+
'transactional_emails.EmailFooterLegal',
|
|
87
|
+
];
|
|
88
|
+
/**
|
|
89
|
+
* Palette components that only make sense when the email declares these variables.
|
|
90
|
+
* Used by the admin editor to hide commerce blocks outside their owning templates.
|
|
91
|
+
*/
|
|
92
|
+
export const EMAIL_COMPONENT_REQUIRED_VARIABLES = {
|
|
93
|
+
'orders.EmailOrderSummary': ['order.items'],
|
|
94
|
+
'orders.EmailOrderId': ['order.businessId'],
|
|
95
|
+
'orders.EmailBillingAddress': ['order.billingAddressText'],
|
|
96
|
+
'orders.EmailShippingAddress': ['order.shippingAddressText'],
|
|
97
|
+
'orders.EmailOrderTotals': ['order.summaryText'],
|
|
98
|
+
'orders.EmailAppliedDiscounts': ['order.discountsText'],
|
|
99
|
+
'orders.EmailDeliveryMethod': ['order.shippingLine'],
|
|
100
|
+
'orders.EmailPaymentMethod': ['order.paymentLine'],
|
|
101
|
+
};
|
|
102
|
+
export function isEmailSafeComponentName(name) {
|
|
103
|
+
return EMAIL_SAFE_COMPONENT_NAMES.includes(name);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=component-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-types.js","sourceRoot":"","sources":["../../src/schema/component-types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,iCAAiC;AA4MjC,iFAAiF;AACjF,MAAM,CAAC,MAAM,gCAAgC,GAAG,EAAE,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,qBAAqB,EAAE;QACrB,KAAK,EAAE,UAAU;QACjB,YAAY,EAAE,OAAO;QACrB,MAAM,EAAE,kBAAkB;QAC1B,WAAW,EAAE,UAAU;KACxB;IACD,4BAA4B,EAAE;QAC5B,KAAK,EAAE,iBAAiB;QACxB,YAAY,EAAE,iBAAiB;QAC/B,MAAM,EAAE,0BAA0B;QAClC,WAAW,EAAE,+BAA+B;KAC7C;IACD,6BAA6B,EAAE;QAC7B,KAAK,EAAE,kBAAkB;QACzB,YAAY,EAAE,kBAAkB;QAChC,MAAM,EAAE,2BAA2B;QACnC,WAAW,EAAE,0BAA0B;KACxC;IACD,yBAAyB,EAAE;QACzB,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,SAAS;QACvB,MAAM,EAAE,mBAAmB;QAC3B,WAAW,EAAE,qCAAqC;KACnD;IACD,8BAA8B,EAAE;QAC9B,KAAK,EAAE,mBAAmB;QAC1B,YAAY,EAAE,mBAAmB;QACjC,MAAM,EAAE,qBAAqB;QAC7B,WAAW,EAAE,sBAAsB;KACpC;IACD,4BAA4B,EAAE;QAC5B,KAAK,EAAE,iBAAiB;QACxB,YAAY,EAAE,iBAAiB;QAC/B,MAAM,EAAE,oBAAoB;QAC5B,WAAW,EAAE,qBAAqB;KACnC;IACD,2BAA2B,EAAE;QAC3B,KAAK,EAAE,gBAAgB;QACvB,YAAY,EAAE,gBAAgB;QAC9B,MAAM,EAAE,mBAAmB;QAC3B,WAAW,EAAE,kBAAkB;KAChC;CACO,CAAC;AA6CX;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,mCAAmC;IACnC,gCAAgC;IAChC,kCAAkC;IAClC,iCAAiC;IACjC,mCAAmC;IACnC,kCAAkC;IAClC,iCAAiC;IACjC,uCAAuC;IACvC,mCAAmC;IACnC,+BAA+B;IAC/B,kCAAkC;IAClC,gCAAgC;IAChC,oCAAoC;IACpC,0BAA0B;IAC1B,0BAA0B;IAC1B,2BAA2B;IAC3B,0BAA0B;IAC1B,qBAAqB;IACrB,4BAA4B;IAC5B,6BAA6B;IAC7B,yBAAyB;IACzB,8BAA8B;IAC9B,4BAA4B;IAC5B,2BAA2B;IAC3B,kCAAkC;IAClC,mCAAmC;IACnC,uCAAuC;CAC/B,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAgD;IAC7F,0BAA0B,EAAE,CAAC,aAAa,CAAC;IAC3C,qBAAqB,EAAE,CAAC,kBAAkB,CAAC;IAC3C,4BAA4B,EAAE,CAAC,0BAA0B,CAAC;IAC1D,6BAA6B,EAAE,CAAC,2BAA2B,CAAC;IAC5D,yBAAyB,EAAE,CAAC,mBAAmB,CAAC;IAChD,8BAA8B,EAAE,CAAC,qBAAqB,CAAC;IACvD,4BAA4B,EAAE,CAAC,oBAAoB,CAAC;IACpD,2BAA2B,EAAE,CAAC,mBAAmB,CAAC;CACnD,CAAC;AAIF,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAQ,0BAAgD,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const CURRENT_EMAIL_SCHEMA_VERSION: 1;
|
|
2
|
+
/**
|
|
3
|
+
* A single Puck data tree as produced by the email editor for one language.
|
|
4
|
+
* Treated as opaque at this layer — Puck's actual type lives in
|
|
5
|
+
* `@measured/puck`; we round-trip the shape verbatim through the envelope.
|
|
6
|
+
*/
|
|
7
|
+
export type PuckDataTree = {
|
|
8
|
+
root?: {
|
|
9
|
+
props?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
content?: unknown[];
|
|
12
|
+
zones?: Record<string, unknown[]>;
|
|
13
|
+
} & Record<string, unknown>;
|
|
14
|
+
export interface EmailContentEnvelope {
|
|
15
|
+
/** Bumped only when the wire shape of a node changes. */
|
|
16
|
+
schema_version: number;
|
|
17
|
+
/** Per-language content trees keyed by BCP-47 language code. */
|
|
18
|
+
languages: Record<string, PuckDataTree>;
|
|
19
|
+
}
|
|
20
|
+
export declare function emptyEmailEnvelope(): EmailContentEnvelope;
|
|
21
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/schema/envelope.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,4BAA4B,EAAG,CAAU,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC3C,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACnC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC;AAED,wBAAgB,kBAAkB,IAAI,oBAAoB,CAEzD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Email content envelope (feature 047) — mirrors the CMS envelope shape so the
|
|
2
|
+
// admin Puck editor produces the same wire format, but is owned here so the
|
|
3
|
+
// backend never imports CMS internals (Constitution Principle I).
|
|
4
|
+
export const CURRENT_EMAIL_SCHEMA_VERSION = 1;
|
|
5
|
+
export function emptyEmailEnvelope() {
|
|
6
|
+
return { schema_version: CURRENT_EMAIL_SCHEMA_VERSION, languages: {} };
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/schema/envelope.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,kEAAkE;AAElE,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAU,CAAC;AAoBvD,MAAM,UAAU,kBAAkB;IAChC,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function walkBlockEmbeds(tree: unknown): Set<string>;
|
|
2
|
+
export declare function walkTemplateEmbeds(tree: unknown): Set<string>;
|
|
3
|
+
/** Component type names present in the tree that are not in `knownNames`. */
|
|
4
|
+
export declare function walkUnknownComponents(tree: unknown, knownNames: ReadonlySet<string>): Set<string>;
|
|
5
|
+
/** Asset ids referenced anywhere in the tree (props whose key ends in `assetId`). */
|
|
6
|
+
export declare function walkAssetIds(tree: unknown): Set<string>;
|
|
7
|
+
//# sourceMappingURL=walk-embeds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-embeds.d.ts","sourceRoot":"","sources":["../../src/tree/walk-embeds.ts"],"names":[],"mappings":"AA2EA,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAE7D;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAQjG;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAgBvD"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Pure content-tree walkers (feature 047) — mirror the CMS content-tree-walker
|
|
2
|
+
// for the email domain. Used to resolve block/template embeds before rendering
|
|
3
|
+
// and to validate references / collect asset ids.
|
|
4
|
+
/**
|
|
5
|
+
* TipTap authoring JSON lives on EmailRichText.props.content and uses node/mark
|
|
6
|
+
* types like `doc`, `paragraph`, `text`, `bold`. Those are not Puck components
|
|
7
|
+
* and must not be flagged by {@link walkUnknownComponents}.
|
|
8
|
+
*/
|
|
9
|
+
const TIPTAP_NODE_OR_MARK_TYPES = new Set([
|
|
10
|
+
'doc',
|
|
11
|
+
'paragraph',
|
|
12
|
+
'text',
|
|
13
|
+
'heading',
|
|
14
|
+
'bulletList',
|
|
15
|
+
'orderedList',
|
|
16
|
+
'listItem',
|
|
17
|
+
'hardBreak',
|
|
18
|
+
'horizontalRule',
|
|
19
|
+
'blockquote',
|
|
20
|
+
'codeBlock',
|
|
21
|
+
'image',
|
|
22
|
+
'bold',
|
|
23
|
+
'italic',
|
|
24
|
+
'underline',
|
|
25
|
+
'strike',
|
|
26
|
+
'code',
|
|
27
|
+
'link',
|
|
28
|
+
]);
|
|
29
|
+
function walk(node, visit) {
|
|
30
|
+
if (Array.isArray(node)) {
|
|
31
|
+
for (const child of node)
|
|
32
|
+
walk(child, visit);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (node && typeof node === 'object') {
|
|
36
|
+
const obj = node;
|
|
37
|
+
if (typeof obj['type'] === 'string')
|
|
38
|
+
visit(obj);
|
|
39
|
+
// EmailRichText.props.content is TipTap JSON — do not treat it as nested Puck.
|
|
40
|
+
if (obj['type'] === 'transactional_emails.EmailRichText') {
|
|
41
|
+
const props = obj['props'];
|
|
42
|
+
if (props && typeof props === 'object') {
|
|
43
|
+
for (const [key, value] of Object.entries(props)) {
|
|
44
|
+
if (key === 'content')
|
|
45
|
+
continue;
|
|
46
|
+
if (value && typeof value === 'object')
|
|
47
|
+
walk(value, visit);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
51
|
+
if (key === 'type' || key === 'props')
|
|
52
|
+
continue;
|
|
53
|
+
if (value && typeof value === 'object')
|
|
54
|
+
walk(value, visit);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
for (const value of Object.values(obj)) {
|
|
59
|
+
if (value && typeof value === 'object')
|
|
60
|
+
walk(value, visit);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function collectEmbedCodes(tree, typeName) {
|
|
65
|
+
const codes = new Set();
|
|
66
|
+
walk(tree, (n) => {
|
|
67
|
+
if (n.type === typeName && n.props && typeof n.props === 'object') {
|
|
68
|
+
const code = n.props['code'];
|
|
69
|
+
if (typeof code === 'string' && code.length > 0)
|
|
70
|
+
codes.add(code);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return codes;
|
|
74
|
+
}
|
|
75
|
+
export function walkBlockEmbeds(tree) {
|
|
76
|
+
return collectEmbedCodes(tree, 'transactional_emails.EmailInsertBlock');
|
|
77
|
+
}
|
|
78
|
+
export function walkTemplateEmbeds(tree) {
|
|
79
|
+
return collectEmbedCodes(tree, 'transactional_emails.EmailInsertTemplate');
|
|
80
|
+
}
|
|
81
|
+
/** Component type names present in the tree that are not in `knownNames`. */
|
|
82
|
+
export function walkUnknownComponents(tree, knownNames) {
|
|
83
|
+
const unknown = new Set();
|
|
84
|
+
walk(tree, (n) => {
|
|
85
|
+
if (typeof n.type !== 'string')
|
|
86
|
+
return;
|
|
87
|
+
if (TIPTAP_NODE_OR_MARK_TYPES.has(n.type))
|
|
88
|
+
return;
|
|
89
|
+
if (!knownNames.has(n.type))
|
|
90
|
+
unknown.add(n.type);
|
|
91
|
+
});
|
|
92
|
+
return unknown;
|
|
93
|
+
}
|
|
94
|
+
/** Asset ids referenced anywhere in the tree (props whose key ends in `assetId`). */
|
|
95
|
+
export function walkAssetIds(tree) {
|
|
96
|
+
const ids = new Set();
|
|
97
|
+
const visit = (node) => {
|
|
98
|
+
if (Array.isArray(node)) {
|
|
99
|
+
for (const c of node)
|
|
100
|
+
visit(c);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (node && typeof node === 'object') {
|
|
104
|
+
for (const [key, value] of Object.entries(node)) {
|
|
105
|
+
if (/assetId$/i.test(key) && typeof value === 'string' && value.length > 0)
|
|
106
|
+
ids.add(value);
|
|
107
|
+
else if (value && typeof value === 'object')
|
|
108
|
+
visit(value);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
visit(tree);
|
|
113
|
+
return ids;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=walk-embeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-embeds.js","sourceRoot":"","sources":["../../src/tree/walk-embeds.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@endora-commerce/email-components",
|
|
3
|
+
"version": "0.100.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Shared transactional-email building blocks (feature 047). Pure, React-free render/* + directives/* + tree/* + schema/* + defaults/* are imported by the backend to render email-client-safe HTML and plain text; the React components/* + config.ts power the admin's email-safe Puck editor. The split keeps React out of the backend send path (Principle I/IV).",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/endora-commerce/endora-commerce.git",
|
|
10
|
+
"directory": "packages/email-components"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./*": {
|
|
23
|
+
"types": "./dist/*.d.ts",
|
|
24
|
+
"default": "./dist/*.js"
|
|
25
|
+
},
|
|
26
|
+
"./components/*": {
|
|
27
|
+
"types": "./dist/components/*.d.ts",
|
|
28
|
+
"default": "./dist/components/*.js"
|
|
29
|
+
},
|
|
30
|
+
"./tailwind.css": "./tailwind.css"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"tailwind.css"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=22.18.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@measured/puck": "*",
|
|
41
|
+
"react": "^19.0.0",
|
|
42
|
+
"react-dom": "^19.0.0",
|
|
43
|
+
"@endora-commerce/page-builder-core": "^0.100.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"@measured/puck": {
|
|
47
|
+
"optional": true
|
|
48
|
+
},
|
|
49
|
+
"react": {
|
|
50
|
+
"optional": true
|
|
51
|
+
},
|
|
52
|
+
"react-dom": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@measured/puck": "*",
|
|
58
|
+
"@types/react": "^19.2.14",
|
|
59
|
+
"react": "^19.0.0",
|
|
60
|
+
"react-dom": "^19.0.0",
|
|
61
|
+
"typescript": "^5.9.3",
|
|
62
|
+
"vitest": "^4.1.11",
|
|
63
|
+
"@endora-commerce/page-builder-core": "^0.100.0"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "tsc -p tsconfig.build.json",
|
|
67
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
68
|
+
"lint": "eslint src",
|
|
69
|
+
"test": "vitest run"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/tailwind.css
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* @endora-commerce/email-components — AUTO-GENERATED by `pnpm --filter backend run manifests:generate`.
|
|
2
|
+
*
|
|
3
|
+
* The `@source` directives this package asks its host to scan
|
|
4
|
+
* (`specs/110-instance-repository/contracts/admin-stylesheet-composition.md` R1).
|
|
5
|
+
* They resolve relative to **this file**, so they hold wherever the package is
|
|
6
|
+
* installed — a workspace link here, `node_modules` in a client's instance.
|
|
7
|
+
*
|
|
8
|
+
* The `dist` line is what a published tarball ships and is what an instance
|
|
9
|
+
* scans; the `src` line is inert there and is what keeps `pnpm --filter admin
|
|
10
|
+
* run dev` reading source in this repository. Do not edit: run
|
|
11
|
+
* `pnpm --filter backend run manifests:generate`.
|
|
12
|
+
*/
|
|
13
|
+
@source "./dist";
|
|
14
|
+
@source "./src";
|