react-email 4.0.16 → 4.1.0-canary.10

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 (470) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dev/index.js +40 -0
  3. package/dev/package.json +13 -0
  4. package/dist/index.js +1 -1
  5. package/package.json +13 -46
  6. package/readme.md +16 -0
  7. package/src/commands/build.ts +306 -0
  8. package/src/commands/dev.ts +27 -0
  9. package/src/commands/export.ts +204 -0
  10. package/src/commands/start.ts +38 -0
  11. package/src/index.ts +55 -0
  12. package/src/utils/__snapshots__/tree.spec.ts.snap +27 -0
  13. package/src/utils/esbuild/renderring-utilities-exporter.ts +1 -1
  14. package/src/utils/get-emails-directory-metadata.spec.ts +1 -1
  15. package/src/utils/get-preview-server-location.ts +51 -0
  16. package/src/utils/index.ts +2 -6
  17. package/src/utils/packageJson.ts +4 -0
  18. package/src/utils/preview/get-env-variables-for-preview-app.ts +14 -0
  19. package/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +284 -0
  20. package/src/utils/preview/hot-reloading/create-dependency-graph.ts +321 -0
  21. package/src/utils/preview/hot-reloading/get-imported-modules.spec.ts +151 -0
  22. package/src/utils/preview/hot-reloading/get-imported-modules.ts +49 -0
  23. package/src/utils/preview/hot-reloading/resolve-path-aliases.spec.ts +11 -0
  24. package/src/utils/preview/hot-reloading/resolve-path-aliases.ts +32 -0
  25. package/src/utils/preview/hot-reloading/setup-hot-reloading.ts +121 -0
  26. package/src/utils/preview/hot-reloading/test/tsconfig.json +8 -0
  27. package/src/utils/preview/index.ts +2 -0
  28. package/src/utils/preview/serve-static-file.ts +51 -0
  29. package/src/utils/preview/start-dev-server.ts +234 -0
  30. package/src/utils/tree.spec.ts +5 -0
  31. package/src/utils/tree.ts +76 -0
  32. package/src/utils/types/hot-reload-change.ts +1 -1
  33. package/src/utils/types/hot-reload-event.ts +1 -1
  34. package/tsconfig.json +4 -10
  35. package/dist/cli/index.d.mts +0 -1
  36. package/dist/cli/index.d.ts +0 -1
  37. package/dist/cli/index.js +0 -2785
  38. package/dist/cli/index.mjs +0 -1361
  39. package/dist/index.d.mts +0 -20
  40. package/dist/index.d.ts +0 -20
  41. package/dist/index.mjs +0 -21
  42. package/dist/package/index.d.mts +0 -33
  43. package/dist/package/index.d.ts +0 -33
  44. package/dist/package/index.js +0 -62
  45. package/dist/package/index.mjs +0 -7
  46. package/dist/preview/.next/BUILD_ID +0 -1
  47. package/dist/preview/.next/app-build-manifest.json +0 -44
  48. package/dist/preview/.next/app-path-routes-manifest.json +0 -6
  49. package/dist/preview/.next/build-manifest.json +0 -33
  50. package/dist/preview/.next/diagnostics/build-diagnostics.json +0 -6
  51. package/dist/preview/.next/diagnostics/framework.json +0 -1
  52. package/dist/preview/.next/export-marker.json +0 -6
  53. package/dist/preview/.next/images-manifest.json +0 -57
  54. package/dist/preview/.next/next-minimal-server.js.nft.json +0 -1
  55. package/dist/preview/.next/next-server.js.nft.json +0 -1
  56. package/dist/preview/.next/package.json +0 -1
  57. package/dist/preview/.next/prerender-manifest.json +0 -41
  58. package/dist/preview/.next/react-loadable-manifest.json +0 -1
  59. package/dist/preview/.next/required-server-files.json +0 -311
  60. package/dist/preview/.next/routes-manifest.json +0 -64
  61. package/dist/preview/.next/server/app/_not-found/page.js +0 -1
  62. package/dist/preview/.next/server/app/_not-found/page.js.nft.json +0 -1
  63. package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  64. package/dist/preview/.next/server/app/favicon.ico/route.js +0 -1
  65. package/dist/preview/.next/server/app/favicon.ico/route.js.nft.json +0 -1
  66. package/dist/preview/.next/server/app/favicon.ico.body +0 -0
  67. package/dist/preview/.next/server/app/favicon.ico.meta +0 -1
  68. package/dist/preview/.next/server/app/page.js +0 -1
  69. package/dist/preview/.next/server/app/page.js.nft.json +0 -1
  70. package/dist/preview/.next/server/app/page_client-reference-manifest.js +0 -1
  71. package/dist/preview/.next/server/app/preview/[...slug]/page.js +0 -321
  72. package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +0 -1
  73. package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +0 -1
  74. package/dist/preview/.next/server/app-paths-manifest.json +0 -6
  75. package/dist/preview/.next/server/chunks/134.js +0 -6
  76. package/dist/preview/.next/server/chunks/235.js +0 -15
  77. package/dist/preview/.next/server/chunks/275.js +0 -1
  78. package/dist/preview/.next/server/chunks/343.js +0 -20
  79. package/dist/preview/.next/server/chunks/428.js +0 -14
  80. package/dist/preview/.next/server/chunks/963.js +0 -1
  81. package/dist/preview/.next/server/functions-config-manifest.json +0 -4
  82. package/dist/preview/.next/server/interception-route-rewrite-manifest.js +0 -1
  83. package/dist/preview/.next/server/middleware-build-manifest.js +0 -1
  84. package/dist/preview/.next/server/middleware-manifest.json +0 -6
  85. package/dist/preview/.next/server/middleware-react-loadable-manifest.js +0 -1
  86. package/dist/preview/.next/server/next-font-manifest.js +0 -1
  87. package/dist/preview/.next/server/next-font-manifest.json +0 -1
  88. package/dist/preview/.next/server/pages/500.html +0 -1
  89. package/dist/preview/.next/server/pages/_app.js +0 -1
  90. package/dist/preview/.next/server/pages/_app.js.nft.json +0 -1
  91. package/dist/preview/.next/server/pages/_document.js +0 -1
  92. package/dist/preview/.next/server/pages/_document.js.nft.json +0 -1
  93. package/dist/preview/.next/server/pages/_error.js +0 -1
  94. package/dist/preview/.next/server/pages/_error.js.nft.json +0 -1
  95. package/dist/preview/.next/server/pages-manifest.json +0 -5
  96. package/dist/preview/.next/server/server-reference-manifest.js +0 -1
  97. package/dist/preview/.next/server/server-reference-manifest.json +0 -1
  98. package/dist/preview/.next/server/webpack-runtime.js +0 -1
  99. package/dist/preview/.next/static/chunks/107-3043079e7cb8bcae.js +0 -1
  100. package/dist/preview/.next/static/chunks/293-297b1eb2241f9a70.js +0 -1
  101. package/dist/preview/.next/static/chunks/3bd82e28-cda2c00a924937c5.js +0 -1
  102. package/dist/preview/.next/static/chunks/45-1021fac82f766268.js +0 -1
  103. package/dist/preview/.next/static/chunks/484-e38a627386aae911.js +0 -1
  104. package/dist/preview/.next/static/chunks/589-817d8691661d370e.js +0 -1
  105. package/dist/preview/.next/static/chunks/902-c34acb56733e0ce1.js +0 -1
  106. package/dist/preview/.next/static/chunks/app/_not-found/page-4cbc7dce3ad33336.js +0 -1
  107. package/dist/preview/.next/static/chunks/app/layout-269b5cbd8f4cd2e3.js +0 -1
  108. package/dist/preview/.next/static/chunks/app/page-2dbfb5b2dc4b1191.js +0 -1
  109. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-79e0c9b528a62f8b.js +0 -1
  110. package/dist/preview/.next/static/chunks/f33a14d2-ec7c5f0b91818561.js +0 -6
  111. package/dist/preview/.next/static/chunks/framework-b887e9fc751a9906.js +0 -1
  112. package/dist/preview/.next/static/chunks/main-9a03e7ba8acb1900.js +0 -1
  113. package/dist/preview/.next/static/chunks/main-app-976577a424e11c75.js +0 -1
  114. package/dist/preview/.next/static/chunks/pages/_app-542a93a5a214e1c0.js +0 -1
  115. package/dist/preview/.next/static/chunks/pages/_error-d5fe1b1612642f76.js +0 -1
  116. package/dist/preview/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  117. package/dist/preview/.next/static/chunks/webpack-31c45daa2bd82a7b.js +0 -1
  118. package/dist/preview/.next/static/css/ac3decd5d6736fbe.css +0 -3
  119. package/dist/preview/.next/static/media/05613964ce6c782e-s.p.otf +0 -0
  120. package/dist/preview/.next/static/media/11c6126b9369e85e-s.p.otf +0 -0
  121. package/dist/preview/.next/static/media/26a46d62cd723877-s.woff2 +0 -0
  122. package/dist/preview/.next/static/media/26cb97734d8cb717-s.p.otf +0 -0
  123. package/dist/preview/.next/static/media/55c55f0601d81cf3-s.woff2 +0 -0
  124. package/dist/preview/.next/static/media/581909926a08bbc8-s.woff2 +0 -0
  125. package/dist/preview/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
  126. package/dist/preview/.next/static/media/97e0cb1ae144a2a9-s.woff2 +0 -0
  127. package/dist/preview/.next/static/media/bb6462617151f6b7-s.p.otf +0 -0
  128. package/dist/preview/.next/static/media/cf6daef822ab0142-s.p.otf +0 -0
  129. package/dist/preview/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  130. package/dist/preview/.next/static/media/e4051546b3043204-s.p.otf +0 -0
  131. package/dist/preview/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
  132. package/dist/preview/.next/static/media/logo.2ce2a759.png +0 -0
  133. package/dist/preview/.next/static/yxjkw7Y7HRLmRWkl3S43z/_buildManifest.js +0 -1
  134. package/dist/preview/.next/static/yxjkw7Y7HRLmRWkl3S43z/_ssgManifest.js +0 -1
  135. package/dist/preview/.next/trace +0 -27
  136. package/dist/preview/.next/types/app/layout.ts +0 -84
  137. package/dist/preview/.next/types/app/page.ts +0 -84
  138. package/dist/preview/.next/types/app/preview/[...slug]/page.ts +0 -84
  139. package/dist/preview/.next/types/cache-life.d.ts +0 -141
  140. package/dist/preview/.next/types/package.json +0 -1
  141. package/module-punycode.d.ts +0 -3
  142. package/next-env.d.ts +0 -5
  143. package/next.config.js +0 -22
  144. package/postcss.config.js +0 -8
  145. package/scripts/build-preview-server.mjs +0 -33
  146. package/scripts/fill-caniemail-data.mjs +0 -36
  147. package/src/actions/email-validation/caniemail-data.ts +0 -85993
  148. package/src/actions/email-validation/check-compatibility.ts +0 -333
  149. package/src/actions/email-validation/check-images.spec.tsx +0 -100
  150. package/src/actions/email-validation/check-images.ts +0 -160
  151. package/src/actions/email-validation/check-links.spec.tsx +0 -113
  152. package/src/actions/email-validation/check-links.ts +0 -113
  153. package/src/actions/email-validation/get-code-location-from-ast-element.ts +0 -18
  154. package/src/actions/email-validation/quick-fetch.ts +0 -14
  155. package/src/actions/get-email-path-from-slug.ts +0 -32
  156. package/src/actions/get-emails-directory-metadata-action.ts +0 -19
  157. package/src/actions/render-email-by-path.tsx +0 -121
  158. package/src/animated-icons-data/help.json +0 -1082
  159. package/src/animated-icons-data/link.json +0 -1309
  160. package/src/animated-icons-data/load.json +0 -443
  161. package/src/animated-icons-data/mail.json +0 -1320
  162. package/src/app/env.ts +0 -15
  163. package/src/app/favicon.ico +0 -0
  164. package/src/app/fonts/SFMono/SFMonoBold.otf +0 -0
  165. package/src/app/fonts/SFMono/SFMonoBoldItalic.otf +0 -0
  166. package/src/app/fonts/SFMono/SFMonoHeavy.otf +0 -0
  167. package/src/app/fonts/SFMono/SFMonoHeavyItalic.otf +0 -0
  168. package/src/app/fonts/SFMono/SFMonoLight.otf +0 -0
  169. package/src/app/fonts/SFMono/SFMonoLightItalic.otf +0 -0
  170. package/src/app/fonts/SFMono/SFMonoMedium.otf +0 -0
  171. package/src/app/fonts/SFMono/SFMonoMediumItalic.otf +0 -0
  172. package/src/app/fonts/SFMono/SFMonoRegular.otf +0 -0
  173. package/src/app/fonts/SFMono/SFMonoRegularItalic.otf +0 -0
  174. package/src/app/fonts/SFMono/SFMonoSemibold.otf +0 -0
  175. package/src/app/fonts/SFMono/SFMonoSemiboldItalic.otf +0 -0
  176. package/src/app/fonts.ts +0 -39
  177. package/src/app/globals.css +0 -15
  178. package/src/app/layout.tsx +0 -43
  179. package/src/app/logo.png +0 -0
  180. package/src/app/page.tsx +0 -46
  181. package/src/app/preview/[...slug]/page.tsx +0 -157
  182. package/src/app/preview/[...slug]/preview.tsx +0 -216
  183. package/src/app/preview/[...slug]/rendering-error.tsx +0 -40
  184. package/src/commands/testing/out/magic-links/aws-verify-email.html +0 -165
  185. package/src/commands/testing/out/magic-links/linear-login-code.html +0 -90
  186. package/src/commands/testing/out/magic-links/notion-magic-link.html +0 -76
  187. package/src/commands/testing/out/magic-links/plaid-verify-identity.html +0 -78
  188. package/src/commands/testing/out/magic-links/raycast-magic-link.html +0 -91
  189. package/src/commands/testing/out/magic-links/slack-confirm.html +0 -240
  190. package/src/commands/testing/out/newsletters/codepen-challengers.html +0 -548
  191. package/src/commands/testing/out/newsletters/google-play-policy-update.html +0 -339
  192. package/src/commands/testing/out/newsletters/stack-overflow-tips.html +0 -231
  193. package/src/commands/testing/out/notifications/github-access-token.html +0 -104
  194. package/src/commands/testing/out/notifications/papermark-year-in-review.html +0 -317
  195. package/src/commands/testing/out/notifications/vercel-invite-user.html +0 -171
  196. package/src/commands/testing/out/notifications/yelp-recent-login.html +0 -195
  197. package/src/commands/testing/out/receipts/apple-receipt.html +0 -677
  198. package/src/commands/testing/out/receipts/nike-receipt.html +0 -724
  199. package/src/commands/testing/out/reset-password/dropbox-reset-password.html +0 -98
  200. package/src/commands/testing/out/reset-password/twitch-reset-password.html +0 -220
  201. package/src/commands/testing/out/reviews/airbnb-review.html +0 -206
  202. package/src/commands/testing/out/reviews/amazon-review.html +0 -356
  203. package/src/commands/testing/out/static/airbnb-logo.png +0 -0
  204. package/src/commands/testing/out/static/airbnb-review-user.jpg +0 -0
  205. package/src/commands/testing/out/static/amazon-book.jpg +0 -0
  206. package/src/commands/testing/out/static/amazon-facebook.jpg +0 -0
  207. package/src/commands/testing/out/static/amazon-instagram.jpg +0 -0
  208. package/src/commands/testing/out/static/amazon-logo.png +0 -0
  209. package/src/commands/testing/out/static/amazon-prime-logo.png +0 -0
  210. package/src/commands/testing/out/static/amazon-rating.gif +0 -0
  211. package/src/commands/testing/out/static/amazon-twitter.jpg +0 -0
  212. package/src/commands/testing/out/static/apple-card-icon.png +0 -0
  213. package/src/commands/testing/out/static/apple-hbo-max-icon.jpeg +0 -0
  214. package/src/commands/testing/out/static/apple-logo.png +0 -0
  215. package/src/commands/testing/out/static/apple-wallet.png +0 -0
  216. package/src/commands/testing/out/static/aws-logo.png +0 -0
  217. package/src/commands/testing/out/static/codepen-challengers.png +0 -0
  218. package/src/commands/testing/out/static/codepen-cube.png +0 -0
  219. package/src/commands/testing/out/static/codepen-pro.png +0 -0
  220. package/src/commands/testing/out/static/dropbox-logo.png +0 -0
  221. package/src/commands/testing/out/static/github.png +0 -0
  222. package/src/commands/testing/out/static/google-play-academy.png +0 -0
  223. package/src/commands/testing/out/static/google-play-chat.png +0 -0
  224. package/src/commands/testing/out/static/google-play-footer.png +0 -0
  225. package/src/commands/testing/out/static/google-play-header.png +0 -0
  226. package/src/commands/testing/out/static/google-play-icon.png +0 -0
  227. package/src/commands/testing/out/static/google-play-logo.png +0 -0
  228. package/src/commands/testing/out/static/google-play-pl.png +0 -0
  229. package/src/commands/testing/out/static/google-play.png +0 -0
  230. package/src/commands/testing/out/static/koala-logo.png +0 -0
  231. package/src/commands/testing/out/static/linear-logo.png +0 -0
  232. package/src/commands/testing/out/static/netlify-logo.png +0 -0
  233. package/src/commands/testing/out/static/nike-logo.png +0 -0
  234. package/src/commands/testing/out/static/nike-phone.png +0 -0
  235. package/src/commands/testing/out/static/nike-product.png +0 -0
  236. package/src/commands/testing/out/static/nike-recomendation-1.png +0 -0
  237. package/src/commands/testing/out/static/nike-recomendation-2.png +0 -0
  238. package/src/commands/testing/out/static/nike-recomendation-3.png +0 -0
  239. package/src/commands/testing/out/static/nike-recomendation-4.png +0 -0
  240. package/src/commands/testing/out/static/notion-logo.png +0 -0
  241. package/src/commands/testing/out/static/plaid-logo.png +0 -0
  242. package/src/commands/testing/out/static/raycast-bg.png +0 -0
  243. package/src/commands/testing/out/static/raycast-logo.png +0 -0
  244. package/src/commands/testing/out/static/slack-facebook.png +0 -0
  245. package/src/commands/testing/out/static/slack-linkedin.png +0 -0
  246. package/src/commands/testing/out/static/slack-logo.png +0 -0
  247. package/src/commands/testing/out/static/slack-twitter.png +0 -0
  248. package/src/commands/testing/out/static/stack-overflow-header.png +0 -0
  249. package/src/commands/testing/out/static/stack-overflow-logo-sm.png +0 -0
  250. package/src/commands/testing/out/static/stack-overflow-logo.png +0 -0
  251. package/src/commands/testing/out/static/stripe-logo.png +0 -0
  252. package/src/commands/testing/out/static/twitch-icon-facebook.png +0 -0
  253. package/src/commands/testing/out/static/twitch-icon-twitter.png +0 -0
  254. package/src/commands/testing/out/static/twitch-logo.png +0 -0
  255. package/src/commands/testing/out/static/vercel-arrow.png +0 -0
  256. package/src/commands/testing/out/static/vercel-logo.png +0 -0
  257. package/src/commands/testing/out/static/vercel-team.png +0 -0
  258. package/src/commands/testing/out/static/vercel-user.png +0 -0
  259. package/src/commands/testing/out/static/yelp-footer.png +0 -0
  260. package/src/commands/testing/out/static/yelp-header.png +0 -0
  261. package/src/commands/testing/out/static/yelp-logo.png +0 -0
  262. package/src/commands/testing/out/welcome/koala-welcome.html +0 -90
  263. package/src/commands/testing/out/welcome/netlify-welcome.html +0 -199
  264. package/src/commands/testing/out/welcome/stripe-welcome.html +0 -153
  265. package/src/components/button.tsx +0 -101
  266. package/src/components/code-container.tsx +0 -164
  267. package/src/components/code-snippet.tsx +0 -9
  268. package/src/components/code.tsx +0 -184
  269. package/src/components/heading.tsx +0 -113
  270. package/src/components/icons/icon-arrow-down.tsx +0 -16
  271. package/src/components/icons/icon-base.tsx +0 -26
  272. package/src/components/icons/icon-bug.tsx +0 -19
  273. package/src/components/icons/icon-button.tsx +0 -23
  274. package/src/components/icons/icon-check.tsx +0 -19
  275. package/src/components/icons/icon-clipboard.tsx +0 -40
  276. package/src/components/icons/icon-download.tsx +0 -19
  277. package/src/components/icons/icon-email.tsx +0 -18
  278. package/src/components/icons/icon-file.tsx +0 -19
  279. package/src/components/icons/icon-folder-open.tsx +0 -19
  280. package/src/components/icons/icon-folder.tsx +0 -18
  281. package/src/components/icons/icon-hide-sidebar.tsx +0 -23
  282. package/src/components/icons/icon-image.tsx +0 -19
  283. package/src/components/icons/icon-info.tsx +0 -18
  284. package/src/components/icons/icon-link.tsx +0 -14
  285. package/src/components/icons/icon-monitor.tsx +0 -19
  286. package/src/components/icons/icon-phone.tsx +0 -26
  287. package/src/components/icons/icon-reload.tsx +0 -18
  288. package/src/components/icons/icon-source.tsx +0 -19
  289. package/src/components/icons/icon-stamp.tsx +0 -14
  290. package/src/components/icons/icon-warning.tsx +0 -31
  291. package/src/components/index.ts +0 -7
  292. package/src/components/logo.tsx +0 -63
  293. package/src/components/resizable-wrapper.tsx +0 -173
  294. package/src/components/send.tsx +0 -134
  295. package/src/components/shell.tsx +0 -95
  296. package/src/components/sidebar/file-tree-directory-children.tsx +0 -134
  297. package/src/components/sidebar/file-tree-directory.tsx +0 -92
  298. package/src/components/sidebar/file-tree.tsx +0 -31
  299. package/src/components/sidebar/index.ts +0 -1
  300. package/src/components/sidebar/sidebar.tsx +0 -43
  301. package/src/components/text.tsx +0 -99
  302. package/src/components/toolbar/checking-results.tsx +0 -150
  303. package/src/components/toolbar/code-preview-line-link.tsx +0 -40
  304. package/src/components/toolbar/compatibility.tsx +0 -113
  305. package/src/components/toolbar/linter.tsx +0 -278
  306. package/src/components/toolbar/results.tsx +0 -51
  307. package/src/components/toolbar/spam-assassin.tsx +0 -155
  308. package/src/components/toolbar/toolbar-button.tsx +0 -52
  309. package/src/components/toolbar/use-cached-state.ts +0 -33
  310. package/src/components/toolbar.tsx +0 -349
  311. package/src/components/tooltip-content.tsx +0 -31
  312. package/src/components/tooltip.tsx +0 -19
  313. package/src/components/topbar/active-view-toggle-group.tsx +0 -86
  314. package/src/components/topbar/view-size-controls.tsx +0 -247
  315. package/src/components/topbar.tsx +0 -59
  316. package/src/contexts/emails.tsx +0 -59
  317. package/src/contexts/fragment-identifier.tsx +0 -48
  318. package/src/contexts/preview.tsx +0 -79
  319. package/src/hooks/use-clamped-state.ts +0 -24
  320. package/src/hooks/use-email-rendering-result.ts +0 -58
  321. package/src/hooks/use-fragment-identifier.ts +0 -14
  322. package/src/hooks/use-hot-reload.ts +0 -31
  323. package/src/hooks/use-icon-animation.ts +0 -41
  324. package/src/hooks/use-rendering-metadata.ts +0 -36
  325. package/src/package/body/dist/index.d.mts +0 -6
  326. package/src/package/body/dist/index.d.ts +0 -6
  327. package/src/package/body/dist/index.js +0 -79
  328. package/src/package/body/dist/index.mjs +0 -45
  329. package/src/package/button/dist/index.d.mts +0 -6
  330. package/src/package/button/dist/index.d.ts +0 -6
  331. package/src/package/button/dist/index.js +0 -252
  332. package/src/package/button/dist/index.mjs +0 -218
  333. package/src/package/code-block/dist/index.d.mts +0 -4906
  334. package/src/package/code-block/dist/index.d.ts +0 -4906
  335. package/src/package/code-block/dist/index.js +0 -18205
  336. package/src/package/code-block/dist/index.mjs +0 -18133
  337. package/src/package/code-inline/dist/index.d.mts +0 -11
  338. package/src/package/code-inline/dist/index.d.ts +0 -11
  339. package/src/package/code-inline/dist/index.js +0 -106
  340. package/src/package/code-inline/dist/index.mjs +0 -72
  341. package/src/package/column/dist/index.d.mts +0 -6
  342. package/src/package/column/dist/index.d.ts +0 -6
  343. package/src/package/column/dist/index.js +0 -79
  344. package/src/package/column/dist/index.mjs +0 -45
  345. package/src/package/components/dist/index.d.mts +0 -20
  346. package/src/package/components/dist/index.d.ts +0 -20
  347. package/src/package/components/dist/index.js +0 -62
  348. package/src/package/components/dist/index.mjs +0 -21
  349. package/src/package/container/dist/index.d.mts +0 -6
  350. package/src/package/container/dist/index.d.ts +0 -6
  351. package/src/package/container/dist/index.js +0 -93
  352. package/src/package/container/dist/index.mjs +0 -59
  353. package/src/package/font/dist/index.d.mts +0 -25
  354. package/src/package/font/dist/index.d.ts +0 -25
  355. package/src/package/font/dist/index.js +0 -55
  356. package/src/package/font/dist/index.mjs +0 -28
  357. package/src/package/head/dist/index.d.mts +0 -6
  358. package/src/package/head/dist/index.d.ts +0 -6
  359. package/src/package/head/dist/index.js +0 -83
  360. package/src/package/head/dist/index.mjs +0 -49
  361. package/src/package/heading/dist/index.d.mts +0 -43
  362. package/src/package/heading/dist/index.d.ts +0 -43
  363. package/src/package/heading/dist/index.js +0 -113
  364. package/src/package/heading/dist/index.mjs +0 -79
  365. package/src/package/hr/dist/index.d.mts +0 -6
  366. package/src/package/hr/dist/index.d.ts +0 -6
  367. package/src/package/hr/dist/index.js +0 -89
  368. package/src/package/hr/dist/index.mjs +0 -55
  369. package/src/package/html/dist/index.d.mts +0 -6
  370. package/src/package/html/dist/index.d.ts +0 -6
  371. package/src/package/html/dist/index.js +0 -79
  372. package/src/package/html/dist/index.mjs +0 -45
  373. package/src/package/img/dist/index.d.mts +0 -6
  374. package/src/package/img/dist/index.d.ts +0 -6
  375. package/src/package/img/dist/index.js +0 -94
  376. package/src/package/img/dist/index.mjs +0 -60
  377. package/src/package/link/dist/index.d.mts +0 -6
  378. package/src/package/link/dist/index.d.ts +0 -6
  379. package/src/package/link/dist/index.js +0 -90
  380. package/src/package/link/dist/index.mjs +0 -56
  381. package/src/package/markdown/dist/index.d.mts +0 -15
  382. package/src/package/markdown/dist/index.d.ts +0 -15
  383. package/src/package/markdown/dist/index.js +0 -92
  384. package/src/package/markdown/dist/index.mjs +0 -58
  385. package/src/package/preview/dist/index.d.mts +0 -12
  386. package/src/package/preview/dist/index.d.ts +0 -12
  387. package/src/package/preview/dist/index.js +0 -108
  388. package/src/package/preview/dist/index.mjs +0 -73
  389. package/src/package/render/dist/browser/index.d.mts +0 -24
  390. package/src/package/render/dist/browser/index.d.ts +0 -24
  391. package/src/package/render/dist/browser/index.js +0 -250
  392. package/src/package/render/dist/browser/index.mjs +0 -214
  393. package/src/package/render/dist/index.d.mts +0 -23
  394. package/src/package/render/dist/index.d.ts +0 -23
  395. package/src/package/render/dist/index.js +0 -768
  396. package/src/package/render/dist/index.mjs +0 -733
  397. package/src/package/render/dist/node/index.d.mts +0 -27
  398. package/src/package/render/dist/node/index.d.ts +0 -27
  399. package/src/package/render/dist/node/index.js +0 -212
  400. package/src/package/render/dist/node/index.mjs +0 -176
  401. package/src/package/row/dist/index.d.mts +0 -10
  402. package/src/package/row/dist/index.d.ts +0 -10
  403. package/src/package/row/dist/index.js +0 -93
  404. package/src/package/row/dist/index.mjs +0 -59
  405. package/src/package/section/dist/index.d.mts +0 -6
  406. package/src/package/section/dist/index.d.ts +0 -6
  407. package/src/package/section/dist/index.js +0 -93
  408. package/src/package/section/dist/index.mjs +0 -59
  409. package/src/package/tailwind/dist/index.d.ts +0 -19
  410. package/src/package/tailwind/dist/index.js +0 -48
  411. package/src/package/tailwind/dist/index.mjs +0 -17167
  412. package/src/package/tailwind/dist/tailwindcss/config.d.ts +0 -376
  413. package/src/package/tailwind/dist/tailwindcss/generated/.gitkeep +0 -0
  414. package/src/package/tailwind/dist/tailwindcss/generated/colors.d.ts +0 -298
  415. package/src/package/tailwind/dist/tailwindcss/generated/corePluginList.d.ts +0 -1
  416. package/src/package/tailwind/dist/tailwindcss/generated/default-theme.d.ts +0 -397
  417. package/src/package/tailwind/dist/tailwindcss/index.d.ts +0 -11
  418. package/src/package/text/dist/index.d.mts +0 -6
  419. package/src/package/text/dist/index.d.ts +0 -6
  420. package/src/package/text/dist/index.js +0 -89
  421. package/src/package/text/dist/index.mjs +0 -55
  422. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +0 -3
  423. package/src/utils/caniemail/all-css-properties.ts +0 -358
  424. package/src/utils/caniemail/ast/__snapshots__/get-object-variables.spec.ts.snap +0 -74
  425. package/src/utils/caniemail/ast/__snapshots__/get-used-style-properties.spec.ts.snap +0 -24
  426. package/src/utils/caniemail/ast/get-object-variables.spec.ts +0 -19
  427. package/src/utils/caniemail/ast/get-object-variables.ts +0 -61
  428. package/src/utils/caniemail/ast/get-used-style-properties.spec.ts +0 -23
  429. package/src/utils/caniemail/ast/get-used-style-properties.ts +0 -91
  430. package/src/utils/caniemail/get-compatibility-stats-for-entry.ts +0 -118
  431. package/src/utils/caniemail/get-css-functions.ts +0 -25
  432. package/src/utils/caniemail/get-css-property-names.ts +0 -32
  433. package/src/utils/caniemail/get-css-property-with-value.ts +0 -14
  434. package/src/utils/caniemail/get-css-unit.ts +0 -3
  435. package/src/utils/caniemail/get-element-attributes.ts +0 -7
  436. package/src/utils/caniemail/get-element-names.ts +0 -20
  437. package/src/utils/caniemail/tailwind/generate-tailwind-rules.ts +0 -30
  438. package/src/utils/caniemail/tailwind/get-tailwind-config.ts +0 -187
  439. package/src/utils/caniemail/tailwind/get-tailwind-metadata.spec.ts +0 -25
  440. package/src/utils/caniemail/tailwind/get-tailwind-metadata.ts +0 -45
  441. package/src/utils/caniemail/tailwind/setup-tailwind-context.ts +0 -15
  442. package/src/utils/cn.ts +0 -6
  443. package/src/utils/constants.ts +0 -6
  444. package/src/utils/contains-email-template.spec.ts +0 -124
  445. package/src/utils/contains-email-template.ts +0 -33
  446. package/src/utils/copy-text-to-clipboard.ts +0 -7
  447. package/src/utils/get-email-component.spec.ts +0 -41
  448. package/src/utils/get-email-component.ts +0 -134
  449. package/src/utils/get-line-and-column-from-offset.spec.ts +0 -11
  450. package/src/utils/get-line-and-column-from-offset.ts +0 -11
  451. package/src/utils/improve-error-with-sourcemap.ts +0 -86
  452. package/src/utils/js-email-detection.spec.ts +0 -24
  453. package/src/utils/language-map.ts +0 -7
  454. package/src/utils/linting.ts +0 -60
  455. package/src/utils/load-stream.ts +0 -15
  456. package/src/utils/result.ts +0 -49
  457. package/src/utils/run-bundled-code.ts +0 -64
  458. package/src/utils/sanitize.ts +0 -6
  459. package/src/utils/static-node-modules-for-vm.ts +0 -93
  460. package/src/utils/testing/js-email-export-default.js +0 -17
  461. package/src/utils/testing/js-email-test.js +0 -18
  462. package/src/utils/testing/mdx-email-test.js +0 -128
  463. package/src/utils/testing/request-response-email.tsx +0 -9
  464. package/src/utils/types/as.ts +0 -26
  465. package/src/utils/types/email-template.ts +0 -8
  466. package/src/utils/types/error-object.ts +0 -11
  467. package/src/utils/unreachable.ts +0 -8
  468. package/tailwind-internals.d.ts +0 -133
  469. package/tailwind.config.ts +0 -99
  470. /package/src/{components/toolbar/results-table.tsx → utils/preview/hot-reloading/test/some-file.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # react-email
2
2
 
3
+ ## 4.1.0-canary.10
4
+
5
+ ## 4.1.0-canary.9
6
+
7
+ ### Patch Changes
8
+
9
+ - 40fb596: Use the same version for the preview-server and react-email
10
+
11
+ ## 4.1.0-canary.8
12
+
13
+ ### Minor Changes
14
+
15
+ - ed2f46a: use a separate package for storing the preview server (@react-email/preview-server)
16
+
17
+ ## 4.1.0-canary.7
18
+
19
+ ### Patch Changes
20
+
21
+ - f00aff6: Fix prettier errors causing NextJS serialization error
22
+
23
+ ## 4.1.0-canary.6
24
+
25
+ ### Patch Changes
26
+
27
+ - 11c4600: Add support for hot reloading with tsconfig path aliases
28
+
29
+ ## 4.1.0-canary.5
30
+
31
+ ### Patch Changes
32
+
33
+ - b947f98: Pre-render email templates on hover
34
+
35
+ ## 4.1.0-canary.4
36
+
37
+ ### Patch Changes
38
+
39
+ - 5c6150d: Add .json import support for hot reloading
40
+ - aae2f59: Ensure dependencies outside emails directory are completely resolved
41
+ - b4b2373: Fix non-email files being rendered during hot reloading
42
+
43
+ ## 4.1.0-canary.3
44
+
45
+ ### Patch Changes
46
+
47
+ - 681d4ed: fix backwards compatibility with `render` versions
48
+
49
+ ## 4.1.0-canary.2
50
+
51
+ ### Patch Changes
52
+
53
+ - 9b1adb0: Use range of versions for dependencies
54
+
55
+ ## 4.1.0-canary.1
56
+
57
+ ### Patch Changes
58
+
59
+ - a587e17: Fix dependent of dependents not causing hot reloads
60
+ - dbf3a64: Add error message for when an email template does not have a default export
61
+
62
+ ## 4.1.0-canary.0
63
+
64
+ ### Minor Changes
65
+
66
+ - 4a0d4e3: Theme switcher for email template
67
+
3
68
  ## 4.0.16
4
69
 
5
70
  ### Patch Changes
package/dev/index.js ADDED
@@ -0,0 +1,40 @@
1
+ import child_process from 'node:child_process';
2
+ import path from 'node:path';
3
+ import url from 'node:url';
4
+
5
+ const filename = url.fileURLToPath(import.meta.url);
6
+ const dirname = path.dirname(filename);
7
+
8
+ const root = path.resolve(dirname, '../src/index.ts');
9
+
10
+ const tsxPath = path.resolve(dirname, './node_modules/.bin/tsx');
11
+
12
+ const tsx = child_process.spawn(tsxPath, [root, ...process.argv.slice(2)], {
13
+ shell: true,
14
+ cwd: process.cwd(),
15
+ stdio: 'inherit',
16
+ });
17
+
18
+ process.on('uncaughtExceptionMonitor', () => {
19
+ tsx.kill();
20
+ });
21
+
22
+ process.on('exit', (code) => {
23
+ tsx.kill(code);
24
+ });
25
+
26
+ process.on('SIGINT', () => {
27
+ tsx.kill('SIGINT');
28
+ });
29
+
30
+ process.on('SIGTERM', () => {
31
+ tsx.kill('SIGTERM');
32
+ });
33
+
34
+ process.on('SIGUSR1', () => {
35
+ tsx.kill('SIGUSR1');
36
+ });
37
+
38
+ process.on('SIGUSR2', () => {
39
+ tsx.kill('SIGUSR2');
40
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "email-dev",
3
+ "version": "0.0.0",
4
+ "bin": "index.js",
5
+ "private": true,
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node ."
9
+ },
10
+ "dependencies": {
11
+ "tsx": "4.19.3"
12
+ }
13
+ }
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ import prompts from "prompts";
106
106
  // package.json
107
107
  var package_default = {
108
108
  name: "react-email",
109
- version: "4.1.0-canary.9",
109
+ version: "4.1.0-canary.10",
110
110
  description: "A live preview of your emails right in your browser.",
111
111
  bin: {
112
112
  email: "./dist/index.js"
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "react-email",
3
- "version": "4.0.16",
3
+ "version": "4.1.0-canary.10",
4
4
  "description": "A live preview of your emails right in your browser.",
5
5
  "bin": {
6
- "email": "./dist/cli/index.mjs"
6
+ "email": "./dist/index.js"
7
7
  },
8
+ "type": "module",
8
9
  "license": "MIT",
9
10
  "repository": {
10
11
  "type": "git",
@@ -27,67 +28,33 @@
27
28
  "debounce": "^2.0.0",
28
29
  "esbuild": "^0.25.0",
29
30
  "glob": "^11.0.0",
31
+ "jiti": "2.4.2",
30
32
  "log-symbols": "^7.0.0",
31
33
  "mime-types": "^3.0.0",
32
- "next": "^15.3.1",
33
34
  "normalize-path": "^3.0.0",
35
+ "nypm": "0.6.0",
34
36
  "ora": "^8.0.0",
35
- "socket.io": "^4.8.1"
37
+ "prompts": "2.4.2",
38
+ "socket.io": "^4.8.1",
39
+ "tsconfig-paths": "4.2.0"
36
40
  },
37
41
  "devDependencies": {
38
- "@babel/core": "7.26.10",
39
- "@lottiefiles/dotlottie-react": "0.13.3",
40
- "@radix-ui/colors": "3.0.0",
41
- "@radix-ui/react-collapsible": "1.1.7",
42
- "@radix-ui/react-dropdown-menu": "2.1.10",
43
- "@radix-ui/react-popover": "1.1.10",
44
- "@radix-ui/react-slot": "1.2.0",
45
- "@radix-ui/react-tabs": "1.1.7",
46
- "@radix-ui/react-toggle-group": "1.1.6",
47
- "@radix-ui/react-tooltip": "1.2.3",
48
- "@swc/core": "1.11.21",
49
42
  "@types/babel__core": "7.20.5",
50
43
  "@types/babel__traverse": "7.20.7",
51
- "@types/fs-extra": "11.0.1",
52
44
  "@types/mime-types": "2.1.4",
53
- "@types/node": "22.14.1",
54
- "@types/normalize-path": "3.0.2",
55
- "@types/react": "19.0.10",
56
- "@types/react-dom": "19.0.4",
57
- "@types/webpack": "5.28.5",
58
- "autoprefixer": "10.4.21",
59
- "clsx": "2.1.1",
60
- "framer-motion": "12.7.5",
61
- "jiti": "2.4.2",
62
- "json5": "2.2.3",
63
- "module-punycode": "npm:punycode@2.3.1",
64
- "node-html-parser": "7.0.1",
65
- "postcss": "8.5.3",
66
- "pretty-bytes": "6.1.1",
67
- "prism-react-renderer": "2.4.1",
45
+ "@types/prompts": "2.4.9",
46
+ "next": "^15.3.2",
68
47
  "react": "19.0.0",
69
48
  "react-dom": "19.0.0",
70
- "sharp": "0.34.1",
71
- "socket.io-client": "4.8.1",
72
- "sonner": "2.0.3",
73
- "source-map-js": "1.2.1",
74
- "spamc": "0.0.5",
75
- "stacktrace-parser": "0.1.11",
76
- "tailwind-merge": "3.2.0",
77
- "tailwindcss": "3.4.0",
78
49
  "tsup": "8.4.0",
79
50
  "tsx": "4.19.3",
80
51
  "typescript": "5.8.3",
81
- "use-debounce": "10.0.4",
82
- "zod": "3.24.3",
83
- "@react-email/components": "0.0.41"
52
+ "@react-email/components": "0.1.0-canary.4"
84
53
  },
85
54
  "scripts": {
86
- "build": "tsup-node && node ./scripts/build-preview-server.mjs && pnpm install --frozen-lockfile",
87
- "caniemail:fetch": "node ./scripts/fill-caniemail-data.mjs",
55
+ "build": "tsup-node",
88
56
  "clean": "rm -rf dist",
89
- "dev": "tsup-node --watch",
90
- "dev:preview": "cd ../../apps/demo && tsx ../../packages/react-email/src/cli/index.ts dev",
57
+ "dev": "tsup-node --watch src",
91
58
  "test": "vitest run",
92
59
  "test:watch": "vitest"
93
60
  }
package/readme.md CHANGED
@@ -39,6 +39,22 @@ Generates the plain HTML files of your emails into a `out` directory.
39
39
  npx react-email export
40
40
  ```
41
41
 
42
+ ## Setting Up the Environment
43
+
44
+ When working in the CLI, a lot of friction can get introduced with installing it and rebuilding for every change. To avoid that, we have a script that can be linked globally to directly run the source code of the CLI. You can use it the same as you would the standard CLI.
45
+
46
+ ### 1. Link `react-email` globally
47
+
48
+ ```sh
49
+ pnpm link ./dev -g
50
+ ```
51
+
52
+ ### 2. Run the CLI
53
+
54
+ ```sh
55
+ email-dev [command] [flags]
56
+ ```
57
+
42
58
  ## License
43
59
 
44
60
  MIT License
@@ -0,0 +1,306 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import logSymbols from 'log-symbols';
5
+ import ora from 'ora';
6
+ import {
7
+ type EmailsDirectory,
8
+ getEmailsDirectoryMetadata,
9
+ } from '../utils/get-emails-directory-metadata.js';
10
+ import { getPreviewServerLocation } from '../utils/get-preview-server-location.js';
11
+ import { registerSpinnerAutostopping } from '../utils/register-spinner-autostopping.js';
12
+
13
+ interface Args {
14
+ dir: string;
15
+ packageManager: string;
16
+ }
17
+
18
+ const buildPreviewApp = (absoluteDirectory: string) => {
19
+ return new Promise<void>((resolve, reject) => {
20
+ const nextBuild = spawn('npm', ['run', 'build'], {
21
+ cwd: absoluteDirectory,
22
+ shell: true,
23
+ });
24
+ nextBuild.stdout.pipe(process.stdout);
25
+ nextBuild.stderr.pipe(process.stderr);
26
+
27
+ nextBuild.on('close', (code) => {
28
+ if (code === 0) {
29
+ resolve();
30
+ } else {
31
+ reject(
32
+ new Error(
33
+ `Unable to build the Next app and it exited with code: ${code}`,
34
+ ),
35
+ );
36
+ }
37
+ });
38
+ });
39
+ };
40
+
41
+ const npmInstall = async (
42
+ builtPreviewAppPath: string,
43
+ packageManager: string,
44
+ ) => {
45
+ return new Promise<void>((resolve, reject) => {
46
+ const childProc = spawn(
47
+ packageManager,
48
+ [
49
+ 'install',
50
+ packageManager === 'deno' ? '' : '--include=dev',
51
+ packageManager === 'deno' ? '--quiet' : '--silent',
52
+ ],
53
+ {
54
+ cwd: builtPreviewAppPath,
55
+ shell: true,
56
+ },
57
+ );
58
+ childProc.stdout.pipe(process.stdout);
59
+ childProc.stderr.pipe(process.stderr);
60
+ childProc.on('close', (code) => {
61
+ if (code === 0) {
62
+ resolve();
63
+ } else {
64
+ reject(
65
+ new Error(
66
+ `Unable to install the dependencies and it exited with code: ${code}`,
67
+ ),
68
+ );
69
+ }
70
+ });
71
+ });
72
+ };
73
+
74
+ const setNextEnvironmentVariablesForBuild = async (
75
+ emailsDirRelativePath: string,
76
+ builtPreviewAppPath: string,
77
+ ) => {
78
+ const nextConfigContents = `
79
+ const path = require('path');
80
+ const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
81
+ const userProjectLocation = '${process.cwd()}';
82
+ /** @type {import('next').NextConfig} */
83
+ module.exports = {
84
+ env: {
85
+ NEXT_PUBLIC_IS_BUILDING: 'true',
86
+ EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
87
+ EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
88
+ USER_PROJECT_LOCATION: userProjectLocation
89
+ },
90
+ // this is needed so that the code for building emails works properly
91
+ webpack: (
92
+ /** @type {import('webpack').Configuration & { externals: string[] }} */
93
+ config,
94
+ { isServer }
95
+ ) => {
96
+ if (isServer) {
97
+ config.externals.push('esbuild');
98
+ }
99
+
100
+ return config;
101
+ },
102
+ typescript: {
103
+ ignoreBuildErrors: true
104
+ },
105
+ eslint: {
106
+ ignoreDuringBuilds: true
107
+ },
108
+ experimental: {
109
+ webpackBuildWorker: true
110
+ },
111
+ }`;
112
+
113
+ await fs.promises.writeFile(
114
+ path.resolve(builtPreviewAppPath, './next.config.js'),
115
+ nextConfigContents,
116
+ 'utf8',
117
+ );
118
+ };
119
+
120
+ const getEmailSlugsFromEmailDirectory = (
121
+ emailDirectory: EmailsDirectory,
122
+ emailsDirectoryAbsolutePath: string,
123
+ ) => {
124
+ const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath
125
+ .replace(emailsDirectoryAbsolutePath, '')
126
+ .trim();
127
+
128
+ const slugs = [] as Array<string>[];
129
+ emailDirectory.emailFilenames.forEach((filename) =>
130
+ slugs.push(
131
+ path
132
+ .join(directoryPathRelativeToEmailsDirectory, filename)
133
+ .split(path.sep)
134
+ // sometimes it gets empty segments due to trailing slashes
135
+ .filter((segment) => segment.length > 0),
136
+ ),
137
+ );
138
+ emailDirectory.subDirectories.forEach((directory) => {
139
+ slugs.push(
140
+ ...getEmailSlugsFromEmailDirectory(
141
+ directory,
142
+ emailsDirectoryAbsolutePath,
143
+ ),
144
+ );
145
+ });
146
+
147
+ return slugs;
148
+ };
149
+
150
+ // we do this because otherwise it won't be able to find the emails
151
+ // after build
152
+ const forceSSGForEmailPreviews = async (
153
+ emailsDirPath: string,
154
+ builtPreviewAppPath: string,
155
+ ) => {
156
+ const emailDirectoryMetadata =
157
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
158
+ (await getEmailsDirectoryMetadata(emailsDirPath))!;
159
+
160
+ const parameters = getEmailSlugsFromEmailDirectory(
161
+ emailDirectoryMetadata,
162
+ emailsDirPath,
163
+ ).map((slug) => ({ slug }));
164
+
165
+ const removeForceDynamic = async (filePath: string) => {
166
+ const contents = await fs.promises.readFile(filePath, 'utf8');
167
+
168
+ await fs.promises.writeFile(
169
+ filePath,
170
+ contents.replace("export const dynamic = 'force-dynamic';", ''),
171
+ 'utf8',
172
+ );
173
+ };
174
+ await removeForceDynamic(
175
+ path.resolve(builtPreviewAppPath, './src/app/layout.tsx'),
176
+ );
177
+ await removeForceDynamic(
178
+ path.resolve(builtPreviewAppPath, './src/app/preview/[...slug]/page.tsx'),
179
+ );
180
+
181
+ await fs.promises.appendFile(
182
+ path.resolve(builtPreviewAppPath, './src/app/preview/[...slug]/page.tsx'),
183
+ `
184
+
185
+ export function generateStaticParams() {
186
+ return Promise.resolve(
187
+ ${JSON.stringify(parameters)}
188
+ );
189
+ }`,
190
+ 'utf8',
191
+ );
192
+ };
193
+
194
+ const updatePackageJson = async (builtPreviewAppPath: string) => {
195
+ const packageJsonPath = path.resolve(builtPreviewAppPath, './package.json');
196
+ const packageJson = JSON.parse(
197
+ await fs.promises.readFile(packageJsonPath, 'utf8'),
198
+ ) as {
199
+ name: string;
200
+ scripts: Record<string, string>;
201
+ dependencies: Record<string, string>;
202
+ devDependencies: Record<string, string>;
203
+ };
204
+ packageJson.scripts.build = 'next build';
205
+ packageJson.scripts.start = 'next start';
206
+ delete packageJson.scripts.postbuild;
207
+
208
+ packageJson.name = 'preview-server';
209
+
210
+ // We remove this one to avoid having resolve issues on our demo build process.
211
+ // This is only used in the `export` command so it's irrelevant to have it here.
212
+ //
213
+ // See `src/actions/render-email-by-path` for more info on how we render the
214
+ // email templates without `@react-email/render` being installed.
215
+ delete packageJson.devDependencies['@react-email/render'];
216
+ delete packageJson.devDependencies['@react-email/components'];
217
+ delete packageJson.scripts.prepare;
218
+
219
+ await fs.promises.writeFile(
220
+ packageJsonPath,
221
+ JSON.stringify(packageJson),
222
+ 'utf8',
223
+ );
224
+ };
225
+
226
+ export const build = async ({
227
+ dir: emailsDirRelativePath,
228
+ packageManager,
229
+ }: Args) => {
230
+ try {
231
+ const previewServerLocation = await getPreviewServerLocation();
232
+
233
+ const spinner = ora({
234
+ text: 'Starting build process...',
235
+ prefixText: ' ',
236
+ }).start();
237
+ registerSpinnerAutostopping(spinner);
238
+
239
+ spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
240
+ if (!fs.existsSync(emailsDirRelativePath)) {
241
+ process.exit(1);
242
+ }
243
+
244
+ const emailsDirPath = path.join(process.cwd(), emailsDirRelativePath);
245
+ const staticPath = path.join(emailsDirPath, 'static');
246
+
247
+ const builtPreviewAppPath = path.join(process.cwd(), '.react-email');
248
+
249
+ if (fs.existsSync(builtPreviewAppPath)) {
250
+ spinner.text = 'Deleting pre-existing `.react-email` folder';
251
+ await fs.promises.rm(builtPreviewAppPath, { recursive: true });
252
+ }
253
+
254
+ spinner.text = 'Copying preview app from CLI to `.react-email`';
255
+ await fs.promises.cp(previewServerLocation, builtPreviewAppPath, {
256
+ recursive: true,
257
+ filter: (source: string) => {
258
+ // do not copy the CLI files
259
+ return (
260
+ !/(\/|\\)cli(\/|\\)?/.test(source) &&
261
+ !/(\/|\\)\.next(\/|\\)?/.test(source) &&
262
+ !/(\/|\\)\.turbo(\/|\\)?/.test(source) &&
263
+ !/(\/|\\)node_modules(\/|\\)?$/.test(source)
264
+ );
265
+ },
266
+ });
267
+
268
+ if (fs.existsSync(staticPath)) {
269
+ spinner.text =
270
+ 'Copying `static` folder into `.react-email/public/static`';
271
+ const builtStaticDirectory = path.resolve(
272
+ builtPreviewAppPath,
273
+ './public/static',
274
+ );
275
+ await fs.promises.cp(staticPath, builtStaticDirectory, {
276
+ recursive: true,
277
+ });
278
+ }
279
+
280
+ spinner.text =
281
+ 'Setting Next environment variables for preview app to work properly';
282
+ await setNextEnvironmentVariablesForBuild(
283
+ emailsDirRelativePath,
284
+ builtPreviewAppPath,
285
+ );
286
+
287
+ spinner.text = 'Setting server side generation for the email preview pages';
288
+ await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
289
+
290
+ spinner.text = "Updating package.json's build and start scripts";
291
+ await updatePackageJson(builtPreviewAppPath);
292
+
293
+ spinner.text = 'Installing dependencies on `.react-email`';
294
+ await npmInstall(builtPreviewAppPath, packageManager);
295
+
296
+ spinner.stopAndPersist({
297
+ text: 'Successfully prepared `.react-email` for `next build`',
298
+ symbol: logSymbols.success,
299
+ });
300
+
301
+ await buildPreviewApp(builtPreviewAppPath);
302
+ } catch (error) {
303
+ console.log(error);
304
+ process.exit(1);
305
+ }
306
+ };
@@ -0,0 +1,27 @@
1
+ import fs from 'node:fs';
2
+ import { setupHotreloading, startDevServer } from '../utils/index.js';
3
+
4
+ interface Args {
5
+ dir: string;
6
+ port: string;
7
+ }
8
+
9
+ export const dev = async ({ dir: emailsDirRelativePath, port }: Args) => {
10
+ try {
11
+ if (!fs.existsSync(emailsDirRelativePath)) {
12
+ console.error(`Missing ${emailsDirRelativePath} folder`);
13
+ process.exit(1);
14
+ }
15
+
16
+ const devServer = await startDevServer(
17
+ emailsDirRelativePath,
18
+ emailsDirRelativePath, // defaults to ./emails/static for the static files that are served to the preview
19
+ Number.parseInt(port),
20
+ );
21
+
22
+ await setupHotreloading(devServer, emailsDirRelativePath);
23
+ } catch (error) {
24
+ console.log(error);
25
+ process.exit(1);
26
+ }
27
+ };