diff --git a/.eslintignore b/.eslintignore
index 4c85ade3..b3801cca 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -4,4 +4,4 @@ dist
node_modules
# Starter template files
-packages/create-jsx-email/starter
\ No newline at end of file
+packages/create-jsx-email/starter
diff --git a/.github/workflows/test-cli.yml b/.github/workflows/test-cli.yml
index fbaffcb2..a9c42e51 100644
--- a/.github/workflows/test-cli.yml
+++ b/.github/workflows/test-cli.yml
@@ -66,4 +66,4 @@ jobs:
# We'll need that for the preview tests below
run: |
pnpm i
- moon repo:test.cli
+ moon test-cli:test.run
diff --git a/.github/workflows/smoke.yml b/.github/workflows/test-smoke.yml
similarity index 97%
rename from .github/workflows/smoke.yml
rename to .github/workflows/test-smoke.yml
index c69b1622..a8e5994a 100644
--- a/.github/workflows/smoke.yml
+++ b/.github/workflows/test-smoke.yml
@@ -66,4 +66,4 @@ jobs:
# We'll need that for the preview tests below
run: |
pnpm i
- moon smoke:run.ci
+ moon test-smoke:run.ci
diff --git a/.moon/workspace.yml b/.moon/workspace.yml
index 11d88b34..465ef3b0 100644
--- a/.moon/workspace.yml
+++ b/.moon/workspace.yml
@@ -5,6 +5,7 @@ projects:
globs:
- 'apps/*'
- 'packages/*'
+ - 'test/cli'
- 'test/smoke'
sources:
root: '.'
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/moon.yml b/moon.yml
index 4fc81d76..2ec68a81 100644
--- a/moon.yml
+++ b/moon.yml
@@ -81,16 +81,3 @@ tasks:
cache: false
outputStyle: 'stream'
runDepsInParallel: false
-
- test.cli:
- command: vitest --config ./shared/vitest.config.ts test/cli --no-threads
- deps:
- - jsx-email:build
- - plugin-inline:build
- - plugin-minify:build
- - plugin-pretty:build
- inputs:
- - test/cli
- options:
- cache: false
- outputStyle: 'stream'
diff --git a/package.json b/package.json
index 14f8a410..6f964c3f 100644
--- a/package.json
+++ b/package.json
@@ -18,13 +18,11 @@
"csstype": "3.1.2",
"eslint-config-shellscape": "^6.0.2",
"eslint-import-resolver-typescript": "^3.6.1",
- "execa": "^9.4.1",
"gh-pages": "^6.0.0",
"happy-dom": "^12.2.1",
"husky": "^8.0.3",
"jsx-email": "workspace:*",
"lint-staged": "14.0.1",
- "strip-ansi": "^7.1.0",
"ts-node": "10.9.1",
"tshy": "^1.14.0",
"typescript": "^5.2.2",
diff --git a/packages/create-jsx-email/bin/create-jsx-email b/packages/create-jsx-email/bin/create-jsx-email
new file mode 100755
index 00000000..3527988e
--- /dev/null
+++ b/packages/create-jsx-email/bin/create-jsx-email
@@ -0,0 +1,2 @@
+#!/usr/bin/env -S node --enable-source-maps --no-warnings=ExperimentalWarning
+import './../dist/index.js';
diff --git a/packages/create-jsx-email/package.json b/packages/create-jsx-email/package.json
index 4779ae7f..49b221a2 100644
--- a/packages/create-jsx-email/package.json
+++ b/packages/create-jsx-email/package.json
@@ -11,14 +11,17 @@
"url": "https://github.com/shellscape/jsx-email.git",
"directory": "packages/create-jsx-email"
},
+ "homepage": "https://jsx.email/",
"main": "dist/src/index.js",
"bin": {
- "create-jsx-email": "./dist/src/index.js"
+ "create-jsx-email": "./bin/create-jsx-email"
},
+ "type": "module",
"engines": {
"node": ">=18.0.0"
},
"files": [
+ "bin/**",
"dist/**"
],
"keywords": [
@@ -27,11 +30,13 @@
"email"
],
"dependencies": {
- "chalk": "4.1.2",
+ "@types/yargs-parser": "^21.0.3",
+ "chalk-template": "^1.1.0",
"detect-package-manager": "^3.0.1",
- "globby": "11.0.4",
+ "globby": "14.0.2",
"mustache": "^4.2.0",
- "prompts": "^2.4.2"
+ "prompts": "^2.4.2",
+ "yargs-parser": "^21.1.1"
},
"devDependencies": {
"@types/fs-extra": "^11.0.2",
diff --git a/packages/create-jsx-email/src/index.ts b/packages/create-jsx-email/src/index.ts
old mode 100755
new mode 100644
index 4607369a..b7544795
--- a/packages/create-jsx-email/src/index.ts
+++ b/packages/create-jsx-email/src/index.ts
@@ -1,16 +1,20 @@
-#!/usr/bin/env node
-/* eslint-disable no-await-in-loop */
+/* eslint-disable no-await-in-loop, no-underscore-dangle */
+
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';
+import chalk from 'chalk-template';
+// Note: https://github.com/egoist/detect-package-manager/issues/18
+// @ts-ignore
import { detect } from 'detect-package-manager';
-import globby from 'globby';
+import { globby } from 'globby';
import mustache from 'mustache';
import prompts from 'prompts';
+import yargs from 'yargs-parser';
-import pkg from '../package.json';
+import * as pkg from './package-info.cjs';
interface CreateEmailArgs {
jsx: boolean;
@@ -18,6 +22,8 @@ interface CreateEmailArgs {
outputPath: string;
}
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
const cancelled = () => {
throw new Error(chalk`{red ✖} Operation cancelled`);
};
@@ -42,10 +48,12 @@ 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;
export const createEmail = async ({ jsx, name, outputPath }: CreateEmailArgs) => {
const data = {
@@ -59,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');
@@ -72,7 +81,6 @@ const run = async () => {
log(intro);
const skip = process.argv.some((arg) => arg === '--yes');
- const argTargetDir = formatTargetDir(process.argv[2]);
let targetPath = argTargetDir || defaultTargetDir;
let result: prompts.Answers<'projectName' | 'projectType' | 'overwrite'>;
const defaults: typeof result = {
@@ -134,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);
@@ -156,7 +165,7 @@ const run = async () => {
await createEmail({ jsx, name: projectName, outputPath });
- const packageManager = await detect();
+ const packageManager = process.env.IS_CLI_TEST ? 'pnpm' : await detect();
const install =
packageManager === 'yarn'
? ` $ yarn\n $ yarn dev`
diff --git a/packages/create-jsx-email/src/package-info.cts b/packages/create-jsx-email/src/package-info.cts
new file mode 100644
index 00000000..f75a4f41
--- /dev/null
+++ b/packages/create-jsx-email/src/package-info.cts
@@ -0,0 +1,5 @@
+// Note: This is a workaround for Node v18 and Node v20 having different import assertion formats
+// eslint-disable-next-line
+const pkg = require('../package.json') as { description: string; name: string; version: string };
+
+export const { description, name, version } = pkg;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1cce6fa0..248ece43 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -48,9 +48,6 @@ importers:
eslint-import-resolver-typescript:
specifier: ^3.6.1
version: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
- execa:
- specifier: ^9.4.1
- version: 9.4.1
gh-pages:
specifier: ^6.0.0
version: 6.0.0
@@ -66,9 +63,6 @@ importers:
lint-staged:
specifier: 14.0.1
version: 14.0.1
- strip-ansi:
- specifier: ^7.1.0
- version: 7.1.0
ts-node:
specifier: 10.9.1
version: 10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.6.2)(typescript@5.2.2)
@@ -138,7 +132,7 @@ importers:
version: 1.18.0
tailwindcss:
specifier: 3.4.0
- version: 3.4.0(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5))
+ version: 3.4.0(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2))
titleize:
specifier: ^4.0.0
version: 4.0.0
@@ -173,21 +167,27 @@ importers:
packages/create-jsx-email:
dependencies:
- chalk:
- specifier: 4.1.2
- version: 4.1.2
+ '@types/yargs-parser':
+ specifier: ^21.0.3
+ version: 21.0.3
+ chalk-template:
+ specifier: ^1.1.0
+ version: 1.1.0
detect-package-manager:
specifier: ^3.0.1
version: 3.0.1
globby:
- specifier: 11.0.4
- version: 11.0.4
+ specifier: 14.0.2
+ version: 14.0.2
mustache:
specifier: ^4.2.0
version: 4.2.0
prompts:
specifier: ^2.4.2
version: 2.4.2
+ yargs-parser:
+ specifier: ^21.1.1
+ version: 21.1.1
devDependencies:
'@types/fs-extra':
specifier: ^11.0.2
@@ -484,6 +484,24 @@ importers:
specifier: ^2.0.1
version: 2.0.1
+ test/cli:
+ dependencies:
+ create-jsx-email:
+ specifier: workspace:^
+ version: link:../../packages/create-jsx-email
+ 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
+ strip-ansi:
+ specifier: ^7.1.0
+ version: 7.1.0
+
test/smoke:
dependencies:
'@playwright/test':
@@ -2147,6 +2165,10 @@ packages:
'@sinclair/typebox@0.27.8':
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+ '@sindresorhus/merge-streams@2.3.0':
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+
'@sindresorhus/merge-streams@4.0.0':
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
@@ -2906,6 +2928,10 @@ packages:
resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
engines: {node: '>=4'}
+ chalk-template@1.1.0:
+ resolution: {integrity: sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==}
+ engines: {node: '>=14.16'}
+
chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -3627,6 +3653,10 @@ packages:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
+ globby@14.0.2:
+ resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==}
+ engines: {node: '>=18'}
+
globby@6.1.0:
resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==}
engines: {node: '>=0.10.0'}
@@ -4472,6 +4502,10 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
+ path-type@5.0.0:
+ resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
+ engines: {node: '>=12'}
+
pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
@@ -4952,6 +4986,10 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
+ slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
+
slice-ansi@5.0.0:
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
engines: {node: '>=12'}
@@ -7102,6 +7140,8 @@ snapshots:
'@sinclair/typebox@0.27.8': {}
+ '@sindresorhus/merge-streams@2.3.0': {}
+
'@sindresorhus/merge-streams@4.0.0': {}
'@swc/core-darwin-arm64@1.3.91':
@@ -8000,6 +8040,10 @@ snapshots:
pathval: 1.1.1
type-detect: 4.0.8
+ chalk-template@1.1.0:
+ dependencies:
+ chalk: 5.3.0
+
chalk@2.4.2:
dependencies:
ansi-styles: 3.2.1
@@ -8475,7 +8519,7 @@ snapshots:
'@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint@8.57.0)(typescript@5.2.2)
'@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.2.2)
eslint: 8.57.0
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-prettier: 4.2.1(eslint@8.57.0)(prettier@2.8.8)
eslint-plugin-typescript-sort-keys: 3.2.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint@8.57.0)(typescript@5.2.2)
prettier: 2.8.8
@@ -8501,7 +8545,7 @@ snapshots:
enhanced-resolve: 5.17.0
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
is-core-module: 2.13.1
@@ -8523,7 +8567,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
+ eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.2.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
@@ -8903,6 +8947,15 @@ snapshots:
merge2: 1.4.1
slash: 3.0.0
+ globby@14.0.2:
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.2
+ ignore: 5.3.1
+ path-type: 5.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.1.0
+
globby@6.1.0:
dependencies:
array-union: 1.0.2
@@ -9796,6 +9849,8 @@ snapshots:
path-type@4.0.0: {}
+ path-type@5.0.0: {}
+
pathe@1.1.2: {}
pathval@1.1.1: {}
@@ -9856,13 +9911,13 @@ snapshots:
camelcase-css: 2.0.1
postcss: 8.4.38
- postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5)):
+ postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2)):
dependencies:
lilconfig: 3.1.1
yaml: 2.4.3
optionalDependencies:
postcss: 8.4.38
- ts-node: 10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5)
+ ts-node: 10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2)
postcss-nested@6.0.1(postcss@8.4.38):
dependencies:
@@ -10343,6 +10398,8 @@ snapshots:
slash@3.0.0: {}
+ slash@5.1.0: {}
+
slice-ansi@5.0.0:
dependencies:
ansi-styles: 6.2.1
@@ -10495,7 +10552,7 @@ snapshots:
tabbable@6.2.0: {}
- tailwindcss@3.4.0(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5)):
+ tailwindcss@3.4.0(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2)):
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@@ -10514,7 +10571,7 @@ snapshots:
postcss: 8.4.38
postcss-import: 15.1.0(postcss@8.4.38)
postcss-js: 4.0.1(postcss@8.4.38)
- postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5))
+ postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2))
postcss-nested: 6.0.1(postcss@8.4.38)
postcss-selector-parser: 6.1.0
resolve: 1.22.8
@@ -10574,7 +10631,7 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.4.5):
+ ts-node@10.9.1(@swc/core@1.3.91(@swc/helpers@0.5.2))(@types/node@20.10.5)(typescript@5.2.2):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
@@ -10588,7 +10645,7 @@ snapshots:
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
- typescript: 5.4.5
+ typescript: 5.2.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
optionalDependencies:
diff --git a/shared/tsconfig.eslint.json b/shared/tsconfig.eslint.json
index 11d4fe67..27148a9c 100644
--- a/shared/tsconfig.eslint.json
+++ b/shared/tsconfig.eslint.json
@@ -10,7 +10,6 @@
"../scripts",
"../shared",
"../test",
- "../vitest.config.ts",
- "../vitest.workspace.ts"
+ "./vitest.config.ts"
]
}
diff --git a/test/cli/.npmrc b/test/cli/.npmrc
new file mode 100644
index 00000000..4447956e
--- /dev/null
+++ b/test/cli/.npmrc
@@ -0,0 +1 @@
+loglevel=error
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..bd67cfb2
--- /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
+ $ pnpm install
+ $ pnpm run 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..d22594c9
--- /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
+ })`IS_CLI_TEST=true create-jsx-email .test/new --yes`;
+ const plain = strip(stdout).replace(/^(.*)create-jsx-email/, 'create-jsx-email');
+
+ 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/create.test.ts b/test/cli/create.test.ts
index 9fd4dc84..a0d0fb31 100644
--- a/test/cli/create.test.ts
+++ b/test/cli/create.test.ts
@@ -2,7 +2,6 @@ import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { execa } from 'execa';
-import { describe, expect, test } from 'vitest';
import strip from 'strip-ansi';
process.chdir(__dirname);
diff --git a/test/cli/moon.yml b/test/cli/moon.yml
new file mode 100644
index 00000000..6f662342
--- /dev/null
+++ b/test/cli/moon.yml
@@ -0,0 +1,17 @@
+# https://moonrepo.dev/docs/config/tasks
+$schema: 'https://moonrepo.dev/schemas/tasks.json'
+
+workspace:
+ inheritedTasks:
+ exclude: ['build', 'compile', 'release', 'test']
+
+tasks:
+ # Naming this differently so it's not picked up bu the main test workflow
+ test.run:
+ command: vitest --config ../../shared/vitest.config.ts . --no-threads
+ inputs:
+ - ./**.*.test.ts
+ - package.json
+ options:
+ cache: false
+ outputStyle: 'stream'
diff --git a/test/cli/package.json b/test/cli/package.json
new file mode 100644
index 00000000..7d1f238b
--- /dev/null
+++ b/test/cli/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "test-cli",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "dependencies": {
+ "create-jsx-email": "workspace:^",
+ "execa": "^9.4.1",
+ "globby": "^14.0.2",
+ "jsx-email": "workspace:^",
+ "strip-ansi": "^7.1.0"
+ }
+}
diff --git a/test/smoke/package.json b/test/smoke/package.json
index 829f3bfe..6e8a01e1 100644
--- a/test/smoke/package.json
+++ b/test/smoke/package.json
@@ -1,5 +1,5 @@
{
- "name": "smoke-test",
+ "name": "test-smoke",
"version": "0.0.0",
"private": true,
"description": "A project to demo and test the `email preview` CLI command",