react-email 3.0.5 → 3.0.7-canary.0
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 +13 -0
- package/dist/cli/index.js +764 -769
- package/dist/cli/index.mjs +488 -499
- package/dist/preview/.next/BUILD_ID +1 -1
- package/dist/preview/.next/app-build-manifest.json +10 -10
- package/dist/preview/.next/build-manifest.json +3 -3
- package/dist/preview/.next/cache/.rscinfo +1 -1
- package/dist/preview/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/preview/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/preview/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/preview/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/preview/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/preview/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/preview/.next/next-server.js.nft.json +1 -1
- package/dist/preview/.next/prerender-manifest.json +1 -1
- package/dist/preview/.next/required-server-files.json +1 -1
- package/dist/preview/.next/server/app/_not-found/page.js +1 -1
- package/dist/preview/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/app/favicon.ico/route.js +1 -1
- package/dist/preview/.next/server/app/page.js +1 -1
- package/dist/preview/.next/server/app/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/app/preview/[...slug]/page.js +7 -6
- package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/chunks/196.js +5 -0
- package/dist/preview/.next/server/chunks/650.js +1 -0
- package/dist/preview/.next/server/chunks/720.js +3 -3
- package/dist/preview/.next/server/middleware-build-manifest.js +1 -1
- package/dist/preview/.next/server/next-font-manifest.js +1 -1
- package/dist/preview/.next/server/next-font-manifest.json +1 -1
- package/dist/preview/.next/server/pages/500.html +1 -1
- package/dist/preview/.next/server/server-reference-manifest.js +1 -1
- package/dist/preview/.next/server/server-reference-manifest.json +1 -1
- package/dist/preview/.next/static/chunks/154-ca55c1fde27d0922.js +1 -0
- package/dist/preview/.next/static/chunks/app/layout-7b9224888c7ffd05.js +1 -0
- package/dist/preview/.next/static/chunks/app/page-36853df2e13e583f.js +1 -0
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-48ce00470ce06446.js +1 -0
- package/dist/preview/.next/static/chunks/main-app-cd104297c6bcc87e.js +1 -0
- package/dist/preview/.next/static/css/{eb0a93282704d7ab.css → a34876a6c565fff8.css} +1 -1
- package/dist/preview/.next/trace +21 -20
- package/dist/preview/.next/types/app/layout.ts +1 -1
- package/dist/preview/.next/types/app/preview/[...slug]/page.ts +1 -1
- package/package.json +4 -8
- package/postcss.config.js +1 -1
- package/src/actions/get-email-path-from-slug.ts +7 -4
- package/src/actions/get-emails-directory-metadata-action.ts +19 -0
- package/src/actions/render-email-by-path.tsx +3 -3
- package/src/app/layout.tsx +2 -2
- package/src/app/page.tsx +1 -1
- package/src/app/preview/[...slug]/page.tsx +2 -2
- package/src/app/preview/[...slug]/preview.tsx +2 -2
- package/src/components/button.tsx +1 -1
- package/src/components/code-container.tsx +1 -1
- package/src/components/heading.tsx +1 -1
- package/src/components/sidebar/sidebar-directory-children.tsx +5 -8
- package/src/components/sidebar/sidebar-directory.tsx +2 -2
- package/src/components/sidebar/sidebar.tsx +2 -2
- package/src/components/text.tsx +1 -1
- package/src/components/tooltip-content.tsx +1 -1
- package/src/components/tooltip.tsx +1 -1
- package/src/components/topbar.tsx +1 -1
- package/src/contexts/emails.tsx +3 -5
- package/src/hooks/use-email-rendering-result.ts +2 -2
- package/src/utils/cn.ts +1 -1
- package/src/utils/esbuild/renderring-utilities-exporter.ts +1 -1
- package/src/utils/get-email-component.ts +6 -6
- package/src/{actions → utils}/get-emails-directory-metadata.spec.ts +1 -2
- package/src/utils/get-emails-directory-metadata.ts +119 -0
- package/src/utils/improve-error-with-sourcemap.ts +1 -1
- package/src/utils/static-node-modules-for-vm.ts +6 -6
- package/tsconfig.json +1 -6
- package/.eslintrc.js +0 -52
- package/.prettierignore +0 -3
- package/.prettierrc.js +0 -8
- package/dist/index.d.mts +0 -20
- package/dist/index.d.ts +0 -20
- package/dist/index.js +0 -96
- package/dist/index.mjs +0 -21
- package/dist/package/index.d.mts +0 -33
- package/dist/package/index.d.ts +0 -33
- package/dist/package/index.js +0 -62
- package/dist/package/index.mjs +0 -7
- package/dist/preview/.next/cache/eslint/.cache_1vyas3k +0 -1
- package/dist/preview/.next/server/chunks/420.js +0 -1
- package/dist/preview/.next/server/chunks/625.js +0 -5
- package/dist/preview/.next/static/chunks/154-69b91a0c2fd801b8.js +0 -1
- package/dist/preview/.next/static/chunks/app/layout-e1b6f1534cbbe5bd.js +0 -1
- package/dist/preview/.next/static/chunks/app/page-2c3e297e38c526ef.js +0 -1
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-2b4988ba6daf34e1.js +0 -1
- package/dist/preview/.next/static/chunks/main-app-2c7f96205a73f128.js +0 -1
- package/src/actions/get-emails-directory-metadata.ts +0 -123
- package/src/package/body/dist/index.d.mts +0 -6
- package/src/package/body/dist/index.d.ts +0 -6
- package/src/package/body/dist/index.js +0 -79
- package/src/package/body/dist/index.mjs +0 -45
- package/src/package/button/dist/index.d.mts +0 -6
- package/src/package/button/dist/index.d.ts +0 -6
- package/src/package/button/dist/index.js +0 -252
- package/src/package/button/dist/index.mjs +0 -218
- package/src/package/code-block/dist/index.d.mts +0 -4906
- package/src/package/code-block/dist/index.d.ts +0 -4906
- package/src/package/code-block/dist/index.js +0 -18205
- package/src/package/code-block/dist/index.mjs +0 -18133
- package/src/package/code-inline/dist/index.d.mts +0 -11
- package/src/package/code-inline/dist/index.d.ts +0 -11
- package/src/package/code-inline/dist/index.js +0 -106
- package/src/package/code-inline/dist/index.mjs +0 -72
- package/src/package/column/dist/index.d.mts +0 -6
- package/src/package/column/dist/index.d.ts +0 -6
- package/src/package/column/dist/index.js +0 -79
- package/src/package/column/dist/index.mjs +0 -45
- package/src/package/components/dist/index.d.mts +0 -20
- package/src/package/components/dist/index.d.ts +0 -20
- package/src/package/components/dist/index.js +0 -62
- package/src/package/components/dist/index.mjs +0 -21
- package/src/package/container/dist/index.d.mts +0 -6
- package/src/package/container/dist/index.d.ts +0 -6
- package/src/package/container/dist/index.js +0 -93
- package/src/package/container/dist/index.mjs +0 -59
- package/src/package/font/dist/index.d.mts +0 -25
- package/src/package/font/dist/index.d.ts +0 -25
- package/src/package/font/dist/index.js +0 -55
- package/src/package/font/dist/index.mjs +0 -28
- package/src/package/head/dist/index.d.mts +0 -6
- package/src/package/head/dist/index.d.ts +0 -6
- package/src/package/head/dist/index.js +0 -83
- package/src/package/head/dist/index.mjs +0 -49
- package/src/package/heading/dist/index.d.mts +0 -43
- package/src/package/heading/dist/index.d.ts +0 -43
- package/src/package/heading/dist/index.js +0 -113
- package/src/package/heading/dist/index.mjs +0 -79
- package/src/package/hr/dist/index.d.mts +0 -6
- package/src/package/hr/dist/index.d.ts +0 -6
- package/src/package/hr/dist/index.js +0 -89
- package/src/package/hr/dist/index.mjs +0 -55
- package/src/package/html/dist/index.d.mts +0 -6
- package/src/package/html/dist/index.d.ts +0 -6
- package/src/package/html/dist/index.js +0 -79
- package/src/package/html/dist/index.mjs +0 -45
- package/src/package/img/dist/index.d.mts +0 -6
- package/src/package/img/dist/index.d.ts +0 -6
- package/src/package/img/dist/index.js +0 -94
- package/src/package/img/dist/index.mjs +0 -60
- package/src/package/link/dist/index.d.mts +0 -6
- package/src/package/link/dist/index.d.ts +0 -6
- package/src/package/link/dist/index.js +0 -90
- package/src/package/link/dist/index.mjs +0 -56
- package/src/package/markdown/dist/index.d.mts +0 -15
- package/src/package/markdown/dist/index.d.ts +0 -15
- package/src/package/markdown/dist/index.js +0 -92
- package/src/package/markdown/dist/index.mjs +0 -58
- package/src/package/preview/dist/index.d.mts +0 -12
- package/src/package/preview/dist/index.d.ts +0 -12
- package/src/package/preview/dist/index.js +0 -108
- package/src/package/preview/dist/index.mjs +0 -73
- package/src/package/render/dist/browser/index.d.mts +0 -24
- package/src/package/render/dist/browser/index.d.ts +0 -24
- package/src/package/render/dist/browser/index.js +0 -250
- package/src/package/render/dist/browser/index.mjs +0 -214
- package/src/package/render/dist/index.d.mts +0 -23
- package/src/package/render/dist/index.d.ts +0 -23
- package/src/package/render/dist/index.js +0 -768
- package/src/package/render/dist/index.mjs +0 -733
- package/src/package/render/dist/node/index.d.mts +0 -27
- package/src/package/render/dist/node/index.d.ts +0 -27
- package/src/package/render/dist/node/index.js +0 -212
- package/src/package/render/dist/node/index.mjs +0 -176
- package/src/package/row/dist/index.d.mts +0 -10
- package/src/package/row/dist/index.d.ts +0 -10
- package/src/package/row/dist/index.js +0 -93
- package/src/package/row/dist/index.mjs +0 -59
- package/src/package/section/dist/index.d.mts +0 -6
- package/src/package/section/dist/index.d.ts +0 -6
- package/src/package/section/dist/index.js +0 -93
- package/src/package/section/dist/index.mjs +0 -59
- package/src/package/tailwind/dist/index.d.ts +0 -19
- package/src/package/tailwind/dist/index.js +0 -48
- package/src/package/tailwind/dist/index.mjs +0 -17167
- package/src/package/tailwind/dist/tailwindcss/config.d.ts +0 -376
- package/src/package/tailwind/dist/tailwindcss/generated/.gitkeep +0 -0
- package/src/package/tailwind/dist/tailwindcss/generated/colors.d.ts +0 -298
- package/src/package/tailwind/dist/tailwindcss/generated/corePluginList.d.ts +0 -1
- package/src/package/tailwind/dist/tailwindcss/generated/default-theme.d.ts +0 -397
- package/src/package/tailwind/dist/tailwindcss/index.d.ts +0 -11
- package/src/package/text/dist/index.d.mts +0 -6
- package/src/package/text/dist/index.d.ts +0 -6
- package/src/package/text/dist/index.js +0 -89
- package/src/package/text/dist/index.mjs +0 -55
- /package/dist/preview/.next/static/{6K68y2QEZ1dLbv-Xhi30p → 3Ni4t_kYMdpL72HxSPHgK}/_buildManifest.js +0 -0
- /package/dist/preview/.next/static/{6K68y2QEZ1dLbv-Xhi30p → 3Ni4t_kYMdpL72HxSPHgK}/_ssgManifest.js +0 -0
package/dist/cli/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { program } from "commander";
|
|
|
13
13
|
// package.json
|
|
14
14
|
var package_default = {
|
|
15
15
|
name: "react-email",
|
|
16
|
-
version: "3.0.
|
|
16
|
+
version: "3.0.7-canary.0",
|
|
17
17
|
description: "A live preview of your emails right in your browser.",
|
|
18
18
|
bin: {
|
|
19
19
|
email: "./dist/cli/index.js"
|
|
@@ -23,8 +23,7 @@ var package_default = {
|
|
|
23
23
|
dev: "tsup-node --watch",
|
|
24
24
|
test: "vitest run",
|
|
25
25
|
"test:watch": "vitest",
|
|
26
|
-
clean: "rm -rf dist"
|
|
27
|
-
lint: "eslint . && tsc"
|
|
26
|
+
clean: "rm -rf dist"
|
|
28
27
|
},
|
|
29
28
|
license: "MIT",
|
|
30
29
|
repository: {
|
|
@@ -32,10 +31,7 @@ var package_default = {
|
|
|
32
31
|
url: "https://github.com/resend/react-email.git",
|
|
33
32
|
directory: "packages/react-email"
|
|
34
33
|
},
|
|
35
|
-
keywords: [
|
|
36
|
-
"react",
|
|
37
|
-
"email"
|
|
38
|
-
],
|
|
34
|
+
keywords: ["react", "email"],
|
|
39
35
|
engines: {
|
|
40
36
|
node: ">=18.0.0"
|
|
41
37
|
},
|
|
@@ -46,7 +42,7 @@ var package_default = {
|
|
|
46
42
|
chokidar: "4.0.3",
|
|
47
43
|
commander: "11.1.0",
|
|
48
44
|
debounce: "2.0.0",
|
|
49
|
-
esbuild: "0.
|
|
45
|
+
esbuild: "0.23.0",
|
|
50
46
|
glob: "10.3.4",
|
|
51
47
|
"log-symbols": "4.1.0",
|
|
52
48
|
"mime-types": "2.1.35",
|
|
@@ -75,9 +71,6 @@ var package_default = {
|
|
|
75
71
|
"@vercel/style-guide": "5.1.0",
|
|
76
72
|
autoprefixer: "10.4.20",
|
|
77
73
|
clsx: "2.1.0",
|
|
78
|
-
eslint: "8.50.0",
|
|
79
|
-
"eslint-config-prettier": "9.0.0",
|
|
80
|
-
"eslint-config-turbo": "2.1.0",
|
|
81
74
|
"framer-motion": "12.0.0-alpha.2",
|
|
82
75
|
postcss: "8.4.40",
|
|
83
76
|
"prism-react-renderer": "2.1.0",
|
|
@@ -97,13 +90,112 @@ var package_default = {
|
|
|
97
90
|
}
|
|
98
91
|
};
|
|
99
92
|
|
|
100
|
-
// src/cli/commands/
|
|
101
|
-
import
|
|
93
|
+
// src/cli/commands/build.ts
|
|
94
|
+
import { spawn } from "node:child_process";
|
|
95
|
+
import fs5 from "node:fs";
|
|
96
|
+
import path8 from "node:path";
|
|
97
|
+
import logSymbols3 from "log-symbols";
|
|
98
|
+
import ora2 from "ora";
|
|
99
|
+
|
|
100
|
+
// src/utils/get-emails-directory-metadata.ts
|
|
101
|
+
import fs from "node:fs";
|
|
102
|
+
import path from "node:path";
|
|
103
|
+
var isFileAnEmail = (fullPath) => {
|
|
104
|
+
const stat = fs.statSync(fullPath);
|
|
105
|
+
if (stat.isDirectory())
|
|
106
|
+
return false;
|
|
107
|
+
const { ext } = path.parse(fullPath);
|
|
108
|
+
if (![".js", ".tsx", ".jsx"].includes(ext))
|
|
109
|
+
return false;
|
|
110
|
+
if (!fs.existsSync(fullPath)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
const fileContents = fs.readFileSync(fullPath, "utf8");
|
|
114
|
+
return /\bexport\s+default\b/gm.test(fileContents);
|
|
115
|
+
};
|
|
116
|
+
var mergeDirectoriesWithSubDirectories = (emailsDirectoryMetadata) => {
|
|
117
|
+
let currentResultingMergedDirectory = emailsDirectoryMetadata;
|
|
118
|
+
while (currentResultingMergedDirectory.emailFilenames.length === 0 && currentResultingMergedDirectory.subDirectories.length === 1) {
|
|
119
|
+
const onlySubDirectory = currentResultingMergedDirectory.subDirectories[0];
|
|
120
|
+
currentResultingMergedDirectory = {
|
|
121
|
+
...onlySubDirectory,
|
|
122
|
+
directoryName: path.join(
|
|
123
|
+
currentResultingMergedDirectory.directoryName,
|
|
124
|
+
onlySubDirectory.directoryName
|
|
125
|
+
)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return currentResultingMergedDirectory;
|
|
129
|
+
};
|
|
130
|
+
var getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFileExtensions = false, isSubDirectory = false, baseDirectoryPath = absolutePathToEmailsDirectory) => {
|
|
131
|
+
if (!fs.existsSync(absolutePathToEmailsDirectory))
|
|
132
|
+
return;
|
|
133
|
+
const dirents = await fs.promises.readdir(absolutePathToEmailsDirectory, {
|
|
134
|
+
withFileTypes: true
|
|
135
|
+
});
|
|
136
|
+
const emailFilenames = dirents.filter(
|
|
137
|
+
(dirent) => isFileAnEmail(path.join(absolutePathToEmailsDirectory, dirent.name))
|
|
138
|
+
).map(
|
|
139
|
+
(dirent) => keepFileExtensions ? dirent.name : dirent.name.replace(path.extname(dirent.name), "")
|
|
140
|
+
);
|
|
141
|
+
const subDirectories = await Promise.all(
|
|
142
|
+
dirents.filter(
|
|
143
|
+
(dirent) => dirent.isDirectory() && !dirent.name.startsWith("_") && dirent.name !== "static"
|
|
144
|
+
).map((dirent) => {
|
|
145
|
+
const direntAbsolutePath = path.join(
|
|
146
|
+
absolutePathToEmailsDirectory,
|
|
147
|
+
dirent.name
|
|
148
|
+
);
|
|
149
|
+
return getEmailsDirectoryMetadata(
|
|
150
|
+
direntAbsolutePath,
|
|
151
|
+
keepFileExtensions,
|
|
152
|
+
true,
|
|
153
|
+
baseDirectoryPath
|
|
154
|
+
);
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
const emailsMetadata = {
|
|
158
|
+
absolutePath: absolutePathToEmailsDirectory,
|
|
159
|
+
relativePath: path.relative(
|
|
160
|
+
baseDirectoryPath,
|
|
161
|
+
absolutePathToEmailsDirectory
|
|
162
|
+
),
|
|
163
|
+
directoryName: absolutePathToEmailsDirectory.split(path.sep).pop(),
|
|
164
|
+
emailFilenames,
|
|
165
|
+
subDirectories
|
|
166
|
+
};
|
|
167
|
+
return isSubDirectory ? mergeDirectoriesWithSubDirectories(emailsMetadata) : emailsMetadata;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// src/utils/register-spinner-autostopping.ts
|
|
171
|
+
import logSymbols from "log-symbols";
|
|
172
|
+
var spinners = /* @__PURE__ */ new Set();
|
|
173
|
+
process.on("SIGINT", () => {
|
|
174
|
+
spinners.forEach((spinner) => {
|
|
175
|
+
if (spinner.isSpinning) {
|
|
176
|
+
spinner.stop();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
process.on("exit", (code) => {
|
|
181
|
+
if (code !== 0) {
|
|
182
|
+
spinners.forEach((spinner) => {
|
|
183
|
+
if (spinner.isSpinning) {
|
|
184
|
+
spinner.stopAndPersist({
|
|
185
|
+
symbol: logSymbols.error
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
var registerSpinnerAutostopping = (spinner) => {
|
|
192
|
+
spinners.add(spinner);
|
|
193
|
+
};
|
|
102
194
|
|
|
103
195
|
// src/cli/utils/tree.ts
|
|
104
|
-
import { promises as
|
|
196
|
+
import { promises as fs2 } from "node:fs";
|
|
105
197
|
import os from "node:os";
|
|
106
|
-
import
|
|
198
|
+
import path2 from "node:path";
|
|
107
199
|
var SYMBOLS = {
|
|
108
200
|
BRANCH: "\u251C\u2500\u2500 ",
|
|
109
201
|
EMPTY: "",
|
|
@@ -113,12 +205,12 @@ var SYMBOLS = {
|
|
|
113
205
|
};
|
|
114
206
|
var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
|
|
115
207
|
const base = process.cwd();
|
|
116
|
-
const dirFullpath =
|
|
117
|
-
const dirname =
|
|
208
|
+
const dirFullpath = path2.resolve(base, dirPath);
|
|
209
|
+
const dirname = path2.basename(dirFullpath);
|
|
118
210
|
let lines = [dirname];
|
|
119
|
-
const dirStat = await
|
|
211
|
+
const dirStat = await fs2.stat(dirFullpath);
|
|
120
212
|
if (dirStat.isDirectory() && currentDepth < depth) {
|
|
121
|
-
const childDirents = await
|
|
213
|
+
const childDirents = await fs2.readdir(dirFullpath, { withFileTypes: true });
|
|
122
214
|
childDirents.sort((a, b) => {
|
|
123
215
|
if (a.isDirectory() && b.isFile()) {
|
|
124
216
|
return -1;
|
|
@@ -136,7 +228,7 @@ var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
|
|
|
136
228
|
if (dirent.isFile()) {
|
|
137
229
|
lines.push(`${branchingSymbol}${dirent.name}`);
|
|
138
230
|
} else {
|
|
139
|
-
const pathToDirectory =
|
|
231
|
+
const pathToDirectory = path2.join(dirFullpath, dirent.name);
|
|
140
232
|
const treeLinesForSubDirectory = await getTreeLines(
|
|
141
233
|
pathToDirectory,
|
|
142
234
|
depth,
|
|
@@ -158,98 +250,46 @@ var tree = async (dirPath, depth) => {
|
|
|
158
250
|
};
|
|
159
251
|
|
|
160
252
|
// src/cli/utils/preview/hot-reloading/setup-hot-reloading.ts
|
|
161
|
-
import
|
|
162
|
-
import { Server as SocketServer } from "socket.io";
|
|
253
|
+
import path7 from "node:path";
|
|
163
254
|
import { watch } from "chokidar";
|
|
164
255
|
import debounce from "debounce";
|
|
256
|
+
import { Server as SocketServer } from "socket.io";
|
|
165
257
|
|
|
166
258
|
// src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
|
|
167
|
-
import
|
|
168
|
-
import
|
|
169
|
-
|
|
170
|
-
// src/cli/utils/preview/hot-reloading/get-imported-modules.ts
|
|
171
|
-
import { traverse } from "@babel/core";
|
|
172
|
-
import { parse } from "@babel/parser";
|
|
173
|
-
var getImportedModules = (contents) => {
|
|
174
|
-
const importedPaths = [];
|
|
175
|
-
const parsedContents = parse(contents, {
|
|
176
|
-
sourceType: "unambiguous",
|
|
177
|
-
strictMode: false,
|
|
178
|
-
errorRecovery: true,
|
|
179
|
-
plugins: ["jsx", "typescript", "decorators"]
|
|
180
|
-
});
|
|
181
|
-
traverse(parsedContents, {
|
|
182
|
-
ImportDeclaration({ node }) {
|
|
183
|
-
importedPaths.push(node.source.value);
|
|
184
|
-
},
|
|
185
|
-
ExportAllDeclaration({ node }) {
|
|
186
|
-
importedPaths.push(node.source.value);
|
|
187
|
-
},
|
|
188
|
-
ExportNamedDeclaration({ node }) {
|
|
189
|
-
if (node.source) {
|
|
190
|
-
importedPaths.push(node.source.value);
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
CallExpression({ node }) {
|
|
194
|
-
if ("name" in node.callee && node.callee.name === "require") {
|
|
195
|
-
if (node.arguments.length === 1) {
|
|
196
|
-
const importPathNode = node.arguments[0];
|
|
197
|
-
if (importPathNode.type === "StringLiteral") {
|
|
198
|
-
importedPaths.push(importPathNode.value);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
return importedPaths;
|
|
205
|
-
};
|
|
259
|
+
import { promises as fs4, existsSync, statSync } from "node:fs";
|
|
260
|
+
import path6 from "node:path";
|
|
206
261
|
|
|
207
262
|
// src/cli/utils/preview/start-dev-server.ts
|
|
208
|
-
import path4 from "node:path";
|
|
209
263
|
import http from "node:http";
|
|
264
|
+
import path5 from "node:path";
|
|
210
265
|
import url from "node:url";
|
|
266
|
+
import chalk from "chalk";
|
|
267
|
+
import logSymbols2 from "log-symbols";
|
|
211
268
|
import next from "next";
|
|
212
269
|
import ora from "ora";
|
|
213
|
-
import logSymbols2 from "log-symbols";
|
|
214
|
-
import chalk from "chalk";
|
|
215
270
|
|
|
216
|
-
// src/utils/
|
|
217
|
-
import
|
|
218
|
-
var
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
process.on("exit", (code) => {
|
|
227
|
-
if (code !== 0) {
|
|
228
|
-
spinners.forEach((spinner) => {
|
|
229
|
-
if (spinner.isSpinning) {
|
|
230
|
-
spinner.stopAndPersist({
|
|
231
|
-
symbol: logSymbols.error
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
var registerSpinnerAutostopping = (spinner) => {
|
|
238
|
-
spinners.add(spinner);
|
|
271
|
+
// src/cli/utils/preview/get-env-variables-for-preview-app.ts
|
|
272
|
+
import path3 from "node:path";
|
|
273
|
+
var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
|
|
274
|
+
return {
|
|
275
|
+
EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
|
|
276
|
+
EMAILS_DIR_ABSOLUTE_PATH: path3.resolve(cwd, relativePathToEmailsDirectory),
|
|
277
|
+
USER_PROJECT_LOCATION: cwd
|
|
278
|
+
};
|
|
239
279
|
};
|
|
240
280
|
|
|
241
281
|
// src/cli/utils/preview/serve-static-file.ts
|
|
242
|
-
import
|
|
243
|
-
import
|
|
282
|
+
import { promises as fs3 } from "node:fs";
|
|
283
|
+
import path4 from "node:path";
|
|
244
284
|
import { lookup } from "mime-types";
|
|
245
285
|
var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
|
|
246
|
-
const staticBaseDir =
|
|
286
|
+
const staticBaseDir = path4.join(process.cwd(), staticDirRelativePath);
|
|
247
287
|
const pathname = parsedUrl.pathname;
|
|
248
|
-
const ext =
|
|
249
|
-
|
|
250
|
-
const fileHandle = await
|
|
288
|
+
const ext = path4.parse(pathname).ext;
|
|
289
|
+
const fileAbsolutePath = path4.join(staticBaseDir, pathname);
|
|
290
|
+
const fileHandle = await fs3.open(fileAbsolutePath, "r");
|
|
251
291
|
try {
|
|
252
|
-
const fileData = await
|
|
292
|
+
const fileData = await fs3.readFile(fileHandle);
|
|
253
293
|
res.setHeader("Content-type", lookup(ext) || "text/plain");
|
|
254
294
|
res.end(fileData);
|
|
255
295
|
} catch (exception) {
|
|
@@ -266,16 +306,6 @@ var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
|
|
|
266
306
|
}
|
|
267
307
|
};
|
|
268
308
|
|
|
269
|
-
// src/cli/utils/preview/get-env-variables-for-preview-app.ts
|
|
270
|
-
import path3 from "node:path";
|
|
271
|
-
var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
|
|
272
|
-
return {
|
|
273
|
-
EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
|
|
274
|
-
EMAILS_DIR_ABSOLUTE_PATH: path3.resolve(cwd, relativePathToEmailsDirectory),
|
|
275
|
-
USER_PROJECT_LOCATION: cwd
|
|
276
|
-
};
|
|
277
|
-
};
|
|
278
|
-
|
|
279
309
|
// src/cli/utils/preview/start-dev-server.ts
|
|
280
310
|
var devServer;
|
|
281
311
|
var safeAsyncServerListen = (server, port) => {
|
|
@@ -290,9 +320,9 @@ var safeAsyncServerListen = (server, port) => {
|
|
|
290
320
|
});
|
|
291
321
|
});
|
|
292
322
|
};
|
|
293
|
-
var isDev = !__filename.endsWith(
|
|
294
|
-
var cliPacakgeLocation = isDev ?
|
|
295
|
-
var previewServerLocation = isDev ?
|
|
323
|
+
var isDev = !__filename.endsWith(path5.join("cli", "index.js"));
|
|
324
|
+
var cliPacakgeLocation = isDev ? path5.resolve(__dirname, "../../../..") : path5.resolve(__dirname, "../..");
|
|
325
|
+
var previewServerLocation = isDev ? path5.resolve(__dirname, "../../../..") : path5.resolve(__dirname, "../preview");
|
|
296
326
|
var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
|
|
297
327
|
devServer = http.createServer((req, res) => {
|
|
298
328
|
if (!req.url) {
|
|
@@ -307,7 +337,7 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
|
|
|
307
337
|
res.setHeader("Pragma", "no-cache");
|
|
308
338
|
res.setHeader("Expires", "-1");
|
|
309
339
|
try {
|
|
310
|
-
if (parsedUrl.path
|
|
340
|
+
if (parsedUrl.path?.includes("static/") && !parsedUrl.path.includes("_next/static/")) {
|
|
311
341
|
void serveStaticFile(res, parsedUrl, staticBaseDirRelativePath);
|
|
312
342
|
} else if (!isNextReady) {
|
|
313
343
|
void nextReadyPromise.then(
|
|
@@ -355,11 +385,11 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
|
|
|
355
385
|
registerSpinnerAutostopping(spinner);
|
|
356
386
|
const timeBeforeNextReady = performance.now();
|
|
357
387
|
process.env = {
|
|
358
|
-
...process.env,
|
|
359
388
|
NODE_ENV: "development",
|
|
389
|
+
...process.env,
|
|
360
390
|
...getEnvVariablesForPreviewApp(
|
|
361
391
|
// If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
|
|
362
|
-
|
|
392
|
+
path5.normalize(emailsDirRelativePath),
|
|
363
393
|
process.cwd()
|
|
364
394
|
)
|
|
365
395
|
};
|
|
@@ -417,12 +447,49 @@ process.on(
|
|
|
417
447
|
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: true })
|
|
418
448
|
);
|
|
419
449
|
|
|
450
|
+
// src/cli/utils/preview/hot-reloading/get-imported-modules.ts
|
|
451
|
+
import { traverse } from "@babel/core";
|
|
452
|
+
import { parse } from "@babel/parser";
|
|
453
|
+
var getImportedModules = (contents) => {
|
|
454
|
+
const importedPaths = [];
|
|
455
|
+
const parsedContents = parse(contents, {
|
|
456
|
+
sourceType: "unambiguous",
|
|
457
|
+
strictMode: false,
|
|
458
|
+
errorRecovery: true,
|
|
459
|
+
plugins: ["jsx", "typescript", "decorators"]
|
|
460
|
+
});
|
|
461
|
+
traverse(parsedContents, {
|
|
462
|
+
ImportDeclaration({ node }) {
|
|
463
|
+
importedPaths.push(node.source.value);
|
|
464
|
+
},
|
|
465
|
+
ExportAllDeclaration({ node }) {
|
|
466
|
+
importedPaths.push(node.source.value);
|
|
467
|
+
},
|
|
468
|
+
ExportNamedDeclaration({ node }) {
|
|
469
|
+
if (node.source) {
|
|
470
|
+
importedPaths.push(node.source.value);
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
CallExpression({ node }) {
|
|
474
|
+
if ("name" in node.callee && node.callee.name === "require") {
|
|
475
|
+
if (node.arguments.length === 1) {
|
|
476
|
+
const importPathNode = node.arguments[0];
|
|
477
|
+
if (importPathNode.type === "StringLiteral") {
|
|
478
|
+
importedPaths.push(importPathNode.value);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
return importedPaths;
|
|
485
|
+
};
|
|
486
|
+
|
|
420
487
|
// src/cli/utils/preview/hot-reloading/create-dependency-graph.ts
|
|
421
488
|
var readAllFilesInsideDirectory = async (directory) => {
|
|
422
489
|
let allFilePaths = [];
|
|
423
|
-
const topLevelDirents = await
|
|
490
|
+
const topLevelDirents = await fs4.readdir(directory, { withFileTypes: true });
|
|
424
491
|
for await (const dirent of topLevelDirents) {
|
|
425
|
-
const pathToDirent =
|
|
492
|
+
const pathToDirent = path6.join(directory, dirent.name);
|
|
426
493
|
if (dirent.isDirectory()) {
|
|
427
494
|
allFilePaths = allFilePaths.concat(
|
|
428
495
|
await readAllFilesInsideDirectory(pathToDirent)
|
|
@@ -434,7 +501,7 @@ var readAllFilesInsideDirectory = async (directory) => {
|
|
|
434
501
|
return allFilePaths;
|
|
435
502
|
};
|
|
436
503
|
var isJavascriptModule = (filePath) => {
|
|
437
|
-
const extensionName =
|
|
504
|
+
const extensionName = path6.extname(filePath);
|
|
438
505
|
return [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(extensionName);
|
|
439
506
|
};
|
|
440
507
|
var checkFileExtensionsUntilItExists = (pathWithoutExtension) => {
|
|
@@ -472,64 +539,63 @@ var createDependencyGraph = async (directory) => {
|
|
|
472
539
|
])
|
|
473
540
|
);
|
|
474
541
|
const getDependencyPaths = async (filePath) => {
|
|
475
|
-
const contents = await
|
|
542
|
+
const contents = await fs4.readFile(filePath, "utf8");
|
|
476
543
|
const importedPaths = getImportedModules(contents);
|
|
477
544
|
const importedPathsRelativeToDirectory = importedPaths.map(
|
|
478
545
|
(dependencyPath) => {
|
|
479
546
|
const isModulePath = !dependencyPath.startsWith(".");
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
547
|
+
if (isModulePath || path6.isAbsolute(dependencyPath)) {
|
|
548
|
+
return dependencyPath;
|
|
549
|
+
}
|
|
550
|
+
let pathToDependencyFromDirectory = path6.resolve(
|
|
551
|
+
/*
|
|
552
|
+
path.resolve resolves paths differently from what imports on javascript do.
|
|
553
|
+
|
|
554
|
+
So if we wouldn't do this, for an email at "/path/to/email.tsx" with a dependecy path of "./other-email"
|
|
555
|
+
would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the
|
|
556
|
+
one the import is meant to go to
|
|
557
|
+
*/
|
|
558
|
+
path6.dirname(filePath),
|
|
559
|
+
dependencyPath
|
|
560
|
+
);
|
|
561
|
+
let isDirectory = false;
|
|
562
|
+
try {
|
|
563
|
+
isDirectory = statSync(pathToDependencyFromDirectory).isDirectory();
|
|
564
|
+
} catch (_) {
|
|
565
|
+
}
|
|
566
|
+
if (isDirectory) {
|
|
567
|
+
const pathToSubDirectory = pathToDependencyFromDirectory;
|
|
568
|
+
const pathWithExtension = checkFileExtensionsUntilItExists(
|
|
569
|
+
`${pathToSubDirectory}/index`
|
|
491
570
|
);
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (isDirectory) {
|
|
498
|
-
const pathToSubDirectory = pathToDependencyFromDirectory;
|
|
499
|
-
const pathWithExtension = checkFileExtensionsUntilItExists(
|
|
500
|
-
`${pathToSubDirectory}/index`
|
|
571
|
+
if (pathWithExtension) {
|
|
572
|
+
pathToDependencyFromDirectory = pathWithExtension;
|
|
573
|
+
} else if (isDev) {
|
|
574
|
+
console.warn(
|
|
575
|
+
`Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`
|
|
501
576
|
);
|
|
502
|
-
if (pathWithExtension) {
|
|
503
|
-
pathToDependencyFromDirectory = pathWithExtension;
|
|
504
|
-
} else if (isDev) {
|
|
505
|
-
console.warn(
|
|
506
|
-
`Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`
|
|
507
|
-
);
|
|
508
|
-
}
|
|
509
577
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
578
|
+
}
|
|
579
|
+
if (!isJavascriptModule(pathToDependencyFromDirectory)) {
|
|
580
|
+
const pathWithExtension = checkFileExtensionsUntilItExists(
|
|
581
|
+
pathToDependencyFromDirectory
|
|
582
|
+
);
|
|
583
|
+
if (pathWithExtension) {
|
|
584
|
+
pathToDependencyFromDirectory = pathWithExtension;
|
|
585
|
+
} else if (isDev) {
|
|
586
|
+
console.warn(
|
|
587
|
+
`Could not determine the file extension for the file at ${pathToDependencyFromDirectory}`
|
|
513
588
|
);
|
|
514
|
-
if (pathWithExtension) {
|
|
515
|
-
pathToDependencyFromDirectory = pathWithExtension;
|
|
516
|
-
} else if (isDev) {
|
|
517
|
-
console.warn(
|
|
518
|
-
`Could not determine the file extension for the file at ${pathToDependencyFromDirectory}`
|
|
519
|
-
);
|
|
520
|
-
}
|
|
521
589
|
}
|
|
522
|
-
return pathToDependencyFromDirectory;
|
|
523
|
-
} else {
|
|
524
|
-
return dependencyPath;
|
|
525
590
|
}
|
|
591
|
+
return pathToDependencyFromDirectory;
|
|
526
592
|
}
|
|
527
593
|
);
|
|
528
594
|
const moduleDependencies = importedPathsRelativeToDirectory.filter(
|
|
529
|
-
(dependencyPath) => !dependencyPath.startsWith(".") && !
|
|
595
|
+
(dependencyPath) => !dependencyPath.startsWith(".") && !path6.isAbsolute(dependencyPath)
|
|
530
596
|
);
|
|
531
597
|
const nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(
|
|
532
|
-
(dependencyPath) => dependencyPath.startsWith(".") ||
|
|
598
|
+
(dependencyPath) => dependencyPath.startsWith(".") || path6.isAbsolute(dependencyPath)
|
|
533
599
|
);
|
|
534
600
|
return {
|
|
535
601
|
dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory,
|
|
@@ -658,7 +724,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
658
724
|
});
|
|
659
725
|
changes = [];
|
|
660
726
|
}, 150);
|
|
661
|
-
const absolutePathToEmailsDirectory =
|
|
727
|
+
const absolutePathToEmailsDirectory = path7.resolve(
|
|
662
728
|
process.cwd(),
|
|
663
729
|
emailDirRelativePath
|
|
664
730
|
);
|
|
@@ -668,7 +734,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
668
734
|
cwd: absolutePathToEmailsDirectory
|
|
669
735
|
});
|
|
670
736
|
const getFilesOutsideEmailsDirectory = () => Object.keys(dependencyGraph).filter(
|
|
671
|
-
(p) =>
|
|
737
|
+
(p) => path7.relative(absolutePathToEmailsDirectory, p).startsWith("..")
|
|
672
738
|
);
|
|
673
739
|
let filesOutsideEmailsDirectory = getFilesOutsideEmailsDirectory();
|
|
674
740
|
for (const p of filesOutsideEmailsDirectory) {
|
|
@@ -680,11 +746,11 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
680
746
|
process.on("SIGINT", exit);
|
|
681
747
|
process.on("uncaughtException", exit);
|
|
682
748
|
watcher.on("all", async (event, relativePathToChangeTarget) => {
|
|
683
|
-
const file = relativePathToChangeTarget.split(
|
|
749
|
+
const file = relativePathToChangeTarget.split(path7.sep);
|
|
684
750
|
if (file.length === 0) {
|
|
685
751
|
return;
|
|
686
752
|
}
|
|
687
|
-
const pathToChangeTarget =
|
|
753
|
+
const pathToChangeTarget = path7.resolve(
|
|
688
754
|
absolutePathToEmailsDirectory,
|
|
689
755
|
relativePathToChangeTarget
|
|
690
756
|
);
|
|
@@ -708,7 +774,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
708
774
|
for (const dependentPath of resolveDependentsOf(pathToChangeTarget)) {
|
|
709
775
|
changes.push({
|
|
710
776
|
event: "change",
|
|
711
|
-
filename:
|
|
777
|
+
filename: path7.relative(absolutePathToEmailsDirectory, dependentPath)
|
|
712
778
|
});
|
|
713
779
|
}
|
|
714
780
|
reload();
|
|
@@ -716,111 +782,256 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
716
782
|
return watcher;
|
|
717
783
|
};
|
|
718
784
|
|
|
719
|
-
// src/cli/commands/
|
|
720
|
-
var
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
785
|
+
// src/cli/commands/build.ts
|
|
786
|
+
var buildPreviewApp = (absoluteDirectory) => {
|
|
787
|
+
return new Promise((resolve, reject) => {
|
|
788
|
+
const nextBuild = spawn("npm", ["run", "build"], {
|
|
789
|
+
cwd: absoluteDirectory,
|
|
790
|
+
shell: true
|
|
791
|
+
});
|
|
792
|
+
nextBuild.stdout.pipe(process.stdout);
|
|
793
|
+
nextBuild.stderr.pipe(process.stderr);
|
|
794
|
+
nextBuild.on("close", (code) => {
|
|
795
|
+
if (code === 0) {
|
|
796
|
+
resolve();
|
|
797
|
+
} else {
|
|
798
|
+
reject(
|
|
799
|
+
new Error(
|
|
800
|
+
`Unable to build the Next app and it exited with code: ${code}`
|
|
801
|
+
)
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
});
|
|
737
806
|
};
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
807
|
+
var setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath) => {
|
|
808
|
+
const nextConfigContents = `
|
|
809
|
+
const path = require('path');
|
|
810
|
+
const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
|
|
811
|
+
const userProjectLocation = path.resolve(process.cwd(), '../');
|
|
812
|
+
/** @type {import('next').NextConfig} */
|
|
813
|
+
module.exports = {
|
|
814
|
+
env: {
|
|
815
|
+
NEXT_PUBLIC_IS_BUILDING: 'true',
|
|
816
|
+
EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
|
|
817
|
+
EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
|
|
818
|
+
USER_PROJECT_LOCATION: userProjectLocation
|
|
819
|
+
},
|
|
820
|
+
// this is needed so that the code for building emails works properly
|
|
821
|
+
webpack: (
|
|
822
|
+
/** @type {import('webpack').Configuration & { externals: string[] }} */
|
|
823
|
+
config,
|
|
824
|
+
{ isServer }
|
|
825
|
+
) => {
|
|
826
|
+
if (isServer) {
|
|
827
|
+
config.externals.push('esbuild');
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
return config;
|
|
831
|
+
},
|
|
832
|
+
typescript: {
|
|
833
|
+
ignoreBuildErrors: true
|
|
834
|
+
},
|
|
835
|
+
eslint: {
|
|
836
|
+
ignoreDuringBuilds: true
|
|
837
|
+
},
|
|
838
|
+
experimental: {
|
|
839
|
+
webpackBuildWorker: true
|
|
840
|
+
},
|
|
841
|
+
}`;
|
|
842
|
+
await fs5.promises.writeFile(
|
|
843
|
+
path8.resolve(builtPreviewAppPath, "./next.config.js"),
|
|
844
|
+
nextConfigContents,
|
|
845
|
+
"utf8"
|
|
846
|
+
);
|
|
764
847
|
};
|
|
765
|
-
var
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
848
|
+
var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePath) => {
|
|
849
|
+
const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
|
|
850
|
+
const slugs = [];
|
|
851
|
+
emailDirectory.emailFilenames.forEach(
|
|
852
|
+
(filename) => slugs.push(
|
|
853
|
+
path8.join(directoryPathRelativeToEmailsDirectory, filename).split(path8.sep).filter((segment) => segment.length > 0)
|
|
854
|
+
)
|
|
855
|
+
);
|
|
856
|
+
emailDirectory.subDirectories.forEach((directory) => {
|
|
857
|
+
slugs.push(
|
|
858
|
+
...getEmailSlugsFromEmailDirectory(
|
|
859
|
+
directory,
|
|
860
|
+
emailsDirectoryAbsolutePath
|
|
774
861
|
)
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
return
|
|
862
|
+
);
|
|
863
|
+
});
|
|
864
|
+
return slugs;
|
|
778
865
|
};
|
|
779
|
-
var
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
866
|
+
var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
|
|
867
|
+
const emailDirectoryMetadata = (
|
|
868
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
869
|
+
await getEmailsDirectoryMetadata(emailsDirPath)
|
|
870
|
+
);
|
|
871
|
+
const parameters = getEmailSlugsFromEmailDirectory(
|
|
872
|
+
emailDirectoryMetadata,
|
|
873
|
+
emailsDirPath
|
|
874
|
+
).map((slug) => ({ slug }));
|
|
875
|
+
const removeForceDynamic = async (filePath) => {
|
|
876
|
+
const contents = await fs5.promises.readFile(filePath, "utf8");
|
|
877
|
+
await fs5.promises.writeFile(
|
|
878
|
+
filePath,
|
|
879
|
+
contents.replace("export const dynamic = 'force-dynamic';", ""),
|
|
880
|
+
"utf8"
|
|
790
881
|
);
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
882
|
+
};
|
|
883
|
+
await removeForceDynamic(
|
|
884
|
+
path8.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
|
|
885
|
+
);
|
|
886
|
+
await removeForceDynamic(
|
|
887
|
+
path8.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
|
|
888
|
+
);
|
|
889
|
+
await fs5.promises.appendFile(
|
|
890
|
+
path8.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
|
|
891
|
+
`
|
|
892
|
+
|
|
893
|
+
export function generateStaticParams() {
|
|
894
|
+
return Promise.resolve(
|
|
895
|
+
${JSON.stringify(parameters)}
|
|
896
|
+
);
|
|
897
|
+
}`,
|
|
898
|
+
"utf8"
|
|
899
|
+
);
|
|
900
|
+
};
|
|
901
|
+
var updatePackageJson = async (builtPreviewAppPath) => {
|
|
902
|
+
const packageJsonPath = path8.resolve(builtPreviewAppPath, "./package.json");
|
|
903
|
+
const packageJson = JSON.parse(
|
|
904
|
+
await fs5.promises.readFile(packageJsonPath, "utf8")
|
|
905
|
+
);
|
|
906
|
+
packageJson.scripts.build = "next build";
|
|
907
|
+
packageJson.scripts.start = "next start";
|
|
908
|
+
packageJson.name = "preview-server";
|
|
909
|
+
delete packageJson.devDependencies["@react-email/render"];
|
|
910
|
+
delete packageJson.devDependencies["@react-email/components"];
|
|
911
|
+
await fs5.promises.writeFile(
|
|
912
|
+
packageJsonPath,
|
|
913
|
+
JSON.stringify(packageJson),
|
|
914
|
+
"utf8"
|
|
915
|
+
);
|
|
916
|
+
};
|
|
917
|
+
var npmInstall = async (builtPreviewAppPath, packageManager) => {
|
|
918
|
+
return new Promise((resolve, reject) => {
|
|
919
|
+
const childProc = spawn(
|
|
920
|
+
packageManager,
|
|
921
|
+
["install", "--silent", "--include=dev"],
|
|
922
|
+
{
|
|
923
|
+
cwd: builtPreviewAppPath,
|
|
924
|
+
shell: true
|
|
925
|
+
}
|
|
926
|
+
);
|
|
927
|
+
childProc.stdout.pipe(process.stdout);
|
|
928
|
+
childProc.stderr.pipe(process.stderr);
|
|
929
|
+
childProc.on("close", (code) => {
|
|
930
|
+
if (code === 0) {
|
|
931
|
+
resolve();
|
|
932
|
+
} else {
|
|
933
|
+
reject(
|
|
934
|
+
new Error(
|
|
935
|
+
`Unable to install the dependencies and it exited with code: ${code}`
|
|
936
|
+
)
|
|
804
937
|
);
|
|
805
|
-
}
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
};
|
|
942
|
+
var build = async ({
|
|
943
|
+
dir: emailsDirRelativePath,
|
|
944
|
+
packageManager
|
|
945
|
+
}) => {
|
|
946
|
+
try {
|
|
947
|
+
const spinner = ora2({
|
|
948
|
+
text: "Starting build process...",
|
|
949
|
+
prefixText: " "
|
|
950
|
+
}).start();
|
|
951
|
+
registerSpinnerAutostopping(spinner);
|
|
952
|
+
spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
|
|
953
|
+
if (!fs5.existsSync(emailsDirRelativePath)) {
|
|
954
|
+
process.exit(1);
|
|
955
|
+
}
|
|
956
|
+
const emailsDirPath = path8.join(process.cwd(), emailsDirRelativePath);
|
|
957
|
+
const staticPath = path8.join(emailsDirPath, "static");
|
|
958
|
+
const builtPreviewAppPath = path8.join(process.cwd(), ".react-email");
|
|
959
|
+
if (fs5.existsSync(builtPreviewAppPath)) {
|
|
960
|
+
spinner.text = "Deleting pre-existing `.react-email` folder";
|
|
961
|
+
await fs5.promises.rm(builtPreviewAppPath, { recursive: true });
|
|
962
|
+
}
|
|
963
|
+
spinner.text = "Copying preview app from CLI to `.react-email`";
|
|
964
|
+
await fs5.promises.cp(cliPacakgeLocation, builtPreviewAppPath, {
|
|
965
|
+
recursive: true,
|
|
966
|
+
filter: (source) => {
|
|
967
|
+
return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
|
|
968
|
+
}
|
|
969
|
+
});
|
|
970
|
+
if (fs5.existsSync(staticPath)) {
|
|
971
|
+
spinner.text = "Copying `static` folder into `.react-email/public/static`";
|
|
972
|
+
const builtStaticDirectory = path8.resolve(
|
|
973
|
+
builtPreviewAppPath,
|
|
974
|
+
"./public/static"
|
|
975
|
+
);
|
|
976
|
+
await fs5.promises.cp(staticPath, builtStaticDirectory, {
|
|
977
|
+
recursive: true
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
spinner.text = "Setting Next environment variables for preview app to work properly";
|
|
981
|
+
await setNextEnvironmentVariablesForBuild(
|
|
982
|
+
emailsDirRelativePath,
|
|
983
|
+
builtPreviewAppPath
|
|
806
984
|
);
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
};
|
|
817
|
-
|
|
985
|
+
spinner.text = "Setting server side generation for the email preview pages";
|
|
986
|
+
await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
|
|
987
|
+
spinner.text = "Updating package.json's build and start scripts";
|
|
988
|
+
await updatePackageJson(builtPreviewAppPath);
|
|
989
|
+
spinner.text = "Installing dependencies on `.react-email`";
|
|
990
|
+
await npmInstall(builtPreviewAppPath, packageManager);
|
|
991
|
+
spinner.stopAndPersist({
|
|
992
|
+
text: "Successfully prepared `.react-email` for `next build`",
|
|
993
|
+
symbol: logSymbols3.success
|
|
994
|
+
});
|
|
995
|
+
await buildPreviewApp(builtPreviewAppPath);
|
|
996
|
+
} catch (error) {
|
|
997
|
+
console.log(error);
|
|
998
|
+
process.exit(1);
|
|
818
999
|
}
|
|
819
|
-
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
// src/cli/commands/dev.ts
|
|
1003
|
+
import fs6 from "node:fs";
|
|
1004
|
+
var dev = async ({ dir: emailsDirRelativePath, port }) => {
|
|
1005
|
+
try {
|
|
1006
|
+
if (!fs6.existsSync(emailsDirRelativePath)) {
|
|
1007
|
+
console.error(`Missing ${emailsDirRelativePath} folder`);
|
|
1008
|
+
process.exit(1);
|
|
1009
|
+
}
|
|
1010
|
+
const devServer2 = await startDevServer(
|
|
1011
|
+
emailsDirRelativePath,
|
|
1012
|
+
emailsDirRelativePath,
|
|
1013
|
+
// defaults to ./emails/static for the static files that are served to the preview
|
|
1014
|
+
Number.parseInt(port)
|
|
1015
|
+
);
|
|
1016
|
+
await setupHotreloading(devServer2, emailsDirRelativePath);
|
|
1017
|
+
} catch (error) {
|
|
1018
|
+
console.log(error);
|
|
1019
|
+
process.exit(1);
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
// src/cli/commands/export.ts
|
|
1024
|
+
import fs8, { unlinkSync, writeFileSync } from "node:fs";
|
|
1025
|
+
import path10 from "node:path";
|
|
1026
|
+
import { build as build2 } from "esbuild";
|
|
1027
|
+
import { glob } from "glob";
|
|
1028
|
+
import logSymbols4 from "log-symbols";
|
|
1029
|
+
import normalize from "normalize-path";
|
|
1030
|
+
import ora3 from "ora";
|
|
820
1031
|
|
|
821
1032
|
// src/utils/esbuild/renderring-utilities-exporter.ts
|
|
822
|
-
import
|
|
823
|
-
import
|
|
1033
|
+
import { promises as fs7 } from "node:fs";
|
|
1034
|
+
import path9 from "node:path";
|
|
824
1035
|
|
|
825
1036
|
// src/utils/esbuild/escape-string-for-regex.ts
|
|
826
1037
|
function escapeStringForRegex(string) {
|
|
@@ -839,11 +1050,11 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
|
|
|
839
1050
|
},
|
|
840
1051
|
async ({ path: pathToFile }) => {
|
|
841
1052
|
return {
|
|
842
|
-
contents: `${await
|
|
1053
|
+
contents: `${await fs7.readFile(pathToFile, "utf8")};
|
|
843
1054
|
export { render } from 'react-email-module-that-will-export-render'
|
|
844
1055
|
export { createElement as reactEmailCreateReactElement } from 'react';
|
|
845
1056
|
`,
|
|
846
|
-
loader:
|
|
1057
|
+
loader: path9.extname(pathToFile).slice(1)
|
|
847
1058
|
};
|
|
848
1059
|
}
|
|
849
1060
|
);
|
|
@@ -874,7 +1085,7 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
|
|
|
874
1085
|
var getEmailTemplatesFromDirectory = (emailDirectory) => {
|
|
875
1086
|
const templatePaths = [];
|
|
876
1087
|
emailDirectory.emailFilenames.forEach(
|
|
877
|
-
(filename) => templatePaths.push(
|
|
1088
|
+
(filename) => templatePaths.push(path10.join(emailDirectory.absolutePath, filename))
|
|
878
1089
|
);
|
|
879
1090
|
emailDirectory.subDirectories.forEach((directory) => {
|
|
880
1091
|
templatePaths.push(...getEmailTemplatesFromDirectory(directory));
|
|
@@ -882,22 +1093,22 @@ var getEmailTemplatesFromDirectory = (emailDirectory) => {
|
|
|
882
1093
|
return templatePaths;
|
|
883
1094
|
};
|
|
884
1095
|
var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
|
|
885
|
-
if (
|
|
886
|
-
|
|
1096
|
+
if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
|
|
1097
|
+
fs8.rmSync(pathToWhereEmailMarkupShouldBeDumped, { recursive: true });
|
|
887
1098
|
}
|
|
888
1099
|
let spinner;
|
|
889
1100
|
if (!options.silent) {
|
|
890
|
-
spinner =
|
|
1101
|
+
spinner = ora3("Preparing files...\n").start();
|
|
891
1102
|
registerSpinnerAutostopping(spinner);
|
|
892
1103
|
}
|
|
893
1104
|
const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
|
|
894
|
-
|
|
1105
|
+
path10.resolve(process.cwd(), emailsDirectoryPath),
|
|
895
1106
|
true
|
|
896
1107
|
);
|
|
897
1108
|
if (typeof emailsDirectoryMetadata === "undefined") {
|
|
898
1109
|
if (spinner) {
|
|
899
1110
|
spinner.stopAndPersist({
|
|
900
|
-
symbol:
|
|
1111
|
+
symbol: logSymbols4.error,
|
|
901
1112
|
text: `Could not find the directory at ${emailsDirectoryPath}`
|
|
902
1113
|
});
|
|
903
1114
|
}
|
|
@@ -905,7 +1116,7 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
|
|
|
905
1116
|
}
|
|
906
1117
|
const allTemplates = getEmailTemplatesFromDirectory(emailsDirectoryMetadata);
|
|
907
1118
|
try {
|
|
908
|
-
await
|
|
1119
|
+
await build2({
|
|
909
1120
|
bundle: true,
|
|
910
1121
|
entryPoints: allTemplates,
|
|
911
1122
|
plugins: [renderingUtilitiesExporter(allTemplates)],
|
|
@@ -921,7 +1132,7 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
|
|
|
921
1132
|
const buildFailure = exception;
|
|
922
1133
|
if (spinner) {
|
|
923
1134
|
spinner.stopAndPersist({
|
|
924
|
-
symbol:
|
|
1135
|
+
symbol: logSymbols4.error,
|
|
925
1136
|
text: "Failed to build emails"
|
|
926
1137
|
});
|
|
927
1138
|
}
|
|
@@ -957,7 +1168,7 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
|
|
|
957
1168
|
} catch (exception) {
|
|
958
1169
|
if (spinner) {
|
|
959
1170
|
spinner.stopAndPersist({
|
|
960
|
-
symbol:
|
|
1171
|
+
symbol: logSymbols4.error,
|
|
961
1172
|
text: `failed when rendering ${template.split("/").pop()}`
|
|
962
1173
|
});
|
|
963
1174
|
}
|
|
@@ -970,23 +1181,23 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
|
|
|
970
1181
|
spinner.text = "Copying static files";
|
|
971
1182
|
spinner.render();
|
|
972
1183
|
}
|
|
973
|
-
const staticDirectoryPath =
|
|
974
|
-
if (
|
|
975
|
-
const pathToDumpStaticFilesInto =
|
|
1184
|
+
const staticDirectoryPath = path10.join(emailsDirectoryPath, "static");
|
|
1185
|
+
if (fs8.existsSync(staticDirectoryPath)) {
|
|
1186
|
+
const pathToDumpStaticFilesInto = path10.join(
|
|
976
1187
|
pathToWhereEmailMarkupShouldBeDumped,
|
|
977
1188
|
"static"
|
|
978
1189
|
);
|
|
979
|
-
if (
|
|
980
|
-
await
|
|
1190
|
+
if (fs8.existsSync(pathToDumpStaticFilesInto))
|
|
1191
|
+
await fs8.promises.rm(pathToDumpStaticFilesInto, { recursive: true });
|
|
981
1192
|
try {
|
|
982
|
-
await
|
|
1193
|
+
await fs8.promises.cp(staticDirectoryPath, pathToDumpStaticFilesInto, {
|
|
983
1194
|
recursive: true
|
|
984
1195
|
});
|
|
985
1196
|
} catch (exception) {
|
|
986
1197
|
console.error(exception);
|
|
987
1198
|
if (spinner) {
|
|
988
1199
|
spinner.stopAndPersist({
|
|
989
|
-
symbol:
|
|
1200
|
+
symbol: logSymbols4.error,
|
|
990
1201
|
text: "Failed to copy static files"
|
|
991
1202
|
});
|
|
992
1203
|
}
|
|
@@ -1001,238 +1212,16 @@ var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirecto
|
|
|
1001
1212
|
const fileTree = await tree(pathToWhereEmailMarkupShouldBeDumped, 4);
|
|
1002
1213
|
console.log(fileTree);
|
|
1003
1214
|
spinner.stopAndPersist({
|
|
1004
|
-
symbol:
|
|
1215
|
+
symbol: logSymbols4.success,
|
|
1005
1216
|
text: "Successfully exported emails"
|
|
1006
1217
|
});
|
|
1007
1218
|
}
|
|
1008
1219
|
};
|
|
1009
1220
|
|
|
1010
|
-
// src/cli/commands/build.ts
|
|
1011
|
-
import fs8 from "node:fs";
|
|
1012
|
-
import path10 from "node:path";
|
|
1013
|
-
import ora3 from "ora";
|
|
1014
|
-
import { spawn } from "node:child_process";
|
|
1015
|
-
import logSymbols4 from "log-symbols";
|
|
1016
|
-
var buildPreviewApp = (absoluteDirectory) => {
|
|
1017
|
-
return new Promise((resolve, reject) => {
|
|
1018
|
-
const nextBuild = spawn("npm", ["run", "build"], {
|
|
1019
|
-
cwd: absoluteDirectory,
|
|
1020
|
-
shell: true
|
|
1021
|
-
});
|
|
1022
|
-
nextBuild.stdout.pipe(process.stdout);
|
|
1023
|
-
nextBuild.stderr.pipe(process.stderr);
|
|
1024
|
-
nextBuild.on("close", (code) => {
|
|
1025
|
-
if (code === 0) {
|
|
1026
|
-
resolve();
|
|
1027
|
-
} else {
|
|
1028
|
-
reject(
|
|
1029
|
-
new Error(
|
|
1030
|
-
`Unable to build the Next app and it exited with code: ${code}`
|
|
1031
|
-
)
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1034
|
-
});
|
|
1035
|
-
});
|
|
1036
|
-
};
|
|
1037
|
-
var setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath) => {
|
|
1038
|
-
const nextConfigContents = `
|
|
1039
|
-
const path = require('path');
|
|
1040
|
-
const emailsDirRelativePath = path.normalize('${emailsDirRelativePath}');
|
|
1041
|
-
const userProjectLocation = path.resolve(process.cwd(), '../');
|
|
1042
|
-
/** @type {import('next').NextConfig} */
|
|
1043
|
-
module.exports = {
|
|
1044
|
-
env: {
|
|
1045
|
-
NEXT_PUBLIC_IS_BUILDING: 'true',
|
|
1046
|
-
EMAILS_DIR_RELATIVE_PATH: emailsDirRelativePath,
|
|
1047
|
-
EMAILS_DIR_ABSOLUTE_PATH: path.resolve(userProjectLocation, emailsDirRelativePath),
|
|
1048
|
-
USER_PROJECT_LOCATION: userProjectLocation
|
|
1049
|
-
},
|
|
1050
|
-
// this is needed so that the code for building emails works properly
|
|
1051
|
-
webpack: (
|
|
1052
|
-
/** @type {import('webpack').Configuration & { externals: string[] }} */
|
|
1053
|
-
config,
|
|
1054
|
-
{ isServer }
|
|
1055
|
-
) => {
|
|
1056
|
-
if (isServer) {
|
|
1057
|
-
config.externals.push('esbuild');
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
return config;
|
|
1061
|
-
},
|
|
1062
|
-
typescript: {
|
|
1063
|
-
ignoreBuildErrors: true
|
|
1064
|
-
},
|
|
1065
|
-
eslint: {
|
|
1066
|
-
ignoreDuringBuilds: true
|
|
1067
|
-
},
|
|
1068
|
-
experimental: {
|
|
1069
|
-
webpackBuildWorker: true
|
|
1070
|
-
},
|
|
1071
|
-
}`;
|
|
1072
|
-
await fs8.promises.writeFile(
|
|
1073
|
-
path10.resolve(builtPreviewAppPath, "./next.config.js"),
|
|
1074
|
-
nextConfigContents,
|
|
1075
|
-
"utf8"
|
|
1076
|
-
);
|
|
1077
|
-
};
|
|
1078
|
-
var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePath) => {
|
|
1079
|
-
const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
|
|
1080
|
-
const slugs = [];
|
|
1081
|
-
emailDirectory.emailFilenames.forEach(
|
|
1082
|
-
(filename) => slugs.push(
|
|
1083
|
-
path10.join(directoryPathRelativeToEmailsDirectory, filename).split(path10.sep).filter((segment) => segment.length > 0)
|
|
1084
|
-
)
|
|
1085
|
-
);
|
|
1086
|
-
emailDirectory.subDirectories.forEach((directory) => {
|
|
1087
|
-
slugs.push(
|
|
1088
|
-
...getEmailSlugsFromEmailDirectory(
|
|
1089
|
-
directory,
|
|
1090
|
-
emailsDirectoryAbsolutePath
|
|
1091
|
-
)
|
|
1092
|
-
);
|
|
1093
|
-
});
|
|
1094
|
-
return slugs;
|
|
1095
|
-
};
|
|
1096
|
-
var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
|
|
1097
|
-
const emailDirectoryMetadata = (
|
|
1098
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1099
|
-
await getEmailsDirectoryMetadata(emailsDirPath)
|
|
1100
|
-
);
|
|
1101
|
-
const parameters = getEmailSlugsFromEmailDirectory(
|
|
1102
|
-
emailDirectoryMetadata,
|
|
1103
|
-
emailsDirPath
|
|
1104
|
-
).map((slug) => ({ slug }));
|
|
1105
|
-
const removeForceDynamic = async (filePath) => {
|
|
1106
|
-
const contents = await fs8.promises.readFile(filePath, "utf8");
|
|
1107
|
-
await fs8.promises.writeFile(
|
|
1108
|
-
filePath,
|
|
1109
|
-
contents.replace("export const dynamic = 'force-dynamic';", ""),
|
|
1110
|
-
"utf8"
|
|
1111
|
-
);
|
|
1112
|
-
};
|
|
1113
|
-
await removeForceDynamic(
|
|
1114
|
-
path10.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
|
|
1115
|
-
);
|
|
1116
|
-
await removeForceDynamic(
|
|
1117
|
-
path10.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
|
|
1118
|
-
);
|
|
1119
|
-
await fs8.promises.appendFile(
|
|
1120
|
-
path10.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
|
|
1121
|
-
`
|
|
1122
|
-
|
|
1123
|
-
export function generateStaticParams() {
|
|
1124
|
-
return Promise.resolve(
|
|
1125
|
-
${JSON.stringify(parameters)}
|
|
1126
|
-
);
|
|
1127
|
-
}`,
|
|
1128
|
-
"utf8"
|
|
1129
|
-
);
|
|
1130
|
-
};
|
|
1131
|
-
var updatePackageJson = async (builtPreviewAppPath) => {
|
|
1132
|
-
const packageJsonPath = path10.resolve(builtPreviewAppPath, "./package.json");
|
|
1133
|
-
const packageJson = JSON.parse(
|
|
1134
|
-
await fs8.promises.readFile(packageJsonPath, "utf8")
|
|
1135
|
-
);
|
|
1136
|
-
packageJson.scripts.build = "next build";
|
|
1137
|
-
packageJson.scripts.start = "next start";
|
|
1138
|
-
packageJson.name = "preview-server";
|
|
1139
|
-
delete packageJson.devDependencies["@react-email/render"];
|
|
1140
|
-
delete packageJson.devDependencies["@react-email/components"];
|
|
1141
|
-
await fs8.promises.writeFile(
|
|
1142
|
-
packageJsonPath,
|
|
1143
|
-
JSON.stringify(packageJson),
|
|
1144
|
-
"utf8"
|
|
1145
|
-
);
|
|
1146
|
-
};
|
|
1147
|
-
var npmInstall = async (builtPreviewAppPath, packageManager) => {
|
|
1148
|
-
return new Promise((resolve, reject) => {
|
|
1149
|
-
const childProc = spawn(
|
|
1150
|
-
packageManager,
|
|
1151
|
-
["install", "--silent", "--include=dev"],
|
|
1152
|
-
{
|
|
1153
|
-
cwd: builtPreviewAppPath,
|
|
1154
|
-
shell: true
|
|
1155
|
-
}
|
|
1156
|
-
);
|
|
1157
|
-
childProc.stdout.pipe(process.stdout);
|
|
1158
|
-
childProc.stderr.pipe(process.stderr);
|
|
1159
|
-
childProc.on("close", (code) => {
|
|
1160
|
-
if (code === 0) {
|
|
1161
|
-
resolve();
|
|
1162
|
-
} else {
|
|
1163
|
-
reject(
|
|
1164
|
-
new Error(
|
|
1165
|
-
`Unable to install the dependencies and it exited with code: ${code}`
|
|
1166
|
-
)
|
|
1167
|
-
);
|
|
1168
|
-
}
|
|
1169
|
-
});
|
|
1170
|
-
});
|
|
1171
|
-
};
|
|
1172
|
-
var build2 = async ({
|
|
1173
|
-
dir: emailsDirRelativePath,
|
|
1174
|
-
packageManager
|
|
1175
|
-
}) => {
|
|
1176
|
-
try {
|
|
1177
|
-
const spinner = ora3({
|
|
1178
|
-
text: "Starting build process...",
|
|
1179
|
-
prefixText: " "
|
|
1180
|
-
}).start();
|
|
1181
|
-
registerSpinnerAutostopping(spinner);
|
|
1182
|
-
spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
|
|
1183
|
-
if (!fs8.existsSync(emailsDirRelativePath)) {
|
|
1184
|
-
process.exit(1);
|
|
1185
|
-
}
|
|
1186
|
-
const emailsDirPath = path10.join(process.cwd(), emailsDirRelativePath);
|
|
1187
|
-
const staticPath = path10.join(emailsDirPath, "static");
|
|
1188
|
-
const builtPreviewAppPath = path10.join(process.cwd(), ".react-email");
|
|
1189
|
-
if (fs8.existsSync(builtPreviewAppPath)) {
|
|
1190
|
-
spinner.text = "Deleting pre-existing `.react-email` folder";
|
|
1191
|
-
await fs8.promises.rm(builtPreviewAppPath, { recursive: true });
|
|
1192
|
-
}
|
|
1193
|
-
spinner.text = "Copying preview app from CLI to `.react-email`";
|
|
1194
|
-
await fs8.promises.cp(cliPacakgeLocation, builtPreviewAppPath, {
|
|
1195
|
-
recursive: true,
|
|
1196
|
-
filter: (source) => {
|
|
1197
|
-
return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
|
|
1198
|
-
}
|
|
1199
|
-
});
|
|
1200
|
-
if (fs8.existsSync(staticPath)) {
|
|
1201
|
-
spinner.text = "Copying `static` folder into `.react-email/public/static`";
|
|
1202
|
-
const builtStaticDirectory = path10.resolve(
|
|
1203
|
-
builtPreviewAppPath,
|
|
1204
|
-
"./public/static"
|
|
1205
|
-
);
|
|
1206
|
-
await fs8.promises.cp(staticPath, builtStaticDirectory, {
|
|
1207
|
-
recursive: true
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
spinner.text = "Setting Next environment variables for preview app to work properly";
|
|
1211
|
-
await setNextEnvironmentVariablesForBuild(
|
|
1212
|
-
emailsDirRelativePath,
|
|
1213
|
-
builtPreviewAppPath
|
|
1214
|
-
);
|
|
1215
|
-
spinner.text = "Setting server side generation for the email preview pages";
|
|
1216
|
-
await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
|
|
1217
|
-
spinner.text = "Updating package.json's build and start scripts";
|
|
1218
|
-
await updatePackageJson(builtPreviewAppPath);
|
|
1219
|
-
spinner.text = "Installing dependencies on `.react-email`";
|
|
1220
|
-
await npmInstall(builtPreviewAppPath, packageManager);
|
|
1221
|
-
spinner.stopAndPersist({
|
|
1222
|
-
text: "Successfully prepared `.react-email` for `next build`",
|
|
1223
|
-
symbol: logSymbols4.success
|
|
1224
|
-
});
|
|
1225
|
-
await buildPreviewApp(builtPreviewAppPath);
|
|
1226
|
-
} catch (error) {
|
|
1227
|
-
console.log(error);
|
|
1228
|
-
process.exit(1);
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
|
|
1232
1221
|
// src/cli/commands/start.ts
|
|
1222
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
1233
1223
|
import fs9 from "node:fs";
|
|
1234
1224
|
import path11 from "node:path";
|
|
1235
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
1236
1225
|
var start = async () => {
|
|
1237
1226
|
try {
|
|
1238
1227
|
const usersProjectLocation = process.cwd();
|
|
@@ -1270,7 +1259,7 @@ program.command("build").description("Copies the preview app for onto .react-ema
|
|
|
1270
1259
|
"-p --packageManager <name>",
|
|
1271
1260
|
"Package name to use on installation on `.react-email`",
|
|
1272
1261
|
"npm"
|
|
1273
|
-
).action(
|
|
1262
|
+
).action(build);
|
|
1274
1263
|
program.command("start").description('Runs the built preview app that is inside of ".react-email"').action(start);
|
|
1275
1264
|
program.command("export").description("Build the templates to the `out` directory").option("--outDir <path>", "Output directory", "out").option("-p, --pretty", "Pretty print the output", false).option("-t, --plainText", "Set output format as plain text", false).option("-d, --dir <path>", "Directory with your email templates", "./emails").option(
|
|
1276
1265
|
"-s, --silent",
|