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" }