react-email 6.0.2 → 6.0.4

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # react-email
2
2
 
3
+ ## 6.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 96af3a7: Replace ora with picospinner for CLI and preview spinner output.
8
+ - 5cf57ae: unpin esbuild
9
+ - Updated dependencies [e0e896f]
10
+ - @react-email/render@2.0.8
11
+
12
+ ## 6.0.3
13
+
14
+ ### Patch Changes
15
+
16
+ - bb51e5e: fix missing react and react-dom peer dependencies
17
+
3
18
  ## 6.0.2
4
19
 
5
20
  ### Patch Changes
@@ -17,9 +17,9 @@ import { fileURLToPath as fileURLToPath$1 } from "url";
17
17
  import { createRequire as createRequire$1 } from "module";
18
18
  import logSymbols from "log-symbols";
19
19
  import { addDevDependency, installDependencies, runScript } from "nypm";
20
- import ora from "ora";
21
20
  import { createJiti } from "jiti";
22
21
  import prompts from "prompts";
22
+ import { Spinner } from "picospinner";
23
23
  import { watch } from "chokidar";
24
24
  import debounce from "debounce";
25
25
  import { Server } from "socket.io";
@@ -6522,7 +6522,7 @@ const getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFil
6522
6522
  //#region package.json
6523
6523
  var package_default = {
6524
6524
  name: "react-email",
6525
- version: "6.0.2",
6525
+ version: "6.0.4",
6526
6526
  description: "A live preview of your emails right in your browser.",
6527
6527
  bin: { "email": "./dist/cli/index.mjs" },
6528
6528
  type: "module",
@@ -6554,16 +6554,20 @@ var package_default = {
6554
6554
  },
6555
6555
  keywords: ["react", "email"],
6556
6556
  engines: { "node": ">=20.0.0" },
6557
+ peerDependencies: {
6558
+ "react": "^18.0 || ^19.0 || ^19.0.0-rc",
6559
+ "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
6560
+ },
6557
6561
  dependencies: {
6558
6562
  "@babel/parser": "catalog:",
6559
6563
  "@babel/traverse": "catalog:",
6560
- "@react-email/render": "workspace:>=2.0.7",
6564
+ "@react-email/render": "workspace:>=2.0.8",
6561
6565
  "chokidar": "^4.0.3",
6562
6566
  "commander": "catalog:",
6563
6567
  "conf": "^15.0.2",
6564
6568
  "css-tree": "3.2.1",
6565
6569
  "debounce": "^2.0.0",
6566
- "esbuild": "catalog:",
6570
+ "esbuild": "^0.28.0",
6567
6571
  "glob": "^13.0.6",
6568
6572
  "jiti": "2.4.2",
6569
6573
  "log-symbols": "catalog:",
@@ -6571,7 +6575,7 @@ var package_default = {
6571
6575
  "mime-types": "^3.0.0",
6572
6576
  "normalize-path": "^3.0.0",
6573
6577
  "nypm": "catalog:",
6574
- "ora": "catalog:",
6578
+ "picospinner": "catalog:",
6575
6579
  "prismjs": "^1.30.0",
6576
6580
  "prompts": "2.4.2",
6577
6581
  "socket.io": "^4.8.1",
@@ -6628,18 +6632,36 @@ const getUiLocation = async () => {
6628
6632
  const spinners = /* @__PURE__ */ new Set();
6629
6633
  process.on("SIGINT", () => {
6630
6634
  spinners.forEach((spinner) => {
6631
- if (spinner.isSpinning) spinner.stop();
6635
+ if (spinner.running) spinner.stop();
6632
6636
  });
6633
6637
  });
6634
6638
  process.on("exit", (code) => {
6635
6639
  if (code !== 0) spinners.forEach((spinner) => {
6636
- if (spinner.isSpinning) spinner.stopAndPersist({ symbol: logSymbols.error });
6640
+ if (spinner.running) spinner.fail();
6637
6641
  });
6638
6642
  });
6639
6643
  const registerSpinnerAutostopping = (spinner) => {
6640
6644
  spinners.add(spinner);
6641
6645
  };
6642
6646
  //#endregion
6647
+ //#region src/cli/utils/spinner.ts
6648
+ const withPrefixText = (prefixText, symbolFormatter) => {
6649
+ if (typeof prefixText === "undefined") return symbolFormatter;
6650
+ return (symbol) => `${prefixText}${symbolFormatter?.(symbol) ?? symbol}`;
6651
+ };
6652
+ const normalizeDisplay = (display) => {
6653
+ if (typeof display === "string") return display;
6654
+ const { prefixText, stream, symbolFormatter, ...spinnerDisplay } = display;
6655
+ return {
6656
+ ...spinnerDisplay,
6657
+ symbolFormatter: withPrefixText(prefixText, symbolFormatter)
6658
+ };
6659
+ };
6660
+ const createSpinner = (display, options) => new Spinner(normalizeDisplay(display), options);
6661
+ const stopSpinnerAndPersist = (spinner, display) => {
6662
+ spinner?.setDisplay(display);
6663
+ };
6664
+ //#endregion
6643
6665
  //#region src/cli/commands/build.ts
6644
6666
  const isInReactEmailMonorepo = !path.dirname(fileURLToPath(import.meta.url)).includes("node_modules");
6645
6667
  const setNextEnvironmentVariablesForBuild = async (emailsDirRelativePath, builtPreviewAppPath, usersProjectLocation) => {
@@ -6711,21 +6733,22 @@ const build$1 = async ({ dir: emailsDirRelativePath, packageManager }) => {
6711
6733
  try {
6712
6734
  const usersProjectLocation = process.cwd();
6713
6735
  const previewServerLocation = await getUiLocation();
6714
- const spinner = ora({
6736
+ const spinner = createSpinner({
6715
6737
  text: "Starting build process...",
6716
6738
  prefixText: " "
6717
- }).start();
6739
+ });
6740
+ spinner.start();
6718
6741
  registerSpinnerAutostopping(spinner);
6719
- spinner.text = `Checking if ${emailsDirRelativePath} folder exists`;
6742
+ spinner.setText(`Checking if ${emailsDirRelativePath} folder exists`);
6720
6743
  if (!fs.existsSync(emailsDirRelativePath)) process.exit(1);
6721
6744
  const emailsDirPath = path.join(usersProjectLocation, emailsDirRelativePath);
6722
6745
  const staticPath = path.join(emailsDirPath, "static");
6723
6746
  const builtPreviewAppPath = path.join(usersProjectLocation, ".react-email");
6724
6747
  if (fs.existsSync(builtPreviewAppPath)) {
6725
- spinner.text = "Deleting pre-existing `.react-email` folder";
6748
+ spinner.setText("Deleting pre-existing `.react-email` folder");
6726
6749
  await fs.promises.rm(builtPreviewAppPath, { recursive: true });
6727
6750
  }
6728
- spinner.text = "Copying preview app from CLI to `.react-email`";
6751
+ spinner.setText("Copying preview app from CLI to `.react-email`");
6729
6752
  await fs.promises.cp(previewServerLocation, builtPreviewAppPath, {
6730
6753
  recursive: true,
6731
6754
  filter: (source) => {
@@ -6734,25 +6757,25 @@ const build$1 = async ({ dir: emailsDirRelativePath, packageManager }) => {
6734
6757
  }
6735
6758
  });
6736
6759
  if (fs.existsSync(staticPath)) {
6737
- spinner.text = "Copying `static` folder into `.react-email/public/static`";
6760
+ spinner.setText("Copying `static` folder into `.react-email/public/static`");
6738
6761
  const builtStaticDirectory = path.resolve(builtPreviewAppPath, "./public/static");
6739
6762
  await fs.promises.cp(staticPath, builtStaticDirectory, { recursive: true });
6740
6763
  }
6741
- spinner.text = "Setting Next environment variables for preview app to work properly";
6764
+ spinner.setText("Setting Next environment variables for preview app to work properly");
6742
6765
  await setNextEnvironmentVariablesForBuild(emailsDirRelativePath, builtPreviewAppPath, usersProjectLocation);
6743
- spinner.text = "Setting server side generation for the email preview pages";
6766
+ spinner.setText("Setting server side generation for the email preview pages");
6744
6767
  await forceSSGForEmailPreviews(emailsDirPath, builtPreviewAppPath);
6745
- spinner.text = "Updating package.json's build and start scripts";
6768
+ spinner.setText("Updating package.json's build and start scripts");
6746
6769
  await updatePackageJson(builtPreviewAppPath);
6747
6770
  if (!isInReactEmailMonorepo) {
6748
- spinner.text = "Installing dependencies on `.react-email`";
6771
+ spinner.setText("Installing dependencies on `.react-email`");
6749
6772
  await installDependencies({
6750
6773
  cwd: builtPreviewAppPath,
6751
6774
  silent: true,
6752
6775
  packageManager
6753
6776
  });
6754
6777
  }
6755
- spinner.stopAndPersist({
6778
+ stopSpinnerAndPersist(spinner, {
6756
6779
  text: "Successfully prepared `.react-email` for `next build`",
6757
6780
  symbol: logSymbols.success
6758
6781
  });
@@ -7129,16 +7152,17 @@ const startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath,
7129
7152
  await app.close();
7130
7153
  });
7131
7154
  devServer.on("error", (e) => {
7132
- spinner.stopAndPersist({
7155
+ stopSpinnerAndPersist(spinner, {
7133
7156
  symbol: logSymbols.error,
7134
7157
  text: `Preview Server had an error: ${e}`
7135
7158
  });
7136
7159
  process.exit(1);
7137
7160
  });
7138
- const spinner = ora({
7161
+ const spinner = createSpinner({
7139
7162
  text: "Getting react-email preview server ready...\n",
7140
7163
  prefixText: " "
7141
- }).start();
7164
+ });
7165
+ spinner.start();
7142
7166
  registerSpinnerAutostopping(spinner);
7143
7167
  const timeBeforeNextReady = performance.now();
7144
7168
  process.env = {
@@ -7164,7 +7188,7 @@ const startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath,
7164
7188
  try {
7165
7189
  await nextReadyPromise;
7166
7190
  } catch (exception) {
7167
- spinner.stopAndPersist({
7191
+ stopSpinnerAndPersist(spinner, {
7168
7192
  symbol: logSymbols.error,
7169
7193
  text: ` Preview Server had an error: ${exception}`
7170
7194
  });
@@ -7172,9 +7196,8 @@ const startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath,
7172
7196
  }
7173
7197
  isNextReady = true;
7174
7198
  const nextHandleRequest = app.getRequestHandler();
7175
- const secondsToNextReady = ((performance.now() - timeBeforeNextReady) / 1e3).toFixed(1);
7176
- spinner.stopAndPersist({
7177
- text: `Ready in ${secondsToNextReady}s\n`,
7199
+ stopSpinnerAndPersist(spinner, {
7200
+ text: `Ready in ${((performance.now() - timeBeforeNextReady) / 1e3).toFixed(1)}s\n`,
7178
7201
  symbol: logSymbols.success
7179
7202
  });
7180
7203
  return devServer;
@@ -7313,12 +7336,13 @@ const require$1 = createRequire(url.fileURLToPath(import.meta.url));
7313
7336
  const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirectoryPath, options) => {
7314
7337
  let spinner;
7315
7338
  if (!options.silent) {
7316
- spinner = ora("Preparing files...\n").start();
7339
+ spinner = createSpinner("Preparing files...\n");
7340
+ spinner.start();
7317
7341
  registerSpinnerAutostopping(spinner);
7318
7342
  }
7319
7343
  const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(path.resolve(process.cwd(), emailsDirectoryPath), true);
7320
7344
  if (typeof emailsDirectoryMetadata === "undefined") {
7321
- if (spinner) spinner.stopAndPersist({
7345
+ if (spinner) stopSpinnerAndPersist(spinner, {
7322
7346
  symbol: logSymbols.error,
7323
7347
  text: `Could not find the directory at ${emailsDirectoryPath}`
7324
7348
  });
@@ -7343,7 +7367,7 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
7343
7367
  write: true
7344
7368
  });
7345
7369
  } catch (exception) {
7346
- if (spinner) spinner.stopAndPersist({
7370
+ if (spinner) stopSpinnerAndPersist(spinner, {
7347
7371
  symbol: logSymbols.error,
7348
7372
  text: "Failed to build emails"
7349
7373
  });
@@ -7352,18 +7376,19 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
7352
7376
  }
7353
7377
  if (spinner) spinner.succeed();
7354
7378
  const allBuiltTemplates = glob.sync(normalize$1(`${pathToWhereEmailMarkupShouldBeDumped}/**/*.cjs`), { absolute: true });
7379
+ if (spinner && allBuiltTemplates.length > 0) {
7380
+ spinner.setText(`rendering ${allBuiltTemplates[0]?.split("/").pop()}`);
7381
+ spinner.start();
7382
+ }
7355
7383
  for await (const template of allBuiltTemplates) try {
7356
- if (spinner) {
7357
- spinner.text = `rendering ${template.split("/").pop()}`;
7358
- spinner.render();
7359
- }
7384
+ if (spinner) spinner.setText(`rendering ${template.split("/").pop()}`);
7360
7385
  delete require$1.cache[template];
7361
7386
  const emailModule = require$1(template);
7362
7387
  const rendered = await emailModule.render(emailModule.reactEmailCreateReactElement(emailModule.default, {}), options);
7363
7388
  writeFileSync(template.replace(".cjs", options.plainText ? ".txt" : ".html"), rendered);
7364
7389
  unlinkSync(template);
7365
7390
  } catch (exception) {
7366
- if (spinner) spinner.stopAndPersist({
7391
+ if (spinner) stopSpinnerAndPersist(spinner, {
7367
7392
  symbol: logSymbols.error,
7368
7393
  text: `failed when rendering ${template.split("/").pop()}`
7369
7394
  });
@@ -7372,8 +7397,8 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
7372
7397
  }
7373
7398
  if (spinner) {
7374
7399
  spinner.succeed("Rendered all files");
7375
- spinner.text = "Copying static files";
7376
- spinner.render();
7400
+ spinner.setText("Copying static files");
7401
+ spinner.start();
7377
7402
  }
7378
7403
  const staticDirectoryPath = path.join(emailsDirectoryPath, "static");
7379
7404
  if (fs.existsSync(staticDirectoryPath)) {
@@ -7383,7 +7408,7 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
7383
7408
  await fs.promises.cp(staticDirectoryPath, pathToDumpStaticFilesInto, { recursive: true });
7384
7409
  } catch (exception) {
7385
7410
  console.error(exception);
7386
- if (spinner) spinner.stopAndPersist({
7411
+ if (spinner) stopSpinnerAndPersist(spinner, {
7387
7412
  symbol: logSymbols.error,
7388
7413
  text: "Failed to copy static files"
7389
7414
  });
@@ -7395,10 +7420,7 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
7395
7420
  spinner.succeed();
7396
7421
  const fileTree = await tree(pathToWhereEmailMarkupShouldBeDumped, 4);
7397
7422
  console.log(fileTree);
7398
- spinner.stopAndPersist({
7399
- symbol: logSymbols.success,
7400
- text: "Successfully exported emails"
7401
- });
7423
+ console.log(`${logSymbols.success} Successfully exported emails`);
7402
7424
  }
7403
7425
  };
7404
7426
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-email",
3
- "version": "6.0.2",
3
+ "version": "6.0.4",
4
4
  "description": "A live preview of your emails right in your browser.",
5
5
  "bin": {
6
6
  "email": "./dist/cli/index.mjs"
@@ -30,16 +30,20 @@
30
30
  "engines": {
31
31
  "node": ">=20.0.0"
32
32
  },
33
+ "peerDependencies": {
34
+ "react": "^18.0 || ^19.0 || ^19.0.0-rc",
35
+ "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
36
+ },
33
37
  "dependencies": {
34
38
  "@babel/parser": "7.27.0",
35
39
  "@babel/traverse": "7.27.0",
36
- "@react-email/render": ">=2.0.7",
40
+ "@react-email/render": ">=2.0.8",
37
41
  "chokidar": "^4.0.3",
38
42
  "commander": "^13.0.0",
39
43
  "conf": "^15.0.2",
40
44
  "css-tree": "3.2.1",
41
45
  "debounce": "^2.0.0",
42
- "esbuild": "0.28.0",
46
+ "esbuild": "^0.28.0",
43
47
  "glob": "^13.0.6",
44
48
  "jiti": "2.4.2",
45
49
  "log-symbols": "^7.0.0",
@@ -47,7 +51,7 @@
47
51
  "mime-types": "^3.0.0",
48
52
  "normalize-path": "^3.0.0",
49
53
  "nypm": "0.6.6",
50
- "ora": "^8.0.0",
54
+ "picospinner": "^3.0.0",
51
55
  "prismjs": "^1.30.0",
52
56
  "prompts": "2.4.2",
53
57
  "socket.io": "^4.8.1",
@@ -70,7 +74,7 @@
70
74
  "tsx": "4.21.0",
71
75
  "typescript": "5.9.3",
72
76
  "yalc": "1.0.0-pre.53",
73
- "@react-email/render": "2.0.7"
77
+ "@react-email/render": "2.0.8"
74
78
  },
75
79
  "scripts": {
76
80
  "build": "tsdown",