react-email 3.0.6 → 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 +7 -0
- package/dist/cli/index.js +761 -765
- package/dist/cli/index.mjs +473 -481
- package/dist/preview/.next/BUILD_ID +1 -1
- package/dist/preview/.next/app-build-manifest.json +6 -6
- package/dist/preview/.next/build-manifest.json +2 -2
- 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/server/app/_not-found/page.js +1 -1
- package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.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 +6 -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/{391.js → 650.js} +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-a2901ed1c2c53661.js → layout-7b9224888c7ffd05.js} +1 -1
- package/dist/preview/.next/static/chunks/app/{page-54a86772095e22e0.js → page-36853df2e13e583f.js} +1 -1
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-48ce00470ce06446.js +1 -0
- package/dist/preview/.next/static/css/{eb0a93282704d7ab.css → a34876a6c565fff8.css} +1 -1
- package/dist/preview/.next/trace +21 -21
- 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/render-email-by-path.tsx +3 -3
- package/src/app/layout.tsx +1 -1
- 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/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/utils/get-emails-directory-metadata.spec.ts +0 -1
- 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/preview/.next/cache/eslint/.cache_1c3sgg +0 -1
- package/dist/preview/.next/static/chunks/154-4202f86af36ccff4.js +0 -1
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-2bfad134b65ddd79.js +0 -1
- /package/dist/preview/.next/static/{Trk1e7GzgKOLunAXBDCy- → 3Ni4t_kYMdpL72HxSPHgK}/_buildManifest.js +0 -0
- /package/dist/preview/.next/static/{Trk1e7GzgKOLunAXBDCy- → 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,300 +782,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
716
782
|
return watcher;
|
|
717
783
|
};
|
|
718
784
|
|
|
719
|
-
// src/cli/commands/dev.ts
|
|
720
|
-
var dev = async ({ dir: emailsDirRelativePath, port }) => {
|
|
721
|
-
try {
|
|
722
|
-
if (!fs4.existsSync(emailsDirRelativePath)) {
|
|
723
|
-
console.error(`Missing ${emailsDirRelativePath} folder`);
|
|
724
|
-
process.exit(1);
|
|
725
|
-
}
|
|
726
|
-
const devServer2 = await startDevServer(
|
|
727
|
-
emailsDirRelativePath,
|
|
728
|
-
emailsDirRelativePath,
|
|
729
|
-
// defaults to ./emails/static for the static files that are served to the preview
|
|
730
|
-
Number.parseInt(port)
|
|
731
|
-
);
|
|
732
|
-
await setupHotreloading(devServer2, emailsDirRelativePath);
|
|
733
|
-
} catch (error) {
|
|
734
|
-
console.log(error);
|
|
735
|
-
process.exit(1);
|
|
736
|
-
}
|
|
737
|
-
};
|
|
738
|
-
|
|
739
|
-
// src/cli/commands/export.ts
|
|
740
|
-
import fs7, { unlinkSync, writeFileSync } from "node:fs";
|
|
741
|
-
import path9 from "node:path";
|
|
742
|
-
import { glob } from "glob";
|
|
743
|
-
import { build } from "esbuild";
|
|
744
|
-
import ora2 from "ora";
|
|
745
|
-
import logSymbols3 from "log-symbols";
|
|
746
|
-
import normalize from "normalize-path";
|
|
747
|
-
|
|
748
|
-
// src/utils/get-emails-directory-metadata.ts
|
|
749
|
-
import fs5 from "node:fs";
|
|
750
|
-
import path7 from "node:path";
|
|
751
|
-
var isFileAnEmail = (fullPath) => {
|
|
752
|
-
const stat = fs5.statSync(fullPath);
|
|
753
|
-
if (stat.isDirectory())
|
|
754
|
-
return false;
|
|
755
|
-
const { ext } = path7.parse(fullPath);
|
|
756
|
-
if (![".js", ".tsx", ".jsx"].includes(ext))
|
|
757
|
-
return false;
|
|
758
|
-
if (!fs5.existsSync(fullPath)) {
|
|
759
|
-
return false;
|
|
760
|
-
}
|
|
761
|
-
const fileContents = fs5.readFileSync(fullPath, "utf8");
|
|
762
|
-
return /\bexport\s+default\b/gm.test(fileContents);
|
|
763
|
-
};
|
|
764
|
-
var mergeDirectoriesWithSubDirectories = (emailsDirectoryMetadata) => {
|
|
765
|
-
let currentResultingMergedDirectory = emailsDirectoryMetadata;
|
|
766
|
-
while (currentResultingMergedDirectory.emailFilenames.length === 0 && currentResultingMergedDirectory.subDirectories.length === 1) {
|
|
767
|
-
const onlySubDirectory = currentResultingMergedDirectory.subDirectories[0];
|
|
768
|
-
currentResultingMergedDirectory = {
|
|
769
|
-
...onlySubDirectory,
|
|
770
|
-
directoryName: path7.join(
|
|
771
|
-
currentResultingMergedDirectory.directoryName,
|
|
772
|
-
onlySubDirectory.directoryName
|
|
773
|
-
)
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
return currentResultingMergedDirectory;
|
|
777
|
-
};
|
|
778
|
-
var getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFileExtensions = false, isSubDirectory = false, baseDirectoryPath = absolutePathToEmailsDirectory) => {
|
|
779
|
-
if (!fs5.existsSync(absolutePathToEmailsDirectory))
|
|
780
|
-
return;
|
|
781
|
-
const dirents = await fs5.promises.readdir(absolutePathToEmailsDirectory, {
|
|
782
|
-
withFileTypes: true
|
|
783
|
-
});
|
|
784
|
-
const emailFilenames = dirents.filter(
|
|
785
|
-
(dirent) => isFileAnEmail(path7.join(absolutePathToEmailsDirectory, dirent.name))
|
|
786
|
-
).map(
|
|
787
|
-
(dirent) => keepFileExtensions ? dirent.name : dirent.name.replace(path7.extname(dirent.name), "")
|
|
788
|
-
);
|
|
789
|
-
const subDirectories = await Promise.all(
|
|
790
|
-
dirents.filter(
|
|
791
|
-
(dirent) => dirent.isDirectory() && !dirent.name.startsWith("_") && dirent.name !== "static"
|
|
792
|
-
).map((dirent) => {
|
|
793
|
-
const direntAbsolutePath = path7.join(
|
|
794
|
-
absolutePathToEmailsDirectory,
|
|
795
|
-
dirent.name
|
|
796
|
-
);
|
|
797
|
-
return getEmailsDirectoryMetadata(
|
|
798
|
-
direntAbsolutePath,
|
|
799
|
-
keepFileExtensions,
|
|
800
|
-
true,
|
|
801
|
-
baseDirectoryPath
|
|
802
|
-
);
|
|
803
|
-
})
|
|
804
|
-
);
|
|
805
|
-
const emailsMetadata = {
|
|
806
|
-
absolutePath: absolutePathToEmailsDirectory,
|
|
807
|
-
relativePath: path7.relative(
|
|
808
|
-
baseDirectoryPath,
|
|
809
|
-
absolutePathToEmailsDirectory
|
|
810
|
-
),
|
|
811
|
-
directoryName: absolutePathToEmailsDirectory.split(path7.sep).pop(),
|
|
812
|
-
emailFilenames,
|
|
813
|
-
subDirectories
|
|
814
|
-
};
|
|
815
|
-
return isSubDirectory ? mergeDirectoriesWithSubDirectories(emailsMetadata) : emailsMetadata;
|
|
816
|
-
};
|
|
817
|
-
|
|
818
|
-
// src/utils/esbuild/renderring-utilities-exporter.ts
|
|
819
|
-
import path8 from "node:path";
|
|
820
|
-
import { promises as fs6 } from "node:fs";
|
|
821
|
-
|
|
822
|
-
// src/utils/esbuild/escape-string-for-regex.ts
|
|
823
|
-
function escapeStringForRegex(string) {
|
|
824
|
-
return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
// src/utils/esbuild/renderring-utilities-exporter.ts
|
|
828
|
-
var renderingUtilitiesExporter = (emailTemplates) => ({
|
|
829
|
-
name: "rendering-utilities-exporter",
|
|
830
|
-
setup: (b) => {
|
|
831
|
-
b.onLoad(
|
|
832
|
-
{
|
|
833
|
-
filter: new RegExp(
|
|
834
|
-
emailTemplates.map((emailPath) => escapeStringForRegex(emailPath)).join("|")
|
|
835
|
-
)
|
|
836
|
-
},
|
|
837
|
-
async ({ path: pathToFile }) => {
|
|
838
|
-
return {
|
|
839
|
-
contents: `${await fs6.readFile(pathToFile, "utf8")};
|
|
840
|
-
export { render } from 'react-email-module-that-will-export-render'
|
|
841
|
-
export { createElement as reactEmailCreateReactElement } from 'react';
|
|
842
|
-
`,
|
|
843
|
-
loader: path8.extname(pathToFile).slice(1)
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
);
|
|
847
|
-
b.onResolve(
|
|
848
|
-
{ filter: /^react-email-module-that-will-export-render$/ },
|
|
849
|
-
async (args) => {
|
|
850
|
-
const options = {
|
|
851
|
-
kind: "import-statement",
|
|
852
|
-
importer: args.importer,
|
|
853
|
-
resolveDir: args.resolveDir,
|
|
854
|
-
namespace: args.namespace
|
|
855
|
-
};
|
|
856
|
-
let result = await b.resolve("@react-email/render", options);
|
|
857
|
-
if (result.errors.length === 0) {
|
|
858
|
-
return result;
|
|
859
|
-
}
|
|
860
|
-
result = await b.resolve("@react-email/components", options);
|
|
861
|
-
if (result.errors.length > 0 && result.errors[0]) {
|
|
862
|
-
result.errors[0].text = "Failed trying to import `render` from either `@react-email/render` or `@react-email/components` to be able to render your email template.\n Maybe you don't have either of them installed?";
|
|
863
|
-
}
|
|
864
|
-
return result;
|
|
865
|
-
}
|
|
866
|
-
);
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
|
|
870
|
-
// src/cli/commands/export.ts
|
|
871
|
-
var getEmailTemplatesFromDirectory = (emailDirectory) => {
|
|
872
|
-
const templatePaths = [];
|
|
873
|
-
emailDirectory.emailFilenames.forEach(
|
|
874
|
-
(filename) => templatePaths.push(path9.join(emailDirectory.absolutePath, filename))
|
|
875
|
-
);
|
|
876
|
-
emailDirectory.subDirectories.forEach((directory) => {
|
|
877
|
-
templatePaths.push(...getEmailTemplatesFromDirectory(directory));
|
|
878
|
-
});
|
|
879
|
-
return templatePaths;
|
|
880
|
-
};
|
|
881
|
-
var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
|
|
882
|
-
if (fs7.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
|
|
883
|
-
fs7.rmSync(pathToWhereEmailMarkupShouldBeDumped, { recursive: true });
|
|
884
|
-
}
|
|
885
|
-
let spinner;
|
|
886
|
-
if (!options.silent) {
|
|
887
|
-
spinner = ora2("Preparing files...\n").start();
|
|
888
|
-
registerSpinnerAutostopping(spinner);
|
|
889
|
-
}
|
|
890
|
-
const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
|
|
891
|
-
path9.resolve(process.cwd(), emailsDirectoryPath),
|
|
892
|
-
true
|
|
893
|
-
);
|
|
894
|
-
if (typeof emailsDirectoryMetadata === "undefined") {
|
|
895
|
-
if (spinner) {
|
|
896
|
-
spinner.stopAndPersist({
|
|
897
|
-
symbol: logSymbols3.error,
|
|
898
|
-
text: `Could not find the directory at ${emailsDirectoryPath}`
|
|
899
|
-
});
|
|
900
|
-
}
|
|
901
|
-
return;
|
|
902
|
-
}
|
|
903
|
-
const allTemplates = getEmailTemplatesFromDirectory(emailsDirectoryMetadata);
|
|
904
|
-
try {
|
|
905
|
-
await build({
|
|
906
|
-
bundle: true,
|
|
907
|
-
entryPoints: allTemplates,
|
|
908
|
-
plugins: [renderingUtilitiesExporter(allTemplates)],
|
|
909
|
-
platform: "node",
|
|
910
|
-
format: "cjs",
|
|
911
|
-
loader: { ".js": "jsx" },
|
|
912
|
-
outExtension: { ".js": ".cjs" },
|
|
913
|
-
jsx: "transform",
|
|
914
|
-
write: true,
|
|
915
|
-
outdir: pathToWhereEmailMarkupShouldBeDumped
|
|
916
|
-
});
|
|
917
|
-
} catch (exception) {
|
|
918
|
-
const buildFailure = exception;
|
|
919
|
-
if (spinner) {
|
|
920
|
-
spinner.stopAndPersist({
|
|
921
|
-
symbol: logSymbols3.error,
|
|
922
|
-
text: "Failed to build emails"
|
|
923
|
-
});
|
|
924
|
-
}
|
|
925
|
-
process.exit(1);
|
|
926
|
-
}
|
|
927
|
-
if (spinner) {
|
|
928
|
-
spinner.succeed();
|
|
929
|
-
}
|
|
930
|
-
const allBuiltTemplates = glob.sync(
|
|
931
|
-
normalize(`${pathToWhereEmailMarkupShouldBeDumped}/**/*.cjs`),
|
|
932
|
-
{
|
|
933
|
-
absolute: true
|
|
934
|
-
}
|
|
935
|
-
);
|
|
936
|
-
for await (const template of allBuiltTemplates) {
|
|
937
|
-
try {
|
|
938
|
-
if (spinner) {
|
|
939
|
-
spinner.text = `rendering ${template.split("/").pop()}`;
|
|
940
|
-
spinner.render();
|
|
941
|
-
}
|
|
942
|
-
delete __require.cache[template];
|
|
943
|
-
const emailModule = __require(template);
|
|
944
|
-
const rendered = await emailModule.render(
|
|
945
|
-
emailModule.reactEmailCreateReactElement(emailModule.default, {}),
|
|
946
|
-
options
|
|
947
|
-
);
|
|
948
|
-
const htmlPath = template.replace(
|
|
949
|
-
".cjs",
|
|
950
|
-
options.plainText ? ".txt" : ".html"
|
|
951
|
-
);
|
|
952
|
-
writeFileSync(htmlPath, rendered);
|
|
953
|
-
unlinkSync(template);
|
|
954
|
-
} catch (exception) {
|
|
955
|
-
if (spinner) {
|
|
956
|
-
spinner.stopAndPersist({
|
|
957
|
-
symbol: logSymbols3.error,
|
|
958
|
-
text: `failed when rendering ${template.split("/").pop()}`
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
console.error(exception);
|
|
962
|
-
process.exit(1);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
if (spinner) {
|
|
966
|
-
spinner.succeed("Rendered all files");
|
|
967
|
-
spinner.text = "Copying static files";
|
|
968
|
-
spinner.render();
|
|
969
|
-
}
|
|
970
|
-
const staticDirectoryPath = path9.join(emailsDirectoryPath, "static");
|
|
971
|
-
if (fs7.existsSync(staticDirectoryPath)) {
|
|
972
|
-
const pathToDumpStaticFilesInto = path9.join(
|
|
973
|
-
pathToWhereEmailMarkupShouldBeDumped,
|
|
974
|
-
"static"
|
|
975
|
-
);
|
|
976
|
-
if (fs7.existsSync(pathToDumpStaticFilesInto))
|
|
977
|
-
await fs7.promises.rm(pathToDumpStaticFilesInto, { recursive: true });
|
|
978
|
-
try {
|
|
979
|
-
await fs7.promises.cp(staticDirectoryPath, pathToDumpStaticFilesInto, {
|
|
980
|
-
recursive: true
|
|
981
|
-
});
|
|
982
|
-
} catch (exception) {
|
|
983
|
-
console.error(exception);
|
|
984
|
-
if (spinner) {
|
|
985
|
-
spinner.stopAndPersist({
|
|
986
|
-
symbol: logSymbols3.error,
|
|
987
|
-
text: "Failed to copy static files"
|
|
988
|
-
});
|
|
989
|
-
}
|
|
990
|
-
console.error(
|
|
991
|
-
`Something went wrong while copying the file to ${pathToWhereEmailMarkupShouldBeDumped}/static, ${exception}`
|
|
992
|
-
);
|
|
993
|
-
process.exit(1);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
if (spinner && !options.silent) {
|
|
997
|
-
spinner.succeed();
|
|
998
|
-
const fileTree = await tree(pathToWhereEmailMarkupShouldBeDumped, 4);
|
|
999
|
-
console.log(fileTree);
|
|
1000
|
-
spinner.stopAndPersist({
|
|
1001
|
-
symbol: logSymbols3.success,
|
|
1002
|
-
text: "Successfully exported emails"
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
};
|
|
1006
|
-
|
|
1007
785
|
// src/cli/commands/build.ts
|
|
1008
|
-
import fs8 from "node:fs";
|
|
1009
|
-
import path10 from "node:path";
|
|
1010
|
-
import ora3 from "ora";
|
|
1011
|
-
import { spawn } from "node:child_process";
|
|
1012
|
-
import logSymbols4 from "log-symbols";
|
|
1013
786
|
var buildPreviewApp = (absoluteDirectory) => {
|
|
1014
787
|
return new Promise((resolve, reject) => {
|
|
1015
788
|
const nextBuild = spawn("npm", ["run", "build"], {
|
|
@@ -1066,8 +839,8 @@ module.exports = {
|
|
|
1066
839
|
webpackBuildWorker: true
|
|
1067
840
|
},
|
|
1068
841
|
}`;
|
|
1069
|
-
await
|
|
1070
|
-
|
|
842
|
+
await fs5.promises.writeFile(
|
|
843
|
+
path8.resolve(builtPreviewAppPath, "./next.config.js"),
|
|
1071
844
|
nextConfigContents,
|
|
1072
845
|
"utf8"
|
|
1073
846
|
);
|
|
@@ -1077,7 +850,7 @@ var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePa
|
|
|
1077
850
|
const slugs = [];
|
|
1078
851
|
emailDirectory.emailFilenames.forEach(
|
|
1079
852
|
(filename) => slugs.push(
|
|
1080
|
-
|
|
853
|
+
path8.join(directoryPathRelativeToEmailsDirectory, filename).split(path8.sep).filter((segment) => segment.length > 0)
|
|
1081
854
|
)
|
|
1082
855
|
);
|
|
1083
856
|
emailDirectory.subDirectories.forEach((directory) => {
|
|
@@ -1100,21 +873,21 @@ var forceSSGForEmailPreviews = async (emailsDirPath, builtPreviewAppPath) => {
|
|
|
1100
873
|
emailsDirPath
|
|
1101
874
|
).map((slug) => ({ slug }));
|
|
1102
875
|
const removeForceDynamic = async (filePath) => {
|
|
1103
|
-
const contents = await
|
|
1104
|
-
await
|
|
876
|
+
const contents = await fs5.promises.readFile(filePath, "utf8");
|
|
877
|
+
await fs5.promises.writeFile(
|
|
1105
878
|
filePath,
|
|
1106
879
|
contents.replace("export const dynamic = 'force-dynamic';", ""),
|
|
1107
880
|
"utf8"
|
|
1108
881
|
);
|
|
1109
882
|
};
|
|
1110
883
|
await removeForceDynamic(
|
|
1111
|
-
|
|
884
|
+
path8.resolve(builtPreviewAppPath, "./src/app/layout.tsx")
|
|
1112
885
|
);
|
|
1113
886
|
await removeForceDynamic(
|
|
1114
|
-
|
|
887
|
+
path8.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx")
|
|
1115
888
|
);
|
|
1116
|
-
await
|
|
1117
|
-
|
|
889
|
+
await fs5.promises.appendFile(
|
|
890
|
+
path8.resolve(builtPreviewAppPath, "./src/app/preview/[...slug]/page.tsx"),
|
|
1118
891
|
`
|
|
1119
892
|
|
|
1120
893
|
export function generateStaticParams() {
|
|
@@ -1126,16 +899,16 @@ export function generateStaticParams() {
|
|
|
1126
899
|
);
|
|
1127
900
|
};
|
|
1128
901
|
var updatePackageJson = async (builtPreviewAppPath) => {
|
|
1129
|
-
const packageJsonPath =
|
|
902
|
+
const packageJsonPath = path8.resolve(builtPreviewAppPath, "./package.json");
|
|
1130
903
|
const packageJson = JSON.parse(
|
|
1131
|
-
await
|
|
904
|
+
await fs5.promises.readFile(packageJsonPath, "utf8")
|
|
1132
905
|
);
|
|
1133
906
|
packageJson.scripts.build = "next build";
|
|
1134
907
|
packageJson.scripts.start = "next start";
|
|
1135
908
|
packageJson.name = "preview-server";
|
|
1136
909
|
delete packageJson.devDependencies["@react-email/render"];
|
|
1137
910
|
delete packageJson.devDependencies["@react-email/components"];
|
|
1138
|
-
await
|
|
911
|
+
await fs5.promises.writeFile(
|
|
1139
912
|
packageJsonPath,
|
|
1140
913
|
JSON.stringify(packageJson),
|
|
1141
914
|
"utf8"
|
|
@@ -1166,41 +939,41 @@ var npmInstall = async (builtPreviewAppPath, packageManager) => {
|
|
|
1166
939
|
});
|
|
1167
940
|
});
|
|
1168
941
|
};
|
|
1169
|
-
var
|
|
942
|
+
var build = async ({
|
|
1170
943
|
dir: emailsDirRelativePath,
|
|
1171
944
|
packageManager
|
|
1172
945
|
}) => {
|
|
1173
946
|
try {
|
|
1174
|
-
const spinner =
|
|
947
|
+
const spinner = ora2({
|
|
1175
948
|
text: "Starting build process...",
|
|
1176
949
|
prefixText: " "
|
|
1177
950
|
}).start();
|
|
1178
951
|
registerSpinnerAutostopping(spinner);
|
|
1179
952
|
spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
|
|
1180
|
-
if (!
|
|
953
|
+
if (!fs5.existsSync(emailsDirRelativePath)) {
|
|
1181
954
|
process.exit(1);
|
|
1182
955
|
}
|
|
1183
|
-
const emailsDirPath =
|
|
1184
|
-
const staticPath =
|
|
1185
|
-
const builtPreviewAppPath =
|
|
1186
|
-
if (
|
|
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)) {
|
|
1187
960
|
spinner.text = "Deleting pre-existing `.react-email` folder";
|
|
1188
|
-
await
|
|
961
|
+
await fs5.promises.rm(builtPreviewAppPath, { recursive: true });
|
|
1189
962
|
}
|
|
1190
963
|
spinner.text = "Copying preview app from CLI to `.react-email`";
|
|
1191
|
-
await
|
|
964
|
+
await fs5.promises.cp(cliPacakgeLocation, builtPreviewAppPath, {
|
|
1192
965
|
recursive: true,
|
|
1193
966
|
filter: (source) => {
|
|
1194
967
|
return !/(\/|\\)cli(\/|\\)?/.test(source) && !/(\/|\\)\.next(\/|\\)?/.test(source) && !/(\/|\\)\.turbo(\/|\\)?/.test(source) && !/(\/|\\)node_modules(\/|\\)?$/.test(source);
|
|
1195
968
|
}
|
|
1196
969
|
});
|
|
1197
|
-
if (
|
|
970
|
+
if (fs5.existsSync(staticPath)) {
|
|
1198
971
|
spinner.text = "Copying `static` folder into `.react-email/public/static`";
|
|
1199
|
-
const builtStaticDirectory =
|
|
972
|
+
const builtStaticDirectory = path8.resolve(
|
|
1200
973
|
builtPreviewAppPath,
|
|
1201
974
|
"./public/static"
|
|
1202
975
|
);
|
|
1203
|
-
await
|
|
976
|
+
await fs5.promises.cp(staticPath, builtStaticDirectory, {
|
|
1204
977
|
recursive: true
|
|
1205
978
|
});
|
|
1206
979
|
}
|
|
@@ -1217,7 +990,7 @@ var build2 = async ({
|
|
|
1217
990
|
await npmInstall(builtPreviewAppPath, packageManager);
|
|
1218
991
|
spinner.stopAndPersist({
|
|
1219
992
|
text: "Successfully prepared `.react-email` for `next build`",
|
|
1220
|
-
symbol:
|
|
993
|
+
symbol: logSymbols3.success
|
|
1221
994
|
});
|
|
1222
995
|
await buildPreviewApp(builtPreviewAppPath);
|
|
1223
996
|
} catch (error) {
|
|
@@ -1226,10 +999,229 @@ var build2 = async ({
|
|
|
1226
999
|
}
|
|
1227
1000
|
};
|
|
1228
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";
|
|
1031
|
+
|
|
1032
|
+
// src/utils/esbuild/renderring-utilities-exporter.ts
|
|
1033
|
+
import { promises as fs7 } from "node:fs";
|
|
1034
|
+
import path9 from "node:path";
|
|
1035
|
+
|
|
1036
|
+
// src/utils/esbuild/escape-string-for-regex.ts
|
|
1037
|
+
function escapeStringForRegex(string) {
|
|
1038
|
+
return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// src/utils/esbuild/renderring-utilities-exporter.ts
|
|
1042
|
+
var renderingUtilitiesExporter = (emailTemplates) => ({
|
|
1043
|
+
name: "rendering-utilities-exporter",
|
|
1044
|
+
setup: (b) => {
|
|
1045
|
+
b.onLoad(
|
|
1046
|
+
{
|
|
1047
|
+
filter: new RegExp(
|
|
1048
|
+
emailTemplates.map((emailPath) => escapeStringForRegex(emailPath)).join("|")
|
|
1049
|
+
)
|
|
1050
|
+
},
|
|
1051
|
+
async ({ path: pathToFile }) => {
|
|
1052
|
+
return {
|
|
1053
|
+
contents: `${await fs7.readFile(pathToFile, "utf8")};
|
|
1054
|
+
export { render } from 'react-email-module-that-will-export-render'
|
|
1055
|
+
export { createElement as reactEmailCreateReactElement } from 'react';
|
|
1056
|
+
`,
|
|
1057
|
+
loader: path9.extname(pathToFile).slice(1)
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
);
|
|
1061
|
+
b.onResolve(
|
|
1062
|
+
{ filter: /^react-email-module-that-will-export-render$/ },
|
|
1063
|
+
async (args) => {
|
|
1064
|
+
const options = {
|
|
1065
|
+
kind: "import-statement",
|
|
1066
|
+
importer: args.importer,
|
|
1067
|
+
resolveDir: args.resolveDir,
|
|
1068
|
+
namespace: args.namespace
|
|
1069
|
+
};
|
|
1070
|
+
let result = await b.resolve("@react-email/render", options);
|
|
1071
|
+
if (result.errors.length === 0) {
|
|
1072
|
+
return result;
|
|
1073
|
+
}
|
|
1074
|
+
result = await b.resolve("@react-email/components", options);
|
|
1075
|
+
if (result.errors.length > 0 && result.errors[0]) {
|
|
1076
|
+
result.errors[0].text = "Failed trying to import `render` from either `@react-email/render` or `@react-email/components` to be able to render your email template.\n Maybe you don't have either of them installed?";
|
|
1077
|
+
}
|
|
1078
|
+
return result;
|
|
1079
|
+
}
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
// src/cli/commands/export.ts
|
|
1085
|
+
var getEmailTemplatesFromDirectory = (emailDirectory) => {
|
|
1086
|
+
const templatePaths = [];
|
|
1087
|
+
emailDirectory.emailFilenames.forEach(
|
|
1088
|
+
(filename) => templatePaths.push(path10.join(emailDirectory.absolutePath, filename))
|
|
1089
|
+
);
|
|
1090
|
+
emailDirectory.subDirectories.forEach((directory) => {
|
|
1091
|
+
templatePaths.push(...getEmailTemplatesFromDirectory(directory));
|
|
1092
|
+
});
|
|
1093
|
+
return templatePaths;
|
|
1094
|
+
};
|
|
1095
|
+
var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
|
|
1096
|
+
if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
|
|
1097
|
+
fs8.rmSync(pathToWhereEmailMarkupShouldBeDumped, { recursive: true });
|
|
1098
|
+
}
|
|
1099
|
+
let spinner;
|
|
1100
|
+
if (!options.silent) {
|
|
1101
|
+
spinner = ora3("Preparing files...\n").start();
|
|
1102
|
+
registerSpinnerAutostopping(spinner);
|
|
1103
|
+
}
|
|
1104
|
+
const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
|
|
1105
|
+
path10.resolve(process.cwd(), emailsDirectoryPath),
|
|
1106
|
+
true
|
|
1107
|
+
);
|
|
1108
|
+
if (typeof emailsDirectoryMetadata === "undefined") {
|
|
1109
|
+
if (spinner) {
|
|
1110
|
+
spinner.stopAndPersist({
|
|
1111
|
+
symbol: logSymbols4.error,
|
|
1112
|
+
text: `Could not find the directory at ${emailsDirectoryPath}`
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
const allTemplates = getEmailTemplatesFromDirectory(emailsDirectoryMetadata);
|
|
1118
|
+
try {
|
|
1119
|
+
await build2({
|
|
1120
|
+
bundle: true,
|
|
1121
|
+
entryPoints: allTemplates,
|
|
1122
|
+
plugins: [renderingUtilitiesExporter(allTemplates)],
|
|
1123
|
+
platform: "node",
|
|
1124
|
+
format: "cjs",
|
|
1125
|
+
loader: { ".js": "jsx" },
|
|
1126
|
+
outExtension: { ".js": ".cjs" },
|
|
1127
|
+
jsx: "transform",
|
|
1128
|
+
write: true,
|
|
1129
|
+
outdir: pathToWhereEmailMarkupShouldBeDumped
|
|
1130
|
+
});
|
|
1131
|
+
} catch (exception) {
|
|
1132
|
+
const buildFailure = exception;
|
|
1133
|
+
if (spinner) {
|
|
1134
|
+
spinner.stopAndPersist({
|
|
1135
|
+
symbol: logSymbols4.error,
|
|
1136
|
+
text: "Failed to build emails"
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
process.exit(1);
|
|
1140
|
+
}
|
|
1141
|
+
if (spinner) {
|
|
1142
|
+
spinner.succeed();
|
|
1143
|
+
}
|
|
1144
|
+
const allBuiltTemplates = glob.sync(
|
|
1145
|
+
normalize(`${pathToWhereEmailMarkupShouldBeDumped}/**/*.cjs`),
|
|
1146
|
+
{
|
|
1147
|
+
absolute: true
|
|
1148
|
+
}
|
|
1149
|
+
);
|
|
1150
|
+
for await (const template of allBuiltTemplates) {
|
|
1151
|
+
try {
|
|
1152
|
+
if (spinner) {
|
|
1153
|
+
spinner.text = `rendering ${template.split("/").pop()}`;
|
|
1154
|
+
spinner.render();
|
|
1155
|
+
}
|
|
1156
|
+
delete __require.cache[template];
|
|
1157
|
+
const emailModule = __require(template);
|
|
1158
|
+
const rendered = await emailModule.render(
|
|
1159
|
+
emailModule.reactEmailCreateReactElement(emailModule.default, {}),
|
|
1160
|
+
options
|
|
1161
|
+
);
|
|
1162
|
+
const htmlPath = template.replace(
|
|
1163
|
+
".cjs",
|
|
1164
|
+
options.plainText ? ".txt" : ".html"
|
|
1165
|
+
);
|
|
1166
|
+
writeFileSync(htmlPath, rendered);
|
|
1167
|
+
unlinkSync(template);
|
|
1168
|
+
} catch (exception) {
|
|
1169
|
+
if (spinner) {
|
|
1170
|
+
spinner.stopAndPersist({
|
|
1171
|
+
symbol: logSymbols4.error,
|
|
1172
|
+
text: `failed when rendering ${template.split("/").pop()}`
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
console.error(exception);
|
|
1176
|
+
process.exit(1);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
if (spinner) {
|
|
1180
|
+
spinner.succeed("Rendered all files");
|
|
1181
|
+
spinner.text = "Copying static files";
|
|
1182
|
+
spinner.render();
|
|
1183
|
+
}
|
|
1184
|
+
const staticDirectoryPath = path10.join(emailsDirectoryPath, "static");
|
|
1185
|
+
if (fs8.existsSync(staticDirectoryPath)) {
|
|
1186
|
+
const pathToDumpStaticFilesInto = path10.join(
|
|
1187
|
+
pathToWhereEmailMarkupShouldBeDumped,
|
|
1188
|
+
"static"
|
|
1189
|
+
);
|
|
1190
|
+
if (fs8.existsSync(pathToDumpStaticFilesInto))
|
|
1191
|
+
await fs8.promises.rm(pathToDumpStaticFilesInto, { recursive: true });
|
|
1192
|
+
try {
|
|
1193
|
+
await fs8.promises.cp(staticDirectoryPath, pathToDumpStaticFilesInto, {
|
|
1194
|
+
recursive: true
|
|
1195
|
+
});
|
|
1196
|
+
} catch (exception) {
|
|
1197
|
+
console.error(exception);
|
|
1198
|
+
if (spinner) {
|
|
1199
|
+
spinner.stopAndPersist({
|
|
1200
|
+
symbol: logSymbols4.error,
|
|
1201
|
+
text: "Failed to copy static files"
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
console.error(
|
|
1205
|
+
`Something went wrong while copying the file to ${pathToWhereEmailMarkupShouldBeDumped}/static, ${exception}`
|
|
1206
|
+
);
|
|
1207
|
+
process.exit(1);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
if (spinner && !options.silent) {
|
|
1211
|
+
spinner.succeed();
|
|
1212
|
+
const fileTree = await tree(pathToWhereEmailMarkupShouldBeDumped, 4);
|
|
1213
|
+
console.log(fileTree);
|
|
1214
|
+
spinner.stopAndPersist({
|
|
1215
|
+
symbol: logSymbols4.success,
|
|
1216
|
+
text: "Successfully exported emails"
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1229
1221
|
// src/cli/commands/start.ts
|
|
1222
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
1230
1223
|
import fs9 from "node:fs";
|
|
1231
1224
|
import path11 from "node:path";
|
|
1232
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
1233
1225
|
var start = async () => {
|
|
1234
1226
|
try {
|
|
1235
1227
|
const usersProjectLocation = process.cwd();
|
|
@@ -1267,7 +1259,7 @@ program.command("build").description("Copies the preview app for onto .react-ema
|
|
|
1267
1259
|
"-p --packageManager <name>",
|
|
1268
1260
|
"Package name to use on installation on `.react-email`",
|
|
1269
1261
|
"npm"
|
|
1270
|
-
).action(
|
|
1262
|
+
).action(build);
|
|
1271
1263
|
program.command("start").description('Runs the built preview app that is inside of ".react-email"').action(start);
|
|
1272
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(
|
|
1273
1265
|
"-s, --silent",
|