@clay-design-system/email 0.2.4 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/MIGRATION.md +31 -0
  2. package/README.md +7 -0
  3. package/dist/build/catalog.d.ts +0 -1
  4. package/dist/generated/email-tokens.d.ts +0 -1
  5. package/dist/generated/email-tokens.js +0 -1
  6. package/dist/index.d.ts +1 -2
  7. package/dist/index.js +0 -1
  8. package/package.json +14 -5
  9. package/dist/build/asset-scoring.d.ts +0 -48
  10. package/dist/build/asset-scoring.d.ts.map +0 -1
  11. package/dist/build/asset-scoring.js +0 -58
  12. package/dist/build/asset-scoring.js.map +0 -1
  13. package/dist/build/braze-transform.d.ts +0 -20
  14. package/dist/build/braze-transform.d.ts.map +0 -1
  15. package/dist/build/braze-transform.js +0 -26
  16. package/dist/build/braze-transform.js.map +0 -1
  17. package/dist/build/catalog.d.ts.map +0 -1
  18. package/dist/build/catalog.js +0 -3
  19. package/dist/build/catalog.js.map +0 -1
  20. package/dist/build/cloudinary-env.d.ts +0 -15
  21. package/dist/build/cloudinary-env.d.ts.map +0 -1
  22. package/dist/build/cloudinary-env.js +0 -36
  23. package/dist/build/cloudinary-env.js.map +0 -1
  24. package/dist/build/cloudinary-manifest.d.ts +0 -33
  25. package/dist/build/cloudinary-manifest.d.ts.map +0 -1
  26. package/dist/build/cloudinary-manifest.js +0 -36
  27. package/dist/build/cloudinary-manifest.js.map +0 -1
  28. package/dist/build/compile.d.ts +0 -11
  29. package/dist/build/compile.d.ts.map +0 -1
  30. package/dist/build/compile.js +0 -234
  31. package/dist/build/compile.js.map +0 -1
  32. package/dist/build/email-config.d.ts +0 -26
  33. package/dist/build/email-config.d.ts.map +0 -1
  34. package/dist/build/email-config.js +0 -17
  35. package/dist/build/email-config.js.map +0 -1
  36. package/dist/build/email-list.d.ts +0 -6
  37. package/dist/build/email-list.d.ts.map +0 -1
  38. package/dist/build/email-list.js +0 -17
  39. package/dist/build/email-list.js.map +0 -1
  40. package/dist/build/email-tree.d.ts +0 -23
  41. package/dist/build/email-tree.d.ts.map +0 -1
  42. package/dist/build/email-tree.js +0 -46
  43. package/dist/build/email-tree.js.map +0 -1
  44. package/dist/build/export-braze.d.ts +0 -22
  45. package/dist/build/export-braze.d.ts.map +0 -1
  46. package/dist/build/export-braze.js +0 -92
  47. package/dist/build/export-braze.js.map +0 -1
  48. package/dist/build/generate-stock-library-map.d.ts +0 -13
  49. package/dist/build/generate-stock-library-map.d.ts.map +0 -1
  50. package/dist/build/generate-stock-library-map.js +0 -202
  51. package/dist/build/generate-stock-library-map.js.map +0 -1
  52. package/dist/build/icon-registry-map.d.ts +0 -34
  53. package/dist/build/icon-registry-map.d.ts.map +0 -1
  54. package/dist/build/icon-registry-map.js +0 -44
  55. package/dist/build/icon-registry-map.js.map +0 -1
  56. package/dist/build/import-examples.d.ts +0 -14
  57. package/dist/build/import-examples.d.ts.map +0 -1
  58. package/dist/build/import-examples.js +0 -65
  59. package/dist/build/import-examples.js.map +0 -1
  60. package/dist/build/persona-character-map.d.ts +0 -32
  61. package/dist/build/persona-character-map.d.ts.map +0 -1
  62. package/dist/build/persona-character-map.js +0 -90
  63. package/dist/build/persona-character-map.js.map +0 -1
  64. package/dist/build/placeholder.d.ts +0 -79
  65. package/dist/build/placeholder.d.ts.map +0 -1
  66. package/dist/build/placeholder.js +0 -148
  67. package/dist/build/placeholder.js.map +0 -1
  68. package/dist/build/stock-library-map.d.ts +0 -57
  69. package/dist/build/stock-library-map.d.ts.map +0 -1
  70. package/dist/build/stock-library-map.js +0 -1261
  71. package/dist/build/stock-library-map.js.map +0 -1
  72. package/dist/build/upload-assets.d.ts +0 -20
  73. package/dist/build/upload-assets.d.ts.map +0 -1
  74. package/dist/build/upload-assets.js +0 -153
  75. package/dist/build/upload-assets.js.map +0 -1
  76. package/dist/build/upload-library-assets.d.ts +0 -21
  77. package/dist/build/upload-library-assets.d.ts.map +0 -1
  78. package/dist/build/upload-library-assets.js +0 -182
  79. package/dist/build/upload-library-assets.js.map +0 -1
  80. package/dist/build/visual-resolver.d.ts +0 -87
  81. package/dist/build/visual-resolver.d.ts.map +0 -1
  82. package/dist/build/visual-resolver.js +0 -439
  83. package/dist/build/visual-resolver.js.map +0 -1
  84. package/dist/examples/manifest.d.ts +0 -21
  85. package/dist/examples/manifest.d.ts.map +0 -1
  86. package/dist/examples/manifest.js +0 -84
  87. package/dist/examples/manifest.js.map +0 -1
  88. package/dist/exports/contact-sales/Images/Contact_sales_Image_16f4175c-d08c-43f6-9d4c-a0606383271d.png +0 -0
  89. package/dist/exports/contact-sales/Images/Contact_sales_Image_659b3091-1da9-40c2-86b0-04250982e529.png +0 -0
  90. package/dist/exports/contact-sales/Images/Contact_sales_Image_79c651f4-5f0f-4a7f-8354-1f6f95ae86d9.png +0 -0
  91. package/dist/exports/contact-sales/index.braze.html +0 -837
  92. package/dist/exports/contact-sales/index.html +0 -837
  93. package/dist/exports/event-confirmation/Images/Confirmation_Image_11938de2-4161-4ae8-8969-90ea0d8b45cb.png +0 -0
  94. package/dist/exports/event-confirmation/Images/Confirmation_Image_3c52e81f-5d4f-452c-bad1-0471a27598f1.png +0 -0
  95. package/dist/exports/event-confirmation/Images/Confirmation_Image_3ec1fec8-bf46-4068-8835-633567a715f9.png +0 -0
  96. package/dist/exports/event-confirmation/Images/Confirmation_Image_c4980c01-c270-4384-a56c-0bae74814cf9.png +0 -0
  97. package/dist/exports/event-confirmation/Images/Confirmation_Image_cde93e8c-0f96-434d-acaf-1b86503c66f0.png +0 -0
  98. package/dist/exports/event-confirmation/index.braze.html +0 -1055
  99. package/dist/exports/event-confirmation/index.html +0 -1055
  100. package/dist/exports/legal-update/Images/v2_Image_07bbcc13-0ab8-46e4-ab94-98f215f85f69.png +0 -0
  101. package/dist/exports/legal-update/Images/v2_Image_34394d50-acdf-4375-b254-eef1f84aaacb.png +0 -0
  102. package/dist/exports/legal-update/Images/v2_Image_4a25f2bd-6270-439b-86c5-4a968a1b104f.png +0 -0
  103. package/dist/exports/legal-update/Images/v2_Image_7e8e814f-3112-4d8c-af5b-4f4616d84d9c.png +0 -0
  104. package/dist/exports/legal-update/Images/v2_Image_b24a04c8-4af0-42a1-be0f-cd3f66595e47.png +0 -0
  105. package/dist/exports/legal-update/Images/v2_Image_b709b9fb-836e-4c20-82e5-a9cb9d702392.png +0 -0
  106. package/dist/exports/legal-update/Images/v2_Image_ed7b924b-35e6-4536-be0c-92ddc8a34fc2.png +0 -0
  107. package/dist/exports/legal-update/index.braze.html +0 -1731
  108. package/dist/exports/legal-update/index.html +0 -1731
  109. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_09be22f6-1f30-4c58-bf33-1df0494b8fc2.png +0 -0
  110. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_2dfb595e-6fe2-4e6e-a73a-942a085b38ab.png +0 -0
  111. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_544c971b-b4b5-4c89-a25a-8f0d92644009.png +0 -0
  112. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_5b6a9576-1c33-40c5-81e3-637514fb6c78.png +0 -0
  113. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_680c6193-793a-4a24-8288-4bb4046f4f5e.png +0 -0
  114. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_75818ba9-026a-45d7-91e4-f992d4ee7690.png +0 -0
  115. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_785f18e6-816d-44d1-8efb-ecc82510b540.png +0 -0
  116. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_8bf9141d-9d63-4601-9e81-5c9d726e17f8.png +0 -0
  117. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_9097d6e0-65d0-4237-9661-963751812786.png +0 -0
  118. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_a4ef2f53-2eaf-438a-bfef-61455ac0915e.png +0 -0
  119. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_b7748f87-a7b7-4a91-981a-16567683e4b4.png +0 -0
  120. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_bc9830a4-2911-4768-808a-32cbbc39215e.png +0 -0
  121. package/dist/exports/newsletter/Images/Status_update_-_July_26_Image_ef0e8e92-9075-43a9-991f-09a77ef6d6d4.png +0 -0
  122. package/dist/exports/newsletter/index.braze.html +0 -125
  123. package/dist/exports/newsletter/index.html +0 -125
  124. package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-blocks.png +0 -0
  125. package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-hero-mcp.png +0 -0
  126. package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-magic.png +0 -0
  127. package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-mcp.png +0 -0
  128. package/dist/exports/newsletter-ai-june-july/Images/newsletter-ai-portfolio.png +0 -0
  129. package/dist/exports/newsletter-ai-june-july/index.braze.html +0 -1640
  130. package/dist/exports/newsletter-ai-june-july/index.html +0 -1640
  131. package/dist/exports/survey/Images/EmailLove_Image_3b6f4a6f-7f5f-418b-be71-9371b25c20ce.png +0 -0
  132. package/dist/exports/survey/Images/EmailLove_Image_f659c728-2401-485d-8d90-98c962d28c0c.png +0 -0
  133. package/dist/exports/survey/index.braze.html +0 -515
  134. package/dist/exports/survey/index.html +0 -515
  135. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_115ccc58-a47f-4eca-a1f2-c0d86e1e1cf4.png +0 -0
  136. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_aec4d0d3-6057-4b8a-8d8f-46fbd024f182.png +0 -0
  137. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Before_d139966a-6051-4383-bf8f-1e5138e1b030.png +0 -0
  138. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_080fa361-a3f2-4593-9ac0-03cf3a7972ff.png +0 -0
  139. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_5ebade34-8f1d-4c2c-9d27-5f9e843ce502.png +0 -0
  140. package/dist/exports/trial-01-welcome/Images/tp1_-_welcome_Image_aa5e4144-9ec8-4525-b01e-077d72f0bab6.png +0 -0
  141. package/dist/exports/trial-01-welcome/index.braze.html +0 -941
  142. package/dist/exports/trial-01-welcome/index.html +0 -941
  143. package/dist/exports/trial-02/Images/tp2_Image_5b0d9bc4-2e38-4252-8f20-d9f27d471c21.png +0 -0
  144. package/dist/exports/trial-02/Images/tp2_Image_b3f77c7c-cc8e-4db8-a5d9-072f4f621e72.png +0 -0
  145. package/dist/exports/trial-02/Images/tp2_Image_cafd1a17-1915-47cd-80f2-1c2d0b133cfe.png +0 -0
  146. package/dist/exports/trial-02/index.braze.html +0 -923
  147. package/dist/exports/trial-02/index.html +0 -923
  148. package/dist/exports/trial-03/Images/tp3_Image_1b96630c-fc4d-4aec-91fb-3c1d4d8544b3.png +0 -0
  149. package/dist/exports/trial-03/Images/tp3_Image_58f3a342-2193-4b5c-b30a-96f7f3338dd8.png +0 -0
  150. package/dist/exports/trial-03/Images/tp3_Image_6c4f307a-bac2-40e7-b4f1-9aa623c9eb8e.png +0 -0
  151. package/dist/exports/trial-03/Images/tp3_Image_848917ce-3f89-4538-a826-558b21f5fea7.png +0 -0
  152. package/dist/exports/trial-03/Images/tp3_Image_aae8410f-556f-4fb9-88f9-f276d75bafd2.png +0 -0
  153. package/dist/exports/trial-03/Images/tp3_Image_b4d5be39-509e-4f22-9601-dd070e4c6561.png +0 -0
  154. package/dist/exports/trial-03/index.braze.html +0 -1129
  155. package/dist/exports/trial-03/index.html +0 -1129
  156. package/dist/exports/trial-04/Images/tp4_Image_03bd5a56-25e3-4dcc-bef5-143bf12312d5.png +0 -0
  157. package/dist/exports/trial-04/Images/tp4_Image_0facbfca-b735-4199-a0d9-05a59341a1e3.gif +0 -0
  158. package/dist/exports/trial-04/Images/tp4_Image_171cee5f-cd3d-42f0-a180-995893d3742a.png +0 -0
  159. package/dist/exports/trial-04/Images/tp4_Image_3509d89d-1825-4817-8c1e-130fa294d0e1.png +0 -0
  160. package/dist/exports/trial-04/Images/tp4_Image_763a0f40-2985-4140-859b-ddd34f20a520.png +0 -0
  161. package/dist/exports/trial-04/Images/tp4_Image_cc2db4f5-b41d-45d7-a798-7a79e7b8d4d8.png +0 -0
  162. package/dist/exports/trial-04/index.braze.html +0 -885
  163. package/dist/exports/trial-04/index.html +0 -885
  164. package/dist/exports/trial-05/Images/tp5_Image_0248a517-5c60-4e84-ad1c-449dcf4f6a64.png +0 -0
  165. package/dist/exports/trial-05/Images/tp5_Image_4c1a2d5a-47d3-4801-bb3a-01c22decc108.png +0 -0
  166. package/dist/exports/trial-05/Images/tp5_Image_63ae77e7-cec7-4b4a-91e0-603b5a80929f.png +0 -0
  167. package/dist/exports/trial-05/Images/tp5_Image_7aa43530-6707-4308-ab0e-e4c38fc1b77d.png +0 -0
  168. package/dist/exports/trial-05/Images/tp5_Image_7efe5b6d-b360-4179-bee1-72908ba569bc.png +0 -0
  169. package/dist/exports/trial-05/Images/tp5_Image_b142bd84-c40a-4a29-b9d5-715b52fdd937.png +0 -0
  170. package/dist/exports/trial-05/Images/tp5_Image_c0c896ea-5b68-4f58-9e27-cdb4a1f1b438.png +0 -0
  171. package/dist/exports/trial-05/index.braze.html +0 -1023
  172. package/dist/exports/trial-05/index.html +0 -1023
  173. package/dist/exports/trial-06/Images/tp6_Image_2267a268-8a80-4e0d-8813-d4c75dbab6f2.png +0 -0
  174. package/dist/exports/trial-06/Images/tp6_Image_637a97b7-837e-478d-8ed1-6e8c2739fdc7.png +0 -0
  175. package/dist/exports/trial-06/Images/tp6_Image_a78df270-ad6f-41e6-8822-ba8ec38313a3.png +0 -0
  176. package/dist/exports/trial-06/index.braze.html +0 -773
  177. package/dist/exports/trial-06/index.html +0 -773
  178. package/dist/exports/winback/Images/_managers_Image_4587ac22-460c-487a-bc37-9dbc487e95a4.png +0 -0
  179. package/dist/exports/winback/Images/_managers_Image_8a77ec2c-ed49-480d-a1a1-7a38abad232a.png +0 -0
  180. package/dist/exports/winback/Images/_managers_Image_bb643775-8a2f-4e28-9dfb-6d1838c3561f.png +0 -0
  181. package/dist/exports/winback/Images/_managers_Image_f7d1bca5-0fcb-4d4c-abcd-40ce2d453b07.png +0 -0
  182. package/dist/exports/winback/index.braze.html +0 -605
  183. package/dist/exports/winback/index.html +0 -605
  184. package/dist/generated/email-tokens.d.ts.map +0 -1
  185. package/dist/generated/email-tokens.js.map +0 -1
  186. package/dist/index.d.ts.map +0 -1
  187. package/dist/index.js.map +0 -1
  188. package/dist/tokens/build-email-assets.d.ts +0 -19
  189. package/dist/tokens/build-email-assets.d.ts.map +0 -1
  190. package/dist/tokens/build-email-assets.js +0 -186
  191. package/dist/tokens/build-email-assets.js.map +0 -1
  192. package/dist/tokens/build-email-tokens.d.ts +0 -17
  193. package/dist/tokens/build-email-tokens.d.ts.map +0 -1
  194. package/dist/tokens/build-email-tokens.js +0 -229
  195. package/dist/tokens/build-email-tokens.js.map +0 -1
@@ -1,234 +0,0 @@
1
- /**
2
- * MJML compile pipeline.
3
- *
4
- * Discovers the container, section previews, and full email compositions; compiles each with MJML;
5
- * writes standalone HTML (+ Braze + static variants for emails) to dist/emails/, and a dist/catalog.json
6
- * that Storybook and the docs read from.
7
- *
8
- * Run via tsx (not the emitted dist copy). Pass --watch to recompile on change.
9
- */
10
- import mjml2html from 'mjml';
11
- import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
12
- import { resolve, dirname, join } from 'node:path';
13
- import { fileURLToPath, pathToFileURL } from 'node:url';
14
- import { brazeTransform } from './braze-transform';
15
- import { loadCloudinaryManifest, indexManifestByCampaignEmailFile } from './cloudinary-manifest';
16
- import { findIconByName } from './icon-registry-map';
17
- import { assetsDir, listDirs, walkEmails } from './email-tree';
18
- // Shared DS asset folders and SVGs always stay base64-inlined (D20: Cloudinary hosting is
19
- // raster-only) — EXCEPT icons/, which has its own hosted PNG per icon.json's cloudinaryPngUrl
20
- // (see below). Campaign assets (anything else, e.g. src/assets/<campaign>/hero.png) get a
21
- // hosted URL instead, once `email:upload` has run — see cloudinary-manifest.ts.
22
- const SHARED_ASSET_DIRS = new Set(['icons', 'integrations', 'logos', 'placeholders']);
23
- const RASTER_EXTS = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp']);
24
- const cloudinaryManifest = loadCloudinaryManifest();
25
- const cloudinaryIndex = cloudinaryManifest ? indexManifestByCampaignEmailFile(cloudinaryManifest) : null;
26
- /**
27
- * Post-process compiled HTML: for each `/assets/<path>` src, prefer a hosted Cloudinary URL and
28
- * otherwise fall back to inlining as a base64 data URI. MJML resolves mj-include itself before
29
- * our pre-processor runs, so assets referenced in included section files survive compilation as
30
- * raw paths — we resolve them here.
31
- *
32
- * Two independent hosted-URL sources:
33
- * - `icons/<name>.svg` → the Clay icon registry's `cloudinaryPngUrl` (icons.json, populated by
34
- * scripts/cloudinary/upload-icons-to-cloudinary.ts). PNG, not the icon's own SVG source: many email
35
- * clients (notably Outlook) don't reliably render SVG in <img>, so hosted icon delivery
36
- * follows the same raster-only rule as everything else here — only the *authoring* format is
37
- * SVG. An icon not yet uploaded (brand-new, before its first `icons:upload-cloudinary` run)
38
- * falls through to local base64 inlining exactly as before this existed.
39
- * - Everything else under a non-shared dir (campaign raster assets) → the per-campaign
40
- * Cloudinary manifest, keyed by campaign/email/filename (unchanged from before).
41
- *
42
- * `campaign`/`email` are only known for actual email compositions; container/section/component
43
- * previews pass empty strings, which simply never match the manifest index (correct — those have
44
- * no campaign context, so non-icon assets always inline in previews).
45
- */
46
- function inlineAssetsInHtml(html, campaign, email) {
47
- return html.replace(/src="([^"]*\/assets\/([^"?#]+))"/g, (_match, _fullPath, filename) => {
48
- const firstSegment = filename.split('/')[0];
49
- const ext = (filename.split('.').pop() ?? '').toLowerCase();
50
- const basename = filename.split('/').pop();
51
- if (firstSegment === 'icons' && basename && ext === 'svg') {
52
- const iconName = basename.slice(0, -'.svg'.length);
53
- const hostedIcon = findIconByName(iconName)?.cloudinaryPngUrl;
54
- if (hostedIcon)
55
- return `src="${hostedIcon}"`;
56
- }
57
- if (cloudinaryIndex && basename && !SHARED_ASSET_DIRS.has(firstSegment) && RASTER_EXTS.has(ext)) {
58
- const hosted = cloudinaryIndex.get(`${campaign}/${email}/${basename}`);
59
- if (hosted)
60
- return `src="${hosted}"`;
61
- }
62
- const absPath = resolve(assetsDir, filename);
63
- if (!existsSync(absPath))
64
- return _match;
65
- const raw = readFileSync(absPath);
66
- const mime = ext === 'svg' ? 'image/svg+xml' : `image/${ext || 'png'}`;
67
- return `src="data:${mime};base64,${raw.toString('base64')}"`;
68
- });
69
- }
70
- const __dirname = dirname(fileURLToPath(import.meta.url));
71
- const srcDir = resolve(__dirname, '..');
72
- const pkgDir = resolve(srcDir, '..');
73
- const distEmails = resolve(pkgDir, 'dist', 'emails');
74
- const distDir = resolve(pkgDir, 'dist');
75
- const titleCase = (slug) => slug.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
76
- /** Compile one .mjml file to HTML, throwing with context on any validation error. */
77
- function compileMjml(filePath, campaign = '', email = '') {
78
- const input = readFileSync(filePath, 'utf-8');
79
- // mjml2html is synchronous in v4; @types/mjml over-declares a Promise, so cast to the real shape.
80
- const { html: rawHtml, errors } = mjml2html(input, {
81
- filePath,
82
- validationLevel: 'soft',
83
- keepComments: true,
84
- minify: false,
85
- });
86
- if (errors && errors.length) {
87
- const msg = errors.map((e) => ` • ${e.formattedMessage ?? e.message}`).join('\n');
88
- throw new Error(`MJML errors in ${filePath}:\n${msg}`);
89
- }
90
- // Inline any local asset paths that survived MJML's mj-include resolution.
91
- return inlineAssetsInHtml(rawHtml, campaign, email);
92
- }
93
- async function loadEmailConfig(emailDir, id) {
94
- const configPath = join(emailDir, `${id}.config.ts`);
95
- if (!existsSync(configPath))
96
- return {};
97
- const mod = await import(pathToFileURL(configPath).href);
98
- return (mod.default ?? {});
99
- }
100
- /**
101
- * Derive the inbox subject + preheader from compiled HTML. The subject is the document `<title>`
102
- * (MJML `<mj-title>`); the preheader is the hidden preview div MJML emits for `<mj-preview>` — the
103
- * only hidden div carrying `opacity:0` (section spacer divs use `mso-hide:all` without it).
104
- */
105
- function extractInboxMeta(html) {
106
- const decode = (s) => s
107
- .replace(/&#x([0-9a-f]+);/gi, (_m, h) => String.fromCodePoint(parseInt(h, 16)))
108
- .replace(/&#(\d+);/g, (_m, d) => String.fromCodePoint(Number(d)))
109
- .replace(/&quot;/g, '"')
110
- .replace(/&lt;/g, '<')
111
- .replace(/&gt;/g, '>')
112
- .replace(/&amp;/g, '&')
113
- .trim();
114
- const titleMatch = html.match(/<title>([\s\S]*?)<\/title>/i);
115
- const previewMatch = html.match(/<div style="[^"]*opacity:0[^"]*">([\s\S]*?)<\/div>/i);
116
- const subject = titleMatch ? decode(titleMatch[1]) : undefined;
117
- const preheader = previewMatch ? decode(previewMatch[1]) : undefined;
118
- return {
119
- subject: subject || undefined,
120
- preheader: preheader || undefined,
121
- };
122
- }
123
- /**
124
- * Compile one email composition and push its catalog item. `catalogId` is the flat id used for
125
- * dist/emails/ output filenames and the catalog (campaign sub-emails flatten to
126
- * `<campaign>-<email-name>`); `fileBaseName` is the actual on-disk file stem inside `emailDir`
127
- * (`<fileBaseName>.mjml` / `.config.ts` / `.static.html`) — the two differ for campaign sub-emails.
128
- */
129
- async function compileOneEmail(catalogId, emailDir, campaign, fileBaseName, items) {
130
- const mjmlPath = join(emailDir, `${fileBaseName}.mjml`);
131
- const html = compileMjml(mjmlPath, campaign, fileBaseName);
132
- writeFileSync(join(distEmails, `${catalogId}.html`), html);
133
- const config = await loadEmailConfig(emailDir, fileBaseName);
134
- // Inbox metadata: derive the truth from the compiled HTML; warn if config declares a divergent value.
135
- const { subject, preheader } = extractInboxMeta(html);
136
- if (config.subject && subject && config.subject !== subject) {
137
- console.warn(` ⚠ ${catalogId}: config.subject "${config.subject}" ≠ <mj-title> "${subject}" — update the config to match.`);
138
- }
139
- if (config.preheader && preheader && config.preheader !== preheader) {
140
- console.warn(` ⚠ ${catalogId}: config.preheader "${config.preheader}" ≠ <mj-preview> "${preheader}" — update the config to match.`);
141
- }
142
- // Braze full-template variant
143
- const brazeConfig = (config.braze ?? {});
144
- const brazeHtml = brazeTransform(html, brazeConfig);
145
- writeFileSync(join(distEmails, `${catalogId}.braze.html`), brazeHtml);
146
- // Static HTML fallback (hand-authored; passed through untouched)
147
- let staticHtml;
148
- const staticPath = join(emailDir, `${fileBaseName}.static.html`);
149
- if (existsSync(staticPath)) {
150
- staticHtml = readFileSync(staticPath, 'utf-8');
151
- writeFileSync(join(distEmails, `${catalogId}.static.html`), staticHtml);
152
- }
153
- items.push({
154
- id: catalogId,
155
- title: titleCase(catalogId),
156
- kind: 'email',
157
- html,
158
- brazeHtml,
159
- staticHtml,
160
- subject,
161
- preheader,
162
- });
163
- }
164
- async function build() {
165
- mkdirSync(distEmails, { recursive: true });
166
- const items = [];
167
- // 1. Container shell
168
- const containerPath = resolve(srcDir, 'container', 'container.mjml');
169
- if (existsSync(containerPath)) {
170
- const html = compileMjml(containerPath);
171
- writeFileSync(join(distEmails, 'container.html'), html);
172
- items.push({ id: 'container', title: 'Container', kind: 'container', html });
173
- }
174
- // 2. Section previews (src/sections/<name>/<name>.preview.mjml)
175
- const sectionsDir = resolve(srcDir, 'sections');
176
- for (const name of listDirs(sectionsDir)) {
177
- const preview = join(sectionsDir, name, `${name}.preview.mjml`);
178
- if (!existsSync(preview))
179
- continue;
180
- const html = compileMjml(preview);
181
- writeFileSync(join(distEmails, `section-${name}.html`), html);
182
- items.push({ id: name, title: titleCase(name), kind: 'section', html });
183
- }
184
- // 2b. Component previews (src/components/<name>/<name>.preview.mjml) — atomic, reusable
185
- // fragments (buttons, images) rather than full narrative sections.
186
- const componentsDir = resolve(srcDir, 'components');
187
- for (const name of listDirs(componentsDir)) {
188
- const preview = join(componentsDir, name, `${name}.preview.mjml`);
189
- if (!existsSync(preview))
190
- continue;
191
- const html = compileMjml(preview);
192
- writeFileSync(join(distEmails, `component-${name}.html`), html);
193
- items.push({ id: name, title: titleCase(name), kind: 'component', html });
194
- }
195
- // 3. Full email compositions — two shapes, both under src/emails/:
196
- // (a) flat single email: src/emails/<name>/<name>.mjml
197
- // (b) campaign sequence: src/emails/<campaign>/<email-name>/<email-name>.mjml
198
- // (the output convention documented in skills/email-campaign/SKILL.md) — each
199
- // sub-email compiles as `<campaign>-<email-name>` in the flat dist/emails/ output.
200
- for (const { catalogId, emailDir, campaign, emailSlug } of walkEmails()) {
201
- await compileOneEmail(catalogId, emailDir, campaign, emailSlug, items);
202
- }
203
- const catalog = {
204
- generatedFrom: '@clay-design-system/email src/build/compile.ts',
205
- items,
206
- };
207
- writeFileSync(resolve(distDir, 'catalog.json'), JSON.stringify(catalog, null, 2));
208
- const counts = items.reduce((a, i) => ((a[i.kind] = (a[i.kind] ?? 0) + 1), a), {});
209
- console.log(`@clay-design-system/email: compiled ${items.length} artifacts ` +
210
- `(${counts.container ?? 0} container, ${counts.section ?? 0} sections, ` +
211
- `${counts.component ?? 0} components, ${counts.email ?? 0} emails)`);
212
- }
213
- async function main() {
214
- await build();
215
- if (process.argv.includes('--watch')) {
216
- const { default: chokidar } = await import('chokidar');
217
- const watchGlobs = [
218
- resolve(srcDir, 'container'),
219
- resolve(srcDir, 'sections'),
220
- resolve(srcDir, 'components'),
221
- resolve(srcDir, 'emails'),
222
- resolve(srcDir, 'generated'),
223
- ];
224
- console.log('@clay-design-system/email: watching for changes…');
225
- chokidar.watch(watchGlobs, { ignoreInitial: true }).on('all', () => {
226
- build().catch((err) => console.error(err.message));
227
- });
228
- }
229
- }
230
- main().catch((err) => {
231
- console.error(err.message);
232
- process.exit(1);
233
- });
234
- //# sourceMappingURL=compile.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/build/compile.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- /**
2
- * Per-email export config schema.
3
- *
4
- * Each `src/emails/<name>/<name>.config.ts` default-exports an object of this shape. It carries the
5
- * delivery metadata that travels with the email to the ESP (Braze): the inbox `subject` line and
6
- * `preheader` (preview) line, plus the CDN asset base and Braze transform settings.
7
- *
8
- * Source-of-truth note: the MJML head (`<mj-title>` / `<mj-preview>`) is what actually renders into
9
- * the compiled HTML. `subject`/`preheader` here mirror those values so they can be read without
10
- * parsing HTML (e.g. by the Braze uploader, since the delivered subject is inbox metadata, not body
11
- * markup). `compile.ts` derives the real values from the compiled HTML and warns on any drift.
12
- */
13
- import type { BrazeConfig } from './braze-transform';
14
- export interface EmailExportConfig {
15
- /** CDN base for hosted assets, e.g. `https://assets.monday.com/email/`. */
16
- assetBaseUrl: string;
17
- /** Inbox subject line. Mirrors the MJML `<mj-title>`. Best practice: ≤35 chars (see 11-subject-and-preheader.md). */
18
- subject: string;
19
- /** Inbox preview / preheader line. Mirrors the MJML `<mj-preview>`. Best practice: ≤50 chars. */
20
- preheader: string;
21
- /** Braze export settings (unsubscribe token, Liquid personalization, import mode). */
22
- braze: BrazeConfig;
23
- }
24
- /** Identity helper for authoring configs with full type inference + checking. */
25
- export declare function defineEmailConfig(config: EmailExportConfig): EmailExportConfig;
26
- //# sourceMappingURL=email-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-config.d.ts","sourceRoot":"","sources":["../../src/build/email-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAA;IACpB,qHAAqH;IACrH,OAAO,EAAE,MAAM,CAAA;IACf,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAA;IACjB,sFAAsF;IACtF,KAAK,EAAE,WAAW,CAAA;CACnB;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAE9E"}
@@ -1,17 +0,0 @@
1
- /**
2
- * Per-email export config schema.
3
- *
4
- * Each `src/emails/<name>/<name>.config.ts` default-exports an object of this shape. It carries the
5
- * delivery metadata that travels with the email to the ESP (Braze): the inbox `subject` line and
6
- * `preheader` (preview) line, plus the CDN asset base and Braze transform settings.
7
- *
8
- * Source-of-truth note: the MJML head (`<mj-title>` / `<mj-preview>`) is what actually renders into
9
- * the compiled HTML. `subject`/`preheader` here mirror those values so they can be read without
10
- * parsing HTML (e.g. by the Braze uploader, since the delivered subject is inbox metadata, not body
11
- * markup). `compile.ts` derives the real values from the compiled HTML and warns on any drift.
12
- */
13
- /** Identity helper for authoring configs with full type inference + checking. */
14
- export function defineEmailConfig(config) {
15
- return config;
16
- }
17
- //# sourceMappingURL=email-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-config.js","sourceRoot":"","sources":["../../src/build/email-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1,6 +0,0 @@
1
- /** Canonical list of EmailLove exports: slug → source folder name. */
2
- export declare const EMAILS: Array<{
3
- slug: string;
4
- dir: string;
5
- }>;
6
- //# sourceMappingURL=email-list.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-list.d.ts","sourceRoot":"","sources":["../../src/build/email-list.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAcvD,CAAA"}
@@ -1,17 +0,0 @@
1
- /** Canonical list of EmailLove exports: slug → source folder name. */
2
- export const EMAILS = [
3
- { slug: 'contact-sales', dir: 'Contact sales email' },
4
- { slug: 'event-confirmation', dir: 'Event confirmation' },
5
- { slug: 'legal-update', dir: 'Legal email' },
6
- { slug: 'newsletter', dir: 'Newsletter' },
7
- { slug: 'survey', dir: 'Survey' },
8
- { slug: 'winback', dir: 'Winback' },
9
- { slug: 'trial-01-welcome', dir: 'tp1 - welcome' },
10
- { slug: 'trial-02', dir: 'tp2' },
11
- { slug: 'trial-03', dir: 'tp3' },
12
- { slug: 'trial-04', dir: 'tp4' },
13
- { slug: 'trial-05', dir: 'tp5' },
14
- { slug: 'trial-06', dir: 'tp6' },
15
- { slug: 'newsletter-ai-june-july', dir: '' },
16
- ];
17
- //# sourceMappingURL=email-list.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-list.js","sourceRoot":"","sources":["../../src/build/email-list.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,MAAM,GAAyC;IAC1D,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,qBAAqB,EAAE;IACrD,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG,EAAE,oBAAoB,EAAE;IACzD,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE;IAC5C,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE;IACzC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE;IACjC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE;IACnC,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,eAAe,EAAE;IAClD,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE;IAChC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE;IAChC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE;IAChC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE;IAChC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE;IAChC,EAAE,IAAI,EAAE,yBAAyB,EAAE,GAAG,EAAE,EAAE,EAAE;CAC7C,CAAA"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Shared directory walk over src/emails/ — both flat single emails and campaign sequences.
3
- * compile.ts and upload-assets.ts both need the same (campaign, emailSlug, mjmlPath) tuples; this
4
- * is the one place that walk is defined, so the two pipelines can never disagree on it.
5
- */
6
- export declare const srcDir: string;
7
- export declare const emailsDir: string;
8
- export declare const assetsDir: string;
9
- export declare function listDirs(parent: string): string[];
10
- export interface EmailEntry {
11
- /** Flattened id used for dist/emails/ output + catalog (campaign sub-emails: `<campaign>-<email>`). */
12
- catalogId: string;
13
- /** Absolute dir containing `<emailSlug>.mjml` / `.config.ts`. */
14
- emailDir: string;
15
- /** Top-level dir under src/emails/. For a flat single email, equals emailSlug. */
16
- campaign: string;
17
- /** The on-disk file stem (`<emailSlug>.mjml` / `.config.ts`). */
18
- emailSlug: string;
19
- mjmlPath: string;
20
- }
21
- /** Every real email (flat or campaign sub-email) under src/emails/ that has an .mjml file. */
22
- export declare function walkEmails(): EmailEntry[];
23
- //# sourceMappingURL=email-tree.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-tree.d.ts","sourceRoot":"","sources":["../../src/build/email-tree.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,eAAO,MAAM,MAAM,QAA2B,CAAA;AAC9C,eAAO,MAAM,SAAS,QAA4B,CAAA;AAClD,eAAO,MAAM,SAAS,QAA4B,CAAA;AAElD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjD;AAED,MAAM,WAAW,UAAU;IACzB,uGAAuG;IACvG,SAAS,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAA;IAChB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,IAAI,UAAU,EAAE,CAuBzC"}
@@ -1,46 +0,0 @@
1
- /**
2
- * Shared directory walk over src/emails/ — both flat single emails and campaign sequences.
3
- * compile.ts and upload-assets.ts both need the same (campaign, emailSlug, mjmlPath) tuples; this
4
- * is the one place that walk is defined, so the two pipelines can never disagree on it.
5
- */
6
- import { existsSync, readdirSync } from 'node:fs';
7
- import { dirname, join, resolve } from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
- const __dirname = dirname(fileURLToPath(import.meta.url));
10
- export const srcDir = resolve(__dirname, '..');
11
- export const emailsDir = resolve(srcDir, 'emails');
12
- export const assetsDir = resolve(srcDir, 'assets');
13
- export function listDirs(parent) {
14
- if (!existsSync(parent))
15
- return [];
16
- return readdirSync(parent, { withFileTypes: true })
17
- .filter((d) => d.isDirectory())
18
- .map((d) => d.name);
19
- }
20
- /** Every real email (flat or campaign sub-email) under src/emails/ that has an .mjml file. */
21
- export function walkEmails() {
22
- const entries = [];
23
- for (const name of listDirs(emailsDir)) {
24
- const dir = join(emailsDir, name);
25
- const flatMjmlPath = join(dir, `${name}.mjml`);
26
- if (existsSync(flatMjmlPath)) {
27
- entries.push({ catalogId: name, emailDir: dir, campaign: name, emailSlug: name, mjmlPath: flatMjmlPath });
28
- continue;
29
- }
30
- for (const subName of listDirs(dir)) {
31
- const subDir = join(dir, subName);
32
- const subMjmlPath = join(subDir, `${subName}.mjml`);
33
- if (!existsSync(subMjmlPath))
34
- continue;
35
- entries.push({
36
- catalogId: `${name}-${subName}`,
37
- emailDir: subDir,
38
- campaign: name,
39
- emailSlug: subName,
40
- mjmlPath: subMjmlPath,
41
- });
42
- }
43
- }
44
- return entries;
45
- }
46
- //# sourceMappingURL=email-tree.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-tree.js","sourceRoot":"","sources":["../../src/build/email-tree.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAC9C,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAElD,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAA;IAClC,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAChD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC;AAcD,8FAA8F;AAC9F,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAiB,EAAE,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;QAC9C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;YACzG,SAAQ;QACV,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YACjC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,OAAO,CAAC,CAAA;YACnD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;gBAAE,SAAQ;YACtC,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,GAAG,IAAI,IAAI,OAAO,EAAE;gBAC/B,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,OAAO;gBAClB,QAAQ,EAAE,WAAW;aACtB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Braze export packager for EmailLove examples.
3
- *
4
- * Reads normalized EmailLove exports from `src/examples/<slug>/` and produces a self-contained
5
- * per-email folder in `dist/exports/<slug>/`:
6
- *
7
- * dist/exports/<slug>/
8
- * index.html ← preview HTML (relative image paths, for local review)
9
- * index.braze.html ← Braze-ready HTML (unsubscribe token applied)
10
- * Images/ ← all images, copied from src/examples/<slug>/Images/
11
- *
12
- * By default images are referenced as `Images/<file>` (relative) — matching the EmailLove
13
- * reference format. Pass `--cdn-base=<url>` to rewrite image src values to absolute CDN URLs
14
- * in index.braze.html, which is required for production Braze delivery.
15
- *
16
- * Usage:
17
- * pnpm --filter @clay-design-system/email export:braze
18
- * pnpm --filter @clay-design-system/email export:braze:cdn
19
- * tsx src/build/export-braze.ts [--cdn-base=https://assets.monday.com/email/]
20
- */
21
- export {};
22
- //# sourceMappingURL=export-braze.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-braze.d.ts","sourceRoot":"","sources":["../../src/build/export-braze.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
@@ -1,92 +0,0 @@
1
- /**
2
- * Braze export packager for EmailLove examples.
3
- *
4
- * Reads normalized EmailLove exports from `src/examples/<slug>/` and produces a self-contained
5
- * per-email folder in `dist/exports/<slug>/`:
6
- *
7
- * dist/exports/<slug>/
8
- * index.html ← preview HTML (relative image paths, for local review)
9
- * index.braze.html ← Braze-ready HTML (unsubscribe token applied)
10
- * Images/ ← all images, copied from src/examples/<slug>/Images/
11
- *
12
- * By default images are referenced as `Images/<file>` (relative) — matching the EmailLove
13
- * reference format. Pass `--cdn-base=<url>` to rewrite image src values to absolute CDN URLs
14
- * in index.braze.html, which is required for production Braze delivery.
15
- *
16
- * Usage:
17
- * pnpm --filter @clay-design-system/email export:braze
18
- * pnpm --filter @clay-design-system/email export:braze:cdn
19
- * tsx src/build/export-braze.ts [--cdn-base=https://assets.monday.com/email/]
20
- */
21
- import { readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, existsSync, statSync, } from 'node:fs';
22
- import { resolve, join, dirname, basename } from 'node:path';
23
- import { fileURLToPath } from 'node:url';
24
- import { brazeTransform } from './braze-transform.js';
25
- import { EMAILS } from './email-list.js';
26
- const __dirname = dirname(fileURLToPath(import.meta.url));
27
- const examplesDir = resolve(__dirname, '..', 'examples');
28
- const pkgDir = resolve(__dirname, '..', '..');
29
- const exportsDir = resolve(pkgDir, 'dist', 'exports');
30
- const cdnBaseArg = process.argv.find((a) => a.startsWith('--cdn-base='));
31
- const cdnBase = cdnBaseArg ? cdnBaseArg.slice('--cdn-base='.length).replace(/\/?$/, '/') : null;
32
- /**
33
- * Rewrite `src="Images/<file>"` to `src="<cdnBase><file>"` for production Braze delivery.
34
- * Only applied when --cdn-base is provided.
35
- */
36
- function rewriteImageSrcs(html, base) {
37
- return html.replace(/src="Images\/([^"]+)"/g, (_m, file) => `src="${base}${file}"`);
38
- }
39
- function exportOne(slug) {
40
- const srcDir = join(examplesDir, slug);
41
- if (!existsSync(srcDir)) {
42
- console.warn(` ${slug.padEnd(20)} SKIP — src/examples/${slug}/ not found (run import-examples first)`);
43
- return;
44
- }
45
- const srcHtml = join(srcDir, 'index.html');
46
- if (!existsSync(srcHtml)) {
47
- console.warn(` ${slug.padEnd(20)} SKIP — no index.html in src/examples/${slug}/`);
48
- return;
49
- }
50
- const srcImages = join(srcDir, 'Images');
51
- const destDir = join(exportsDir, slug);
52
- const destImages = join(destDir, 'Images');
53
- mkdirSync(destImages, { recursive: true });
54
- // Copy images
55
- let imageCount = 0;
56
- let totalBytes = 0;
57
- if (existsSync(srcImages)) {
58
- for (const file of readdirSync(srcImages)) {
59
- const src = join(srcImages, file);
60
- if (statSync(src).isFile()) {
61
- copyFileSync(src, join(destImages, basename(file)));
62
- totalBytes += statSync(src).size;
63
- imageCount++;
64
- }
65
- }
66
- }
67
- const previewHtml = readFileSync(srcHtml, 'utf-8');
68
- // index.html — plain preview, relative image paths
69
- writeFileSync(join(destDir, 'index.html'), previewHtml);
70
- // index.braze.html — Braze transforms applied; optionally CDN-absolute image paths
71
- let brazeHtml = brazeTransform(previewHtml, { unsubscribe: true });
72
- if (cdnBase)
73
- brazeHtml = rewriteImageSrcs(brazeHtml, cdnBase);
74
- writeFileSync(join(destDir, 'index.braze.html'), brazeHtml);
75
- const kbLabel = `(${(totalBytes / 1024).toFixed(0)} KB)`;
76
- const cdnLabel = cdnBase ? ` → ${cdnBase}` : '';
77
- console.log(` ${slug.padEnd(20)} ${String(imageCount).padStart(2)} images ${kbLabel.padEnd(12)}${cdnLabel}`);
78
- }
79
- function main() {
80
- const mode = cdnBase ? `CDN mode (${cdnBase})` : 'relative-path mode';
81
- console.log(`\nExporting ${EMAILS.length} emails to dist/exports/ [${mode}]\n`);
82
- mkdirSync(exportsDir, { recursive: true });
83
- for (const { slug } of EMAILS)
84
- exportOne(slug);
85
- console.log(`\nDone → ${exportsDir}`);
86
- if (!cdnBase) {
87
- console.log('\nTip: run with --cdn-base=https://assets.monday.com/email/ to get absolute image\n' +
88
- 'URLs in index.braze.html for production Braze delivery.');
89
- }
90
- }
91
- main();
92
- //# sourceMappingURL=export-braze.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-braze.js","sourceRoot":"","sources":["../../src/build/export-braze.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * Generates stock-library-map.ts from stock-library-source.csv (D5.5, board item Clay Lifecycle D5).
3
- *
4
- * stock-library-source.csv is the authored source — same "CSV is authored, other artifacts are
5
- * generated from it, never hand-edit the generated file" convention as the Asset Catalog's own
6
- * CatalogTest.csv → chips_seed.sql (see .../Assets/Asset Catalog/Table/SCHEMA.md). This script is
7
- * the equivalent of that repo's `build_seed.py`.
8
- *
9
- * Usage:
10
- * pnpm --filter @clay-design-system/email library:generate-map
11
- */
12
- export {};
13
- //# sourceMappingURL=generate-stock-library-map.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-stock-library-map.d.ts","sourceRoot":"","sources":["../../src/build/generate-stock-library-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}