From 3fe7a33c3123d97858c175508bfa623290c814e7 Mon Sep 17 00:00:00 2001 From: shellscape Date: Sat, 2 Nov 2024 11:09:02 -0400 Subject: [PATCH 1/3] refactor(create-jsx-email): use esm, add tests --- .eslintignore | 2 +- .github/workflows/test-cli.yml | 2 +- .../workflows/{smoke.yml => test-smoke.yml} | 2 +- .moon/workspace.yml | 1 + moon.yml | 13 ---- package.json | 2 - .../create-jsx-email/bin/create-jsx-email | 2 + packages/create-jsx-email/package.json | 12 ++-- packages/create-jsx-email/src/index.ts | 19 +++-- .../create-jsx-email/src/package-info.cts | 5 ++ pnpm-lock.yaml | 70 ++++++++++++++++--- shared/tsconfig.eslint.json | 3 +- test/cli/create.test.ts | 1 - test/cli/moon.yml | 16 +++++ test/cli/package.json | 11 +++ test/smoke/package.json | 2 +- 16 files changed, 120 insertions(+), 43 deletions(-) rename .github/workflows/{smoke.yml => test-smoke.yml} (97%) create mode 100755 packages/create-jsx-email/bin/create-jsx-email mode change 100755 => 100644 packages/create-jsx-email/src/index.ts create mode 100644 packages/create-jsx-email/src/package-info.cts create mode 100644 test/cli/moon.yml create mode 100644 test/cli/package.json 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..1d06bfc1 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 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/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..3004a3e3 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,12 @@ "email" ], "dependencies": { - "chalk": "4.1.2", + "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..bb1333d1 --- 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 { 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`); }; @@ -46,6 +52,8 @@ const typeProps = `\nexport type TemplateProps = { email: string; name: string; }`; +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 = { @@ -72,7 +80,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 = { 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..f2a7fac0 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) @@ -173,21 +167,24 @@ importers: packages/create-jsx-email: dependencies: - chalk: - specifier: 4.1.2 - version: 4.1.2 + 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 +481,18 @@ importers: specifier: ^2.0.1 version: 2.0.1 + test/cli: + dependencies: + execa: + specifier: ^9.4.1 + version: 9.4.1 + 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 +2156,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 +2919,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 +3644,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 +4493,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 +4977,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 +7131,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 +8031,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 @@ -8903,6 +8938,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 +9840,8 @@ snapshots: path-type@4.0.0: {} + path-type@5.0.0: {} + pathe@1.1.2: {} pathval@1.1.1: {} @@ -10343,6 +10389,8 @@ snapshots: slash@3.0.0: {} + slash@5.1.0: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 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/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..264c7d04 --- /dev/null +++ b/test/cli/moon.yml @@ -0,0 +1,16 @@ +# https://moonrepo.dev/docs/config/tasks +$schema: 'https://moonrepo.dev/schemas/tasks.json' + +workspace: + inheritedTasks: + exclude: ['build', 'compile', 'release', 'test'] + +tasks: + test: + 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..0abb7b25 --- /dev/null +++ b/test/cli/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-cli", + "version": "0.0.0", + "private": true, + "type": "module", + "dependencies": { + "execa": "^9.4.1", + "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", From 53387d3f06edd53fd6afc3cf0585de85a21ea28f Mon Sep 17 00:00:00 2001 From: shellscape Date: Sat, 2 Nov 2024 11:25:12 -0400 Subject: [PATCH 2/3] chore: types --- packages/create-jsx-email/package.json | 1 + pnpm-lock.yaml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/packages/create-jsx-email/package.json b/packages/create-jsx-email/package.json index 3004a3e3..49b221a2 100644 --- a/packages/create-jsx-email/package.json +++ b/packages/create-jsx-email/package.json @@ -30,6 +30,7 @@ "email" ], "dependencies": { + "@types/yargs-parser": "^21.0.3", "chalk-template": "^1.1.0", "detect-package-manager": "^3.0.1", "globby": "14.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2a7fac0..6835eb1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,6 +167,9 @@ importers: packages/create-jsx-email: dependencies: + '@types/yargs-parser': + specifier: ^21.0.3 + version: 21.0.3 chalk-template: specifier: ^1.1.0 version: 1.1.0 From 330d16f793bcf3f2456dd11defd0f0ef43d98da6 Mon Sep 17 00:00:00 2001 From: shellscape Date: Sat, 2 Nov 2024 14:28:42 -0400 Subject: [PATCH 3/3] chore: test --- .github/workflows/test-cli.yml | 2 +- assets/templates/email.mustache | 12 +- packages/create-jsx-email/src/index.ts | 16 ++- pnpm-lock.yaml | 26 ++-- test/cli/.npmrc | 1 + .../.snapshots/create-jsx-email.test.ts.snap | 134 ++++++++++++++++++ test/cli/create-jsx-email.test.ts | 28 ++++ test/cli/moon.yml | 3 +- test/cli/package.json | 2 + 9 files changed, 200 insertions(+), 24 deletions(-) create mode 100644 test/cli/.npmrc create mode 100644 test/cli/.snapshots/create-jsx-email.test.ts.snap create mode 100644 test/cli/create-jsx-email.test.ts diff --git a/.github/workflows/test-cli.yml b/.github/workflows/test-cli.yml index 1d06bfc1..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 test-cli:test + moon test-cli:test.run 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..b7544795 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); @@ -163,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/pnpm-lock.yaml b/pnpm-lock.yaml index 6835eb1b..248ece43 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,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 @@ -486,9 +486,15 @@ importers: 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 @@ -8513,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 @@ -8539,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 @@ -8561,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 @@ -9905,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: @@ -10546,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 @@ -10565,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 @@ -10625,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 @@ -10639,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/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/moon.yml b/test/cli/moon.yml index 264c7d04..6f662342 100644 --- a/test/cli/moon.yml +++ b/test/cli/moon.yml @@ -6,7 +6,8 @@ workspace: exclude: ['build', 'compile', 'release', 'test'] tasks: - test: + # 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 diff --git a/test/cli/package.json b/test/cli/package.json index 0abb7b25..7d1f238b 100644 --- a/test/cli/package.json +++ b/test/cli/package.json @@ -4,7 +4,9 @@ "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" }