react-email 4.1.0-canary.4 → 4.1.0-canary.5

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 (114) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/cli/index.mjs +190 -166
  3. package/dist/preview/.next/BUILD_ID +1 -1
  4. package/dist/preview/.next/app-build-manifest.json +32 -32
  5. package/dist/preview/.next/build-manifest.json +14 -14
  6. package/dist/preview/.next/diagnostics/framework.json +1 -1
  7. package/dist/preview/.next/next-minimal-server.js.nft.json +1 -1
  8. package/dist/preview/.next/next-server.js.nft.json +1 -1
  9. package/dist/preview/.next/prerender-manifest.json +3 -3
  10. package/dist/preview/.next/required-server-files.json +8 -7
  11. package/dist/preview/.next/server/app/_not-found/page.js +1 -1
  12. package/dist/preview/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/dist/preview/.next/server/app/favicon.ico/route.js +1 -1
  15. package/dist/preview/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  16. package/dist/preview/.next/server/app/page.js +1 -1
  17. package/dist/preview/.next/server/app/page.js.nft.json +1 -1
  18. package/dist/preview/.next/server/app/page_client-reference-manifest.js +1 -1
  19. package/dist/preview/.next/server/app/preview/[...slug]/page.js +188 -128
  20. package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
  21. package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
  22. package/dist/preview/.next/server/chunks/134.js +6 -0
  23. package/dist/preview/.next/server/chunks/235.js +15 -0
  24. package/dist/preview/.next/server/chunks/300.js +1 -0
  25. package/dist/preview/.next/server/chunks/343.js +20 -0
  26. package/dist/preview/.next/server/chunks/428.js +14 -0
  27. package/dist/preview/.next/server/chunks/963.js +1 -0
  28. package/dist/preview/.next/server/middleware-build-manifest.js +1 -1
  29. package/dist/preview/.next/server/next-font-manifest.js +1 -1
  30. package/dist/preview/.next/server/next-font-manifest.json +1 -1
  31. package/dist/preview/.next/server/pages/500.html +1 -1
  32. package/dist/preview/.next/server/pages/_app.js +1 -1
  33. package/dist/preview/.next/server/pages/_app.js.nft.json +1 -1
  34. package/dist/preview/.next/server/pages/_document.js +1 -1
  35. package/dist/preview/.next/server/pages/_document.js.nft.json +1 -1
  36. package/dist/preview/.next/server/pages/_error.js +1 -1
  37. package/dist/preview/.next/server/pages/_error.js.nft.json +1 -1
  38. package/dist/preview/.next/server/server-reference-manifest.js +1 -1
  39. package/dist/preview/.next/server/server-reference-manifest.json +1 -1
  40. package/dist/preview/.next/static/chunks/107-3043079e7cb8bcae.js +1 -0
  41. package/dist/preview/.next/static/chunks/293-297b1eb2241f9a70.js +1 -0
  42. package/dist/preview/.next/static/chunks/3bd82e28-cda2c00a924937c5.js +1 -0
  43. package/dist/preview/.next/static/chunks/45-1021fac82f766268.js +1 -0
  44. package/dist/preview/.next/static/chunks/484-e1100258e8f13026.js +1 -0
  45. package/dist/preview/.next/static/chunks/589-817d8691661d370e.js +1 -0
  46. package/dist/preview/.next/static/chunks/902-c34acb56733e0ce1.js +1 -0
  47. package/dist/preview/.next/static/chunks/app/_not-found/page-4cbc7dce3ad33336.js +1 -0
  48. package/dist/preview/.next/static/chunks/app/layout-ae0864a2f95fa465.js +1 -0
  49. package/dist/preview/.next/static/chunks/app/page-65fd67d48528e2ba.js +1 -0
  50. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-8aac52e1ccbb9d9b.js +1 -0
  51. package/dist/preview/.next/static/chunks/f33a14d2-ec7c5f0b91818561.js +6 -0
  52. package/dist/preview/.next/static/chunks/framework-b887e9fc751a9906.js +1 -0
  53. package/dist/preview/.next/static/chunks/main-9a03e7ba8acb1900.js +1 -0
  54. package/dist/preview/.next/static/chunks/main-app-dbd8e1ec12eabb66.js +1 -0
  55. package/dist/preview/.next/static/chunks/pages/_app-542a93a5a214e1c0.js +1 -0
  56. package/dist/preview/.next/static/chunks/pages/_error-d5fe1b1612642f76.js +1 -0
  57. package/dist/preview/.next/static/chunks/webpack-31c45daa2bd82a7b.js +1 -0
  58. package/dist/preview/.next/static/css/6f42d128f111d7fa.css +3 -0
  59. package/dist/preview/.next/static/{JZPm9ao1byHQqJdt3oG1X → zs2-dZFPht_M4xAoOGgCM}/_buildManifest.js +1 -1
  60. package/dist/preview/.next/trace +28 -27
  61. package/package.json +41 -42
  62. package/src/actions/email-validation/check-compatibility.ts +1 -1
  63. package/src/actions/email-validation/check-images.spec.tsx +1 -1
  64. package/src/actions/email-validation/check-links.spec.tsx +1 -1
  65. package/src/actions/email-validation/quick-fetch.ts +1 -1
  66. package/src/actions/render-email-by-path.tsx +2 -2
  67. package/src/app/preview/[...slug]/preview.tsx +1 -1
  68. package/src/components/sidebar/file-tree-directory-children.tsx +7 -2
  69. package/src/components/toolbar.tsx +1 -0
  70. package/src/contexts/emails.tsx +1 -3
  71. package/src/contexts/fragment-identifier.tsx +3 -1
  72. package/src/contexts/preview.tsx +1 -3
  73. package/src/hooks/use-email-rendering-result.ts +1 -1
  74. package/src/hooks/use-hot-reload.ts +1 -1
  75. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +1 -1
  76. package/src/utils/caniemail/ast/get-object-variables.ts +1 -1
  77. package/src/utils/caniemail/tailwind/generate-tailwind-rules.ts +1 -1
  78. package/src/utils/caniemail/tailwind/get-tailwind-config.ts +1 -1
  79. package/src/utils/caniemail/tailwind/get-tailwind-metadata.ts +1 -1
  80. package/src/utils/get-email-component.ts +1 -1
  81. package/src/utils/get-emails-directory-metadata.ts +24 -13
  82. package/src/utils/index.ts +2 -2
  83. package/src/utils/run-bundled-code.ts +1 -1
  84. package/tailwind.config.ts +2 -1
  85. package/tsconfig.json +1 -1
  86. package/dist/cli/index.d.mts +0 -1
  87. package/dist/cli/index.d.ts +0 -1
  88. package/dist/cli/index.js +0 -1325
  89. package/dist/preview/.next/server/chunks/362.js +0 -1
  90. package/dist/preview/.next/server/chunks/395.js +0 -1
  91. package/dist/preview/.next/server/chunks/574.js +0 -6
  92. package/dist/preview/.next/server/chunks/735.js +0 -13
  93. package/dist/preview/.next/server/chunks/840.js +0 -14
  94. package/dist/preview/.next/server/chunks/886.js +0 -8
  95. package/dist/preview/.next/static/chunks/246-e7336e2929971f63.js +0 -1
  96. package/dist/preview/.next/static/chunks/270-688096d43c717256.js +0 -1
  97. package/dist/preview/.next/static/chunks/539-6e9405ecdc007bb7.js +0 -1
  98. package/dist/preview/.next/static/chunks/587-11b31fa1b8f77a29.js +0 -1
  99. package/dist/preview/.next/static/chunks/782947c8-c6cfd05e68542601.js +0 -1
  100. package/dist/preview/.next/static/chunks/803-db74f262c4755323.js +0 -1
  101. package/dist/preview/.next/static/chunks/853-a01d49f63a859f3d.js +0 -1
  102. package/dist/preview/.next/static/chunks/afa401a5-55858bf5265319eb.js +0 -6
  103. package/dist/preview/.next/static/chunks/app/_not-found/page-85e83b2d4bd569a2.js +0 -1
  104. package/dist/preview/.next/static/chunks/app/layout-58e02c2c8b197b04.js +0 -1
  105. package/dist/preview/.next/static/chunks/app/page-dd13899a1b8e35f9.js +0 -1
  106. package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-94fd27d6538e2c16.js +0 -1
  107. package/dist/preview/.next/static/chunks/framework-b5f555f62da46ed9.js +0 -1
  108. package/dist/preview/.next/static/chunks/main-a839e2fbd78a08fa.js +0 -1
  109. package/dist/preview/.next/static/chunks/main-app-2cfbaf0185a1cd0e.js +0 -1
  110. package/dist/preview/.next/static/chunks/pages/_app-ee26b5d329c4bb79.js +0 -1
  111. package/dist/preview/.next/static/chunks/pages/_error-90cb3f6367e28bcd.js +0 -1
  112. package/dist/preview/.next/static/chunks/webpack-6755bde10ea8daa8.js +0 -1
  113. package/dist/preview/.next/static/css/67e57230289273a9.css +0 -3
  114. /package/dist/preview/.next/static/{JZPm9ao1byHQqJdt3oG1X → zs2-dZFPht_M4xAoOGgCM}/_ssgManifest.js +0 -0
@@ -1,11 +1,4 @@
1
1
  #!/usr/bin/env node
2
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
- }) : x)(function(x) {
5
- if (typeof require !== "undefined")
6
- return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x + '" is not supported');
8
- });
9
2
 
10
3
  // src/cli/index.ts
11
4
  import { program } from "commander";
@@ -13,13 +6,14 @@ import { program } from "commander";
13
6
  // package.json
14
7
  var package_default = {
15
8
  name: "react-email",
16
- version: "4.1.0-canary.4",
9
+ version: "4.1.0-canary.5",
17
10
  description: "A live preview of your emails right in your browser.",
18
11
  bin: {
19
- email: "./dist/cli/index.js"
12
+ email: "./dist/cli/index.mjs"
20
13
  },
21
14
  scripts: {
22
- build: "tsup-node && node ./scripts/build-preview-server.mjs && pnpm install --frozen-lockfile",
15
+ build: "tsup-node && node ./scripts/build-preview-server.mjs",
16
+ postbuild: "pnpm install --frozen-lockfile",
23
17
  "caniemail:fetch": "node ./scripts/fill-caniemail-data.mjs",
24
18
  clean: "rm -rf dist",
25
19
  dev: "tsup-node --watch",
@@ -33,75 +27,76 @@ var package_default = {
33
27
  url: "https://github.com/resend/react-email.git",
34
28
  directory: "packages/react-email"
35
29
  },
36
- keywords: ["react", "email"],
30
+ keywords: [
31
+ "react",
32
+ "email"
33
+ ],
37
34
  engines: {
38
35
  node: ">=18.0.0"
39
36
  },
40
37
  dependencies: {
41
- "@babel/parser": "^7.24.5",
42
- "@babel/traverse": "^7.25.6",
43
- chalk: "^4.1.2",
38
+ "@babel/parser": "^7.27.0",
39
+ "@babel/traverse": "^7.27.0",
40
+ chalk: "^5.0.0",
44
41
  chokidar: "^4.0.3",
45
- commander: "^11.1.0",
42
+ commander: "^13.0.0",
46
43
  debounce: "^2.0.0",
47
44
  esbuild: "^0.25.0",
48
- glob: "^10.3.4",
49
- "log-symbols": "^4.1.0",
50
- "mime-types": "^2.1.35",
51
- next: "^15.2.4",
45
+ glob: "^11.0.0",
46
+ "log-symbols": "^7.0.0",
47
+ "mime-types": "^3.0.0",
48
+ next: "^15.3.1",
52
49
  "normalize-path": "^3.0.0",
53
- ora: "^5.4.1",
50
+ ora: "^8.0.0",
54
51
  "socket.io": "^4.8.1"
55
52
  },
56
53
  devDependencies: {
57
54
  "@babel/core": "7.26.10",
58
- "@lottiefiles/dotlottie-react": "0.12.3",
59
- "@radix-ui/colors": "1.0.1",
60
- "@radix-ui/react-collapsible": "1.1.0",
61
- "@radix-ui/react-dropdown-menu": "2.1.4",
62
- "@radix-ui/react-popover": "1.1.1",
63
- "@radix-ui/react-slot": "1.1.0",
64
- "@radix-ui/react-tabs": "1.1.1",
65
- "@radix-ui/react-toggle-group": "1.1.0",
66
- "@radix-ui/react-tooltip": "1.1.2",
55
+ "@lottiefiles/dotlottie-react": "0.13.3",
56
+ "@radix-ui/colors": "3.0.0",
57
+ "@radix-ui/react-collapsible": "1.1.7",
58
+ "@radix-ui/react-dropdown-menu": "2.1.10",
59
+ "@radix-ui/react-popover": "1.1.10",
60
+ "@radix-ui/react-slot": "1.2.0",
61
+ "@radix-ui/react-tabs": "1.1.7",
62
+ "@radix-ui/react-toggle-group": "1.1.6",
63
+ "@radix-ui/react-tooltip": "1.2.3",
67
64
  "@react-email/components": "workspace:*",
68
- "@swc/core": "1.4.15",
65
+ "@swc/core": "1.11.21",
69
66
  "@types/babel__core": "7.20.5",
70
- "@types/babel__traverse": "*",
67
+ "@types/babel__traverse": "7.20.7",
71
68
  "@types/fs-extra": "11.0.1",
72
69
  "@types/mime-types": "2.1.4",
73
- "@types/node": "22.10.2",
70
+ "@types/node": "22.14.1",
74
71
  "@types/normalize-path": "3.0.2",
75
72
  "@types/react": "19.0.10",
76
73
  "@types/react-dom": "19.0.4",
77
74
  "@types/webpack": "5.28.5",
78
- "@vercel/style-guide": "5.1.0",
79
- autoprefixer: "10.4.20",
75
+ autoprefixer: "10.4.21",
80
76
  clsx: "2.1.1",
81
- "framer-motion": "12.0.0-alpha.2",
77
+ "framer-motion": "12.7.5",
82
78
  jiti: "2.4.2",
83
79
  json5: "2.2.3",
84
80
  "module-punycode": "npm:punycode@2.3.1",
85
- "node-html-parser": "6.1.13",
86
- postcss: "8.4.40",
87
- "prettier-plugin-tailwindcss": "0.6.6",
81
+ "node-html-parser": "7.0.1",
82
+ postcss: "8.5.3",
88
83
  "pretty-bytes": "6.1.1",
89
- "prism-react-renderer": "2.1.0",
84
+ "prism-react-renderer": "2.4.1",
90
85
  react: "19.0.0",
91
86
  "react-dom": "19.0.0",
92
- sharp: "0.33.3",
93
- "socket.io-client": "4.8.0",
94
- sonner: "1.7.1",
95
- "source-map-js": "1.0.2",
87
+ sharp: "0.34.1",
88
+ "socket.io-client": "4.8.1",
89
+ sonner: "2.0.3",
90
+ "source-map-js": "1.2.1",
96
91
  spamc: "0.0.5",
97
- "stacktrace-parser": "0.1.10",
98
- "tailwind-merge": "2.2.0",
92
+ "stacktrace-parser": "0.1.11",
93
+ "tailwind-merge": "3.2.0",
99
94
  tailwindcss: "3.4.0",
100
- tsup: "7.2.0",
101
- tsx: "4.9.0",
102
- typescript: "5.8.2",
95
+ tsup: "8.4.0",
96
+ tsx: "4.19.3",
97
+ typescript: "5.8.3",
103
98
  "use-debounce": "10.0.4",
104
- zod: "3.24.2"
99
+ zod: "3.24.3"
105
100
  }
106
101
  };
107
102
 
@@ -115,17 +110,26 @@ import ora2 from "ora";
115
110
  // src/utils/get-emails-directory-metadata.ts
116
111
  import fs from "node:fs";
117
112
  import path from "node:path";
118
- var isFileAnEmail = (fullPath) => {
119
- const stat = fs.statSync(fullPath);
120
- if (stat.isDirectory())
113
+ var isFileAnEmail = async (fullPath) => {
114
+ let fileHandle;
115
+ try {
116
+ fileHandle = await fs.promises.open(fullPath, "r");
117
+ } catch (exception) {
118
+ console.warn(exception);
121
119
  return false;
122
- const { ext } = path.parse(fullPath);
123
- if (![".js", ".tsx", ".jsx"].includes(ext))
120
+ }
121
+ const stat = await fileHandle.stat();
122
+ if (stat.isDirectory()) {
123
+ await fileHandle.close();
124
124
  return false;
125
- if (!fs.existsSync(fullPath)) {
125
+ }
126
+ const { ext } = path.parse(fullPath);
127
+ if (![".js", ".tsx", ".jsx"].includes(ext)) {
128
+ await fileHandle.close();
126
129
  return false;
127
130
  }
128
- const fileContents = fs.readFileSync(fullPath, "utf8");
131
+ const fileContents = await fileHandle.readFile("utf8");
132
+ await fileHandle.close();
129
133
  const hasES6DefaultExport = /\bexport\s+default\b/gm.test(fileContents);
130
134
  const hasCommonJSExport = /\bmodule\.exports\s*=/gm.test(fileContents);
131
135
  const hasNamedExport = /\bexport\s+\{[^}]*\bdefault\b[^}]*\}/gm.test(
@@ -148,14 +152,16 @@ var mergeDirectoriesWithSubDirectories = (emailsDirectoryMetadata) => {
148
152
  return currentResultingMergedDirectory;
149
153
  };
150
154
  var getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFileExtensions = false, isSubDirectory = false, baseDirectoryPath = absolutePathToEmailsDirectory) => {
151
- if (!fs.existsSync(absolutePathToEmailsDirectory))
152
- return;
155
+ if (!fs.existsSync(absolutePathToEmailsDirectory)) return;
153
156
  const dirents = await fs.promises.readdir(absolutePathToEmailsDirectory, {
154
157
  withFileTypes: true
155
158
  });
156
- const emailFilenames = dirents.filter(
157
- (dirent) => isFileAnEmail(path.join(absolutePathToEmailsDirectory, dirent.name))
158
- ).map(
159
+ const isEmailPredicates = await Promise.all(
160
+ dirents.map(
161
+ (dirent) => isFileAnEmail(path.join(absolutePathToEmailsDirectory, dirent.name))
162
+ )
163
+ );
164
+ const emailFilenames = dirents.filter((_, i) => isEmailPredicates[i]).map(
159
165
  (dirent) => keepFileExtensions ? dirent.name : dirent.name.replace(path.extname(dirent.name), "")
160
166
  );
161
167
  const subDirectories = await Promise.all(
@@ -212,76 +218,19 @@ var registerSpinnerAutostopping = (spinner) => {
212
218
  spinners.add(spinner);
213
219
  };
214
220
 
215
- // src/cli/utils/tree.ts
216
- import { promises as fs2 } from "node:fs";
217
- import os from "node:os";
218
- import path2 from "node:path";
219
- var SYMBOLS = {
220
- BRANCH: "\u251C\u2500\u2500 ",
221
- EMPTY: "",
222
- INDENT: " ",
223
- LAST_BRANCH: "\u2514\u2500\u2500 ",
224
- VERTICAL: "\u2502 "
225
- };
226
- var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
227
- const base = process.cwd();
228
- const dirFullpath = path2.resolve(base, dirPath);
229
- const dirname = path2.basename(dirFullpath);
230
- let lines = [dirname];
231
- const dirStat = await fs2.stat(dirFullpath);
232
- if (dirStat.isDirectory() && currentDepth < depth) {
233
- const childDirents = await fs2.readdir(dirFullpath, { withFileTypes: true });
234
- childDirents.sort((a, b) => {
235
- if (a.isDirectory() && b.isFile()) {
236
- return -1;
237
- }
238
- if (a.isFile() && b.isDirectory()) {
239
- return 1;
240
- }
241
- return b.name > a.name ? -1 : 1;
242
- });
243
- for (let i = 0; i < childDirents.length; i++) {
244
- const dirent = childDirents[i];
245
- const isLast = i === childDirents.length - 1;
246
- const branchingSymbol = isLast ? SYMBOLS.LAST_BRANCH : SYMBOLS.BRANCH;
247
- const verticalSymbol = isLast ? SYMBOLS.INDENT : SYMBOLS.VERTICAL;
248
- if (dirent.isFile()) {
249
- lines.push(`${branchingSymbol}${dirent.name}`);
250
- } else {
251
- const pathToDirectory = path2.join(dirFullpath, dirent.name);
252
- const treeLinesForSubDirectory = await getTreeLines(
253
- pathToDirectory,
254
- depth,
255
- currentDepth + 1
256
- );
257
- lines = lines.concat(
258
- treeLinesForSubDirectory.map(
259
- (line, index) => index === 0 ? `${branchingSymbol}${line}` : `${verticalSymbol}${line}`
260
- )
261
- );
262
- }
263
- }
264
- }
265
- return lines;
266
- };
267
- var tree = async (dirPath, depth) => {
268
- const lines = await getTreeLines(dirPath, depth);
269
- return lines.join(os.EOL);
270
- };
271
-
272
221
  // src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
273
- import path7 from "node:path";
222
+ import path6 from "node:path";
274
223
  import { watch } from "chokidar";
275
224
  import debounce from "debounce";
276
225
  import { Server as SocketServer } from "socket.io";
277
226
 
278
227
  // src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
279
- import { promises as fs4, existsSync as existsSync2, statSync } from "node:fs";
280
- import path6 from "node:path";
228
+ import { existsSync as existsSync2, promises as fs3, statSync } from "node:fs";
229
+ import path5 from "node:path";
281
230
 
282
231
  // src/cli/utils/preview/start-dev-server.ts
283
232
  import http from "node:http";
284
- import path5 from "node:path";
233
+ import path4 from "node:path";
285
234
  import url from "node:url";
286
235
  import chalk from "chalk";
287
236
  import logSymbols2 from "log-symbols";
@@ -289,28 +238,33 @@ import next from "next";
289
238
  import ora from "ora";
290
239
 
291
240
  // src/cli/utils/preview/get-env-variables-for-preview-app.ts
292
- import path3 from "node:path";
241
+ import path2 from "node:path";
293
242
  var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
294
243
  return {
295
244
  EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
296
- EMAILS_DIR_ABSOLUTE_PATH: path3.resolve(cwd, relativePathToEmailsDirectory),
245
+ EMAILS_DIR_ABSOLUTE_PATH: path2.resolve(cwd, relativePathToEmailsDirectory),
297
246
  USER_PROJECT_LOCATION: cwd,
298
247
  NEXT_PUBLIC_IS_PREVIEW_DEVELOPMENT: isDev ? "true" : "false"
299
248
  };
300
249
  };
301
250
 
302
251
  // src/cli/utils/preview/serve-static-file.ts
303
- import { promises as fs3, existsSync } from "node:fs";
304
- import path4 from "node:path";
252
+ import { existsSync, promises as fs2 } from "node:fs";
253
+ import path3 from "node:path";
305
254
  import { lookup } from "mime-types";
306
255
  var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
307
- const staticBaseDir = path4.join(process.cwd(), staticDirRelativePath);
308
- const pathname = parsedUrl.pathname;
309
- const ext = path4.parse(pathname).ext;
310
- const fileAbsolutePath = path4.join(staticBaseDir, pathname);
256
+ const pathname = parsedUrl.pathname.replace("/static", "./static");
257
+ const ext = path3.parse(pathname).ext;
258
+ const staticBaseDir = path3.resolve(process.cwd(), staticDirRelativePath);
259
+ const fileAbsolutePath = path3.resolve(staticBaseDir, pathname);
260
+ if (!fileAbsolutePath.startsWith(staticBaseDir)) {
261
+ res.statusCode = 403;
262
+ res.end();
263
+ return;
264
+ }
311
265
  try {
312
- const fileHandle = await fs3.open(fileAbsolutePath, "r");
313
- const fileData = await fs3.readFile(fileHandle);
266
+ const fileHandle = await fs2.open(fileAbsolutePath, "r");
267
+ const fileData = await fs2.readFile(fileHandle);
314
268
  res.setHeader("Content-type", lookup(ext) || "text/plain");
315
269
  res.end(fileData);
316
270
  fileHandle.close();
@@ -346,9 +300,11 @@ var safeAsyncServerListen = (server, port) => {
346
300
  });
347
301
  });
348
302
  };
349
- var isDev = !__filename.endsWith(path5.join("cli", "index.js"));
350
- var cliPackageLocation = isDev ? path5.resolve(__dirname, "../../../..") : path5.resolve(__dirname, "../..");
351
- var previewServerLocation = isDev ? path5.resolve(__dirname, "../../../..") : path5.resolve(__dirname, "../preview");
303
+ var filename = url.fileURLToPath(import.meta.url);
304
+ var dirname = path4.dirname(filename);
305
+ var isDev = !filename.endsWith(path4.join("cli", "index.mjs"));
306
+ var cliPackageLocation = isDev ? path4.resolve(dirname, "../../../..") : path4.resolve(dirname, "../..");
307
+ var previewServerLocation = isDev ? path4.resolve(dirname, "../../../..") : path4.resolve(dirname, "../preview");
352
308
  var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
353
309
  devServer = http.createServer((req, res) => {
354
310
  if (!req.url) {
@@ -415,7 +371,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
415
371
  ...process.env,
416
372
  ...getEnvVariablesForPreviewApp(
417
373
  // If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
418
- path5.normalize(emailsDirRelativePath),
374
+ path4.normalize(emailsDirRelativePath),
419
375
  process.cwd()
420
376
  )
421
377
  };
@@ -475,7 +431,8 @@ process.on(
475
431
 
476
432
  // src/cli/utils/preview/hot-reloading/get-imported-modules.ts
477
433
  import { parse } from "@babel/parser";
478
- import traverse from "@babel/traverse";
434
+ import traverseModule from "@babel/traverse";
435
+ var traverse = traverseModule.default;
479
436
  var getImportedModules = (contents) => {
480
437
  const importedPaths = [];
481
438
  const parsedContents = parse(contents, {
@@ -496,6 +453,9 @@ var getImportedModules = (contents) => {
496
453
  importedPaths.push(node.source.value);
497
454
  }
498
455
  },
456
+ TSExternalModuleReference({ node }) {
457
+ importedPaths.push(node.expression.value);
458
+ },
499
459
  CallExpression({ node }) {
500
460
  if ("name" in node.callee && node.callee.name === "require") {
501
461
  if (node.arguments.length === 1) {
@@ -513,9 +473,9 @@ var getImportedModules = (contents) => {
513
473
  // src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
514
474
  var readAllFilesInsideDirectory = async (directory) => {
515
475
  let allFilePaths = [];
516
- const topLevelDirents = await fs4.readdir(directory, { withFileTypes: true });
476
+ const topLevelDirents = await fs3.readdir(directory, { withFileTypes: true });
517
477
  for await (const dirent of topLevelDirents) {
518
- const pathToDirent = path6.join(directory, dirent.name);
478
+ const pathToDirent = path5.join(directory, dirent.name);
519
479
  if (dirent.isDirectory()) {
520
480
  allFilePaths = allFilePaths.concat(
521
481
  await readAllFilesInsideDirectory(pathToDirent)
@@ -527,7 +487,7 @@ var readAllFilesInsideDirectory = async (directory) => {
527
487
  return allFilePaths;
528
488
  };
529
489
  var isJavascriptModule = (filePath) => {
530
- const extensionName = path6.extname(filePath);
490
+ const extensionName = path5.extname(filePath);
531
491
  return [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(extensionName);
532
492
  };
533
493
  var checkFileExtensionsUntilItExists = (pathWithoutExtension) => {
@@ -565,15 +525,15 @@ var createDependencyGraph = async (directory) => {
565
525
  ])
566
526
  );
567
527
  const getDependencyPaths = async (filePath) => {
568
- const contents = await fs4.readFile(filePath, "utf8");
528
+ const contents = await fs3.readFile(filePath, "utf8");
569
529
  const importedPaths = isJavascriptModule(filePath) ? getImportedModules(contents) : [];
570
530
  const importedPathsRelativeToDirectory = importedPaths.map(
571
531
  (dependencyPath) => {
572
532
  const isModulePath = !dependencyPath.startsWith(".");
573
- if (isModulePath || path6.isAbsolute(dependencyPath)) {
533
+ if (isModulePath || path5.isAbsolute(dependencyPath)) {
574
534
  return dependencyPath;
575
535
  }
576
- let pathToDependencyFromDirectory = path6.resolve(
536
+ let pathToDependencyFromDirectory = path5.resolve(
577
537
  /*
578
538
  path.resolve resolves paths differently from what imports on javascript do.
579
539
 
@@ -581,7 +541,7 @@ var createDependencyGraph = async (directory) => {
581
541
  would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the
582
542
  one the import is meant to go to
583
543
  */
584
- path6.dirname(filePath),
544
+ path5.dirname(filePath),
585
545
  dependencyPath
586
546
  );
587
547
  let isDirectory = false;
@@ -603,7 +563,7 @@ var createDependencyGraph = async (directory) => {
603
563
  }
604
564
  }
605
565
  if (!isJavascriptModule(pathToDependencyFromDirectory)) {
606
- const pathWithExtension = path6.extname(pathToDependencyFromDirectory).length > 0 ? pathToDependencyFromDirectory : checkFileExtensionsUntilItExists(pathToDependencyFromDirectory);
566
+ const pathWithExtension = path5.extname(pathToDependencyFromDirectory).length > 0 ? pathToDependencyFromDirectory : checkFileExtensionsUntilItExists(pathToDependencyFromDirectory);
607
567
  if (pathWithExtension) {
608
568
  pathToDependencyFromDirectory = pathWithExtension;
609
569
  } else if (isDev) {
@@ -616,10 +576,10 @@ var createDependencyGraph = async (directory) => {
616
576
  }
617
577
  );
618
578
  const moduleDependencies = importedPathsRelativeToDirectory.filter(
619
- (dependencyPath) => !dependencyPath.startsWith(".") && !path6.isAbsolute(dependencyPath)
579
+ (dependencyPath) => !dependencyPath.startsWith(".") && !path5.isAbsolute(dependencyPath)
620
580
  );
621
581
  const nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(
622
- (dependencyPath) => dependencyPath.startsWith(".") || path6.isAbsolute(dependencyPath)
582
+ (dependencyPath) => dependencyPath.startsWith(".") || path5.isAbsolute(dependencyPath)
623
583
  );
624
584
  return {
625
585
  dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory,
@@ -638,8 +598,7 @@ var createDependencyGraph = async (directory) => {
638
598
  const { moduleDependencies, dependencyPaths: newDependencyPaths } = await getDependencyPaths(moduleFilePath);
639
599
  graph[moduleFilePath].moduleDependencies = moduleDependencies;
640
600
  for (const dependencyPath of graph[moduleFilePath].dependencyPaths) {
641
- if (newDependencyPaths.includes(dependencyPath))
642
- continue;
601
+ if (newDependencyPaths.includes(dependencyPath)) continue;
643
602
  const dependencyModule = graph[dependencyPath];
644
603
  if (dependencyModule !== void 0) {
645
604
  dependencyModule.dependentPaths = dependencyModule.dependentPaths.filter(
@@ -751,14 +710,14 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
751
710
  changes.filter(
752
711
  (change) => (
753
712
  // Ensures only changes inside the emails directory are emitted
754
- path7.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
713
+ path6.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
755
714
  )
756
715
  )
757
716
  );
758
717
  });
759
718
  changes = [];
760
719
  }, 150);
761
- const absolutePathToEmailsDirectory = path7.resolve(
720
+ const absolutePathToEmailsDirectory = path6.resolve(
762
721
  process.cwd(),
763
722
  emailDirRelativePath
764
723
  );
@@ -768,7 +727,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
768
727
  cwd: absolutePathToEmailsDirectory
769
728
  });
770
729
  const getFilesOutsideEmailsDirectory = () => Object.keys(dependencyGraph).filter(
771
- (p) => path7.relative(absolutePathToEmailsDirectory, p).startsWith("..")
730
+ (p) => path6.relative(absolutePathToEmailsDirectory, p).startsWith("..")
772
731
  );
773
732
  let filesOutsideEmailsDirectory = getFilesOutsideEmailsDirectory();
774
733
  for (const p of filesOutsideEmailsDirectory) {
@@ -780,11 +739,11 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
780
739
  process.on("SIGINT", exit);
781
740
  process.on("uncaughtException", exit);
782
741
  watcher.on("all", async (event, relativePathToChangeTarget) => {
783
- const file = relativePathToChangeTarget.split(path7.sep);
742
+ const file = relativePathToChangeTarget.split(path6.sep);
784
743
  if (file.length === 0) {
785
744
  return;
786
745
  }
787
- const pathToChangeTarget = path7.resolve(
746
+ const pathToChangeTarget = path6.resolve(
788
747
  absolutePathToEmailsDirectory,
789
748
  relativePathToChangeTarget
790
749
  );
@@ -808,7 +767,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
808
767
  for (const dependentPath of resolveDependentsOf(pathToChangeTarget)) {
809
768
  changes.push({
810
769
  event: "change",
811
- filename: path7.relative(absolutePathToEmailsDirectory, dependentPath)
770
+ filename: path6.relative(absolutePathToEmailsDirectory, dependentPath)
812
771
  });
813
772
  }
814
773
  reload();
@@ -816,6 +775,63 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
816
775
  return watcher;
817
776
  };
818
777
 
778
+ // src/cli/utils/tree.ts
779
+ import { promises as fs4 } from "node:fs";
780
+ import os from "node:os";
781
+ import path7 from "node:path";
782
+ var SYMBOLS = {
783
+ BRANCH: "\u251C\u2500\u2500 ",
784
+ EMPTY: "",
785
+ INDENT: " ",
786
+ LAST_BRANCH: "\u2514\u2500\u2500 ",
787
+ VERTICAL: "\u2502 "
788
+ };
789
+ var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
790
+ const base = process.cwd();
791
+ const dirFullpath = path7.resolve(base, dirPath);
792
+ const dirname2 = path7.basename(dirFullpath);
793
+ let lines = [dirname2];
794
+ const dirStat = await fs4.stat(dirFullpath);
795
+ if (dirStat.isDirectory() && currentDepth < depth) {
796
+ const childDirents = await fs4.readdir(dirFullpath, { withFileTypes: true });
797
+ childDirents.sort((a, b) => {
798
+ if (a.isDirectory() && b.isFile()) {
799
+ return -1;
800
+ }
801
+ if (a.isFile() && b.isDirectory()) {
802
+ return 1;
803
+ }
804
+ return b.name > a.name ? -1 : 1;
805
+ });
806
+ for (let i = 0; i < childDirents.length; i++) {
807
+ const dirent = childDirents[i];
808
+ const isLast = i === childDirents.length - 1;
809
+ const branchingSymbol = isLast ? SYMBOLS.LAST_BRANCH : SYMBOLS.BRANCH;
810
+ const verticalSymbol = isLast ? SYMBOLS.INDENT : SYMBOLS.VERTICAL;
811
+ if (dirent.isFile()) {
812
+ lines.push(`${branchingSymbol}${dirent.name}`);
813
+ } else {
814
+ const pathToDirectory = path7.join(dirFullpath, dirent.name);
815
+ const treeLinesForSubDirectory = await getTreeLines(
816
+ pathToDirectory,
817
+ depth,
818
+ currentDepth + 1
819
+ );
820
+ lines = lines.concat(
821
+ treeLinesForSubDirectory.map(
822
+ (line, index) => index === 0 ? `${branchingSymbol}${line}` : `${verticalSymbol}${line}`
823
+ )
824
+ );
825
+ }
826
+ }
827
+ }
828
+ return lines;
829
+ };
830
+ var tree = async (dirPath, depth) => {
831
+ const lines = await getTreeLines(dirPath, depth);
832
+ return lines.join(os.EOL);
833
+ };
834
+
819
835
  // src/cli/commands/build.ts
820
836
  var buildPreviewApp = (absoluteDirectory) => {
821
837
  return new Promise((resolve, reject) => {
@@ -883,8 +899,8 @@ var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePa
883
899
  const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
884
900
  const slugs = [];
885
901
  emailDirectory.emailFilenames.forEach(
886
- (filename) => slugs.push(
887
- path8.join(directoryPathRelativeToEmailsDirectory, filename).split(path8.sep).filter((segment) => segment.length > 0)
902
+ (filename3) => slugs.push(
903
+ path8.join(directoryPathRelativeToEmailsDirectory, filename3).split(path8.sep).filter((segment) => segment.length > 0)
888
904
  )
889
905
  );
890
906
  emailDirectory.subDirectories.forEach((directory) => {
@@ -939,6 +955,7 @@ var updatePackageJson = async (builtPreviewAppPath) => {
939
955
  );
940
956
  packageJson.scripts.build = "next build";
941
957
  packageJson.scripts.start = "next start";
958
+ delete packageJson.scripts.postbuild;
942
959
  packageJson.name = "preview-server";
943
960
  delete packageJson.devDependencies["@react-email/render"];
944
961
  delete packageJson.devDependencies["@react-email/components"];
@@ -1061,7 +1078,9 @@ var dev = async ({ dir: emailsDirRelativePath, port }) => {
1061
1078
 
1062
1079
  // src/cli/commands/export.ts
1063
1080
  import fs8, { unlinkSync, writeFileSync } from "node:fs";
1081
+ import { createRequire } from "node:module";
1064
1082
  import path10 from "node:path";
1083
+ import url2 from "node:url";
1065
1084
  import { build as build2 } from "esbuild";
1066
1085
  import { glob } from "glob";
1067
1086
  import logSymbols4 from "log-symbols";
@@ -1124,13 +1143,15 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
1124
1143
  var getEmailTemplatesFromDirectory = (emailDirectory) => {
1125
1144
  const templatePaths = [];
1126
1145
  emailDirectory.emailFilenames.forEach(
1127
- (filename) => templatePaths.push(path10.join(emailDirectory.absolutePath, filename))
1146
+ (filename3) => templatePaths.push(path10.join(emailDirectory.absolutePath, filename3))
1128
1147
  );
1129
1148
  emailDirectory.subDirectories.forEach((directory) => {
1130
1149
  templatePaths.push(...getEmailTemplatesFromDirectory(directory));
1131
1150
  });
1132
1151
  return templatePaths;
1133
1152
  };
1153
+ var filename2 = url2.fileURLToPath(import.meta.url);
1154
+ var require2 = createRequire(filename2);
1134
1155
  var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
1135
1156
  if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
1136
1157
  fs8.rmSync(pathToWhereEmailMarkupShouldBeDumped, { recursive: true });
@@ -1158,23 +1179,26 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
1158
1179
  await build2({
1159
1180
  bundle: true,
1160
1181
  entryPoints: allTemplates,
1161
- plugins: [renderingUtilitiesExporter(allTemplates)],
1162
- platform: "node",
1163
1182
  format: "cjs",
1183
+ jsx: "transform",
1164
1184
  loader: { ".js": "jsx" },
1185
+ logLevel: "silent",
1165
1186
  outExtension: { ".js": ".cjs" },
1166
- jsx: "transform",
1167
- write: true,
1168
- outdir: pathToWhereEmailMarkupShouldBeDumped
1187
+ outdir: pathToWhereEmailMarkupShouldBeDumped,
1188
+ platform: "node",
1189
+ plugins: [renderingUtilitiesExporter(allTemplates)],
1190
+ write: true
1169
1191
  });
1170
1192
  } catch (exception) {
1171
- const buildFailure = exception;
1172
1193
  if (spinner) {
1173
1194
  spinner.stopAndPersist({
1174
1195
  symbol: logSymbols4.error,
1175
1196
  text: "Failed to build emails"
1176
1197
  });
1177
1198
  }
1199
+ const buildFailure = exception;
1200
+ console.error(`
1201
+ ${buildFailure.message}`);
1178
1202
  process.exit(1);
1179
1203
  }
1180
1204
  if (spinner) {
@@ -1192,8 +1216,8 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
1192
1216
  spinner.text = `rendering ${template.split("/").pop()}`;
1193
1217
  spinner.render();
1194
1218
  }
1195
- delete __require.cache[template];
1196
- const emailModule = __require(template);
1219
+ delete require2.cache[template];
1220
+ const emailModule = require2(template);
1197
1221
  const rendered = await emailModule.render(
1198
1222
  emailModule.reactEmailCreateReactElement(emailModule.default, {}),
1199
1223
  options
@@ -1 +1 @@
1
- JZPm9ao1byHQqJdt3oG1X
1
+ zs2-dZFPht_M4xAoOGgCM