react-email 4.1.0-canary.9 → 4.1.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 +38 -0
- package/dev/CHANGELOG.md +3 -0
- package/dev/index.js +44 -0
- package/dev/package.json +13 -0
- package/dist/cli/index.mjs +1391 -0
- package/dist/index.js +256 -259
- package/dist/preview/.next/BUILD_ID +1 -0
- package/dist/preview/.next/app-build-manifest.json +44 -0
- package/dist/preview/.next/app-path-routes-manifest.json +6 -0
- package/dist/preview/.next/build-manifest.json +33 -0
- package/dist/preview/.next/diagnostics/build-diagnostics.json +6 -0
- package/dist/preview/.next/diagnostics/framework.json +1 -0
- package/dist/preview/.next/export-marker.json +6 -0
- package/dist/preview/.next/images-manifest.json +57 -0
- package/dist/preview/.next/next-minimal-server.js.nft.json +1 -0
- package/dist/preview/.next/next-server.js.nft.json +1 -0
- package/dist/preview/.next/package.json +1 -0
- package/dist/preview/.next/prerender-manifest.json +41 -0
- package/dist/preview/.next/react-loadable-manifest.json +1 -0
- package/dist/preview/.next/required-server-files.json +311 -0
- package/dist/preview/.next/routes-manifest.json +64 -0
- package/dist/preview/.next/server/app/_not-found/page.js +1 -0
- package/dist/preview/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/dist/preview/.next/server/app/favicon.ico/route.js +1 -0
- package/dist/preview/.next/server/app/favicon.ico/route.js.nft.json +1 -0
- package/dist/preview/.next/server/app/favicon.ico.body +0 -0
- package/dist/preview/.next/server/app/favicon.ico.meta +1 -0
- package/dist/preview/.next/server/app/page.js +1 -0
- package/dist/preview/.next/server/app/page.js.nft.json +1 -0
- package/dist/preview/.next/server/app/page_client-reference-manifest.js +1 -0
- package/dist/preview/.next/server/app/preview/[...slug]/page.js +321 -0
- package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +1 -0
- package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -0
- package/dist/preview/.next/server/app-paths-manifest.json +6 -0
- package/dist/preview/.next/server/chunks/134.js +6 -0
- package/dist/preview/.next/server/chunks/235.js +15 -0
- package/dist/preview/.next/server/chunks/343.js +20 -0
- package/dist/preview/.next/server/chunks/428.js +14 -0
- package/dist/preview/.next/server/chunks/934.js +1 -0
- package/dist/preview/.next/server/chunks/963.js +1 -0
- package/dist/preview/.next/server/functions-config-manifest.json +4 -0
- package/dist/preview/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/dist/preview/.next/server/middleware-build-manifest.js +1 -0
- package/dist/preview/.next/server/middleware-manifest.json +6 -0
- package/dist/preview/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/dist/preview/.next/server/next-font-manifest.js +1 -0
- package/dist/preview/.next/server/next-font-manifest.json +1 -0
- package/dist/preview/.next/server/pages/500.html +1 -0
- package/dist/preview/.next/server/pages/_app.js +1 -0
- package/dist/preview/.next/server/pages/_app.js.nft.json +1 -0
- package/dist/preview/.next/server/pages/_document.js +1 -0
- package/dist/preview/.next/server/pages/_document.js.nft.json +1 -0
- package/dist/preview/.next/server/pages/_error.js +1 -0
- package/dist/preview/.next/server/pages/_error.js.nft.json +1 -0
- package/dist/preview/.next/server/pages-manifest.json +5 -0
- package/dist/preview/.next/server/server-reference-manifest.js +1 -0
- package/dist/preview/.next/server/server-reference-manifest.json +1 -0
- package/dist/preview/.next/server/webpack-runtime.js +1 -0
- package/dist/preview/.next/static/FZEE-q531kq1Juxsda2po/_buildManifest.js +1 -0
- package/dist/preview/.next/static/FZEE-q531kq1Juxsda2po/_ssgManifest.js +1 -0
- package/dist/preview/.next/static/chunks/107-3043079e7cb8bcae.js +1 -0
- package/dist/preview/.next/static/chunks/293-297b1eb2241f9a70.js +1 -0
- package/dist/preview/.next/static/chunks/3bd82e28-cda2c00a924937c5.js +1 -0
- package/dist/preview/.next/static/chunks/45-1021fac82f766268.js +1 -0
- package/dist/preview/.next/static/chunks/484-f5954e7b4b93f109.js +1 -0
- package/dist/preview/.next/static/chunks/589-817d8691661d370e.js +1 -0
- package/dist/preview/.next/static/chunks/902-c34acb56733e0ce1.js +1 -0
- package/dist/preview/.next/static/chunks/app/_not-found/page-4cbc7dce3ad33336.js +1 -0
- package/dist/preview/.next/static/chunks/app/layout-89c12abbc616c3a1.js +1 -0
- package/dist/preview/.next/static/chunks/app/page-0492cd9ce15b7980.js +1 -0
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-c670410568d530db.js +1 -0
- package/dist/preview/.next/static/chunks/f33a14d2-ec7c5f0b91818561.js +6 -0
- package/dist/preview/.next/static/chunks/framework-b887e9fc751a9906.js +1 -0
- package/dist/preview/.next/static/chunks/main-9a03e7ba8acb1900.js +1 -0
- package/dist/preview/.next/static/chunks/main-app-951f948d1c44189f.js +1 -0
- package/dist/preview/.next/static/chunks/pages/_app-542a93a5a214e1c0.js +1 -0
- package/dist/preview/.next/static/chunks/pages/_error-d5fe1b1612642f76.js +1 -0
- package/dist/preview/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/preview/.next/static/chunks/webpack-31c45daa2bd82a7b.js +1 -0
- package/dist/preview/.next/static/css/78c81281aa95270f.css +3 -0
- package/dist/preview/.next/static/media/05613964ce6c782e-s.p.otf +0 -0
- package/dist/preview/.next/static/media/11c6126b9369e85e-s.p.otf +0 -0
- package/dist/preview/.next/static/media/26a46d62cd723877-s.woff2 +0 -0
- package/dist/preview/.next/static/media/26cb97734d8cb717-s.p.otf +0 -0
- package/dist/preview/.next/static/media/55c55f0601d81cf3-s.woff2 +0 -0
- package/dist/preview/.next/static/media/581909926a08bbc8-s.woff2 +0 -0
- package/dist/preview/.next/static/media/8e9860b6e62d6359-s.woff2 +0 -0
- package/dist/preview/.next/static/media/97e0cb1ae144a2a9-s.woff2 +0 -0
- package/dist/preview/.next/static/media/bb6462617151f6b7-s.p.otf +0 -0
- package/dist/preview/.next/static/media/cf6daef822ab0142-s.p.otf +0 -0
- package/dist/preview/.next/static/media/df0a9ae256c0569c-s.woff2 +0 -0
- package/dist/preview/.next/static/media/e4051546b3043204-s.p.otf +0 -0
- package/dist/preview/.next/static/media/e4af272ccee01ff0-s.p.woff2 +0 -0
- package/dist/preview/.next/static/media/logo.2ce2a759.png +0 -0
- package/dist/preview/.next/trace +27 -0
- package/dist/preview/.next/types/app/layout.ts +84 -0
- package/dist/preview/.next/types/app/page.ts +84 -0
- package/dist/preview/.next/types/app/preview/[...slug]/page.ts +84 -0
- package/dist/preview/.next/types/cache-life.d.ts +141 -0
- package/dist/preview/.next/types/package.json +1 -0
- package/package.json +3 -3
- package/readme.md +16 -0
- package/src/actions/email-validation/__snapshots__/check-images.spec.tsx.snap +84 -0
- package/src/utils/preview/get-env-variables-for-preview-app.ts +0 -2
- package/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +1 -70
- package/src/utils/preview/hot-reloading/create-dependency-graph.ts +2 -5
- package/src/utils/preview/serve-static-file.ts +2 -1
- package/src/utils/preview/start-dev-server.ts +1 -6
package/dist/index.js
CHANGED
|
@@ -106,7 +106,7 @@ import prompts from "prompts";
|
|
|
106
106
|
// package.json
|
|
107
107
|
var package_default = {
|
|
108
108
|
name: "react-email",
|
|
109
|
-
version: "4.1.0
|
|
109
|
+
version: "4.1.0",
|
|
110
110
|
description: "A live preview of your emails right in your browser.",
|
|
111
111
|
bin: {
|
|
112
112
|
email: "./dist/index.js"
|
|
@@ -114,8 +114,8 @@ var package_default = {
|
|
|
114
114
|
type: "module",
|
|
115
115
|
scripts: {
|
|
116
116
|
build: "tsup-node",
|
|
117
|
+
"build:watch": "tsup-node --watch src",
|
|
117
118
|
clean: "rm -rf dist",
|
|
118
|
-
dev: "tsup-node --watch src",
|
|
119
119
|
test: "vitest run",
|
|
120
120
|
"test:watch": "vitest"
|
|
121
121
|
},
|
|
@@ -326,8 +326,8 @@ var getEmailSlugsFromEmailDirectory = (emailDirectory, emailsDirectoryAbsolutePa
|
|
|
326
326
|
const directoryPathRelativeToEmailsDirectory = emailDirectory.absolutePath.replace(emailsDirectoryAbsolutePath, "").trim();
|
|
327
327
|
const slugs = [];
|
|
328
328
|
emailDirectory.emailFilenames.forEach(
|
|
329
|
-
(
|
|
330
|
-
path3.join(directoryPathRelativeToEmailsDirectory,
|
|
329
|
+
(filename2) => slugs.push(
|
|
330
|
+
path3.join(directoryPathRelativeToEmailsDirectory, filename2).split(path3.sep).filter((segment) => segment.length > 0)
|
|
331
331
|
)
|
|
332
332
|
);
|
|
333
333
|
emailDirectory.subDirectories.forEach((directory) => {
|
|
@@ -458,234 +458,14 @@ var build = async ({
|
|
|
458
458
|
import fs6 from "node:fs";
|
|
459
459
|
|
|
460
460
|
// src/utils/preview/hot-reloading/setup-hot-reloading.ts
|
|
461
|
-
import
|
|
461
|
+
import path6 from "node:path";
|
|
462
462
|
import { watch } from "chokidar";
|
|
463
463
|
import debounce from "debounce";
|
|
464
464
|
import { Server as SocketServer } from "socket.io";
|
|
465
465
|
|
|
466
466
|
// src/utils/preview/hot-reloading/create-dependency-graph.ts
|
|
467
|
-
import { existsSync
|
|
468
|
-
import path8 from "node:path";
|
|
469
|
-
|
|
470
|
-
// src/utils/preview/start-dev-server.ts
|
|
471
|
-
import http from "node:http";
|
|
472
|
-
import path6 from "node:path";
|
|
473
|
-
import url2 from "node:url";
|
|
474
|
-
import chalk from "chalk";
|
|
475
|
-
import { createJiti as createJiti2 } from "jiti";
|
|
476
|
-
import logSymbols3 from "log-symbols";
|
|
477
|
-
import ora2 from "ora";
|
|
478
|
-
|
|
479
|
-
// src/utils/preview/get-env-variables-for-preview-app.ts
|
|
480
|
-
import path4 from "node:path";
|
|
481
|
-
var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
|
|
482
|
-
return {
|
|
483
|
-
EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
|
|
484
|
-
EMAILS_DIR_ABSOLUTE_PATH: path4.resolve(cwd, relativePathToEmailsDirectory),
|
|
485
|
-
USER_PROJECT_LOCATION: cwd,
|
|
486
|
-
NEXT_PUBLIC_IS_PREVIEW_DEVELOPMENT: isDev ? "true" : "false"
|
|
487
|
-
};
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
// src/utils/preview/serve-static-file.ts
|
|
491
|
-
import { existsSync, promises as fs3 } from "node:fs";
|
|
467
|
+
import { existsSync, promises as fs3, statSync } from "node:fs";
|
|
492
468
|
import path5 from "node:path";
|
|
493
|
-
import { lookup } from "mime-types";
|
|
494
|
-
var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
|
|
495
|
-
const pathname = parsedUrl.pathname.replace("/static", "./static");
|
|
496
|
-
const ext = path5.parse(pathname).ext;
|
|
497
|
-
const staticBaseDir = path5.resolve(process.cwd(), staticDirRelativePath);
|
|
498
|
-
const fileAbsolutePath = path5.resolve(staticBaseDir, pathname);
|
|
499
|
-
if (!fileAbsolutePath.startsWith(staticBaseDir)) {
|
|
500
|
-
res.statusCode = 403;
|
|
501
|
-
res.end();
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
try {
|
|
505
|
-
const fileHandle = await fs3.open(fileAbsolutePath, "r");
|
|
506
|
-
const fileData = await fs3.readFile(fileHandle);
|
|
507
|
-
res.setHeader("Content-type", lookup(ext) || "text/plain");
|
|
508
|
-
res.end(fileData);
|
|
509
|
-
fileHandle.close();
|
|
510
|
-
} catch (exception) {
|
|
511
|
-
if (!existsSync(fileAbsolutePath)) {
|
|
512
|
-
res.statusCode = 404;
|
|
513
|
-
res.end();
|
|
514
|
-
} else {
|
|
515
|
-
const sanitizedFilePath = fileAbsolutePath.replace(/\n|\r/g, "");
|
|
516
|
-
console.error(
|
|
517
|
-
`Could not read file at ${sanitizedFilePath} to be served, here's the exception:`,
|
|
518
|
-
exception
|
|
519
|
-
);
|
|
520
|
-
res.statusCode = 500;
|
|
521
|
-
res.end(
|
|
522
|
-
"Could not read file to be served! Check your terminal for more information."
|
|
523
|
-
);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
// src/utils/preview/start-dev-server.ts
|
|
529
|
-
var devServer;
|
|
530
|
-
var safeAsyncServerListen = (server, port) => {
|
|
531
|
-
return new Promise((resolve) => {
|
|
532
|
-
server.listen(port, () => {
|
|
533
|
-
resolve({ portAlreadyInUse: false });
|
|
534
|
-
});
|
|
535
|
-
server.on("error", (e) => {
|
|
536
|
-
if (e.code === "EADDRINUSE") {
|
|
537
|
-
resolve({ portAlreadyInUse: true });
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
};
|
|
542
|
-
var filename = url2.fileURLToPath(import.meta.url);
|
|
543
|
-
var dirname = path6.dirname(filename);
|
|
544
|
-
var isDev = !dirname.includes("dist");
|
|
545
|
-
var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
|
|
546
|
-
const [majorNodeVersion] = process.versions.node.split(".");
|
|
547
|
-
if (majorNodeVersion && Number.parseInt(majorNodeVersion) < 18) {
|
|
548
|
-
console.error(
|
|
549
|
-
` ${logSymbols3.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
|
|
550
|
-
);
|
|
551
|
-
process.exit(1);
|
|
552
|
-
}
|
|
553
|
-
const previewServerLocation = await getPreviewServerLocation();
|
|
554
|
-
const previewServer = createJiti2(previewServerLocation);
|
|
555
|
-
const { default: next } = await previewServer.import("next");
|
|
556
|
-
devServer = http.createServer((req, res) => {
|
|
557
|
-
if (!req.url) {
|
|
558
|
-
res.end(404);
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
const parsedUrl = url2.parse(req.url, true);
|
|
562
|
-
res.setHeader(
|
|
563
|
-
"Cache-Control",
|
|
564
|
-
"no-cache, max-age=0, must-revalidate, no-store"
|
|
565
|
-
);
|
|
566
|
-
res.setHeader("Pragma", "no-cache");
|
|
567
|
-
res.setHeader("Expires", "-1");
|
|
568
|
-
try {
|
|
569
|
-
if (parsedUrl.path?.includes("static/") && !parsedUrl.path.includes("_next/static/")) {
|
|
570
|
-
void serveStaticFile(res, parsedUrl, staticBaseDirRelativePath);
|
|
571
|
-
} else if (!isNextReady) {
|
|
572
|
-
void nextReadyPromise.then(
|
|
573
|
-
() => nextHandleRequest?.(req, res, parsedUrl)
|
|
574
|
-
);
|
|
575
|
-
} else {
|
|
576
|
-
void nextHandleRequest?.(req, res, parsedUrl);
|
|
577
|
-
}
|
|
578
|
-
} catch (e) {
|
|
579
|
-
console.error("caught error", e);
|
|
580
|
-
res.writeHead(500);
|
|
581
|
-
res.end();
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
const { portAlreadyInUse } = await safeAsyncServerListen(devServer, port);
|
|
585
|
-
if (!portAlreadyInUse) {
|
|
586
|
-
console.log(chalk.greenBright(` React Email ${package_default.version}`));
|
|
587
|
-
console.log(` Running preview at: http://localhost:${port}
|
|
588
|
-
`);
|
|
589
|
-
} else {
|
|
590
|
-
const nextPortToTry = port + 1;
|
|
591
|
-
console.warn(
|
|
592
|
-
` ${logSymbols3.warning} Port ${port} is already in use, trying ${nextPortToTry}`
|
|
593
|
-
);
|
|
594
|
-
return startDevServer(
|
|
595
|
-
emailsDirRelativePath,
|
|
596
|
-
staticBaseDirRelativePath,
|
|
597
|
-
nextPortToTry
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
devServer.on("close", async () => {
|
|
601
|
-
await app.close();
|
|
602
|
-
});
|
|
603
|
-
devServer.on("error", (e) => {
|
|
604
|
-
spinner.stopAndPersist({
|
|
605
|
-
symbol: logSymbols3.error,
|
|
606
|
-
text: `Preview Server had an error: ${e}`
|
|
607
|
-
});
|
|
608
|
-
process.exit(1);
|
|
609
|
-
});
|
|
610
|
-
const spinner = ora2({
|
|
611
|
-
text: "Getting react-email preview server ready...\n",
|
|
612
|
-
prefixText: " "
|
|
613
|
-
}).start();
|
|
614
|
-
registerSpinnerAutostopping(spinner);
|
|
615
|
-
const timeBeforeNextReady = performance.now();
|
|
616
|
-
process.env = {
|
|
617
|
-
NODE_ENV: "development",
|
|
618
|
-
...process.env,
|
|
619
|
-
...getEnvVariablesForPreviewApp(
|
|
620
|
-
// If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
|
|
621
|
-
path6.normalize(emailsDirRelativePath),
|
|
622
|
-
process.cwd()
|
|
623
|
-
)
|
|
624
|
-
};
|
|
625
|
-
const app = next({
|
|
626
|
-
// passing in env here does not get the environment variables there
|
|
627
|
-
dev: isDev,
|
|
628
|
-
conf: {
|
|
629
|
-
images: {
|
|
630
|
-
// This is to avoid the warning with sharp
|
|
631
|
-
unoptimized: true
|
|
632
|
-
}
|
|
633
|
-
},
|
|
634
|
-
hostname: "localhost",
|
|
635
|
-
port,
|
|
636
|
-
dir: previewServerLocation
|
|
637
|
-
});
|
|
638
|
-
let isNextReady = false;
|
|
639
|
-
const nextReadyPromise = app.prepare();
|
|
640
|
-
try {
|
|
641
|
-
await nextReadyPromise;
|
|
642
|
-
} catch (exception) {
|
|
643
|
-
spinner.stopAndPersist({
|
|
644
|
-
symbol: logSymbols3.error,
|
|
645
|
-
text: ` Preview Server had an error: ${exception}`
|
|
646
|
-
});
|
|
647
|
-
process.exit(1);
|
|
648
|
-
}
|
|
649
|
-
isNextReady = true;
|
|
650
|
-
const nextHandleRequest = app.getRequestHandler();
|
|
651
|
-
const secondsToNextReady = ((performance.now() - timeBeforeNextReady) / 1e3).toFixed(1);
|
|
652
|
-
spinner.stopAndPersist({
|
|
653
|
-
text: `Ready in ${secondsToNextReady}s
|
|
654
|
-
`,
|
|
655
|
-
symbol: logSymbols3.success
|
|
656
|
-
});
|
|
657
|
-
return devServer;
|
|
658
|
-
};
|
|
659
|
-
var makeExitHandler = (options) => (codeSignalOrError) => {
|
|
660
|
-
if (typeof devServer !== "undefined") {
|
|
661
|
-
console.log("\nshutting down dev server");
|
|
662
|
-
devServer.close();
|
|
663
|
-
devServer = void 0;
|
|
664
|
-
}
|
|
665
|
-
if (codeSignalOrError instanceof Error) {
|
|
666
|
-
console.error(codeSignalOrError);
|
|
667
|
-
}
|
|
668
|
-
if (options?.shouldKillProcess) {
|
|
669
|
-
process.exit(options.killWithErrorCode ? 1 : 0);
|
|
670
|
-
}
|
|
671
|
-
};
|
|
672
|
-
process.on("exit", makeExitHandler());
|
|
673
|
-
process.on(
|
|
674
|
-
"SIGINT",
|
|
675
|
-
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
676
|
-
);
|
|
677
|
-
process.on(
|
|
678
|
-
"SIGUSR1",
|
|
679
|
-
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
680
|
-
);
|
|
681
|
-
process.on(
|
|
682
|
-
"SIGUSR2",
|
|
683
|
-
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
684
|
-
);
|
|
685
|
-
process.on(
|
|
686
|
-
"uncaughtException",
|
|
687
|
-
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: true })
|
|
688
|
-
);
|
|
689
469
|
|
|
690
470
|
// src/utils/preview/hot-reloading/get-imported-modules.ts
|
|
691
471
|
import { parse } from "@babel/parser";
|
|
@@ -733,7 +513,7 @@ var getImportedModules = (contents) => {
|
|
|
733
513
|
};
|
|
734
514
|
|
|
735
515
|
// src/utils/preview/hot-reloading/resolve-path-aliases.ts
|
|
736
|
-
import
|
|
516
|
+
import path4 from "node:path";
|
|
737
517
|
import { createMatchPath, loadConfig } from "tsconfig-paths";
|
|
738
518
|
var resolvePathAliases = (importPaths, projectPath) => {
|
|
739
519
|
const configLoadResult = loadConfig(projectPath);
|
|
@@ -752,7 +532,7 @@ var resolvePathAliases = (importPaths, projectPath) => {
|
|
|
752
532
|
".mjs"
|
|
753
533
|
]);
|
|
754
534
|
if (unaliasedPath) {
|
|
755
|
-
return `./${
|
|
535
|
+
return `./${path4.relative(projectPath, unaliasedPath)}`;
|
|
756
536
|
}
|
|
757
537
|
return importedPath;
|
|
758
538
|
});
|
|
@@ -763,9 +543,9 @@ var resolvePathAliases = (importPaths, projectPath) => {
|
|
|
763
543
|
// src/utils/preview/hot-reloading/create-dependency-graph.ts
|
|
764
544
|
var readAllFilesInsideDirectory = async (directory) => {
|
|
765
545
|
let allFilePaths = [];
|
|
766
|
-
const topLevelDirents = await
|
|
546
|
+
const topLevelDirents = await fs3.readdir(directory, { withFileTypes: true });
|
|
767
547
|
for await (const dirent of topLevelDirents) {
|
|
768
|
-
const pathToDirent =
|
|
548
|
+
const pathToDirent = path5.join(directory, dirent.name);
|
|
769
549
|
if (dirent.isDirectory()) {
|
|
770
550
|
allFilePaths = allFilePaths.concat(
|
|
771
551
|
await readAllFilesInsideDirectory(pathToDirent)
|
|
@@ -777,26 +557,26 @@ var readAllFilesInsideDirectory = async (directory) => {
|
|
|
777
557
|
return allFilePaths;
|
|
778
558
|
};
|
|
779
559
|
var isJavascriptModule = (filePath) => {
|
|
780
|
-
const extensionName =
|
|
560
|
+
const extensionName = path5.extname(filePath);
|
|
781
561
|
return [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(extensionName);
|
|
782
562
|
};
|
|
783
563
|
var checkFileExtensionsUntilItExists = (pathWithoutExtension) => {
|
|
784
|
-
if (
|
|
564
|
+
if (existsSync(`${pathWithoutExtension}.ts`)) {
|
|
785
565
|
return `${pathWithoutExtension}.ts`;
|
|
786
566
|
}
|
|
787
|
-
if (
|
|
567
|
+
if (existsSync(`${pathWithoutExtension}.tsx`)) {
|
|
788
568
|
return `${pathWithoutExtension}.tsx`;
|
|
789
569
|
}
|
|
790
|
-
if (
|
|
570
|
+
if (existsSync(`${pathWithoutExtension}.js`)) {
|
|
791
571
|
return `${pathWithoutExtension}.js`;
|
|
792
572
|
}
|
|
793
|
-
if (
|
|
573
|
+
if (existsSync(`${pathWithoutExtension}.jsx`)) {
|
|
794
574
|
return `${pathWithoutExtension}.jsx`;
|
|
795
575
|
}
|
|
796
|
-
if (
|
|
576
|
+
if (existsSync(`${pathWithoutExtension}.mjs`)) {
|
|
797
577
|
return `${pathWithoutExtension}.mjs`;
|
|
798
578
|
}
|
|
799
|
-
if (
|
|
579
|
+
if (existsSync(`${pathWithoutExtension}.cjs`)) {
|
|
800
580
|
return `${pathWithoutExtension}.cjs`;
|
|
801
581
|
}
|
|
802
582
|
};
|
|
@@ -815,15 +595,15 @@ var createDependencyGraph = async (directory) => {
|
|
|
815
595
|
])
|
|
816
596
|
);
|
|
817
597
|
const getDependencyPaths = async (filePath) => {
|
|
818
|
-
const contents = await
|
|
819
|
-
const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents),
|
|
598
|
+
const contents = await fs3.readFile(filePath, "utf8");
|
|
599
|
+
const importedPaths = isJavascriptModule(filePath) ? resolvePathAliases(getImportedModules(contents), path5.dirname(filePath)) : [];
|
|
820
600
|
const importedPathsRelativeToDirectory = importedPaths.map(
|
|
821
601
|
(dependencyPath) => {
|
|
822
602
|
const isModulePath = !dependencyPath.startsWith(".");
|
|
823
|
-
if (isModulePath ||
|
|
603
|
+
if (isModulePath || path5.isAbsolute(dependencyPath)) {
|
|
824
604
|
return dependencyPath;
|
|
825
605
|
}
|
|
826
|
-
let pathToDependencyFromDirectory =
|
|
606
|
+
let pathToDependencyFromDirectory = path5.resolve(
|
|
827
607
|
/*
|
|
828
608
|
path.resolve resolves paths differently from what imports on javascript do.
|
|
829
609
|
|
|
@@ -831,7 +611,7 @@ var createDependencyGraph = async (directory) => {
|
|
|
831
611
|
would end up going into /path/to/email.tsx/other-email instead of /path/to/other-email which is the
|
|
832
612
|
one the import is meant to go to
|
|
833
613
|
*/
|
|
834
|
-
|
|
614
|
+
path5.dirname(filePath),
|
|
835
615
|
dependencyPath
|
|
836
616
|
);
|
|
837
617
|
let isDirectory = false;
|
|
@@ -846,15 +626,15 @@ var createDependencyGraph = async (directory) => {
|
|
|
846
626
|
);
|
|
847
627
|
if (pathWithExtension) {
|
|
848
628
|
pathToDependencyFromDirectory = pathWithExtension;
|
|
849
|
-
} else
|
|
629
|
+
} else {
|
|
850
630
|
console.warn(
|
|
851
631
|
`Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`
|
|
852
632
|
);
|
|
853
633
|
}
|
|
854
634
|
}
|
|
855
|
-
const extension =
|
|
635
|
+
const extension = path5.extname(pathToDependencyFromDirectory);
|
|
856
636
|
const pathWithEnsuredExtension = (() => {
|
|
857
|
-
if (extension.length > 0 &&
|
|
637
|
+
if (extension.length > 0 && existsSync(pathToDependencyFromDirectory)) {
|
|
858
638
|
return pathToDependencyFromDirectory;
|
|
859
639
|
}
|
|
860
640
|
return checkFileExtensionsUntilItExists(
|
|
@@ -863,7 +643,7 @@ var createDependencyGraph = async (directory) => {
|
|
|
863
643
|
})();
|
|
864
644
|
if (pathWithEnsuredExtension) {
|
|
865
645
|
pathToDependencyFromDirectory = pathWithEnsuredExtension;
|
|
866
|
-
} else
|
|
646
|
+
} else {
|
|
867
647
|
console.warn(
|
|
868
648
|
`Could not find file at ${pathToDependencyFromDirectory}`
|
|
869
649
|
);
|
|
@@ -872,10 +652,10 @@ var createDependencyGraph = async (directory) => {
|
|
|
872
652
|
}
|
|
873
653
|
);
|
|
874
654
|
const moduleDependencies = importedPathsRelativeToDirectory.filter(
|
|
875
|
-
(dependencyPath) => !dependencyPath.startsWith(".") && !
|
|
655
|
+
(dependencyPath) => !dependencyPath.startsWith(".") && !path5.isAbsolute(dependencyPath)
|
|
876
656
|
);
|
|
877
657
|
const nonNodeModuleImportPathsRelativeToDirectory = importedPathsRelativeToDirectory.filter(
|
|
878
|
-
(dependencyPath) => dependencyPath.startsWith(".") ||
|
|
658
|
+
(dependencyPath) => dependencyPath.startsWith(".") || path5.isAbsolute(dependencyPath)
|
|
879
659
|
);
|
|
880
660
|
return {
|
|
881
661
|
dependencyPaths: nonNodeModuleImportPathsRelativeToDirectory,
|
|
@@ -1006,14 +786,14 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
1006
786
|
changes.filter(
|
|
1007
787
|
(change) => (
|
|
1008
788
|
// Ensures only changes inside the emails directory are emitted
|
|
1009
|
-
|
|
789
|
+
path6.resolve(absolutePathToEmailsDirectory, change.filename).startsWith(absolutePathToEmailsDirectory)
|
|
1010
790
|
)
|
|
1011
791
|
)
|
|
1012
792
|
);
|
|
1013
793
|
});
|
|
1014
794
|
changes = [];
|
|
1015
795
|
}, 150);
|
|
1016
|
-
const absolutePathToEmailsDirectory =
|
|
796
|
+
const absolutePathToEmailsDirectory = path6.resolve(
|
|
1017
797
|
process.cwd(),
|
|
1018
798
|
emailDirRelativePath
|
|
1019
799
|
);
|
|
@@ -1023,7 +803,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
1023
803
|
cwd: absolutePathToEmailsDirectory
|
|
1024
804
|
});
|
|
1025
805
|
const getFilesOutsideEmailsDirectory = () => Object.keys(dependencyGraph).filter(
|
|
1026
|
-
(p) =>
|
|
806
|
+
(p) => path6.relative(absolutePathToEmailsDirectory, p).startsWith("..")
|
|
1027
807
|
);
|
|
1028
808
|
let filesOutsideEmailsDirectory = getFilesOutsideEmailsDirectory();
|
|
1029
809
|
for (const p of filesOutsideEmailsDirectory) {
|
|
@@ -1035,11 +815,11 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
1035
815
|
process.on("SIGINT", exit);
|
|
1036
816
|
process.on("uncaughtException", exit);
|
|
1037
817
|
watcher.on("all", async (event, relativePathToChangeTarget) => {
|
|
1038
|
-
const file = relativePathToChangeTarget.split(
|
|
818
|
+
const file = relativePathToChangeTarget.split(path6.sep);
|
|
1039
819
|
if (file.length === 0) {
|
|
1040
820
|
return;
|
|
1041
821
|
}
|
|
1042
|
-
const pathToChangeTarget =
|
|
822
|
+
const pathToChangeTarget = path6.resolve(
|
|
1043
823
|
absolutePathToEmailsDirectory,
|
|
1044
824
|
relativePathToChangeTarget
|
|
1045
825
|
);
|
|
@@ -1063,7 +843,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
1063
843
|
for (const dependentPath of resolveDependentsOf(pathToChangeTarget)) {
|
|
1064
844
|
changes.push({
|
|
1065
845
|
event: "change",
|
|
1066
|
-
filename:
|
|
846
|
+
filename: path6.relative(absolutePathToEmailsDirectory, dependentPath)
|
|
1067
847
|
});
|
|
1068
848
|
}
|
|
1069
849
|
reload();
|
|
@@ -1071,6 +851,223 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
1071
851
|
return watcher;
|
|
1072
852
|
};
|
|
1073
853
|
|
|
854
|
+
// src/utils/preview/start-dev-server.ts
|
|
855
|
+
import http from "node:http";
|
|
856
|
+
import path9 from "node:path";
|
|
857
|
+
import url2 from "node:url";
|
|
858
|
+
import chalk from "chalk";
|
|
859
|
+
import { createJiti as createJiti2 } from "jiti";
|
|
860
|
+
import logSymbols3 from "log-symbols";
|
|
861
|
+
import ora2 from "ora";
|
|
862
|
+
|
|
863
|
+
// src/utils/preview/get-env-variables-for-preview-app.ts
|
|
864
|
+
import path7 from "node:path";
|
|
865
|
+
var getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, cwd) => {
|
|
866
|
+
return {
|
|
867
|
+
EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
|
|
868
|
+
EMAILS_DIR_ABSOLUTE_PATH: path7.resolve(cwd, relativePathToEmailsDirectory),
|
|
869
|
+
USER_PROJECT_LOCATION: cwd
|
|
870
|
+
};
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
// src/utils/preview/serve-static-file.ts
|
|
874
|
+
import { existsSync as existsSync2, promises as fs4 } from "node:fs";
|
|
875
|
+
import path8 from "node:path";
|
|
876
|
+
import { lookup } from "mime-types";
|
|
877
|
+
var serveStaticFile = async (res, parsedUrl, staticDirRelativePath) => {
|
|
878
|
+
const pathname = parsedUrl.pathname.replace("/static", "./static");
|
|
879
|
+
const ext = path8.parse(pathname).ext;
|
|
880
|
+
const staticBaseDir = path8.resolve(process.cwd(), staticDirRelativePath);
|
|
881
|
+
const fileAbsolutePath = path8.resolve(staticBaseDir, pathname);
|
|
882
|
+
if (!fileAbsolutePath.startsWith(staticBaseDir)) {
|
|
883
|
+
res.statusCode = 403;
|
|
884
|
+
res.end();
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
try {
|
|
888
|
+
const fileHandle = await fs4.open(fileAbsolutePath, "r");
|
|
889
|
+
const fileData = await fs4.readFile(fileHandle);
|
|
890
|
+
res.setHeader("Content-type", lookup(ext) || "text/plain");
|
|
891
|
+
res.end(fileData);
|
|
892
|
+
fileHandle.close();
|
|
893
|
+
} catch (exception) {
|
|
894
|
+
if (!existsSync2(fileAbsolutePath)) {
|
|
895
|
+
res.statusCode = 404;
|
|
896
|
+
res.end();
|
|
897
|
+
} else {
|
|
898
|
+
const sanitizedFilePath = fileAbsolutePath.replace(/\n|\r/g, "");
|
|
899
|
+
console.error(
|
|
900
|
+
`Could not read file at %s to be served, here's the exception:`,
|
|
901
|
+
sanitizedFilePath,
|
|
902
|
+
exception
|
|
903
|
+
);
|
|
904
|
+
res.statusCode = 500;
|
|
905
|
+
res.end(
|
|
906
|
+
"Could not read file to be served! Check your terminal for more information."
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
// src/utils/preview/start-dev-server.ts
|
|
913
|
+
var devServer;
|
|
914
|
+
var safeAsyncServerListen = (server, port) => {
|
|
915
|
+
return new Promise((resolve) => {
|
|
916
|
+
server.listen(port, () => {
|
|
917
|
+
resolve({ portAlreadyInUse: false });
|
|
918
|
+
});
|
|
919
|
+
server.on("error", (e) => {
|
|
920
|
+
if (e.code === "EADDRINUSE") {
|
|
921
|
+
resolve({ portAlreadyInUse: true });
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, port) => {
|
|
927
|
+
const [majorNodeVersion] = process.versions.node.split(".");
|
|
928
|
+
if (majorNodeVersion && Number.parseInt(majorNodeVersion) < 18) {
|
|
929
|
+
console.error(
|
|
930
|
+
` ${logSymbols3.error} Node ${majorNodeVersion} is not supported. Please upgrade to Node 18 or higher.`
|
|
931
|
+
);
|
|
932
|
+
process.exit(1);
|
|
933
|
+
}
|
|
934
|
+
const previewServerLocation = await getPreviewServerLocation();
|
|
935
|
+
const previewServer = createJiti2(previewServerLocation);
|
|
936
|
+
const { default: next } = await previewServer.import("next");
|
|
937
|
+
devServer = http.createServer((req, res) => {
|
|
938
|
+
if (!req.url) {
|
|
939
|
+
res.end(404);
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
const parsedUrl = url2.parse(req.url, true);
|
|
943
|
+
res.setHeader(
|
|
944
|
+
"Cache-Control",
|
|
945
|
+
"no-cache, max-age=0, must-revalidate, no-store"
|
|
946
|
+
);
|
|
947
|
+
res.setHeader("Pragma", "no-cache");
|
|
948
|
+
res.setHeader("Expires", "-1");
|
|
949
|
+
try {
|
|
950
|
+
if (parsedUrl.path?.includes("static/") && !parsedUrl.path.includes("_next/static/")) {
|
|
951
|
+
void serveStaticFile(res, parsedUrl, staticBaseDirRelativePath);
|
|
952
|
+
} else if (!isNextReady) {
|
|
953
|
+
void nextReadyPromise.then(
|
|
954
|
+
() => nextHandleRequest?.(req, res, parsedUrl)
|
|
955
|
+
);
|
|
956
|
+
} else {
|
|
957
|
+
void nextHandleRequest?.(req, res, parsedUrl);
|
|
958
|
+
}
|
|
959
|
+
} catch (e) {
|
|
960
|
+
console.error("caught error", e);
|
|
961
|
+
res.writeHead(500);
|
|
962
|
+
res.end();
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
const { portAlreadyInUse } = await safeAsyncServerListen(devServer, port);
|
|
966
|
+
if (!portAlreadyInUse) {
|
|
967
|
+
console.log(chalk.greenBright(` React Email ${package_default.version}`));
|
|
968
|
+
console.log(` Running preview at: http://localhost:${port}
|
|
969
|
+
`);
|
|
970
|
+
} else {
|
|
971
|
+
const nextPortToTry = port + 1;
|
|
972
|
+
console.warn(
|
|
973
|
+
` ${logSymbols3.warning} Port ${port} is already in use, trying ${nextPortToTry}`
|
|
974
|
+
);
|
|
975
|
+
return startDevServer(
|
|
976
|
+
emailsDirRelativePath,
|
|
977
|
+
staticBaseDirRelativePath,
|
|
978
|
+
nextPortToTry
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
devServer.on("close", async () => {
|
|
982
|
+
await app.close();
|
|
983
|
+
});
|
|
984
|
+
devServer.on("error", (e) => {
|
|
985
|
+
spinner.stopAndPersist({
|
|
986
|
+
symbol: logSymbols3.error,
|
|
987
|
+
text: `Preview Server had an error: ${e}`
|
|
988
|
+
});
|
|
989
|
+
process.exit(1);
|
|
990
|
+
});
|
|
991
|
+
const spinner = ora2({
|
|
992
|
+
text: "Getting react-email preview server ready...\n",
|
|
993
|
+
prefixText: " "
|
|
994
|
+
}).start();
|
|
995
|
+
registerSpinnerAutostopping(spinner);
|
|
996
|
+
const timeBeforeNextReady = performance.now();
|
|
997
|
+
process.env = {
|
|
998
|
+
NODE_ENV: "development",
|
|
999
|
+
...process.env,
|
|
1000
|
+
...getEnvVariablesForPreviewApp(
|
|
1001
|
+
// If we don't do normalization here, stuff like https://github.com/resend/react-email/issues/1354 happens.
|
|
1002
|
+
path9.normalize(emailsDirRelativePath),
|
|
1003
|
+
process.cwd()
|
|
1004
|
+
)
|
|
1005
|
+
};
|
|
1006
|
+
const app = next({
|
|
1007
|
+
// passing in env here does not get the environment variables there
|
|
1008
|
+
dev: false,
|
|
1009
|
+
conf: {
|
|
1010
|
+
images: {
|
|
1011
|
+
// This is to avoid the warning with sharp
|
|
1012
|
+
unoptimized: true
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
hostname: "localhost",
|
|
1016
|
+
port,
|
|
1017
|
+
dir: previewServerLocation
|
|
1018
|
+
});
|
|
1019
|
+
let isNextReady = false;
|
|
1020
|
+
const nextReadyPromise = app.prepare();
|
|
1021
|
+
try {
|
|
1022
|
+
await nextReadyPromise;
|
|
1023
|
+
} catch (exception) {
|
|
1024
|
+
spinner.stopAndPersist({
|
|
1025
|
+
symbol: logSymbols3.error,
|
|
1026
|
+
text: ` Preview Server had an error: ${exception}`
|
|
1027
|
+
});
|
|
1028
|
+
process.exit(1);
|
|
1029
|
+
}
|
|
1030
|
+
isNextReady = true;
|
|
1031
|
+
const nextHandleRequest = app.getRequestHandler();
|
|
1032
|
+
const secondsToNextReady = ((performance.now() - timeBeforeNextReady) / 1e3).toFixed(1);
|
|
1033
|
+
spinner.stopAndPersist({
|
|
1034
|
+
text: `Ready in ${secondsToNextReady}s
|
|
1035
|
+
`,
|
|
1036
|
+
symbol: logSymbols3.success
|
|
1037
|
+
});
|
|
1038
|
+
return devServer;
|
|
1039
|
+
};
|
|
1040
|
+
var makeExitHandler = (options) => (codeSignalOrError) => {
|
|
1041
|
+
if (typeof devServer !== "undefined") {
|
|
1042
|
+
console.log("\nshutting down dev server");
|
|
1043
|
+
devServer.close();
|
|
1044
|
+
devServer = void 0;
|
|
1045
|
+
}
|
|
1046
|
+
if (codeSignalOrError instanceof Error) {
|
|
1047
|
+
console.error(codeSignalOrError);
|
|
1048
|
+
}
|
|
1049
|
+
if (options?.shouldKillProcess) {
|
|
1050
|
+
process.exit(options.killWithErrorCode ? 1 : 0);
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
process.on("exit", makeExitHandler());
|
|
1054
|
+
process.on(
|
|
1055
|
+
"SIGINT",
|
|
1056
|
+
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
1057
|
+
);
|
|
1058
|
+
process.on(
|
|
1059
|
+
"SIGUSR1",
|
|
1060
|
+
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
1061
|
+
);
|
|
1062
|
+
process.on(
|
|
1063
|
+
"SIGUSR2",
|
|
1064
|
+
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: false })
|
|
1065
|
+
);
|
|
1066
|
+
process.on(
|
|
1067
|
+
"uncaughtException",
|
|
1068
|
+
makeExitHandler({ shouldKillProcess: true, killWithErrorCode: true })
|
|
1069
|
+
);
|
|
1070
|
+
|
|
1074
1071
|
// src/utils/tree.ts
|
|
1075
1072
|
import { promises as fs5 } from "node:fs";
|
|
1076
1073
|
import os from "node:os";
|
|
@@ -1085,8 +1082,8 @@ var SYMBOLS = {
|
|
|
1085
1082
|
var getTreeLines = async (dirPath, depth, currentDepth = 0) => {
|
|
1086
1083
|
const base = process.cwd();
|
|
1087
1084
|
const dirFullpath = path10.resolve(base, dirPath);
|
|
1088
|
-
const
|
|
1089
|
-
let lines = [
|
|
1085
|
+
const dirname = path10.basename(dirFullpath);
|
|
1086
|
+
let lines = [dirname];
|
|
1090
1087
|
const dirStat = await fs5.stat(dirFullpath);
|
|
1091
1088
|
if (dirStat.isDirectory() && currentDepth < depth) {
|
|
1092
1089
|
const childDirents = await fs5.readdir(dirFullpath, { withFileTypes: true });
|
|
@@ -1215,15 +1212,15 @@ var renderingUtilitiesExporter = (emailTemplates) => ({
|
|
|
1215
1212
|
var getEmailTemplatesFromDirectory = (emailDirectory) => {
|
|
1216
1213
|
const templatePaths = [];
|
|
1217
1214
|
emailDirectory.emailFilenames.forEach(
|
|
1218
|
-
(
|
|
1215
|
+
(filename2) => templatePaths.push(path12.join(emailDirectory.absolutePath, filename2))
|
|
1219
1216
|
);
|
|
1220
1217
|
emailDirectory.subDirectories.forEach((directory) => {
|
|
1221
1218
|
templatePaths.push(...getEmailTemplatesFromDirectory(directory));
|
|
1222
1219
|
});
|
|
1223
1220
|
return templatePaths;
|
|
1224
1221
|
};
|
|
1225
|
-
var
|
|
1226
|
-
var require2 = createRequire(
|
|
1222
|
+
var filename = url3.fileURLToPath(import.meta.url);
|
|
1223
|
+
var require2 = createRequire(filename);
|
|
1227
1224
|
var exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
|
|
1228
1225
|
if (fs8.existsSync(pathToWhereEmailMarkupShouldBeDumped)) {
|
|
1229
1226
|
fs8.rmSync(pathToWhereEmailMarkupShouldBeDumped, { recursive: true });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
FZEE-q531kq1Juxsda2po
|