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