react-email 4.1.0-canary.7 → 4.1.0-canary.9

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} +445 -422
  3. package/package.json +11 -46
  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 +51 -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/343.js +0 -20
  64. package/dist/preview/.next/server/chunks/425.js +0 -1
  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/4K22R8mt8Z5akBgUuivvR/_buildManifest.js +0 -1
  86. package/dist/preview/.next/static/4K22R8mt8Z5akBgUuivvR/_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-25cf313c25750c6a.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-ce14b7ba365bfddc.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-35fab824504104aa.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 -85
  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.7",
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,115 @@ 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
+
106
+ // package.json
107
+ var package_default = {
108
+ name: "react-email",
109
+ version: "4.1.0-canary.9",
110
+ description: "A live preview of your emails right in your browser.",
111
+ bin: {
112
+ email: "./dist/index.js"
113
+ },
114
+ type: "module",
115
+ scripts: {
116
+ build: "tsup-node",
117
+ clean: "rm -rf dist",
118
+ dev: "tsup-node --watch src",
119
+ test: "vitest run",
120
+ "test:watch": "vitest"
121
+ },
122
+ license: "MIT",
123
+ repository: {
124
+ type: "git",
125
+ url: "https://github.com/resend/react-email.git",
126
+ directory: "packages/react-email"
127
+ },
128
+ keywords: [
129
+ "react",
130
+ "email"
131
+ ],
132
+ engines: {
133
+ node: ">=18.0.0"
134
+ },
135
+ dependencies: {
136
+ "@babel/parser": "^7.27.0",
137
+ "@babel/traverse": "^7.27.0",
138
+ chalk: "^5.0.0",
139
+ chokidar: "^4.0.3",
140
+ commander: "^13.0.0",
141
+ debounce: "^2.0.0",
142
+ esbuild: "^0.25.0",
143
+ glob: "^11.0.0",
144
+ jiti: "2.4.2",
145
+ "log-symbols": "^7.0.0",
146
+ "mime-types": "^3.0.0",
147
+ "normalize-path": "^3.0.0",
148
+ nypm: "0.6.0",
149
+ ora: "^8.0.0",
150
+ prompts: "2.4.2",
151
+ "socket.io": "^4.8.1",
152
+ "tsconfig-paths": "4.2.0"
153
+ },
154
+ devDependencies: {
155
+ "@react-email/components": "workspace:*",
156
+ "@types/babel__core": "7.20.5",
157
+ "@types/babel__traverse": "7.20.7",
158
+ "@types/mime-types": "2.1.4",
159
+ "@types/prompts": "2.4.9",
160
+ next: "^15.3.2",
161
+ react: "19.0.0",
162
+ "react-dom": "19.0.0",
163
+ tsup: "8.4.0",
164
+ tsx: "4.19.3",
165
+ typescript: "5.8.3"
166
+ }
167
+ };
168
+
169
+ // src/utils/get-preview-server-location.ts
170
+ var ensurePreviewServerInstalled = async (message) => {
171
+ const response = await prompts({
172
+ type: "confirm",
173
+ name: "installPreviewServer",
174
+ message,
175
+ initial: true
176
+ });
177
+ if (response.installPreviewServer) {
178
+ console.log('Installing "@react-email/preview-server"');
179
+ await addDevDependency(
180
+ `@react-email/preview-server@${package_default.version}`
181
+ );
182
+ process.exit(0);
183
+ } else {
184
+ process.exit(0);
185
+ }
186
+ };
187
+ var getPreviewServerLocation = async () => {
188
+ const usersProject = createJiti(process.cwd());
189
+ let previewServerLocation;
190
+ try {
191
+ previewServerLocation = path2.dirname(
192
+ url.parse(usersProject.esmResolve("@react-email/preview-server"), true).path
193
+ );
194
+ } catch (_exception) {
195
+ await ensurePreviewServerInstalled(
196
+ 'To run the preview server, the package "@react-email/preview-server" must be installed. Would you like to install it?'
197
+ );
198
+ }
199
+ const { version } = await usersProject.import("@react-email/preview-server");
200
+ if (version !== package_default.version) {
201
+ await ensurePreviewServerInstalled(
202
+ `To run the preview server, the version of "@react-email/preview-server" must match the version of "react-email" (${package_default.version}). Would you like to install it?`
203
+ );
204
+ }
205
+ return previewServerLocation;
206
+ };
207
+
197
208
  // src/utils/register-spinner-autostopping.ts
198
209
  import logSymbols from "log-symbols";
199
210
  var spinners = /* @__PURE__ */ new Set();
@@ -214,58 +225,285 @@ process.on("exit", (code) => {
214
225
  }
215
226
  });
216
227
  }
217
- });
218
- var registerSpinnerAutostopping = (spinner) => {
219
- spinners.add(spinner);
228
+ });
229
+ var registerSpinnerAutostopping = (spinner) => {
230
+ spinners.add(spinner);
231
+ };
232
+
233
+ // src/commands/build.ts
234
+ var buildPreviewApp = (absoluteDirectory) => {
235
+ return new Promise((resolve, reject) => {
236
+ const nextBuild = spawn("npm", ["run", "build"], {
237
+ cwd: absoluteDirectory,
238
+ shell: true
239
+ });
240
+ nextBuild.stdout.pipe(process.stdout);
241
+ nextBuild.stderr.pipe(process.stderr);
242
+ nextBuild.on("close", (code) => {
243
+ if (code === 0) {
244
+ resolve();
245
+ } else {
246
+ reject(
247
+ new Error(
248
+ `Unable to build the Next app and it exited with code: ${code}`
249
+ )
250
+ );
251
+ }
252
+ });
253
+ });
254
+ };
255
+ var npmInstall = async (builtPreviewAppPath, packageManager) => {
256
+ return new Promise((resolve, reject) => {
257
+ const childProc = spawn(
258
+ packageManager,
259
+ [
260
+ "install",
261
+ packageManager === "deno" ? "" : "--include=dev",
262
+ packageManager === "deno" ? "--quiet" : "--silent"
263
+ ],
264
+ {
265
+ cwd: builtPreviewAppPath,
266
+ shell: true
267
+ }
268
+ );
269
+ childProc.stdout.pipe(process.stdout);
270
+ childProc.stderr.pipe(process.stderr);
271
+ childProc.on("close", (code) => {
272
+ if (code === 0) {
273
+ resolve();
274
+ } else {
275
+ reject(
276
+ new Error(
277
+ `Unable to install the dependencies and it exited with code: ${code}`
278
+ )
279
+ );
280
+ }
281
+ });
282
+ });
283
+ };
284
+ var setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath) => {
285
+ const nextConfigContents = `
286
+ const path = require('path');
287
+ const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
288
+ const userProjectLocation = '${process.cwd()}';
289
+ /** @type {import('next').NextConfig} */
290
+ module.exports = {
291
+ env: {
292
+ NEXT_PUBLIC_IS_BUILDING: 'true',
293
+ EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
294
+ EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
295
+ USER_PROJECT_LOCATION: userProjectLocation
296
+ },
297
+ // this is needed so that the code for building emails works properly
298
+ webpack: (
299
+ /** @type {import('webpack').Configuration & { externals: string[] }} */
300
+ config,
301
+ { isServer }
302
+ ) => {
303
+ if (isServer) {
304
+ config.externals.push('esbuild');
305
+ }
306
+
307
+ return config;
308
+ },
309
+ typescript: {
310
+ ignoreBuildErrors: true
311
+ },
312
+ eslint: {
313
+ ignoreDuringBuilds: true
314
+ },
315
+ experimental: {
316
+ webpackBuildWorker: true
317
+ },
318
+ }`;
319
+ await fs2.promises.writeFile(
320
+ path3.resolve(builtPreviewAppPath, "./next.config.js"),
321
+ nextConfigContents,
322
+ "utf8"
323
+ );
324
+ };
325
+ var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePath) => {
326
+ const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
327
+ const slugs = [];
328
+ emailDirectory.emailFilenames.forEach(
329
+ (filename3) => slugs.push(
330
+ path3.join(directoryPathRelativeToEmailsDirectory, filename3).split(path3.sep).filter((segment) => segment.length > 0)
331
+ )
332
+ );
333
+ emailDirectory.subDirectories.forEach((directory) => {
334
+ slugs.push(
335
+ ...getEmailSlugsFromEmailDirectory(
336
+ directory,
337
+ emailsDirectoryAbsolutePath
338
+ )
339
+ );
340
+ });
341
+ return slugs;
342
+ };
343
+ var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
344
+ const emailDirectoryMetadata = (
345
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
346
+ await getEmailsDirectoryMetadata(emailsDirPath)
347
+ );
348
+ const parameters = getEmailSlugsFromEmailDirectory(
349
+ emailDirectoryMetadata,
350
+ emailsDirPath
351
+ ).map((slug) => ({ slug }));
352
+ const removeForceDynamic = async (filePath) => {
353
+ const contents = await fs2.promises.readFile(filePath, "utf8");
354
+ await fs2.promises.writeFile(
355
+ filePath,
356
+ contents.replace("export const dynamic = 'force-dynamic';", ""),
357
+ "utf8"
358
+ );
359
+ };
360
+ await removeForceDynamic(
361
+ path3.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
362
+ );
363
+ await removeForceDynamic(
364
+ path3.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
365
+ );
366
+ await fs2.promises.appendFile(
367
+ path3.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
368
+ `
369
+
370
+ export function generateStaticParams() {
371
+ return Promise.resolve(
372
+ ${JSON.stringify(parameters)}
373
+ );
374
+ }`,
375
+ "utf8"
376
+ );
377
+ };
378
+ var updatePackageJson = async (builtPreviewAppPath) => {
379
+ const packageJsonPath = path3.resolve(builtPreviewAppPath, "./package.json");
380
+ const packageJson = JSON.parse(
381
+ await fs2.promises.readFile(packageJsonPath, "utf8")
382
+ );
383
+ packageJson.scripts.build = "next build";
384
+ packageJson.scripts.start = "next start";
385
+ delete packageJson.scripts.postbuild;
386
+ packageJson.name = "preview-server";
387
+ delete packageJson.devDependencies["@react-email/render"];
388
+ delete packageJson.devDependencies["@react-email/components"];
389
+ delete packageJson.scripts.prepare;
390
+ await fs2.promises.writeFile(
391
+ packageJsonPath,
392
+ JSON.stringify(packageJson),
393
+ "utf8"
394
+ );
395
+ };
396
+ var build = async ({
397
+ dir: emailsDirRelativePath,
398
+ packageManager
399
+ }) => {
400
+ try {
401
+ const previewServerLocation = await getPreviewServerLocation();
402
+ const spinner = ora({
403
+ text: "Starting build process...",
404
+ prefixText: " "
405
+ }).start();
406
+ registerSpinnerAutostopping(spinner);
407
+ spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
408
+ if (!fs2.existsSync(emailsDirRelativePath)) {
409
+ process.exit(1);
410
+ }
411
+ const emailsDirPath = path3.join(process.cwd(), emailsDirRelativePath);
412
+ const staticPath = path3.join(emailsDirPath, "static");
413
+ const builtPreviewAppPath = path3.join(process.cwd(), ".react-email");
414
+ if (fs2.existsSync(builtPreviewAppPath)) {
415
+ spinner.text = "Deleting pre-existing `.react-email` folder";
416
+ await fs2.promises.rm(builtPreviewAppPath, { recursive: true });
417
+ }
418
+ spinner.text = "Copying preview app from CLI to `.react-email`";
419
+ await fs2.promises.cp(previewServerLocation, builtPreviewAppPath, {
420
+ recursive: true,
421
+ filter: (source) => {
422
+ return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
423
+ }
424
+ });
425
+ if (fs2.existsSync(staticPath)) {
426
+ spinner.text = "Copying `static` folder into `.react-email/public/static`";
427
+ const builtStaticDirectory = path3.resolve(
428
+ builtPreviewAppPath,
429
+ "./public/static"
430
+ );
431
+ await fs2.promises.cp(staticPath, builtStaticDirectory, {
432
+ recursive: true
433
+ });
434
+ }
435
+ spinner.text = "Setting Next environment variables for preview app to work properly";
436
+ await setNextEnvironmentVariablesForBuild(
437
+ emailsDirRelativePath,
438
+ builtPreviewAppPath
439
+ );
440
+ spinner.text = "Setting server side generation for the email preview pages";
441
+ await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
442
+ spinner.text = "Updating package.json's build and start scripts";
443
+ await updatePackageJson(builtPreviewAppPath);
444
+ spinner.text = "Installing dependencies on `.react-email`";
445
+ await npmInstall(builtPreviewAppPath, packageManager);
446
+ spinner.stopAndPersist({
447
+ text: "Successfully prepared `.react-email` for `next build`",
448
+ symbol: logSymbols2.success
449
+ });
450
+ await buildPreviewApp(builtPreviewAppPath);
451
+ } catch (error) {
452
+ console.log(error);
453
+ process.exit(1);
454
+ }
220
455
  };
221
456
 
222
- // src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
223
- import path7 from "node:path";
457
+ // src/commands/dev.ts
458
+ import fs6 from "node:fs";
459
+
460
+ // src/utils/preview/hot-reloading/setup-hot-reloading.ts
461
+ import path9 from "node:path";
224
462
  import { watch } from "chokidar";
225
463
  import debounce from "debounce";
226
464
  import { Server as SocketServer } from "socket.io";
227
465
 
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";
466
+ // src/utils/preview/hot-reloading/create-dependency-graph.ts
467
+ import { existsSync as existsSync2, promises as fs4, statSync } from "node:fs";
468
+ import path8 from "node:path";
231
469
 
232
- // src/cli/utils/preview/start-dev-server.ts
470
+ // src/utils/preview/start-dev-server.ts
233
471
  import http from "node:http";
234
- import path4 from "node:path";
235
- import url from "node:url";
472
+ import path6 from "node:path";
473
+ import url2 from "node:url";
236
474
  import chalk from "chalk";
237
- import logSymbols2 from "log-symbols";
238
- import next from "next";
239
- import ora from "ora";
475
+ import { createJiti as createJiti2 } from "jiti";
476
+ import logSymbols3 from "log-symbols";
477
+ import ora2 from "ora";
240
478
 
241
- // src/cli/utils/preview/get-env-variables-for-preview-app.ts
242
- import path2 from "node:path";
479
+ // src/utils/preview/get-env-variables-for-preview-app.ts
480
+ import path4 from "node:path";
243
481
  var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
244
482
  return {
245
483
  EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
246
- EMAILS_DIR_ABSOLUTE_PATH: path2.resolve(cwd, relativePathToEmailsDirectory),
484
+ EMAILS_DIR_ABSOLUTE_PATH: path4.resolve(cwd, relativePathToEmailsDirectory),
247
485
  USER_PROJECT_LOCATION: cwd,
248
486
  NEXT_PUBLIC_IS_PREVIEW_DEVELOPMENT: isDev ? "true" : "false"
249
487
  };
250
488
  };
251
489
 
252
- // src/cli/utils/preview/serve-static-file.ts
253
- import { existsSync, promises as fs2 } from "node:fs";
254
- import path3 from "node:path";
490
+ // src/utils/preview/serve-static-file.ts
491
+ import { existsSync, promises as fs3 } from "node:fs";
492
+ import path5 from "node:path";
255
493
  import { lookup } from "mime-types";
256
494
  var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
257
495
  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);
496
+ const ext = path5.parse(pathname).ext;
497
+ const staticBaseDir = path5.resolve(process.cwd(), staticDirRelativePath);
498
+ const fileAbsolutePath = path5.resolve(staticBaseDir, pathname);
261
499
  if (!fileAbsolutePath.startsWith(staticBaseDir)) {
262
500
  res.statusCode = 403;
263
501
  res.end();
264
502
  return;
265
503
  }
266
504
  try {
267
- const fileHandle = await fs2.open(fileAbsolutePath, "r");
268
- const fileData = await fs2.readFile(fileHandle);
505
+ const fileHandle = await fs3.open(fileAbsolutePath, "r");
506
+ const fileData = await fs3.readFile(fileHandle);
269
507
  res.setHeader("Content-type", lookup(ext) || "text/plain");
270
508
  res.end(fileData);
271
509
  fileHandle.close();
@@ -287,7 +525,7 @@ var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
287
525
  }
288
526
  };
289
527
 
290
- // src/cli/utils/preview/start-dev-server.ts
528
+ // src/utils/preview/start-dev-server.ts
291
529
  var devServer;
292
530
  var safeAsyncServerListen = (server, port) => {
293
531
  return new Promise((resolve) => {
@@ -301,25 +539,26 @@ var safeAsyncServerListen = (server, port) => {
301
539
  });
302
540
  });
303
541
  };
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");
542
+ var filename = url2.fileURLToPath(import.meta.url);
543
+ var dirname = path6.dirname(filename);
544
+ var isDev = !dirname.includes("dist");
309
545
  var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
310
546
  const [majorNodeVersion] = process.versions.node.split(".");
311
547
  if (majorNodeVersion && Number.parseInt(majorNodeVersion) < 18) {
312
548
  console.error(
313
- ` ${logSymbols2.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
549
+ ` ${logSymbols3.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
314
550
  );
315
551
  process.exit(1);
316
552
  }
553
+ const previewServerLocation = await getPreviewServerLocation();
554
+ const previewServer = createJiti2(previewServerLocation);
555
+ const { default: next } = await previewServer.import("next");
317
556
  devServer = http.createServer((req, res) => {
318
557
  if (!req.url) {
319
558
  res.end(404);
320
559
  return;
321
560
  }
322
- const parsedUrl = url.parse(req.url, true);
561
+ const parsedUrl = url2.parse(req.url, true);
323
562
  res.setHeader(
324
563
  "Cache-Control",
325
564
  "no-cache, max-age=0, must-revalidate, no-store"
@@ -350,7 +589,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
350
589
  } else {
351
590
  const nextPortToTry = port + 1;
352
591
  console.warn(
353
- ` ${logSymbols2.warning} Port ${port} is already in use, trying ${nextPortToTry}`
592
+ ` ${logSymbols3.warning} Port ${port} is already in use, trying ${nextPortToTry}`
354
593
  );
355
594
  return startDevServer(
356
595
  emailsDirRelativePath,
@@ -363,12 +602,12 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
363
602
  });
364
603
  devServer.on("error", (e) => {
365
604
  spinner.stopAndPersist({
366
- symbol: logSymbols2.error,
605
+ symbol: logSymbols3.error,
367
606
  text: `Preview Server had an error: ${e}`
368
607
  });
369
608
  process.exit(1);
370
609
  });
371
- const spinner = ora({
610
+ const spinner = ora2({
372
611
  text: "Getting react-email preview server ready...\n",
373
612
  prefixText: " "
374
613
  }).start();
@@ -379,7 +618,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
379
618
  ...process.env,
380
619
  ...getEnvVariablesForPreviewApp(
381
620
  // If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
382
- path4.normalize(emailsDirRelativePath),
621
+ path6.normalize(emailsDirRelativePath),
383
622
  process.cwd()
384
623
  )
385
624
  };
@@ -402,7 +641,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
402
641
  await nextReadyPromise;
403
642
  } catch (exception) {
404
643
  spinner.stopAndPersist({
405
- symbol: logSymbols2.error,
644
+ symbol: logSymbols3.error,
406
645
  text: ` Preview Server had an error: ${exception}`
407
646
  });
408
647
  process.exit(1);
@@ -413,16 +652,19 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
413
652
  spinner.stopAndPersist({
414
653
  text: `Ready in ${secondsToNextReady}s
415
654
  `,
416
- symbol: logSymbols2.success
655
+ symbol: logSymbols3.success
417
656
  });
418
657
  return devServer;
419
658
  };
420
- var makeExitHandler = (options) => (_codeOrSignal) => {
659
+ var makeExitHandler = (options) => (codeSignalOrError) => {
421
660
  if (typeof devServer !== "undefined") {
422
- console.log("\n shutting down dev server");
661
+ console.log("\nshutting down dev server");
423
662
  devServer.close();
424
663
  devServer = void 0;
425
664
  }
665
+ if (codeSignalOrError instanceof Error) {
666
+ console.error(codeSignalOrError);
667
+ }
426
668
  if (options?.shouldKillProcess) {
427
669
  process.exit(options.killWithErrorCode ? 1 : 0);
428
670
  }
@@ -445,10 +687,14 @@ process.on(
445
687
  makeExitHandler({ shouldKillProcess: true, killWithErrorCode: true })
446
688
  );
447
689
 
448
- // src/cli/utils/preview/hot-reloading/get-imported-modules.ts
690
+ // src/utils/preview/hot-reloading/get-imported-modules.ts
449
691
  import { parse } from "@babel/parser";
450
692
  import traverseModule from "@babel/traverse";
451
- var traverse = traverseModule.default;
693
+ var traverse = (
694
+ // we keep this check here so that this still works with the dev:preview
695
+ // script's use of tsx
696
+ typeof traverseModule === "function" ? traverseModule : traverseModule.default
697
+ );
452
698
  var getImportedModules = (contents) => {
453
699
  const importedPaths = [];
454
700
  const parsedContents = parse(contents, {
@@ -486,8 +732,8 @@ var getImportedModules = (contents) => {
486
732
  return importedPaths;
487
733
  };
488
734
 
489
- // src/cli/utils/preview/hot-reloading/resolve-path-aliases.ts
490
- import path5 from "node:path";
735
+ // src/utils/preview/hot-reloading/resolve-path-aliases.ts
736
+ import path7 from "node:path";
491
737
  import { createMatchPath, loadConfig } from "tsconfig-paths";
492
738
  var resolvePathAliases = (importPaths, projectPath) => {
493
739
  const configLoadResult = loadConfig(projectPath);
@@ -506,7 +752,7 @@ var resolvePathAliases = (importPaths, projectPath) => {
506
752
  ".mjs"
507
753
  ]);
508
754
  if (unaliasedPath) {
509
- return `./${path5.relative(projectPath, unaliasedPath)}`;
755
+ return `./${path7.relative(projectPath, unaliasedPath)}`;
510
756
  }
511
757
  return importedPath;
512
758
  });
@@ -514,12 +760,12 @@ var resolvePathAliases = (importPaths, projectPath) => {
514
760
  return importPaths;
515
761
  };
516
762
 
517
- // src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
763
+ // src/utils/preview/hot-reloading/create-dependency-graph.ts
518
764
  var readAllFilesInsideDirectory = async (directory) => {
519
765
  let allFilePaths = [];
520
- const topLevelDirents = await fs3.readdir(directory, { withFileTypes: true });
766
+ const topLevelDirents = await fs4.readdir(directory, { withFileTypes: true });
521
767
  for await (const dirent of topLevelDirents) {
522
- const pathToDirent = path6.join(directory, dirent.name);
768
+ const pathToDirent = path8.join(directory, dirent.name);
523
769
  if (dirent.isDirectory()) {
524
770
  allFilePaths = allFilePaths.concat(
525
771
  await readAllFilesInsideDirectory(pathToDirent)
@@ -531,7 +777,7 @@ var readAllFilesInsideDirectory = async (directory) => {
531
777
  return allFilePaths;
532
778
  };
533
779
  var isJavascriptModule = (filePath) => {
534
- const extensionName = path6.extname(filePath);
780
+ const extensionName = path8.extname(filePath);
535
781
  return [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(extensionName);
536
782
  };
537
783
  var checkFileExtensionsUntilItExists = (pathWithoutExtension) => {
@@ -558,10 +804,10 @@ var createDependencyGraph = async (directory) => {
558
804
  const filePaths = await readAllFilesInsideDirectory(directory);
559
805
  const modulePaths = filePaths.filter(isJavascriptModule);
560
806
  const graph = Object.fromEntries(
561
- modulePaths.map((path13) => [
562
- path13,
807
+ modulePaths.map((path14) => [
808
+ path14,
563
809
  {
564
- path: path13,
810
+ path: path14,
565
811
  dependencyPaths: [],
566
812
  dependentPaths: [],
567
813
  moduleDependencies: []
@@ -569,15 +815,15 @@ var createDependencyGraph = async (directory) => {
569
815
  ])
570
816
  );
571
817
  const getDependencyPaths = async (filePath) => {
572
- const contents = await fs3.readFile(filePath, "utf8");
573
- const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents), path6.dirname(filePath)) : [];
818
+ const contents = await fs4.readFile(filePath, "utf8");
819
+ const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents), path8.dirname(filePath)) : [];
574
820
  const importedPathsRelativeToDirectory = importedPaths.map(
575
821
  (dependencyPath) => {
576
822
  const isModulePath = !dependencyPath.startsWith(".");
577
- if (isModulePath || path6.isAbsolute(dependencyPath)) {
823
+ if (isModulePath || path8.isAbsolute(dependencyPath)) {
578
824
  return dependencyPath;
579
825
  }
580
- let pathToDependencyFromDirectory = path6.resolve(
826
+ let pathToDependencyFromDirectory = path8.resolve(
581
827
  /*
582
828
  path.resolve resolves paths differently from what imports on javascript do.
583
829
 
@@ -585,7 +831,7 @@ var createDependencyGraph = async (directory) => {
585
831
  would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the
586
832
  one the import is meant to go to
587
833
  */
588
- path6.dirname(filePath),
834
+ path8.dirname(filePath),
589
835
  dependencyPath
590
836
  );
591
837
  let isDirectory = false;
@@ -606,7 +852,7 @@ var createDependencyGraph = async (directory) => {
606
852
  );
607
853
  }
608
854
  }
609
- const extension = path6.extname(pathToDependencyFromDirectory);
855
+ const extension = path8.extname(pathToDependencyFromDirectory);
610
856
  const pathWithEnsuredExtension = (() => {
611
857
  if (extension.length > 0 && existsSync2(pathToDependencyFromDirectory)) {
612
858
  return pathToDependencyFromDirectory;
@@ -626,10 +872,10 @@ var createDependencyGraph = async (directory) => {
626
872
  }
627
873
  );
628
874
  const moduleDependencies = importedPathsRelativeToDirectory.filter(
629
- (dependencyPath) => !dependencyPath.startsWith(".") && !path6.isAbsolute(dependencyPath)
875
+ (dependencyPath) => !dependencyPath.startsWith(".") && !path8.isAbsolute(dependencyPath)
630
876
  );
631
877
  const nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(
632
- (dependencyPath) => dependencyPath.startsWith(".") || path6.isAbsolute(dependencyPath)
878
+ (dependencyPath) => dependencyPath.startsWith(".") || path8.isAbsolute(dependencyPath)
633
879
  );
634
880
  return {
635
881
  dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory,
@@ -742,7 +988,7 @@ var createDependencyGraph = async (directory) => {
742
988
  ];
743
989
  };
744
990
 
745
- // src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
991
+ // src/utils/preview/hot-reloading/setup-hot-reloading.ts
746
992
  var setupHotreloading = async (devServer2, emailDirRelativePath) => {
747
993
  let clients = [];
748
994
  const io = new SocketServer(devServer2);
@@ -760,14 +1006,14 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
760
1006
  changes.filter(
761
1007
  (change) => (
762
1008
  // Ensures only changes inside the emails directory are emitted
763
- path7.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
1009
+ path9.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
764
1010
  )
765
1011
  )
766
1012
  );
767
1013
  });
768
1014
  changes = [];
769
1015
  }, 150);
770
- const absolutePathToEmailsDirectory = path7.resolve(
1016
+ const absolutePathToEmailsDirectory = path9.resolve(
771
1017
  process.cwd(),
772
1018
  emailDirRelativePath
773
1019
  );
@@ -777,7 +1023,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
777
1023
  cwd: absolutePathToEmailsDirectory
778
1024
  });
779
1025
  const getFilesOutsideEmailsDirectory = () => Object.keys(dependencyGraph).filter(
780
- (p) => path7.relative(absolutePathToEmailsDirectory, p).startsWith("..")
1026
+ (p) => path9.relative(absolutePathToEmailsDirectory, p).startsWith("..")
781
1027
  );
782
1028
  let filesOutsideEmailsDirectory = getFilesOutsideEmailsDirectory();
783
1029
  for (const p of filesOutsideEmailsDirectory) {
@@ -789,11 +1035,11 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
789
1035
  process.on("SIGINT", exit);
790
1036
  process.on("uncaughtException", exit);
791
1037
  watcher.on("all", async (event, relativePathToChangeTarget) => {
792
- const file = relativePathToChangeTarget.split(path7.sep);
1038
+ const file = relativePathToChangeTarget.split(path9.sep);
793
1039
  if (file.length === 0) {
794
1040
  return;
795
1041
  }
796
- const pathToChangeTarget = path7.resolve(
1042
+ const pathToChangeTarget = path9.resolve(
797
1043
  absolutePathToEmailsDirectory,
798
1044
  relativePathToChangeTarget
799
1045
  );
@@ -817,7 +1063,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
817
1063
  for (const dependentPath of resolveDependentsOf(pathToChangeTarget)) {
818
1064
  changes.push({
819
1065
  event: "change",
820
- filename: path7.relative(absolutePathToEmailsDirectory, dependentPath)
1066
+ filename: path9.relative(absolutePathToEmailsDirectory, dependentPath)
821
1067
  });
822
1068
  }
823
1069
  reload();
@@ -825,10 +1071,10 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
825
1071
  return watcher;
826
1072
  };
827
1073
 
828
- // src/cli/utils/tree.ts
829
- import { promises as fs4 } from "node:fs";
1074
+ // src/utils/tree.ts
1075
+ import { promises as fs5 } from "node:fs";
830
1076
  import os from "node:os";
831
- import path8 from "node:path";
1077
+ import path10 from "node:path";
832
1078
  var SYMBOLS = {
833
1079
  BRANCH: "\u251C\u2500\u2500 ",
834
1080
  EMPTY: "",
@@ -838,12 +1084,12 @@ var SYMBOLS = {
838
1084
  };
839
1085
  var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
840
1086
  const base = process.cwd();
841
- const dirFullpath = path8.resolve(base, dirPath);
842
- const dirname2 = path8.basename(dirFullpath);
1087
+ const dirFullpath = path10.resolve(base, dirPath);
1088
+ const dirname2 = path10.basename(dirFullpath);
843
1089
  let lines = [dirname2];
844
- const dirStat = await fs4.stat(dirFullpath);
1090
+ const dirStat = await fs5.stat(dirFullpath);
845
1091
  if (dirStat.isDirectory() && currentDepth < depth) {
846
- const childDirents = await fs4.readdir(dirFullpath, { withFileTypes: true });
1092
+ const childDirents = await fs5.readdir(dirFullpath, { withFileTypes: true });
847
1093
  childDirents.sort((a, b) => {
848
1094
  if (a.isDirectory() && b.isFile()) {
849
1095
  return -1;
@@ -861,7 +1107,7 @@ var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
861
1107
  if (dirent.isFile()) {
862
1108
  lines.push(`${branchingSymbol}${dirent.name}`);
863
1109
  } else {
864
- const pathToDirectory = path8.join(dirFullpath, dirent.name);
1110
+ const pathToDirectory = path10.join(dirFullpath, dirent.name);
865
1111
  const treeLinesForSubDirectory = await getTreeLines(
866
1112
  pathToDirectory,
867
1113
  depth,
@@ -882,231 +1128,7 @@ var tree = async (dirPath, depth) => {
882
1128
  return lines.join(os.EOL);
883
1129
  };
884
1130
 
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";
1131
+ // src/commands/dev.ts
1110
1132
  var dev = async ({ dir: emailsDirRelativePath, port }) => {
1111
1133
  try {
1112
1134
  if (!fs6.existsSync(emailsDirRelativePath)) {
@@ -1126,11 +1148,11 @@ var dev = async ({ dir: emailsDirRelativePath, port }) => {
1126
1148
  }
1127
1149
  };
1128
1150
 
1129
- // src/cli/commands/export.ts
1151
+ // src/commands/export.ts
1130
1152
  import fs8, { unlinkSync, writeFileSync } from "node:fs";
1131
1153
  import { createRequire } from "node:module";
1132
- import path11 from "node:path";
1133
- import url2 from "node:url";
1154
+ import path12 from "node:path";
1155
+ import url3 from "node:url";
1134
1156
  import { build as build2 } from "esbuild";
1135
1157
  import { glob } from "glob";
1136
1158
  import logSymbols4 from "log-symbols";
@@ -1139,7 +1161,7 @@ import ora3 from "ora";
1139
1161
 
1140
1162
  // src/utils/esbuild/renderring-utilities-exporter.ts
1141
1163
  import { promises as fs7 } from "node:fs";
1142
- import path10 from "node:path";
1164
+ import path11 from "node:path";
1143
1165
 
1144
1166
  // src/utils/esbuild/escape-string-for-regex.ts
1145
1167
  function escapeStringForRegex(string) {
@@ -1162,7 +1184,7 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
1162
1184
  export { render } from 'react-email-module-that-will-export-render'
1163
1185
  export { createElement as reactEmailCreateReactElement } from 'react';
1164
1186
  `,
1165
- loader: path10.extname(pathToFile).slice(1)
1187
+ loader: path11.extname(pathToFile).slice(1)
1166
1188
  };
1167
1189
  }
1168
1190
  );
@@ -1189,18 +1211,18 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
1189
1211
  }
1190
1212
  });
1191
1213
 
1192
- // src/cli/commands/export.ts
1214
+ // src/commands/export.ts
1193
1215
  var getEmailTemplatesFromDirectory = (emailDirectory) => {
1194
1216
  const templatePaths = [];
1195
1217
  emailDirectory.emailFilenames.forEach(
1196
- (filename3) => templatePaths.push(path11.join(emailDirectory.absolutePath, filename3))
1218
+ (filename3) => templatePaths.push(path12.join(emailDirectory.absolutePath, filename3))
1197
1219
  );
1198
1220
  emailDirectory.subDirectories.forEach((directory) => {
1199
1221
  templatePaths.push(...getEmailTemplatesFromDirectory(directory));
1200
1222
  });
1201
1223
  return templatePaths;
1202
1224
  };
1203
- var filename2 = url2.fileURLToPath(import.meta.url);
1225
+ var filename2 = url3.fileURLToPath(import.meta.url);
1204
1226
  var require2 = createRequire(filename2);
1205
1227
  var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
1206
1228
  if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
@@ -1212,7 +1234,7 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
1212
1234
  registerSpinnerAutostopping(spinner);
1213
1235
  }
1214
1236
  const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
1215
- path11.resolve(process.cwd(), emailsDirectoryPath),
1237
+ path12.resolve(process.cwd(), emailsDirectoryPath),
1216
1238
  true
1217
1239
  );
1218
1240
  if (typeof emailsDirectoryMetadata === "undefined") {
@@ -1294,9 +1316,9 @@ ${buildFailure.message}`);
1294
1316
  spinner.text = "Copying static files";
1295
1317
  spinner.render();
1296
1318
  }
1297
- const staticDirectoryPath = path11.join(emailsDirectoryPath, "static");
1319
+ const staticDirectoryPath = path12.join(emailsDirectoryPath, "static");
1298
1320
  if (fs8.existsSync(staticDirectoryPath)) {
1299
- const pathToDumpStaticFilesInto = path11.join(
1321
+ const pathToDumpStaticFilesInto = path12.join(
1300
1322
  pathToWhereEmailMarkupShouldBeDumped,
1301
1323
  "static"
1302
1324
  );
@@ -1331,14 +1353,15 @@ ${buildFailure.message}`);
1331
1353
  }
1332
1354
  };
1333
1355
 
1334
- // src/cli/commands/start.ts
1356
+ // src/commands/start.ts
1335
1357
  import { spawn as spawn2 } from "node:child_process";
1336
1358
  import fs9 from "node:fs";
1337
- import path12 from "node:path";
1359
+ import path13 from "node:path";
1338
1360
  var start = async () => {
1339
1361
  try {
1362
+ const previewServerLocation = await getPreviewServerLocation();
1340
1363
  const usersProjectLocation = process.cwd();
1341
- const builtPreviewPath = path12.resolve(
1364
+ const builtPreviewPath = path13.resolve(
1342
1365
  usersProjectLocation,
1343
1366
  "./.react-email"
1344
1367
  );
@@ -1348,8 +1371,8 @@ var start = async () => {
1348
1371
  );
1349
1372
  process.exit(1);
1350
1373
  }
1351
- const nextStart = spawn2("npm", ["start"], {
1352
- cwd: builtPreviewPath,
1374
+ const nextStart = spawn2("npx", ["next", "start", builtPreviewPath], {
1375
+ cwd: previewServerLocation,
1353
1376
  stdio: "inherit"
1354
1377
  });
1355
1378
  process.on("SIGINT", () => {
@@ -1364,7 +1387,7 @@ var start = async () => {
1364
1387
  }
1365
1388
  };
1366
1389
 
1367
- // src/cli/index.ts
1390
+ // src/index.ts
1368
1391
  var PACKAGE_NAME = "react-email";
1369
1392
  program.name(PACKAGE_NAME).description("A live preview of your emails right in your browser").version(package_default.version);
1370
1393
  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);