diff --git a/assets/templates/email.mustache b/assets/templates/email.mustache
index 6258a2f3..a18f87c9 100644
--- a/assets/templates/email.mustache
+++ b/assets/templates/email.mustache
@@ -10,7 +10,7 @@ import {
Section,
Text
} from 'jsx-email';
-
+{{ typeProps }}
const main = {
backgroundColor: '#f6f9fc',
fontFamily:
@@ -46,8 +46,8 @@ const anchor = {
const button = {
fontWeight: 'bold',
- textDecoration: 'none',
- padding: '10px'
+ padding: '10px',
+ textDecoration: 'none'
};
export const previewProps = {
@@ -66,13 +66,15 @@ export const Template = ({ email, name }{{ propsType }}) => (
This is our email body text
diff --git a/packages/create-jsx-email/src/index.ts b/packages/create-jsx-email/src/index.ts
index bb1333d1..ed509097 100644
--- a/packages/create-jsx-email/src/index.ts
+++ b/packages/create-jsx-email/src/index.ts
@@ -2,7 +2,7 @@
import { existsSync, readdirSync, rmSync } from 'fs';
import { mkdir, readFile, writeFile } from 'fs/promises';
-import { basename, dirname, join, resolve, win32, posix } from 'path';
+import { basename, dirname, join, relative, resolve, win32, posix } from 'path';
import { fileURLToPath } from 'node:url';
import chalk from 'chalk-template';
@@ -48,10 +48,10 @@ const isEmpty = (path: string) => {
const { log } = console;
const normalizePath = (filename: string) => filename.split(win32.sep).join(posix.sep);
const typeDep = ',\n"@types/react": "^18.2.0",\n"typescript": "^5.2.2"';
-const typeProps = `\nexport type TemplateProps = {
+const typeProps = `\ninterface TemplateProps {
email: string;
name: string;
-}`;
+}\n`;
const argv = yargs(process.argv.slice(2), { configuration: { 'strip-dashed': true } });
const argTargetDir: string = argv._[0] as string;
@@ -67,9 +67,10 @@ export const createEmail = async ({ jsx, name, outputPath }: CreateEmailArgs) =>
const fileName = basename(templatePath)
.replace('_', '')
.replace('.mustache', jsx ? '.jsx' : '.tsx');
- const outPath = join(outputPath, fileName);
+ const relativePath = relative(process.cwd(), outputPath);
+ const outPath = join(relativePath, fileName);
- log('Creating a new template at', outPath);
+ log(chalk`{blue Creating a new template} at: {cyan ${outPath}}`);
await writeFile(outPath, contents, 'utf8');
@@ -141,9 +142,10 @@ const run = async () => {
const templates = await globby([normalizePath(join(generatorsPath, '/*.*'))]);
const outputPath = join(root, 'templates');
const templateData = { name: projectName, typeDep: jsx ? '' : typeDep };
+ const relativePath = relative(process.cwd(), outputPath);
log('');
- log(chalk`{blue Creating Project} at: {dim ${root}}`);
+ log(chalk`{blue Creating Project} at: {dim ${relativePath}}`);
if (overwrite && existsSync(root)) clearDirectory(root);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6835eb1b..06a1755e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -489,6 +489,9 @@ importers:
execa:
specifier: ^9.4.1
version: 9.4.1
+ globby:
+ specifier: ^14.0.2
+ version: 14.0.2
jsx-email:
specifier: workspace:^
version: link:../../packages/jsx-email
diff --git a/test/cli/.snapshots/create-jsx-email.test.ts.snap b/test/cli/.snapshots/create-jsx-email.test.ts.snap
new file mode 100644
index 00000000..d2aa9665
--- /dev/null
+++ b/test/cli/.snapshots/create-jsx-email.test.ts.snap
@@ -0,0 +1,134 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`create-jsx-email > command 1`] = `
+"
+create-jsx-email v2.0.3
+
+The fastest way to get started with JSX Email
+
+
+Creating Project at: .test/new/templates
+Creating a new template at: .test/new/templates/email.tsx
+
+✓ jsx-email Project Created
+
+Next, run:
+
+ $ cd email-project
+ $ yarn
+ $ yarn dev
+
+Check out the docs! http://jsx.email/docs/quick-start
+"
+`;
+
+exports[`create-jsx-email > command 2`] = `
+"import {
+ Body,
+ Button,
+ Container,
+ Head,
+ Hr,
+ Html,
+ Link,
+ Preview,
+ Section,
+ Text
+} from 'jsx-email';
+
+interface TemplateProps {
+ email: string;
+ name: string;
+}
+
+const main = {
+ backgroundColor: '#f6f9fc',
+ fontFamily:
+ '-apple-system,BlinkMacSystemFont,\\"Segoe UI\\",Roboto,\\"Helvetica Neue\\",Ubuntu,sans-serif'
+};
+
+const container = {
+ backgroundColor: '#ffffff',
+ margin: '0 auto',
+ marginBottom: '64px',
+ padding: '20px 0 48px'
+};
+
+const box = {
+ padding: '0 48px'
+};
+
+const hr = {
+ borderColor: '#e6ebf1',
+ margin: '20px 0'
+};
+
+const paragraph = {
+ color: '#777',
+ fontSize: '16px',
+ lineHeight: '24px',
+ textAlign: 'left' as const
+};
+
+const anchor = {
+ color: '#777'
+};
+
+const button = {
+ fontWeight: 'bold',
+ padding: '10px',
+ textDecoration: 'none'
+};
+
+export const previewProps = {
+ email: 'batman@example.com',
+ name: 'Bruce Wayne'
+};
+
+export const templateName = 'email-project';
+
+export const Template = ({ email, name }: TemplateProps) => (
+
+
+ This is our email preview text for {name} <{email}>
+
+
+
+ This is our email body text
+
+
+
+ This is text content with a{' '}
+
+ link
+
+ .
+
+
+
+
+
+);
+"
+`;
+
+exports[`create-jsx-email > command 3`] = `
+[
+ ".test/new/README.md",
+ ".test/new/package.json",
+ ".test/new/tsconfig.json",
+ ".test/new/templates/email.tsx",
+]
+`;
diff --git a/test/cli/create-jsx-email.test.ts b/test/cli/create-jsx-email.test.ts
new file mode 100644
index 00000000..35b21cf2
--- /dev/null
+++ b/test/cli/create-jsx-email.test.ts
@@ -0,0 +1,28 @@
+import { readFile } from 'node:fs/promises';
+import { join } from 'node:path';
+
+import { execa } from 'execa';
+import { globby } from 'globby';
+import strip from 'strip-ansi';
+
+process.chdir(__dirname);
+
+describe('create-jsx-email', async () => {
+ test('command', async () => {
+ const { stdout } = await execa({
+ cwd: __dirname,
+ shell: true
+ // Note: For some reason `pnpm exec` is fucking with our CWD, and resets it to
+ // packages/jsx-email, which causes the config not to be found. so we use npx instead
+ })`pnpm exec create-jsx-email .test/new --yes`;
+ const plain = strip(stdout);
+
+ expect(plain).toMatchSnapshot();
+
+ const contents = await readFile(join(__dirname, '.test/new/templates/email.tsx'), 'utf8');
+ expect(contents).toMatchSnapshot();
+
+ const files = await globby('.test/new/**/*');
+ expect(files).toMatchSnapshot();
+ });
+});
diff --git a/test/cli/package.json b/test/cli/package.json
index 0abb7b25..adf17963 100644
--- a/test/cli/package.json
+++ b/test/cli/package.json
@@ -5,6 +5,7 @@
"type": "module",
"dependencies": {
"execa": "^9.4.1",
+ "globby": "^14.0.2",
"jsx-email": "workspace:^",
"strip-ansi": "^7.1.0"
}