react-email 4.1.0-canary.6 → 4.1.0-canary.8

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 (282) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{cli/index.mjs → index.js} +437 -429
  3. package/package.json +10 -45
  4. package/src/commands/build.ts +306 -0
  5. package/src/commands/dev.ts +27 -0
  6. package/src/commands/export.ts +204 -0
  7. package/src/commands/start.ts +38 -0
  8. package/src/index.ts +55 -0
  9. package/src/utils/__snapshots__/tree.spec.ts.snap +27 -0
  10. package/src/utils/esbuild/renderring-utilities-exporter.ts +1 -1
  11. package/src/utils/get-emails-directory-metadata.spec.ts +1 -1
  12. package/src/utils/get-preview-server-location.ts +32 -0
  13. package/src/utils/index.ts +2 -6
  14. package/src/utils/packageJson.ts +4 -0
  15. package/src/utils/preview/get-env-variables-for-preview-app.ts +14 -0
  16. package/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +281 -0
  17. package/src/utils/preview/hot-reloading/create-dependency-graph.ts +321 -0
  18. package/src/utils/preview/hot-reloading/get-imported-modules.spec.ts +151 -0
  19. package/src/utils/preview/hot-reloading/get-imported-modules.ts +49 -0
  20. package/src/utils/preview/hot-reloading/resolve-path-aliases.spec.ts +11 -0
  21. package/src/utils/preview/hot-reloading/resolve-path-aliases.ts +32 -0
  22. package/src/utils/preview/hot-reloading/setup-hot-reloading.ts +121 -0
  23. package/src/utils/preview/hot-reloading/test/tsconfig.json +8 -0
  24. package/src/utils/preview/index.ts +2 -0
  25. package/src/utils/preview/serve-static-file.ts +51 -0
  26. package/src/utils/preview/start-dev-server.ts +234 -0
  27. package/src/utils/tree.spec.ts +5 -0
  28. package/src/utils/tree.ts +76 -0
  29. package/src/utils/types/hot-reload-change.ts +1 -1
  30. package/src/utils/types/hot-reload-event.ts +1 -1
  31. package/tsconfig.json +4 -10
  32. package/dist/preview/.next/BUILD_ID +0 -1
  33. package/dist/preview/.next/app-build-manifest.json +0 -44
  34. package/dist/preview/.next/app-path-routes-manifest.json +0 -6
  35. package/dist/preview/.next/build-manifest.json +0 -33
  36. package/dist/preview/.next/diagnostics/build-diagnostics.json +0 -6
  37. package/dist/preview/.next/diagnostics/framework.json +0 -1
  38. package/dist/preview/.next/export-marker.json +0 -6
  39. package/dist/preview/.next/images-manifest.json +0 -57
  40. package/dist/preview/.next/next-minimal-server.js.nft.json +0 -1
  41. package/dist/preview/.next/next-server.js.nft.json +0 -1
  42. package/dist/preview/.next/package.json +0 -1
  43. package/dist/preview/.next/prerender-manifest.json +0 -41
  44. package/dist/preview/.next/react-loadable-manifest.json +0 -1
  45. package/dist/preview/.next/required-server-files.json +0 -311
  46. package/dist/preview/.next/routes-manifest.json +0 -64
  47. package/dist/preview/.next/server/app/_not-found/page.js +0 -1
  48. package/dist/preview/.next/server/app/_not-found/page.js.nft.json +0 -1
  49. package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  50. package/dist/preview/.next/server/app/favicon.ico/route.js +0 -1
  51. package/dist/preview/.next/server/app/favicon.ico/route.js.nft.json +0 -1
  52. package/dist/preview/.next/server/app/favicon.ico.body +0 -0
  53. package/dist/preview/.next/server/app/favicon.ico.meta +0 -1
  54. package/dist/preview/.next/server/app/page.js +0 -1
  55. package/dist/preview/.next/server/app/page.js.nft.json +0 -1
  56. package/dist/preview/.next/server/app/page_client-reference-manifest.js +0 -1
  57. package/dist/preview/.next/server/app/preview/[...slug]/page.js +0 -321
  58. package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +0 -1
  59. package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +0 -1
  60. package/dist/preview/.next/server/app-paths-manifest.json +0 -6
  61. package/dist/preview/.next/server/chunks/134.js +0 -6
  62. package/dist/preview/.next/server/chunks/235.js +0 -15
  63. package/dist/preview/.next/server/chunks/315.js +0 -1
  64. package/dist/preview/.next/server/chunks/343.js +0 -20
  65. package/dist/preview/.next/server/chunks/428.js +0 -14
  66. package/dist/preview/.next/server/chunks/963.js +0 -1
  67. package/dist/preview/.next/server/functions-config-manifest.json +0 -4
  68. package/dist/preview/.next/server/interception-route-rewrite-manifest.js +0 -1
  69. package/dist/preview/.next/server/middleware-build-manifest.js +0 -1
  70. package/dist/preview/.next/server/middleware-manifest.json +0 -6
  71. package/dist/preview/.next/server/middleware-react-loadable-manifest.js +0 -1
  72. package/dist/preview/.next/server/next-font-manifest.js +0 -1
  73. package/dist/preview/.next/server/next-font-manifest.json +0 -1
  74. package/dist/preview/.next/server/pages/500.html +0 -1
  75. package/dist/preview/.next/server/pages/_app.js +0 -1
  76. package/dist/preview/.next/server/pages/_app.js.nft.json +0 -1
  77. package/dist/preview/.next/server/pages/_document.js +0 -1
  78. package/dist/preview/.next/server/pages/_document.js.nft.json +0 -1
  79. package/dist/preview/.next/server/pages/_error.js +0 -1
  80. package/dist/preview/.next/server/pages/_error.js.nft.json +0 -1
  81. package/dist/preview/.next/server/pages-manifest.json +0 -5
  82. package/dist/preview/.next/server/server-reference-manifest.js +0 -1
  83. package/dist/preview/.next/server/server-reference-manifest.json +0 -1
  84. package/dist/preview/.next/server/webpack-runtime.js +0 -1
  85. package/dist/preview/.next/static/EYH0WN4--LLC3GZrZIVN8/_buildManifest.js +0 -1
  86. package/dist/preview/.next/static/EYH0WN4--LLC3GZrZIVN8/_ssgManifest.js +0 -1
  87. package/dist/preview/.next/static/chunks/107-3043079e7cb8bcae.js +0 -1
  88. package/dist/preview/.next/static/chunks/293-297b1eb2241f9a70.js +0 -1
  89. package/dist/preview/.next/static/chunks/3bd82e28-cda2c00a924937c5.js +0 -1
  90. package/dist/preview/.next/static/chunks/45-1021fac82f766268.js +0 -1
  91. package/dist/preview/.next/static/chunks/484-a7b30a88a7939680.js +0 -1
  92. package/dist/preview/.next/static/chunks/589-817d8691661d370e.js +0 -1
  93. package/dist/preview/.next/static/chunks/902-c34acb56733e0ce1.js +0 -1
  94. package/dist/preview/.next/static/chunks/app/_not-found/page-4cbc7dce3ad33336.js +0 -1
  95. package/dist/preview/.next/static/chunks/app/layout-46a09d953364e102.js +0 -1
  96. package/dist/preview/.next/static/chunks/app/page-65fd67d48528e2ba.js +0 -1
  97. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-5e69ffe7506383a0.js +0 -1
  98. package/dist/preview/.next/static/chunks/f33a14d2-ec7c5f0b91818561.js +0 -6
  99. package/dist/preview/.next/static/chunks/framework-b887e9fc751a9906.js +0 -1
  100. package/dist/preview/.next/static/chunks/main-9a03e7ba8acb1900.js +0 -1
  101. package/dist/preview/.next/static/chunks/main-app-dbd8e1ec12eabb66.js +0 -1
  102. package/dist/preview/.next/static/chunks/pages/_app-542a93a5a214e1c0.js +0 -1
  103. package/dist/preview/.next/static/chunks/pages/_error-d5fe1b1612642f76.js +0 -1
  104. package/dist/preview/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  105. package/dist/preview/.next/static/chunks/webpack-31c45daa2bd82a7b.js +0 -1
  106. package/dist/preview/.next/static/css/6f42d128f111d7fa.css +0 -3
  107. package/dist/preview/.next/static/media/05613964ce6c782e-s.p.otf +0 -0
  108. package/dist/preview/.next/static/media/11c6126b9369e85e-s.p.otf +0 -0
  109. package/dist/preview/.next/static/media/26a46d62cd723877-s.woff2 +0 -0
  110. package/dist/preview/.next/static/media/26cb97734d8cb717-s.p.otf +0 -0
  111. package/dist/preview/.next/static/media/55c55f0601d81cf3-s.woff2 +0 -0
  112. package/dist/preview/.next/static/media/581909926a08bbc8-s.woff2 +0 -0
  113. package/dist/preview/.next/static/media/6d93bde91c0c2823-s.woff2 +0 -0
  114. package/dist/preview/.next/static/media/97e0cb1ae144a2a9-s.woff2 +0 -0
  115. package/dist/preview/.next/static/media/a34f9d1faa5f3315-s.p.woff2 +0 -0
  116. package/dist/preview/.next/static/media/bb6462617151f6b7-s.p.otf +0 -0
  117. package/dist/preview/.next/static/media/cf6daef822ab0142-s.p.otf +0 -0
  118. package/dist/preview/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
  119. package/dist/preview/.next/static/media/e4051546b3043204-s.p.otf +0 -0
  120. package/dist/preview/.next/static/media/logo.2ce2a759.png +0 -0
  121. package/dist/preview/.next/trace +0 -28
  122. package/dist/preview/.next/types/app/layout.ts +0 -84
  123. package/dist/preview/.next/types/app/page.ts +0 -84
  124. package/dist/preview/.next/types/app/preview/[...slug]/page.ts +0 -84
  125. package/dist/preview/.next/types/cache-life.d.ts +0 -141
  126. package/dist/preview/.next/types/package.json +0 -1
  127. package/module-punycode.d.ts +0 -3
  128. package/next-env.d.ts +0 -5
  129. package/next.config.js +0 -22
  130. package/postcss.config.js +0 -8
  131. package/scripts/build-preview-server.mjs +0 -33
  132. package/scripts/fill-caniemail-data.mjs +0 -36
  133. package/src/actions/email-validation/caniemail-data.ts +0 -85993
  134. package/src/actions/email-validation/check-compatibility.ts +0 -333
  135. package/src/actions/email-validation/check-images.spec.tsx +0 -100
  136. package/src/actions/email-validation/check-images.ts +0 -160
  137. package/src/actions/email-validation/check-links.spec.tsx +0 -113
  138. package/src/actions/email-validation/check-links.ts +0 -113
  139. package/src/actions/email-validation/get-code-location-from-ast-element.ts +0 -18
  140. package/src/actions/email-validation/quick-fetch.ts +0 -14
  141. package/src/actions/get-email-path-from-slug.ts +0 -32
  142. package/src/actions/get-emails-directory-metadata-action.ts +0 -19
  143. package/src/actions/render-email-by-path.tsx +0 -121
  144. package/src/animated-icons-data/help.json +0 -1082
  145. package/src/animated-icons-data/link.json +0 -1309
  146. package/src/animated-icons-data/load.json +0 -443
  147. package/src/animated-icons-data/mail.json +0 -1320
  148. package/src/app/env.ts +0 -15
  149. package/src/app/favicon.ico +0 -0
  150. package/src/app/fonts/SFMono/SFMonoBold.otf +0 -0
  151. package/src/app/fonts/SFMono/SFMonoBoldItalic.otf +0 -0
  152. package/src/app/fonts/SFMono/SFMonoHeavy.otf +0 -0
  153. package/src/app/fonts/SFMono/SFMonoHeavyItalic.otf +0 -0
  154. package/src/app/fonts/SFMono/SFMonoLight.otf +0 -0
  155. package/src/app/fonts/SFMono/SFMonoLightItalic.otf +0 -0
  156. package/src/app/fonts/SFMono/SFMonoMedium.otf +0 -0
  157. package/src/app/fonts/SFMono/SFMonoMediumItalic.otf +0 -0
  158. package/src/app/fonts/SFMono/SFMonoRegular.otf +0 -0
  159. package/src/app/fonts/SFMono/SFMonoRegularItalic.otf +0 -0
  160. package/src/app/fonts/SFMono/SFMonoSemibold.otf +0 -0
  161. package/src/app/fonts/SFMono/SFMonoSemiboldItalic.otf +0 -0
  162. package/src/app/fonts.ts +0 -39
  163. package/src/app/globals.css +0 -15
  164. package/src/app/layout.tsx +0 -45
  165. package/src/app/logo.png +0 -0
  166. package/src/app/page.tsx +0 -46
  167. package/src/app/preview/[...slug]/page.tsx +0 -157
  168. package/src/app/preview/[...slug]/preview.tsx +0 -234
  169. package/src/app/preview/[...slug]/rendering-error.tsx +0 -40
  170. package/src/components/button.tsx +0 -101
  171. package/src/components/code-container.tsx +0 -164
  172. package/src/components/code-snippet.tsx +0 -9
  173. package/src/components/code.tsx +0 -184
  174. package/src/components/heading.tsx +0 -113
  175. package/src/components/icons/icon-arrow-down.tsx +0 -16
  176. package/src/components/icons/icon-base.tsx +0 -26
  177. package/src/components/icons/icon-bug.tsx +0 -19
  178. package/src/components/icons/icon-button.tsx +0 -23
  179. package/src/components/icons/icon-check.tsx +0 -19
  180. package/src/components/icons/icon-clipboard.tsx +0 -40
  181. package/src/components/icons/icon-download.tsx +0 -19
  182. package/src/components/icons/icon-email.tsx +0 -18
  183. package/src/components/icons/icon-file.tsx +0 -19
  184. package/src/components/icons/icon-folder-open.tsx +0 -19
  185. package/src/components/icons/icon-folder.tsx +0 -18
  186. package/src/components/icons/icon-hide-sidebar.tsx +0 -23
  187. package/src/components/icons/icon-image.tsx +0 -19
  188. package/src/components/icons/icon-info.tsx +0 -18
  189. package/src/components/icons/icon-link.tsx +0 -14
  190. package/src/components/icons/icon-monitor.tsx +0 -19
  191. package/src/components/icons/icon-moon.tsx +0 -16
  192. package/src/components/icons/icon-phone.tsx +0 -26
  193. package/src/components/icons/icon-reload.tsx +0 -18
  194. package/src/components/icons/icon-source.tsx +0 -19
  195. package/src/components/icons/icon-stamp.tsx +0 -14
  196. package/src/components/icons/icon-sun.tsx +0 -16
  197. package/src/components/icons/icon-warning.tsx +0 -31
  198. package/src/components/index.ts +0 -7
  199. package/src/components/logo.tsx +0 -63
  200. package/src/components/resizable-wrapper.tsx +0 -173
  201. package/src/components/send.tsx +0 -134
  202. package/src/components/shell.tsx +0 -92
  203. package/src/components/sidebar/file-tree-directory-children.tsx +0 -139
  204. package/src/components/sidebar/file-tree-directory.tsx +0 -92
  205. package/src/components/sidebar/file-tree.tsx +0 -31
  206. package/src/components/sidebar/index.ts +0 -1
  207. package/src/components/sidebar/sidebar.tsx +0 -43
  208. package/src/components/text.tsx +0 -99
  209. package/src/components/toolbar/checking-results.tsx +0 -150
  210. package/src/components/toolbar/code-preview-line-link.tsx +0 -40
  211. package/src/components/toolbar/compatibility.tsx +0 -113
  212. package/src/components/toolbar/linter.tsx +0 -278
  213. package/src/components/toolbar/results.tsx +0 -51
  214. package/src/components/toolbar/spam-assassin.tsx +0 -155
  215. package/src/components/toolbar/toolbar-button.tsx +0 -52
  216. package/src/components/toolbar/use-cached-state.ts +0 -33
  217. package/src/components/toolbar.tsx +0 -349
  218. package/src/components/tooltip-content.tsx +0 -31
  219. package/src/components/tooltip.tsx +0 -19
  220. package/src/components/topbar/active-view-toggle-group.tsx +0 -86
  221. package/src/components/topbar/theme-toggle-group.tsx +0 -87
  222. package/src/components/topbar/view-size-controls.tsx +0 -247
  223. package/src/components/topbar.tsx +0 -59
  224. package/src/contexts/emails.tsx +0 -59
  225. package/src/contexts/fragment-identifier.tsx +0 -48
  226. package/src/contexts/preview.tsx +0 -79
  227. package/src/hooks/use-clamped-state.ts +0 -24
  228. package/src/hooks/use-email-rendering-result.ts +0 -58
  229. package/src/hooks/use-fragment-identifier.ts +0 -14
  230. package/src/hooks/use-hot-reload.ts +0 -31
  231. package/src/hooks/use-icon-animation.ts +0 -41
  232. package/src/hooks/use-iframe-color-scheme.ts +0 -35
  233. package/src/hooks/use-rendering-metadata.ts +0 -36
  234. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +0 -3
  235. package/src/utils/caniemail/all-css-properties.ts +0 -358
  236. package/src/utils/caniemail/ast/__snapshots__/get-object-variables.spec.ts.snap +0 -74
  237. package/src/utils/caniemail/ast/__snapshots__/get-used-style-properties.spec.ts.snap +0 -24
  238. package/src/utils/caniemail/ast/get-object-variables.spec.ts +0 -19
  239. package/src/utils/caniemail/ast/get-object-variables.ts +0 -61
  240. package/src/utils/caniemail/ast/get-used-style-properties.spec.ts +0 -23
  241. package/src/utils/caniemail/ast/get-used-style-properties.ts +0 -91
  242. package/src/utils/caniemail/get-compatibility-stats-for-entry.ts +0 -118
  243. package/src/utils/caniemail/get-css-functions.ts +0 -25
  244. package/src/utils/caniemail/get-css-property-names.ts +0 -32
  245. package/src/utils/caniemail/get-css-property-with-value.ts +0 -14
  246. package/src/utils/caniemail/get-css-unit.ts +0 -3
  247. package/src/utils/caniemail/get-element-attributes.ts +0 -7
  248. package/src/utils/caniemail/get-element-names.ts +0 -20
  249. package/src/utils/caniemail/tailwind/generate-tailwind-rules.ts +0 -30
  250. package/src/utils/caniemail/tailwind/get-tailwind-config.ts +0 -187
  251. package/src/utils/caniemail/tailwind/get-tailwind-metadata.spec.ts +0 -25
  252. package/src/utils/caniemail/tailwind/get-tailwind-metadata.ts +0 -45
  253. package/src/utils/caniemail/tailwind/setup-tailwind-context.ts +0 -15
  254. package/src/utils/cn.ts +0 -6
  255. package/src/utils/constants.ts +0 -6
  256. package/src/utils/contains-email-template.spec.ts +0 -107
  257. package/src/utils/contains-email-template.ts +0 -33
  258. package/src/utils/copy-text-to-clipboard.ts +0 -7
  259. package/src/utils/get-email-component.spec.ts +0 -41
  260. package/src/utils/get-email-component.ts +0 -134
  261. package/src/utils/get-line-and-column-from-offset.spec.ts +0 -11
  262. package/src/utils/get-line-and-column-from-offset.ts +0 -11
  263. package/src/utils/improve-error-with-sourcemap.ts +0 -86
  264. package/src/utils/js-email-detection.spec.ts +0 -24
  265. package/src/utils/language-map.ts +0 -7
  266. package/src/utils/linting.ts +0 -60
  267. package/src/utils/load-stream.ts +0 -15
  268. package/src/utils/result.ts +0 -49
  269. package/src/utils/run-bundled-code.ts +0 -64
  270. package/src/utils/sanitize.ts +0 -6
  271. package/src/utils/static-node-modules-for-vm.ts +0 -93
  272. package/src/utils/testing/js-email-export-default.js +0 -17
  273. package/src/utils/testing/js-email-test.js +0 -18
  274. package/src/utils/testing/mdx-email-test.js +0 -128
  275. package/src/utils/testing/request-response-email.tsx +0 -9
  276. package/src/utils/types/as.ts +0 -26
  277. package/src/utils/types/email-template.ts +0 -8
  278. package/src/utils/types/error-object.ts +0 -11
  279. package/src/utils/unreachable.ts +0 -8
  280. package/tailwind-internals.d.ts +0 -133
  281. package/tailwind.config.ts +0 -99
  282. /package/src/{components/toolbar/results-table.tsx → utils/preview/hot-reloading/test/some-file.ts} +0 -0
@@ -1,112 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/cli/index.ts
3
+ // src/index.ts
4
4
  import { program } from "commander";
5
5
 
6
- // package.json
7
- var package_default = {
8
- name: "react-email",
9
- version: "4.1.0-canary.6",
10
- description: "A live preview of your emails right in your browser.",
11
- bin: {
12
- email: "./dist/cli/index.mjs"
13
- },
14
- scripts: {
15
- build: "tsup-node && node ./scripts/build-preview-server.mjs",
16
- postbuild: "pnpm install --frozen-lockfile",
17
- "caniemail:fetch": "node ./scripts/fill-caniemail-data.mjs",
18
- clean: "rm -rf dist",
19
- dev: "tsup-node --watch",
20
- "dev:preview": "cd ../../apps/demo && tsx ../../packages/react-email/src/cli/index.ts dev",
21
- test: "vitest run",
22
- "test:watch": "vitest"
23
- },
24
- license: "MIT",
25
- repository: {
26
- type: "git",
27
- url: "https://github.com/resend/react-email.git",
28
- directory: "packages/react-email"
29
- },
30
- keywords: [
31
- "react",
32
- "email"
33
- ],
34
- engines: {
35
- node: ">=18.0.0"
36
- },
37
- dependencies: {
38
- "@babel/parser": "^7.27.0",
39
- "@babel/traverse": "^7.27.0",
40
- chalk: "^5.0.0",
41
- chokidar: "^4.0.3",
42
- commander: "^13.0.0",
43
- debounce: "^2.0.0",
44
- esbuild: "^0.25.0",
45
- glob: "^11.0.0",
46
- "log-symbols": "^7.0.0",
47
- "mime-types": "^3.0.0",
48
- next: "^15.3.1",
49
- "normalize-path": "^3.0.0",
50
- ora: "^8.0.0",
51
- "socket.io": "^4.8.1",
52
- "tsconfig-paths": "4.2.0"
53
- },
54
- devDependencies: {
55
- "@babel/core": "7.26.10",
56
- "@lottiefiles/dotlottie-react": "0.13.3",
57
- "@radix-ui/colors": "3.0.0",
58
- "@radix-ui/react-collapsible": "1.1.7",
59
- "@radix-ui/react-dropdown-menu": "2.1.10",
60
- "@radix-ui/react-popover": "1.1.10",
61
- "@radix-ui/react-slot": "1.2.0",
62
- "@radix-ui/react-tabs": "1.1.7",
63
- "@radix-ui/react-toggle-group": "1.1.6",
64
- "@radix-ui/react-tooltip": "1.2.3",
65
- "@react-email/components": "workspace:*",
66
- "@swc/core": "1.11.21",
67
- "@types/babel__core": "7.20.5",
68
- "@types/babel__traverse": "7.20.7",
69
- "@types/fs-extra": "11.0.1",
70
- "@types/mime-types": "2.1.4",
71
- "@types/node": "22.14.1",
72
- "@types/normalize-path": "3.0.2",
73
- "@types/react": "19.0.10",
74
- "@types/react-dom": "19.0.4",
75
- "@types/webpack": "5.28.5",
76
- autoprefixer: "10.4.21",
77
- clsx: "2.1.1",
78
- "framer-motion": "12.7.5",
79
- jiti: "2.4.2",
80
- json5: "2.2.3",
81
- "module-punycode": "npm:punycode@2.3.1",
82
- "node-html-parser": "7.0.1",
83
- postcss: "8.5.3",
84
- "pretty-bytes": "6.1.1",
85
- "prism-react-renderer": "2.4.1",
86
- react: "19.0.0",
87
- "react-dom": "19.0.0",
88
- sharp: "0.34.1",
89
- "socket.io-client": "4.8.1",
90
- sonner: "2.0.3",
91
- "source-map-js": "1.2.1",
92
- spamc: "0.0.5",
93
- "stacktrace-parser": "0.1.11",
94
- "tailwind-merge": "3.2.0",
95
- tailwindcss: "3.4.0",
96
- tsup: "8.4.0",
97
- tsx: "4.19.3",
98
- typescript: "5.8.3",
99
- "use-debounce": "10.0.4",
100
- zod: "3.24.3"
101
- }
102
- };
103
-
104
- // src/cli/commands/build.ts
6
+ // src/commands/build.ts
105
7
  import { spawn } from "node:child_process";
106
- import fs5 from "node:fs";
107
- import path9 from "node:path";
108
- import logSymbols3 from "log-symbols";
109
- import ora2 from "ora";
8
+ import fs2 from "node:fs";
9
+ import path3 from "node:path";
10
+ import logSymbols2 from "log-symbols";
11
+ import ora from "ora";
110
12
 
111
13
  // src/utils/get-emails-directory-metadata.ts
112
14
  import fs from "node:fs";
@@ -194,6 +96,37 @@ var getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFileE
194
96
  return isSubDirectory ? mergeDirectoriesWithSubDirectories(emailsMetadata) : emailsMetadata;
195
97
  };
196
98
 
99
+ // src/utils/get-preview-server-location.ts
100
+ import path2 from "node:path";
101
+ import url from "node:url";
102
+ import { createJiti } from "jiti";
103
+ import { addDevDependency } from "nypm";
104
+ import prompts from "prompts";
105
+ var getPreviewServerLocation = async () => {
106
+ const usersProject = createJiti(process.cwd());
107
+ let previewServerLocation;
108
+ try {
109
+ previewServerLocation = path2.dirname(
110
+ url.parse(usersProject.esmResolve("@react-email/preview-server"), true).path
111
+ );
112
+ } catch (exception) {
113
+ const response = await prompts({
114
+ type: "confirm",
115
+ name: "installPreviewServer",
116
+ message: 'To run the preview server, the pacakge "@react-email/preview-server" must be installed. Would you like to install it?',
117
+ initial: true
118
+ });
119
+ if (response.installPreviewServer) {
120
+ console.log('Installing "@react-email/preview-server"');
121
+ await addDevDependency("@react-email/preview-server");
122
+ process.exit(0);
123
+ } else {
124
+ process.exit(0);
125
+ }
126
+ }
127
+ return previewServerLocation;
128
+ };
129
+
197
130
  // src/utils/register-spinner-autostopping.ts
198
131
  import logSymbols from "log-symbols";
199
132
  var spinners = /* @__PURE__ */ new Set();
@@ -214,58 +147,348 @@ process.on("exit", (code) => {
214
147
  }
215
148
  });
216
149
  }
217
- });
218
- var registerSpinnerAutostopping = (spinner) => {
219
- spinners.add(spinner);
150
+ });
151
+ var registerSpinnerAutostopping = (spinner) => {
152
+ spinners.add(spinner);
153
+ };
154
+
155
+ // src/commands/build.ts
156
+ var buildPreviewApp = (absoluteDirectory) => {
157
+ return new Promise((resolve, reject) => {
158
+ const nextBuild = spawn("npm", ["run", "build"], {
159
+ cwd: absoluteDirectory,
160
+ shell: true
161
+ });
162
+ nextBuild.stdout.pipe(process.stdout);
163
+ nextBuild.stderr.pipe(process.stderr);
164
+ nextBuild.on("close", (code) => {
165
+ if (code === 0) {
166
+ resolve();
167
+ } else {
168
+ reject(
169
+ new Error(
170
+ `Unable to build the Next app and it exited with code: ${code}`
171
+ )
172
+ );
173
+ }
174
+ });
175
+ });
176
+ };
177
+ var npmInstall = async (builtPreviewAppPath, packageManager) => {
178
+ return new Promise((resolve, reject) => {
179
+ const childProc = spawn(
180
+ packageManager,
181
+ [
182
+ "install",
183
+ packageManager === "deno" ? "" : "--include=dev",
184
+ packageManager === "deno" ? "--quiet" : "--silent"
185
+ ],
186
+ {
187
+ cwd: builtPreviewAppPath,
188
+ shell: true
189
+ }
190
+ );
191
+ childProc.stdout.pipe(process.stdout);
192
+ childProc.stderr.pipe(process.stderr);
193
+ childProc.on("close", (code) => {
194
+ if (code === 0) {
195
+ resolve();
196
+ } else {
197
+ reject(
198
+ new Error(
199
+ `Unable to install the dependencies and it exited with code: ${code}`
200
+ )
201
+ );
202
+ }
203
+ });
204
+ });
205
+ };
206
+ var setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath) => {
207
+ const nextConfigContents = `
208
+ const path = require('path');
209
+ const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
210
+ const userProjectLocation = '${process.cwd()}';
211
+ /** @type {import('next').NextConfig} */
212
+ module.exports = {
213
+ env: {
214
+ NEXT_PUBLIC_IS_BUILDING: 'true',
215
+ EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
216
+ EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
217
+ USER_PROJECT_LOCATION: userProjectLocation
218
+ },
219
+ // this is needed so that the code for building emails works properly
220
+ webpack: (
221
+ /** @type {import('webpack').Configuration & { externals: string[] }} */
222
+ config,
223
+ { isServer }
224
+ ) => {
225
+ if (isServer) {
226
+ config.externals.push('esbuild');
227
+ }
228
+
229
+ return config;
230
+ },
231
+ typescript: {
232
+ ignoreBuildErrors: true
233
+ },
234
+ eslint: {
235
+ ignoreDuringBuilds: true
236
+ },
237
+ experimental: {
238
+ webpackBuildWorker: true
239
+ },
240
+ }`;
241
+ await fs2.promises.writeFile(
242
+ path3.resolve(builtPreviewAppPath, "./next.config.js"),
243
+ nextConfigContents,
244
+ "utf8"
245
+ );
246
+ };
247
+ var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePath) => {
248
+ const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
249
+ const slugs = [];
250
+ emailDirectory.emailFilenames.forEach(
251
+ (filename3) => slugs.push(
252
+ path3.join(directoryPathRelativeToEmailsDirectory, filename3).split(path3.sep).filter((segment) => segment.length > 0)
253
+ )
254
+ );
255
+ emailDirectory.subDirectories.forEach((directory) => {
256
+ slugs.push(
257
+ ...getEmailSlugsFromEmailDirectory(
258
+ directory,
259
+ emailsDirectoryAbsolutePath
260
+ )
261
+ );
262
+ });
263
+ return slugs;
264
+ };
265
+ var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
266
+ const emailDirectoryMetadata = (
267
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
268
+ await getEmailsDirectoryMetadata(emailsDirPath)
269
+ );
270
+ const parameters = getEmailSlugsFromEmailDirectory(
271
+ emailDirectoryMetadata,
272
+ emailsDirPath
273
+ ).map((slug) => ({ slug }));
274
+ const removeForceDynamic = async (filePath) => {
275
+ const contents = await fs2.promises.readFile(filePath, "utf8");
276
+ await fs2.promises.writeFile(
277
+ filePath,
278
+ contents.replace("export const dynamic = 'force-dynamic';", ""),
279
+ "utf8"
280
+ );
281
+ };
282
+ await removeForceDynamic(
283
+ path3.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
284
+ );
285
+ await removeForceDynamic(
286
+ path3.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
287
+ );
288
+ await fs2.promises.appendFile(
289
+ path3.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
290
+ `
291
+
292
+ export function generateStaticParams() {
293
+ return Promise.resolve(
294
+ ${JSON.stringify(parameters)}
295
+ );
296
+ }`,
297
+ "utf8"
298
+ );
299
+ };
300
+ var updatePackageJson = async (builtPreviewAppPath) => {
301
+ const packageJsonPath = path3.resolve(builtPreviewAppPath, "./package.json");
302
+ const packageJson = JSON.parse(
303
+ await fs2.promises.readFile(packageJsonPath, "utf8")
304
+ );
305
+ packageJson.scripts.build = "next build";
306
+ packageJson.scripts.start = "next start";
307
+ delete packageJson.scripts.postbuild;
308
+ packageJson.name = "preview-server";
309
+ delete packageJson.devDependencies["@react-email/render"];
310
+ delete packageJson.devDependencies["@react-email/components"];
311
+ delete packageJson.scripts.prepare;
312
+ await fs2.promises.writeFile(
313
+ packageJsonPath,
314
+ JSON.stringify(packageJson),
315
+ "utf8"
316
+ );
317
+ };
318
+ var build = async ({
319
+ dir: emailsDirRelativePath,
320
+ packageManager
321
+ }) => {
322
+ try {
323
+ const previewServerLocation = await getPreviewServerLocation();
324
+ const spinner = ora({
325
+ text: "Starting build process...",
326
+ prefixText: " "
327
+ }).start();
328
+ registerSpinnerAutostopping(spinner);
329
+ spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
330
+ if (!fs2.existsSync(emailsDirRelativePath)) {
331
+ process.exit(1);
332
+ }
333
+ const emailsDirPath = path3.join(process.cwd(), emailsDirRelativePath);
334
+ const staticPath = path3.join(emailsDirPath, "static");
335
+ const builtPreviewAppPath = path3.join(process.cwd(), ".react-email");
336
+ if (fs2.existsSync(builtPreviewAppPath)) {
337
+ spinner.text = "Deleting pre-existing `.react-email` folder";
338
+ await fs2.promises.rm(builtPreviewAppPath, { recursive: true });
339
+ }
340
+ spinner.text = "Copying preview app from CLI to `.react-email`";
341
+ await fs2.promises.cp(previewServerLocation, builtPreviewAppPath, {
342
+ recursive: true,
343
+ filter: (source) => {
344
+ return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
345
+ }
346
+ });
347
+ if (fs2.existsSync(staticPath)) {
348
+ spinner.text = "Copying `static` folder into `.react-email/public/static`";
349
+ const builtStaticDirectory = path3.resolve(
350
+ builtPreviewAppPath,
351
+ "./public/static"
352
+ );
353
+ await fs2.promises.cp(staticPath, builtStaticDirectory, {
354
+ recursive: true
355
+ });
356
+ }
357
+ spinner.text = "Setting Next environment variables for preview app to work properly";
358
+ await setNextEnvironmentVariablesForBuild(
359
+ emailsDirRelativePath,
360
+ builtPreviewAppPath
361
+ );
362
+ spinner.text = "Setting server side generation for the email preview pages";
363
+ await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
364
+ spinner.text = "Updating package.json's build and start scripts";
365
+ await updatePackageJson(builtPreviewAppPath);
366
+ spinner.text = "Installing dependencies on `.react-email`";
367
+ await npmInstall(builtPreviewAppPath, packageManager);
368
+ spinner.stopAndPersist({
369
+ text: "Successfully prepared `.react-email` for `next build`",
370
+ symbol: logSymbols2.success
371
+ });
372
+ await buildPreviewApp(builtPreviewAppPath);
373
+ } catch (error) {
374
+ console.log(error);
375
+ process.exit(1);
376
+ }
377
+ };
378
+
379
+ // src/commands/dev.ts
380
+ import fs6 from "node:fs";
381
+
382
+ // src/utils/preview/hot-reloading/setup-hot-reloading.ts
383
+ import path9 from "node:path";
384
+ import { watch } from "chokidar";
385
+ import debounce from "debounce";
386
+ import { Server as SocketServer } from "socket.io";
387
+
388
+ // src/utils/preview/hot-reloading/create-dependency-graph.ts
389
+ import { existsSync as existsSync2, promises as fs4, statSync } from "node:fs";
390
+ import path8 from "node:path";
391
+
392
+ // src/utils/preview/start-dev-server.ts
393
+ import http from "node:http";
394
+ import path6 from "node:path";
395
+ import url2 from "node:url";
396
+ import chalk from "chalk";
397
+ import { createJiti as createJiti2 } from "jiti";
398
+ import logSymbols3 from "log-symbols";
399
+ import ora2 from "ora";
400
+
401
+ // package.json
402
+ var package_default = {
403
+ name: "react-email",
404
+ version: "4.1.0-canary.8",
405
+ description: "A live preview of your emails right in your browser.",
406
+ bin: {
407
+ email: "./dist/index.js"
408
+ },
409
+ type: "module",
410
+ scripts: {
411
+ build: "tsup-node",
412
+ clean: "rm -rf dist",
413
+ dev: "tsup-node --watch src",
414
+ test: "vitest run",
415
+ "test:watch": "vitest"
416
+ },
417
+ license: "MIT",
418
+ repository: {
419
+ type: "git",
420
+ url: "https://github.com/resend/react-email.git",
421
+ directory: "packages/react-email"
422
+ },
423
+ keywords: [
424
+ "react",
425
+ "email"
426
+ ],
427
+ engines: {
428
+ node: ">=18.0.0"
429
+ },
430
+ dependencies: {
431
+ "@babel/parser": "^7.27.0",
432
+ "@babel/traverse": "^7.27.0",
433
+ chalk: "^5.0.0",
434
+ chokidar: "^4.0.3",
435
+ commander: "^13.0.0",
436
+ debounce: "^2.0.0",
437
+ esbuild: "^0.25.0",
438
+ glob: "^11.0.0",
439
+ jiti: "2.4.2",
440
+ "log-symbols": "^7.0.0",
441
+ "mime-types": "^3.0.0",
442
+ "normalize-path": "^3.0.0",
443
+ nypm: "0.6.0",
444
+ ora: "^8.0.0",
445
+ prompts: "2.4.2",
446
+ "socket.io": "^4.8.1",
447
+ "tsconfig-paths": "4.2.0"
448
+ },
449
+ devDependencies: {
450
+ "@react-email/components": "workspace:*",
451
+ "@types/babel__core": "7.20.5",
452
+ "@types/babel__traverse": "7.20.7",
453
+ "@types/mime-types": "2.1.4",
454
+ "@types/prompts": "2.4.9",
455
+ next: "^15.3.1",
456
+ react: "19.0.0",
457
+ "react-dom": "19.0.0",
458
+ tsup: "8.4.0",
459
+ tsx: "4.19.3",
460
+ typescript: "5.8.3"
461
+ }
220
462
  };
221
463
 
222
- // src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
223
- import path7 from "node:path";
224
- import { watch } from "chokidar";
225
- import debounce from "debounce";
226
- import { Server as SocketServer } from "socket.io";
227
-
228
- // src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
229
- import { existsSync as existsSync2, promises as fs3, statSync } from "node:fs";
230
- import path6 from "node:path";
231
-
232
- // src/cli/utils/preview/start-dev-server.ts
233
- import http from "node:http";
464
+ // src/utils/preview/get-env-variables-for-preview-app.ts
234
465
  import path4 from "node:path";
235
- import url from "node:url";
236
- import chalk from "chalk";
237
- import logSymbols2 from "log-symbols";
238
- import next from "next";
239
- import ora from "ora";
240
-
241
- // src/cli/utils/preview/get-env-variables-for-preview-app.ts
242
- import path2 from "node:path";
243
466
  var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
244
467
  return {
245
468
  EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
246
- EMAILS_DIR_ABSOLUTE_PATH: path2.resolve(cwd, relativePathToEmailsDirectory),
469
+ EMAILS_DIR_ABSOLUTE_PATH: path4.resolve(cwd, relativePathToEmailsDirectory),
247
470
  USER_PROJECT_LOCATION: cwd,
248
471
  NEXT_PUBLIC_IS_PREVIEW_DEVELOPMENT: isDev ? "true" : "false"
249
472
  };
250
473
  };
251
474
 
252
- // src/cli/utils/preview/serve-static-file.ts
253
- import { existsSync, promises as fs2 } from "node:fs";
254
- import path3 from "node:path";
475
+ // src/utils/preview/serve-static-file.ts
476
+ import { existsSync, promises as fs3 } from "node:fs";
477
+ import path5 from "node:path";
255
478
  import { lookup } from "mime-types";
256
479
  var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
257
480
  const pathname = parsedUrl.pathname.replace("/static", "./static");
258
- const ext = path3.parse(pathname).ext;
259
- const staticBaseDir = path3.resolve(process.cwd(), staticDirRelativePath);
260
- const fileAbsolutePath = path3.resolve(staticBaseDir, pathname);
481
+ const ext = path5.parse(pathname).ext;
482
+ const staticBaseDir = path5.resolve(process.cwd(), staticDirRelativePath);
483
+ const fileAbsolutePath = path5.resolve(staticBaseDir, pathname);
261
484
  if (!fileAbsolutePath.startsWith(staticBaseDir)) {
262
485
  res.statusCode = 403;
263
486
  res.end();
264
487
  return;
265
488
  }
266
489
  try {
267
- const fileHandle = await fs2.open(fileAbsolutePath, "r");
268
- const fileData = await fs2.readFile(fileHandle);
490
+ const fileHandle = await fs3.open(fileAbsolutePath, "r");
491
+ const fileData = await fs3.readFile(fileHandle);
269
492
  res.setHeader("Content-type", lookup(ext) || "text/plain");
270
493
  res.end(fileData);
271
494
  fileHandle.close();
@@ -287,7 +510,7 @@ var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
287
510
  }
288
511
  };
289
512
 
290
- // src/cli/utils/preview/start-dev-server.ts
513
+ // src/utils/preview/start-dev-server.ts
291
514
  var devServer;
292
515
  var safeAsyncServerListen = (server, port) => {
293
516
  return new Promise((resolve) => {
@@ -301,25 +524,26 @@ var safeAsyncServerListen = (server, port) => {
301
524
  });
302
525
  });
303
526
  };
304
- var filename = url.fileURLToPath(import.meta.url);
305
- var dirname = path4.dirname(filename);
306
- var isDev = !filename.endsWith(path4.join("cli", "index.mjs"));
307
- var cliPackageLocation = isDev ? path4.resolve(dirname, "../../../..") : path4.resolve(dirname, "../..");
308
- var previewServerLocation = isDev ? path4.resolve(dirname, "../../../..") : path4.resolve(dirname, "../preview");
527
+ var filename = url2.fileURLToPath(import.meta.url);
528
+ var dirname = path6.dirname(filename);
529
+ var isDev = !dirname.includes("dist");
309
530
  var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
310
531
  const [majorNodeVersion] = process.versions.node.split(".");
311
532
  if (majorNodeVersion && Number.parseInt(majorNodeVersion) < 18) {
312
533
  console.error(
313
- ` ${logSymbols2.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
534
+ ` ${logSymbols3.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
314
535
  );
315
536
  process.exit(1);
316
537
  }
538
+ const previewServerLocation = await getPreviewServerLocation();
539
+ const previewServer = createJiti2(previewServerLocation);
540
+ const { default: next } = await previewServer.import("next");
317
541
  devServer = http.createServer((req, res) => {
318
542
  if (!req.url) {
319
543
  res.end(404);
320
544
  return;
321
545
  }
322
- const parsedUrl = url.parse(req.url, true);
546
+ const parsedUrl = url2.parse(req.url, true);
323
547
  res.setHeader(
324
548
  "Cache-Control",
325
549
  "no-cache, max-age=0, must-revalidate, no-store"
@@ -350,7 +574,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
350
574
  } else {
351
575
  const nextPortToTry = port + 1;
352
576
  console.warn(
353
- ` ${logSymbols2.warning} Port ${port} is already in use, trying ${nextPortToTry}`
577
+ ` ${logSymbols3.warning} Port ${port} is already in use, trying ${nextPortToTry}`
354
578
  );
355
579
  return startDevServer(
356
580
  emailsDirRelativePath,
@@ -363,12 +587,12 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
363
587
  });
364
588
  devServer.on("error", (e) => {
365
589
  spinner.stopAndPersist({
366
- symbol: logSymbols2.error,
590
+ symbol: logSymbols3.error,
367
591
  text: `Preview Server had an error: ${e}`
368
592
  });
369
593
  process.exit(1);
370
594
  });
371
- const spinner = ora({
595
+ const spinner = ora2({
372
596
  text: "Getting react-email preview server ready...\n",
373
597
  prefixText: " "
374
598
  }).start();
@@ -379,7 +603,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
379
603
  ...process.env,
380
604
  ...getEnvVariablesForPreviewApp(
381
605
  // If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
382
- path4.normalize(emailsDirRelativePath),
606
+ path6.normalize(emailsDirRelativePath),
383
607
  process.cwd()
384
608
  )
385
609
  };
@@ -402,7 +626,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
402
626
  await nextReadyPromise;
403
627
  } catch (exception) {
404
628
  spinner.stopAndPersist({
405
- symbol: logSymbols2.error,
629
+ symbol: logSymbols3.error,
406
630
  text: ` Preview Server had an error: ${exception}`
407
631
  });
408
632
  process.exit(1);
@@ -413,16 +637,19 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
413
637
  spinner.stopAndPersist({
414
638
  text: `Ready in ${secondsToNextReady}s
415
639
  `,
416
- symbol: logSymbols2.success
640
+ symbol: logSymbols3.success
417
641
  });
418
642
  return devServer;
419
643
  };
420
- var makeExitHandler = (options) => (_codeOrSignal) => {
644
+ var makeExitHandler = (options) => (codeSignalOrError) => {
421
645
  if (typeof devServer !== "undefined") {
422
- console.log("\n shutting down dev server");
646
+ console.log("\nshutting down dev server");
423
647
  devServer.close();
424
648
  devServer = void 0;
425
649
  }
650
+ if (codeSignalOrError instanceof Error) {
651
+ console.error(codeSignalOrError);
652
+ }
426
653
  if (options?.shouldKillProcess) {
427
654
  process.exit(options.killWithErrorCode ? 1 : 0);
428
655
  }
@@ -445,10 +672,14 @@ process.on(
445
672
  makeExitHandler({ shouldKillProcess: true, killWithErrorCode: true })
446
673
  );
447
674
 
448
- // src/cli/utils/preview/hot-reloading/get-imported-modules.ts
675
+ // src/utils/preview/hot-reloading/get-imported-modules.ts
449
676
  import { parse } from "@babel/parser";
450
677
  import traverseModule from "@babel/traverse";
451
- var traverse = traverseModule.default;
678
+ var traverse = (
679
+ // we keep this check here so that this still works with the dev:preview
680
+ // script's use of tsx
681
+ typeof traverseModule === "function" ? traverseModule : traverseModule.default
682
+ );
452
683
  var getImportedModules = (contents) => {
453
684
  const importedPaths = [];
454
685
  const parsedContents = parse(contents, {
@@ -486,8 +717,8 @@ var getImportedModules = (contents) => {
486
717
  return importedPaths;
487
718
  };
488
719
 
489
- // src/cli/utils/preview/hot-reloading/resolve-path-aliases.ts
490
- import path5 from "node:path";
720
+ // src/utils/preview/hot-reloading/resolve-path-aliases.ts
721
+ import path7 from "node:path";
491
722
  import { createMatchPath, loadConfig } from "tsconfig-paths";
492
723
  var resolvePathAliases = (importPaths, projectPath) => {
493
724
  const configLoadResult = loadConfig(projectPath);
@@ -506,7 +737,7 @@ var resolvePathAliases = (importPaths, projectPath) => {
506
737
  ".mjs"
507
738
  ]);
508
739
  if (unaliasedPath) {
509
- return `./${path5.relative(projectPath, unaliasedPath)}`;
740
+ return `./${path7.relative(projectPath, unaliasedPath)}`;
510
741
  }
511
742
  return importedPath;
512
743
  });
@@ -514,12 +745,12 @@ var resolvePathAliases = (importPaths, projectPath) => {
514
745
  return importPaths;
515
746
  };
516
747
 
517
- // src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
748
+ // src/utils/preview/hot-reloading/create-dependency-graph.ts
518
749
  var readAllFilesInsideDirectory = async (directory) => {
519
750
  let allFilePaths = [];
520
- const topLevelDirents = await fs3.readdir(directory, { withFileTypes: true });
751
+ const topLevelDirents = await fs4.readdir(directory, { withFileTypes: true });
521
752
  for await (const dirent of topLevelDirents) {
522
- const pathToDirent = path6.join(directory, dirent.name);
753
+ const pathToDirent = path8.join(directory, dirent.name);
523
754
  if (dirent.isDirectory()) {
524
755
  allFilePaths = allFilePaths.concat(
525
756
  await readAllFilesInsideDirectory(pathToDirent)
@@ -531,7 +762,7 @@ var readAllFilesInsideDirectory = async (directory) => {
531
762
  return allFilePaths;
532
763
  };
533
764
  var isJavascriptModule = (filePath) => {
534
- const extensionName = path6.extname(filePath);
765
+ const extensionName = path8.extname(filePath);
535
766
  return [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(extensionName);
536
767
  };
537
768
  var checkFileExtensionsUntilItExists = (pathWithoutExtension) => {
@@ -558,10 +789,10 @@ var createDependencyGraph = async (directory) => {
558
789
  const filePaths = await readAllFilesInsideDirectory(directory);
559
790
  const modulePaths = filePaths.filter(isJavascriptModule);
560
791
  const graph = Object.fromEntries(
561
- modulePaths.map((path13) => [
562
- path13,
792
+ modulePaths.map((path14) => [
793
+ path14,
563
794
  {
564
- path: path13,
795
+ path: path14,
565
796
  dependencyPaths: [],
566
797
  dependentPaths: [],
567
798
  moduleDependencies: []
@@ -569,15 +800,15 @@ var createDependencyGraph = async (directory) => {
569
800
  ])
570
801
  );
571
802
  const getDependencyPaths = async (filePath) => {
572
- const contents = await fs3.readFile(filePath, "utf8");
573
- const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents), path6.dirname(filePath)) : [];
803
+ const contents = await fs4.readFile(filePath, "utf8");
804
+ const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents), path8.dirname(filePath)) : [];
574
805
  const importedPathsRelativeToDirectory = importedPaths.map(
575
806
  (dependencyPath) => {
576
807
  const isModulePath = !dependencyPath.startsWith(".");
577
- if (isModulePath || path6.isAbsolute(dependencyPath)) {
808
+ if (isModulePath || path8.isAbsolute(dependencyPath)) {
578
809
  return dependencyPath;
579
810
  }
580
- let pathToDependencyFromDirectory = path6.resolve(
811
+ let pathToDependencyFromDirectory = path8.resolve(
581
812
  /*
582
813
  path.resolve resolves paths differently from what imports on javascript do.
583
814
 
@@ -585,7 +816,7 @@ var createDependencyGraph = async (directory) => {
585
816
  would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the
586
817
  one the import is meant to go to
587
818
  */
588
- path6.dirname(filePath),
819
+ path8.dirname(filePath),
589
820
  dependencyPath
590
821
  );
591
822
  let isDirectory = false;
@@ -606,7 +837,7 @@ var createDependencyGraph = async (directory) => {
606
837
  );
607
838
  }
608
839
  }
609
- const extension = path6.extname(pathToDependencyFromDirectory);
840
+ const extension = path8.extname(pathToDependencyFromDirectory);
610
841
  const pathWithEnsuredExtension = (() => {
611
842
  if (extension.length > 0 && existsSync2(pathToDependencyFromDirectory)) {
612
843
  return pathToDependencyFromDirectory;
@@ -626,10 +857,10 @@ var createDependencyGraph = async (directory) => {
626
857
  }
627
858
  );
628
859
  const moduleDependencies = importedPathsRelativeToDirectory.filter(
629
- (dependencyPath) => !dependencyPath.startsWith(".") && !path6.isAbsolute(dependencyPath)
860
+ (dependencyPath) => !dependencyPath.startsWith(".") && !path8.isAbsolute(dependencyPath)
630
861
  );
631
862
  const nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(
632
- (dependencyPath) => dependencyPath.startsWith(".") || path6.isAbsolute(dependencyPath)
863
+ (dependencyPath) => dependencyPath.startsWith(".") || path8.isAbsolute(dependencyPath)
633
864
  );
634
865
  return {
635
866
  dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory,
@@ -742,7 +973,7 @@ var createDependencyGraph = async (directory) => {
742
973
  ];
743
974
  };
744
975
 
745
- // src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
976
+ // src/utils/preview/hot-reloading/setup-hot-reloading.ts
746
977
  var setupHotreloading = async (devServer2, emailDirRelativePath) => {
747
978
  let clients = [];
748
979
  const io = new SocketServer(devServer2);
@@ -760,14 +991,14 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
760
991
  changes.filter(
761
992
  (change) => (
762
993
  // Ensures only changes inside the emails directory are emitted
763
- path7.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
994
+ path9.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
764
995
  )
765
996
  )
766
997
  );
767
998
  });
768
999
  changes = [];
769
1000
  }, 150);
770
- const absolutePathToEmailsDirectory = path7.resolve(
1001
+ const absolutePathToEmailsDirectory = path9.resolve(
771
1002
  process.cwd(),
772
1003
  emailDirRelativePath
773
1004
  );
@@ -777,7 +1008,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
777
1008
  cwd: absolutePathToEmailsDirectory
778
1009
  });
779
1010
  const getFilesOutsideEmailsDirectory = () => Object.keys(dependencyGraph).filter(
780
- (p) => path7.relative(absolutePathToEmailsDirectory, p).startsWith("..")
1011
+ (p) => path9.relative(absolutePathToEmailsDirectory, p).startsWith("..")
781
1012
  );
782
1013
  let filesOutsideEmailsDirectory = getFilesOutsideEmailsDirectory();
783
1014
  for (const p of filesOutsideEmailsDirectory) {
@@ -789,11 +1020,11 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
789
1020
  process.on("SIGINT", exit);
790
1021
  process.on("uncaughtException", exit);
791
1022
  watcher.on("all", async (event, relativePathToChangeTarget) => {
792
- const file = relativePathToChangeTarget.split(path7.sep);
1023
+ const file = relativePathToChangeTarget.split(path9.sep);
793
1024
  if (file.length === 0) {
794
1025
  return;
795
1026
  }
796
- const pathToChangeTarget = path7.resolve(
1027
+ const pathToChangeTarget = path9.resolve(
797
1028
  absolutePathToEmailsDirectory,
798
1029
  relativePathToChangeTarget
799
1030
  );
@@ -817,7 +1048,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
817
1048
  for (const dependentPath of resolveDependentsOf(pathToChangeTarget)) {
818
1049
  changes.push({
819
1050
  event: "change",
820
- filename: path7.relative(absolutePathToEmailsDirectory, dependentPath)
1051
+ filename: path9.relative(absolutePathToEmailsDirectory, dependentPath)
821
1052
  });
822
1053
  }
823
1054
  reload();
@@ -825,10 +1056,10 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
825
1056
  return watcher;
826
1057
  };
827
1058
 
828
- // src/cli/utils/tree.ts
829
- import { promises as fs4 } from "node:fs";
1059
+ // src/utils/tree.ts
1060
+ import { promises as fs5 } from "node:fs";
830
1061
  import os from "node:os";
831
- import path8 from "node:path";
1062
+ import path10 from "node:path";
832
1063
  var SYMBOLS = {
833
1064
  BRANCH: "\u251C\u2500\u2500 ",
834
1065
  EMPTY: "",
@@ -838,12 +1069,12 @@ var SYMBOLS = {
838
1069
  };
839
1070
  var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
840
1071
  const base = process.cwd();
841
- const dirFullpath = path8.resolve(base, dirPath);
842
- const dirname2 = path8.basename(dirFullpath);
1072
+ const dirFullpath = path10.resolve(base, dirPath);
1073
+ const dirname2 = path10.basename(dirFullpath);
843
1074
  let lines = [dirname2];
844
- const dirStat = await fs4.stat(dirFullpath);
1075
+ const dirStat = await fs5.stat(dirFullpath);
845
1076
  if (dirStat.isDirectory() && currentDepth < depth) {
846
- const childDirents = await fs4.readdir(dirFullpath, { withFileTypes: true });
1077
+ const childDirents = await fs5.readdir(dirFullpath, { withFileTypes: true });
847
1078
  childDirents.sort((a, b) => {
848
1079
  if (a.isDirectory() && b.isFile()) {
849
1080
  return -1;
@@ -861,7 +1092,7 @@ var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
861
1092
  if (dirent.isFile()) {
862
1093
  lines.push(`${branchingSymbol}${dirent.name}`);
863
1094
  } else {
864
- const pathToDirectory = path8.join(dirFullpath, dirent.name);
1095
+ const pathToDirectory = path10.join(dirFullpath, dirent.name);
865
1096
  const treeLinesForSubDirectory = await getTreeLines(
866
1097
  pathToDirectory,
867
1098
  depth,
@@ -882,231 +1113,7 @@ var tree = async (dirPath, depth) => {
882
1113
  return lines.join(os.EOL);
883
1114
  };
884
1115
 
885
- // src/cli/commands/build.ts
886
- var buildPreviewApp = (absoluteDirectory) => {
887
- return new Promise((resolve, reject) => {
888
- const nextBuild = spawn("npm", ["run", "build"], {
889
- cwd: absoluteDirectory,
890
- shell: true
891
- });
892
- nextBuild.stdout.pipe(process.stdout);
893
- nextBuild.stderr.pipe(process.stderr);
894
- nextBuild.on("close", (code) => {
895
- if (code === 0) {
896
- resolve();
897
- } else {
898
- reject(
899
- new Error(
900
- `Unable to build the Next app and it exited with code: ${code}`
901
- )
902
- );
903
- }
904
- });
905
- });
906
- };
907
- var setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath) => {
908
- const nextConfigContents = `
909
- const path = require('path');
910
- const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
911
- const userProjectLocation = path.resolve(process.cwd(), '../');
912
- /** @type {import('next').NextConfig} */
913
- module.exports = {
914
- env: {
915
- NEXT_PUBLIC_IS_BUILDING: 'true',
916
- EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
917
- EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
918
- USER_PROJECT_LOCATION: userProjectLocation
919
- },
920
- // this is needed so that the code for building emails works properly
921
- webpack: (
922
- /** @type {import('webpack').Configuration & { externals: string[] }} */
923
- config,
924
- { isServer }
925
- ) => {
926
- if (isServer) {
927
- config.externals.push('esbuild');
928
- }
929
-
930
- return config;
931
- },
932
- typescript: {
933
- ignoreBuildErrors: true
934
- },
935
- eslint: {
936
- ignoreDuringBuilds: true
937
- },
938
- experimental: {
939
- webpackBuildWorker: true
940
- },
941
- }`;
942
- await fs5.promises.writeFile(
943
- path9.resolve(builtPreviewAppPath, "./next.config.js"),
944
- nextConfigContents,
945
- "utf8"
946
- );
947
- };
948
- var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePath) => {
949
- const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
950
- const slugs = [];
951
- emailDirectory.emailFilenames.forEach(
952
- (filename3) => slugs.push(
953
- path9.join(directoryPathRelativeToEmailsDirectory, filename3).split(path9.sep).filter((segment) => segment.length > 0)
954
- )
955
- );
956
- emailDirectory.subDirectories.forEach((directory) => {
957
- slugs.push(
958
- ...getEmailSlugsFromEmailDirectory(
959
- directory,
960
- emailsDirectoryAbsolutePath
961
- )
962
- );
963
- });
964
- return slugs;
965
- };
966
- var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
967
- const emailDirectoryMetadata = (
968
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
969
- await getEmailsDirectoryMetadata(emailsDirPath)
970
- );
971
- const parameters = getEmailSlugsFromEmailDirectory(
972
- emailDirectoryMetadata,
973
- emailsDirPath
974
- ).map((slug) => ({ slug }));
975
- const removeForceDynamic = async (filePath) => {
976
- const contents = await fs5.promises.readFile(filePath, "utf8");
977
- await fs5.promises.writeFile(
978
- filePath,
979
- contents.replace("export const dynamic = 'force-dynamic';", ""),
980
- "utf8"
981
- );
982
- };
983
- await removeForceDynamic(
984
- path9.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
985
- );
986
- await removeForceDynamic(
987
- path9.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
988
- );
989
- await fs5.promises.appendFile(
990
- path9.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
991
- `
992
-
993
- export function generateStaticParams() {
994
- return Promise.resolve(
995
- ${JSON.stringify(parameters)}
996
- );
997
- }`,
998
- "utf8"
999
- );
1000
- };
1001
- var updatePackageJson = async (builtPreviewAppPath) => {
1002
- const packageJsonPath = path9.resolve(builtPreviewAppPath, "./package.json");
1003
- const packageJson = JSON.parse(
1004
- await fs5.promises.readFile(packageJsonPath, "utf8")
1005
- );
1006
- packageJson.scripts.build = "next build";
1007
- packageJson.scripts.start = "next start";
1008
- delete packageJson.scripts.postbuild;
1009
- packageJson.name = "preview-server";
1010
- delete packageJson.devDependencies["@react-email/render"];
1011
- delete packageJson.devDependencies["@react-email/components"];
1012
- delete packageJson.scripts.prepare;
1013
- await fs5.promises.writeFile(
1014
- packageJsonPath,
1015
- JSON.stringify(packageJson),
1016
- "utf8"
1017
- );
1018
- };
1019
- var npmInstall = async (builtPreviewAppPath, packageManager) => {
1020
- return new Promise((resolve, reject) => {
1021
- const childProc = spawn(
1022
- packageManager,
1023
- [
1024
- "install",
1025
- packageManager === "deno" ? "" : "--include=dev",
1026
- packageManager === "deno" ? "--quiet" : "--silent"
1027
- ],
1028
- {
1029
- cwd: builtPreviewAppPath,
1030
- shell: true
1031
- }
1032
- );
1033
- childProc.stdout.pipe(process.stdout);
1034
- childProc.stderr.pipe(process.stderr);
1035
- childProc.on("close", (code) => {
1036
- if (code === 0) {
1037
- resolve();
1038
- } else {
1039
- reject(
1040
- new Error(
1041
- `Unable to install the dependencies and it exited with code: ${code}`
1042
- )
1043
- );
1044
- }
1045
- });
1046
- });
1047
- };
1048
- var build = async ({
1049
- dir: emailsDirRelativePath,
1050
- packageManager
1051
- }) => {
1052
- try {
1053
- const spinner = ora2({
1054
- text: "Starting build process...",
1055
- prefixText: " "
1056
- }).start();
1057
- registerSpinnerAutostopping(spinner);
1058
- spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
1059
- if (!fs5.existsSync(emailsDirRelativePath)) {
1060
- process.exit(1);
1061
- }
1062
- const emailsDirPath = path9.join(process.cwd(), emailsDirRelativePath);
1063
- const staticPath = path9.join(emailsDirPath, "static");
1064
- const builtPreviewAppPath = path9.join(process.cwd(), ".react-email");
1065
- if (fs5.existsSync(builtPreviewAppPath)) {
1066
- spinner.text = "Deleting pre-existing `.react-email` folder";
1067
- await fs5.promises.rm(builtPreviewAppPath, { recursive: true });
1068
- }
1069
- spinner.text = "Copying preview app from CLI to `.react-email`";
1070
- await fs5.promises.cp(cliPackageLocation, builtPreviewAppPath, {
1071
- recursive: true,
1072
- filter: (source) => {
1073
- return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
1074
- }
1075
- });
1076
- if (fs5.existsSync(staticPath)) {
1077
- spinner.text = "Copying `static` folder into `.react-email/public/static`";
1078
- const builtStaticDirectory = path9.resolve(
1079
- builtPreviewAppPath,
1080
- "./public/static"
1081
- );
1082
- await fs5.promises.cp(staticPath, builtStaticDirectory, {
1083
- recursive: true
1084
- });
1085
- }
1086
- spinner.text = "Setting Next environment variables for preview app to work properly";
1087
- await setNextEnvironmentVariablesForBuild(
1088
- emailsDirRelativePath,
1089
- builtPreviewAppPath
1090
- );
1091
- spinner.text = "Setting server side generation for the email preview pages";
1092
- await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
1093
- spinner.text = "Updating package.json's build and start scripts";
1094
- await updatePackageJson(builtPreviewAppPath);
1095
- spinner.text = "Installing dependencies on `.react-email`";
1096
- await npmInstall(builtPreviewAppPath, packageManager);
1097
- spinner.stopAndPersist({
1098
- text: "Successfully prepared `.react-email` for `next build`",
1099
- symbol: logSymbols3.success
1100
- });
1101
- await buildPreviewApp(builtPreviewAppPath);
1102
- } catch (error) {
1103
- console.log(error);
1104
- process.exit(1);
1105
- }
1106
- };
1107
-
1108
- // src/cli/commands/dev.ts
1109
- import fs6 from "node:fs";
1116
+ // src/commands/dev.ts
1110
1117
  var dev = async ({ dir: emailsDirRelativePath, port }) => {
1111
1118
  try {
1112
1119
  if (!fs6.existsSync(emailsDirRelativePath)) {
@@ -1126,11 +1133,11 @@ var dev = async ({ dir: emailsDirRelativePath, port }) => {
1126
1133
  }
1127
1134
  };
1128
1135
 
1129
- // src/cli/commands/export.ts
1136
+ // src/commands/export.ts
1130
1137
  import fs8, { unlinkSync, writeFileSync } from "node:fs";
1131
1138
  import { createRequire } from "node:module";
1132
- import path11 from "node:path";
1133
- import url2 from "node:url";
1139
+ import path12 from "node:path";
1140
+ import url3 from "node:url";
1134
1141
  import { build as build2 } from "esbuild";
1135
1142
  import { glob } from "glob";
1136
1143
  import logSymbols4 from "log-symbols";
@@ -1139,7 +1146,7 @@ import ora3 from "ora";
1139
1146
 
1140
1147
  // src/utils/esbuild/renderring-utilities-exporter.ts
1141
1148
  import { promises as fs7 } from "node:fs";
1142
- import path10 from "node:path";
1149
+ import path11 from "node:path";
1143
1150
 
1144
1151
  // src/utils/esbuild/escape-string-for-regex.ts
1145
1152
  function escapeStringForRegex(string) {
@@ -1162,7 +1169,7 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
1162
1169
  export { render } from 'react-email-module-that-will-export-render'
1163
1170
  export { createElement as reactEmailCreateReactElement } from 'react';
1164
1171
  `,
1165
- loader: path10.extname(pathToFile).slice(1)
1172
+ loader: path11.extname(pathToFile).slice(1)
1166
1173
  };
1167
1174
  }
1168
1175
  );
@@ -1189,18 +1196,18 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
1189
1196
  }
1190
1197
  });
1191
1198
 
1192
- // src/cli/commands/export.ts
1199
+ // src/commands/export.ts
1193
1200
  var getEmailTemplatesFromDirectory = (emailDirectory) => {
1194
1201
  const templatePaths = [];
1195
1202
  emailDirectory.emailFilenames.forEach(
1196
- (filename3) => templatePaths.push(path11.join(emailDirectory.absolutePath, filename3))
1203
+ (filename3) => templatePaths.push(path12.join(emailDirectory.absolutePath, filename3))
1197
1204
  );
1198
1205
  emailDirectory.subDirectories.forEach((directory) => {
1199
1206
  templatePaths.push(...getEmailTemplatesFromDirectory(directory));
1200
1207
  });
1201
1208
  return templatePaths;
1202
1209
  };
1203
- var filename2 = url2.fileURLToPath(import.meta.url);
1210
+ var filename2 = url3.fileURLToPath(import.meta.url);
1204
1211
  var require2 = createRequire(filename2);
1205
1212
  var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
1206
1213
  if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
@@ -1212,7 +1219,7 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
1212
1219
  registerSpinnerAutostopping(spinner);
1213
1220
  }
1214
1221
  const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
1215
- path11.resolve(process.cwd(), emailsDirectoryPath),
1222
+ path12.resolve(process.cwd(), emailsDirectoryPath),
1216
1223
  true
1217
1224
  );
1218
1225
  if (typeof emailsDirectoryMetadata === "undefined") {
@@ -1294,9 +1301,9 @@ ${buildFailure.message}`);
1294
1301
  spinner.text = "Copying static files";
1295
1302
  spinner.render();
1296
1303
  }
1297
- const staticDirectoryPath = path11.join(emailsDirectoryPath, "static");
1304
+ const staticDirectoryPath = path12.join(emailsDirectoryPath, "static");
1298
1305
  if (fs8.existsSync(staticDirectoryPath)) {
1299
- const pathToDumpStaticFilesInto = path11.join(
1306
+ const pathToDumpStaticFilesInto = path12.join(
1300
1307
  pathToWhereEmailMarkupShouldBeDumped,
1301
1308
  "static"
1302
1309
  );
@@ -1331,14 +1338,15 @@ ${buildFailure.message}`);
1331
1338
  }
1332
1339
  };
1333
1340
 
1334
- // src/cli/commands/start.ts
1341
+ // src/commands/start.ts
1335
1342
  import { spawn as spawn2 } from "node:child_process";
1336
1343
  import fs9 from "node:fs";
1337
- import path12 from "node:path";
1344
+ import path13 from "node:path";
1338
1345
  var start = async () => {
1339
1346
  try {
1347
+ const previewServerLocation = await getPreviewServerLocation();
1340
1348
  const usersProjectLocation = process.cwd();
1341
- const builtPreviewPath = path12.resolve(
1349
+ const builtPreviewPath = path13.resolve(
1342
1350
  usersProjectLocation,
1343
1351
  "./.react-email"
1344
1352
  );
@@ -1348,8 +1356,8 @@ var start = async () => {
1348
1356
  );
1349
1357
  process.exit(1);
1350
1358
  }
1351
- const nextStart = spawn2("npm", ["start"], {
1352
- cwd: builtPreviewPath,
1359
+ const nextStart = spawn2("npx", ["next", "start", builtPreviewPath], {
1360
+ cwd: previewServerLocation,
1353
1361
  stdio: "inherit"
1354
1362
  });
1355
1363
  process.on("SIGINT", () => {
@@ -1364,7 +1372,7 @@ var start = async () => {
1364
1372
  }
1365
1373
  };
1366
1374
 
1367
- // src/cli/index.ts
1375
+ // src/index.ts
1368
1376
  var PACKAGE_NAME = "react-email";
1369
1377
  program.name(PACKAGE_NAME).description("A live preview of your emails right in your browser").version(package_default.version);
1370
1378
  program.command("dev").description("Starts the preview email development app").option("-d, --dir <path>", "Directory with your email templates", "./emails").option("-p --port <port>", "Port to run dev server on", "3000").action(dev);