Skip to content

Commit

Permalink
feat(react-email): Added react email package (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
TriPSs authored Dec 19, 2023
2 parents ccbdf90 + e5e64c8 commit f6bb593
Show file tree
Hide file tree
Showing 22 changed files with 1,474 additions and 42 deletions.
15 changes: 15 additions & 0 deletions e2e/react-email-e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
displayName: 'react-email-e2e',
preset: '../../jest.preset.js',
globals: {},
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json'
}
]
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/e2e/react-email-e2e'
}
19 changes: 19 additions & 0 deletions e2e/react-email-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "react-email-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "e2e/react-email-e2e/src",
"targets": {
"e2e": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "e2e/react-email-e2e/jest.config.js",
"runInBand": true,
"passWithNoTests": false
},
"dependsOn": ["react-email:build"]
}
},
"tags": [],
"implicitDependencies": ["react-email"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`react email e2e should be able to export 1`] = `"<!DOCTYPE html PUBLIC \\"-//W3C//DTD XHTML 1.0 Transitional//EN\\" \\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\"><html dir=\\"ltr\\" lang=\\"en\\"><a href=\\"https://example.com\\" style=\\"background:#000;color:#fff;padding:12px 20px 12px 20px;line-height:100%;text-decoration:none;display:inline-block;max-width:100%\\" target=\\"_blank\\"><span><!--[if mso]><i style=\\"letter-spacing: 20px;mso-font-width:-100%;mso-text-raise:18\\" hidden>&nbsp;</i><![endif]--></span><span style=\\"max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px\\">Click me</span><span><!--[if mso]><i style=\\"letter-spacing: 20px;mso-font-width:-100%\\" hidden>&nbsp;</i><![endif]--></span></a></html>"`;
47 changes: 47 additions & 0 deletions e2e/react-email-e2e/tests/react-email.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
runNxCommandAsync,
readJson,
updateFile, readFile
} from '@nx/plugin/testing'
import { ensureNxProject } from '../../utils/workspace'

describe('react email e2e', () => {

beforeAll(() => ensureNxProject([
'@nx-extend/core:dist/packages/core',
'@nx-extend/react-email:dist/packages/react-email'
]))

const appName = 'react-email-test'
it('should be able to add', async () => {
await runNxCommandAsync(`generate @nx-extend/react-email:init ${appName}`)

expect(readJson(`${appName}/project.json`).targets).toEqual(
expect.objectContaining({
serve: {
executor: '@nx-extend/react-email:serve',
options: {}
},
export: {
executor: '@nx-extend/react-email:export',
outputs: ['{options.outputPath}'],
defaultConfiguration: 'production',
options: {
outputPath: `dist/${appName}`
},
configurations: {
production: {
pretty: false
}
}
}
})
)
}, 300000)

it('should be able to export', async () => {
await runNxCommandAsync(`export ${appName}`)

expect(readFile(`dist/${appName}/index.html`)).toMatchSnapshot()
}, 300000)
})
13 changes: 13 additions & 0 deletions e2e/react-email-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.e2e.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
9 changes: 9 additions & 0 deletions e2e/react-email-e2e/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
19 changes: 19 additions & 0 deletions packages/react-email/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,23 @@

```sh
npm install -D @nx-extend/react-email
nx g @nx-extend/react-email:init
```

## Usage

### Serve

#### Available options:

| name | type | default | description |
|------|------|---------|-------------|

### Export

#### Available options:

| name | type | default | description |
|--------------------|----------|---------|------------------------------------|
| **`--outputPath`** | `string` | | Output path to output the build to |

21 changes: 20 additions & 1 deletion packages/react-email/executors.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
{
"executors": {

"serve": {
"implementation": "./src/executors/serve/serve.impl",
"schema": "./src/executors/serve/schema.json",
"description": "Start react email in dev mode."
},
"export": {
"implementation": "./src/executors/export/export.impl",
"schema": "./src/executors/export/schema.json",
"description": "export react email"
}
},
"builders": {
"serve": {
"implementation": "./src/executors/serve/serve.impl",
"schema": "./src/executors/serve/schema.json",
"description": "Start react email in dev mode."
},
"export": {
"implementation": "./src/executors/export/export.impl",
"schema": "./src/executors/export/schema.json",
"description": "export react email"
}
}
}
6 changes: 5 additions & 1 deletion packages/react-email/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"name": "react-email",
"version": "0.0.1",
"generators": {

"init": {
"factory": "./src/generators/init/init.impl",
"schema": "./src/generators/init/schema.json",
"description": "react email generator"
}
}
}
4 changes: 4 additions & 0 deletions packages/react-email/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
},
"license": "MIT",
"main": "src/index.js",
"devDependencies": {
"@react-email/components": "^0.0.12",
"react-email": "^1.10.0"
},
"builders": "./executors.json",
"generators": "./generators.json"
}
5 changes: 5 additions & 0 deletions packages/react-email/src/executors/export/compat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { convertNxExecutor } from '@nx/devkit'

import { exportExecutor } from './export.impl'

export default convertNxExecutor(exportExecutor)
33 changes: 33 additions & 0 deletions packages/react-email/src/executors/export/export.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ExecutorContext } from '@nx/devkit'
import { buildCommand, execPackageManagerCommand } from '@nx-extend/core'

import 'dotenv/config'

export interface ServeExecutorOptions {
outputPath: string
pretty?: boolean
plainText?: boolean
}

export async function exportExecutor(
options: ServeExecutorOptions,
context: ExecutorContext
): Promise<{ success: boolean }> {
const { sourceRoot, root } = context.workspace.projects[context.projectName]

if (!options.outputPath) {
throw new Error('No "outputPath" defined in options!')
}

return execPackageManagerCommand(buildCommand([
'email export',
`--dir=${sourceRoot || root}`,
`--outDir=${options.outputPath}`,
options.pretty && `--pretty`,
options.plainText && `--plainText`
]), {
env: process.env
})
}

export default exportExecutor
21 changes: 21 additions & 0 deletions packages/react-email/src/executors/export/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": 2,
"outputCapture": "direct-nodejs",
"type": "object",
"title": "Export executor",
"description": "Export react email",
"properties": {
"outputPath": {
"type": "string"
},
"pretty": {
"type": "boolean",
"default": false
},
"plainText": {
"type": "boolean",
"default": false
}
},
"required": ["outputPath"]
}
5 changes: 5 additions & 0 deletions packages/react-email/src/executors/serve/compat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { convertNxExecutor } from '@nx/devkit'

import { serveExecutor } from './serve.impl'

export default convertNxExecutor(serveExecutor)
13 changes: 13 additions & 0 deletions packages/react-email/src/executors/serve/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 2,
"outputCapture": "direct-nodejs",
"type": "object",
"title": "Serve executor",
"description": "Runs react email",
"properties": {
"port": {
"type": "string"
}
},
"required": []
}
25 changes: 25 additions & 0 deletions packages/react-email/src/executors/serve/serve.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ExecutorContext } from '@nx/devkit'
import { buildCommand, execPackageManagerCommand } from '@nx-extend/core'

import 'dotenv/config'

export interface ServeExecutorOptions {
port?: string
}

export async function serveExecutor(
options: ServeExecutorOptions,
context: ExecutorContext
): Promise<{ success: boolean }> {
const { sourceRoot, root } = context.workspace.projects[context.projectName]

return execPackageManagerCommand(buildCommand([
'email dev',
`--dir=${sourceRoot || root}`,
options.port && `--port=${options.port}`
]), {
env: process.env
})
}

export default serveExecutor
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Button, Html } from "@react-email/components";
import * as React from "react";

export default function Email() {
return (
<Html>
<Button
href="https://example.com"
style={{ background: "#000", color: "#fff", padding: "12px 20px" }}
>
Click me
</Button>
</Html>
);
}
68 changes: 68 additions & 0 deletions packages/react-email/src/generators/init/init.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
addDependenciesToPackageJson,
addProjectConfiguration,
formatFiles,
generateFiles,
names,
offsetFromRoot, runTasksInSerial,
Tree
} from '@nx/devkit'
import { NormalizedSchema, normalizeOptions } from '@nx-extend/core'
import * as path from 'path'

import type { ReactEmailSchema } from './schema'

import { devDependencies } from '../../../package.json'

function addFiles(host: Tree, options: NormalizedSchema) {
generateFiles(host, path.join(__dirname, 'files'), options.projectRoot, {
...options,
...names(options.name),
offsetFromRoot: offsetFromRoot(options.projectRoot),
template: ''
})
}

export default async function (host: Tree, options: ReactEmailSchema) {
const normalizedOptions = normalizeOptions(host, options)

addProjectConfiguration(host, normalizedOptions.projectName, {
root: normalizedOptions.projectRoot,
projectType: 'application',
sourceRoot: `${normalizedOptions.projectRoot}/src`,
targets: {
serve: {
executor: '@nx-extend/react-email:serve',
options: {}
},
export: {
executor: '@nx-extend/react-email:export',
outputs: ['{options.outputPath}'],
defaultConfiguration: 'production',
options: {
outputPath: `dist/${normalizedOptions.projectRoot}`
},
configurations: {
production: {
pretty: false
}
}
}
},
tags: normalizedOptions.parsedTags
})

addFiles(host, normalizedOptions)
await formatFiles(host)

return runTasksInSerial(
addDependenciesToPackageJson(
host,
{},
{
'react-email': devDependencies['react-email'],
'@react-email/components': devDependencies['@react-email/components']
}
)
)
}
5 changes: 5 additions & 0 deletions packages/react-email/src/generators/init/schema.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ReactEmailSchema {
name: string
tags?: string
directory?: string
}
Loading

0 comments on commit f6bb593

Please sign in to comment.