react-email 5.0.0-canary.6 → 5.0.0-canary.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # react-email
2
2
 
3
+ ## 5.0.0-canary.8
4
+
5
+ ### Patch Changes
6
+
7
+ - b6b027c: improved integration setup flow
8
+
9
+ ## 5.0.0-canary.7
10
+
3
11
  ## 5.0.0-canary.6
4
12
 
5
13
  ## 5.0.0-canary.5
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ import { parse } from "@babel/parser";
17
17
  import traverseModule from "@babel/traverse";
18
18
  import { createMatchPath, loadConfig } from "tsconfig-paths";
19
19
  import http from "node:http";
20
+ import Conf from "conf";
20
21
  import * as nodeUtil from "node:util";
21
22
  import { lookup } from "mime-types";
22
23
  import os from "node:os";
@@ -86,7 +87,7 @@ const getEmailsDirectoryMetadata = async (absolutePathToEmailsDirectory, keepFil
86
87
  //#region package.json
87
88
  var package_default = {
88
89
  name: "react-email",
89
- version: "5.0.0-canary.6",
90
+ version: "5.0.0-canary.8",
90
91
  description: "A live preview of your emails right in your browser.",
91
92
  bin: { "email": "./dist/index.js" },
92
93
  type: "module",
@@ -110,6 +111,7 @@ var package_default = {
110
111
  "@babel/traverse": "^7.27.0",
111
112
  "chokidar": "^4.0.3",
112
113
  "commander": "^13.0.0",
114
+ "conf": "^15.0.2",
113
115
  "debounce": "^2.0.0",
114
116
  "esbuild": "^0.25.0",
115
117
  "glob": "^11.0.0",
@@ -585,18 +587,27 @@ const setupHotreloading = async (devServer$1, emailDirRelativePath) => {
585
587
  return watcher;
586
588
  };
587
589
 
590
+ //#endregion
591
+ //#region src/utils/conf.ts
592
+ const encryptionKey = "h2#x658}1#qY(@!:7,BD1J)q12$[tM25";
593
+ const conf = new Conf({
594
+ projectName: "react-email",
595
+ encryptionKey
596
+ });
597
+
588
598
  //#endregion
589
599
  //#region src/utils/style-text.ts
590
600
  const styleText = nodeUtil.styleText ? nodeUtil.styleText : (_, text) => text;
591
601
 
592
602
  //#endregion
593
603
  //#region src/utils/preview/get-env-variables-for-preview-app.ts
594
- const getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, previewServerLocation, cwd) => {
604
+ const getEnvVariablesForPreviewApp = (relativePathToEmailsDirectory, previewServerLocation, cwd, resendApiKey) => {
595
605
  return {
596
606
  EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
597
607
  EMAILS_DIR_ABSOLUTE_PATH: path.resolve(cwd, relativePathToEmailsDirectory),
598
608
  PREVIEW_SERVER_LOCATION: previewServerLocation,
599
- USER_PROJECT_LOCATION: cwd
609
+ USER_PROJECT_LOCATION: cwd,
610
+ RESEND_API_KEY: resendApiKey
600
611
  };
601
612
  };
602
613
 
@@ -699,7 +710,7 @@ const startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath,
699
710
  process.env = {
700
711
  NODE_ENV: "development",
701
712
  ...process.env,
702
- ...getEnvVariablesForPreviewApp(path.normalize(emailsDirRelativePath), previewServerLocation, process.cwd())
713
+ ...getEnvVariablesForPreviewApp(path.normalize(emailsDirRelativePath), previewServerLocation, process.cwd(), conf.get("resendApiKey"))
703
714
  };
704
715
  const app = (await previewServer.import("next", { default: true }))({
705
716
  dev: false,
@@ -955,6 +966,30 @@ const exportTemplates = async (pathToWhereEmailMarkupShouldBeDumped, emailsDirec
955
966
  }
956
967
  };
957
968
 
969
+ //#endregion
970
+ //#region src/commands/resend/reset.ts
971
+ async function resendReset() {
972
+ conf.delete("resendApiKey");
973
+ console.info(`${logSymbols.success} Resend API Key successfully deleted`);
974
+ }
975
+
976
+ //#endregion
977
+ //#region src/commands/resend/setup.ts
978
+ async function resendSetup() {
979
+ const previousValue = conf.get("resendApiKey");
980
+ if (typeof previousValue === "string" && previousValue.length > 0) console.info(`You already have a Resend API Key configured (${styleText("grey", previousValue.slice(0, 11))}...), continuing will replace it.`);
981
+ const { apiKey } = await prompts({
982
+ type: "password",
983
+ name: "apiKey",
984
+ message: "Enter your API Key (make sure it has \"Full Access\")"
985
+ });
986
+ if (apiKey?.trim().length > 0) {
987
+ conf.set("resendApiKey", apiKey);
988
+ console.info(`${logSymbols.success} Resend integration successfully set up`);
989
+ console.info(`You can always remove it with ${styleText("green", "npx react-email@latest resend reset")}`);
990
+ }
991
+ }
992
+
958
993
  //#endregion
959
994
  //#region src/commands/start.ts
960
995
  const start = async () => {
@@ -997,6 +1032,9 @@ program.command("export").description("Build the templates to the `out` director
997
1032
  plainText,
998
1033
  pretty
999
1034
  }));
1035
+ const resend = program.command("resend");
1036
+ resend.command("setup").description("Sets up the integration between the React Email CLI, and your Resend account through an API Key").action(resendSetup);
1037
+ resend.command("reset").description("Deletes your API Key from the React Email configuration").action(resendReset);
1000
1038
  program.parse();
1001
1039
 
1002
1040
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-email",
3
- "version": "5.0.0-canary.6",
3
+ "version": "5.0.0-canary.8",
4
4
  "description": "A live preview of your emails right in your browser.",
5
5
  "bin": {
6
6
  "email": "./dist/index.js"
@@ -24,6 +24,7 @@
24
24
  "@babel/traverse": "^7.27.0",
25
25
  "chokidar": "^4.0.3",
26
26
  "commander": "^13.0.0",
27
+ "conf": "^15.0.2",
27
28
  "debounce": "^2.0.0",
28
29
  "esbuild": "^0.25.0",
29
30
  "glob": "^11.0.0",
@@ -0,0 +1,8 @@
1
+ import logSymbols from 'log-symbols';
2
+ import { conf } from '../../utils/conf.js';
3
+
4
+ export async function resendReset() {
5
+ conf.delete('resendApiKey');
6
+
7
+ console.info(`${logSymbols.success} Resend API Key successfully deleted`);
8
+ }
@@ -0,0 +1,29 @@
1
+ import logSymbols from 'log-symbols';
2
+ import prompts from 'prompts';
3
+ import { conf } from '../../utils/conf.js';
4
+ import { styleText } from '../../utils/style-text.js';
5
+
6
+ export async function resendSetup() {
7
+ const previousValue = conf.get('resendApiKey');
8
+ if (typeof previousValue === 'string' && previousValue.length > 0) {
9
+ console.info(
10
+ `You already have a Resend API Key configured (${styleText('grey', previousValue.slice(0, 11))}...), continuing will replace it.`,
11
+ );
12
+ }
13
+
14
+ const { apiKey } = await prompts({
15
+ type: 'password',
16
+ name: 'apiKey',
17
+ message: 'Enter your API Key (make sure it has "Full Access")',
18
+ });
19
+
20
+ if (apiKey?.trim().length > 0) {
21
+ conf.set('resendApiKey', apiKey);
22
+ console.info(
23
+ `${logSymbols.success} Resend integration successfully set up`,
24
+ );
25
+ console.info(
26
+ `You can always remove it with ${styleText('green', 'npx react-email@latest resend reset')}`,
27
+ );
28
+ }
29
+ }
package/src/index.ts CHANGED
@@ -3,6 +3,8 @@ import { program } from 'commander';
3
3
  import { build } from './commands/build.js';
4
4
  import { dev } from './commands/dev.js';
5
5
  import { exportTemplates } from './commands/export.js';
6
+ import { resendReset } from './commands/resend/reset.js';
7
+ import { resendSetup } from './commands/resend/setup.js';
6
8
  import { start } from './commands/start.js';
7
9
  import { packageJson } from './utils/packageJson.js';
8
10
 
@@ -52,4 +54,18 @@ program
52
54
  exportTemplates(outDir, srcDir, { silent, plainText, pretty }),
53
55
  );
54
56
 
57
+ const resend = program.command('resend');
58
+
59
+ resend
60
+ .command('setup')
61
+ .description(
62
+ 'Sets up the integration between the React Email CLI, and your Resend account through an API Key',
63
+ )
64
+ .action(resendSetup);
65
+
66
+ resend
67
+ .command('reset')
68
+ .description('Deletes your API Key from the React Email configuration')
69
+ .action(resendReset);
70
+
55
71
  program.parse();
@@ -16,6 +16,7 @@ exports[`tree(__dirname, 2) 1`] = `
16
16
  ├── types
17
17
  │ ├── hot-reload-change.ts
18
18
  │ └── hot-reload-event.ts
19
+ ├── conf.ts
19
20
  ├── get-emails-directory-metadata.spec.ts
20
21
  ├── get-emails-directory-metadata.ts
21
22
  ├── get-preview-server-location.ts
@@ -0,0 +1,9 @@
1
+ import Conf from 'conf';
2
+
3
+ // Just simple encryption. This isn't completely safe
4
+ // because anyone can find this key here
5
+ const encryptionKey = 'h2#x658}1#qY(@!:7,BD1J)q12$[tM25';
6
+
7
+ export const conf = new Conf<{
8
+ resendApiKey?: string;
9
+ }>({ projectName: 'react-email', encryptionKey });
@@ -4,11 +4,13 @@ export const getEnvVariablesForPreviewApp = (
4
4
  relativePathToEmailsDirectory: string,
5
5
  previewServerLocation: string,
6
6
  cwd: string,
7
+ resendApiKey?: string,
7
8
  ) => {
8
9
  return {
9
10
  EMAILS_DIR_RELATIVE_PATH: relativePathToEmailsDirectory,
10
11
  EMAILS_DIR_ABSOLUTE_PATH: path.resolve(cwd, relativePathToEmailsDirectory),
11
12
  PREVIEW_SERVER_LOCATION: previewServerLocation,
12
13
  USER_PROJECT_LOCATION: cwd,
14
+ RESEND_API_KEY: resendApiKey,
13
15
  } as const;
14
16
  };
@@ -5,6 +5,7 @@ import { createJiti } from 'jiti';
5
5
  import logSymbols from 'log-symbols';
6
6
  import ora from 'ora';
7
7
  import { registerSpinnerAutostopping } from '../../utils/register-spinner-autostopping.js';
8
+ import { conf } from '../conf.js';
8
9
  import { getPreviewServerLocation } from '../get-preview-server-location.js';
9
10
  import { packageJson } from '../packageJson.js';
10
11
  import { styleText } from '../style-text.js';
@@ -131,6 +132,7 @@ export const startDevServer = async (
131
132
  path.normalize(emailsDirRelativePath),
132
133
  previewServerLocation,
133
134
  process.cwd(),
135
+ conf.get('resendApiKey'),
134
136
  ),
135
137
  };
136
138
 
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import * as nodeUtil from 'node:util';
6
6
 
7
- type StyleTextFunction = (style: string, text: string) => string;
7
+ type StyleTextFunction = typeof nodeUtil.styleText;
8
8
 
9
9
  export const styleText: StyleTextFunction = (nodeUtil as any).styleText
10
10
  ? (nodeUtil as any).styleText