react-email 3.0.5 → 3.0.7-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/cli/index.js +764 -769
- package/dist/cli/index.mjs +488 -499
- package/dist/preview/.next/BUILD_ID +1 -1
- package/dist/preview/.next/app-build-manifest.json +10 -10
- package/dist/preview/.next/build-manifest.json +3 -3
- package/dist/preview/.next/cache/.rscinfo +1 -1
- package/dist/preview/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/preview/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/preview/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/preview/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/preview/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/preview/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/preview/.next/next-server.js.nft.json +1 -1
- package/dist/preview/.next/prerender-manifest.json +1 -1
- package/dist/preview/.next/required-server-files.json +1 -1
- package/dist/preview/.next/server/app/_not-found/page.js +1 -1
- package/dist/preview/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/app/favicon.ico/route.js +1 -1
- package/dist/preview/.next/server/app/page.js +1 -1
- package/dist/preview/.next/server/app/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/app/preview/[...slug]/page.js +7 -6
- package/dist/preview/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
- package/dist/preview/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
- package/dist/preview/.next/server/chunks/196.js +5 -0
- package/dist/preview/.next/server/chunks/650.js +1 -0
- package/dist/preview/.next/server/chunks/720.js +3 -3
- package/dist/preview/.next/server/middleware-build-manifest.js +1 -1
- package/dist/preview/.next/server/next-font-manifest.js +1 -1
- package/dist/preview/.next/server/next-font-manifest.json +1 -1
- package/dist/preview/.next/server/pages/500.html +1 -1
- package/dist/preview/.next/server/server-reference-manifest.js +1 -1
- package/dist/preview/.next/server/server-reference-manifest.json +1 -1
- package/dist/preview/.next/static/chunks/154-ca55c1fde27d0922.js +1 -0
- package/dist/preview/.next/static/chunks/app/layout-7b9224888c7ffd05.js +1 -0
- package/dist/preview/.next/static/chunks/app/page-36853df2e13e583f.js +1 -0
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-48ce00470ce06446.js +1 -0
- package/dist/preview/.next/static/chunks/main-app-cd104297c6bcc87e.js +1 -0
- package/dist/preview/.next/static/css/{eb0a93282704d7ab.css → a34876a6c565fff8.css} +1 -1
- package/dist/preview/.next/trace +21 -20
- package/dist/preview/.next/types/app/layout.ts +1 -1
- package/dist/preview/.next/types/app/preview/[...slug]/page.ts +1 -1
- package/package.json +4 -8
- package/postcss.config.js +1 -1
- package/src/actions/get-email-path-from-slug.ts +7 -4
- package/src/actions/get-emails-directory-metadata-action.ts +19 -0
- package/src/actions/render-email-by-path.tsx +3 -3
- package/src/app/layout.tsx +2 -2
- package/src/app/page.tsx +1 -1
- package/src/app/preview/[...slug]/page.tsx +2 -2
- package/src/app/preview/[...slug]/preview.tsx +2 -2
- package/src/components/button.tsx +1 -1
- package/src/components/code-container.tsx +1 -1
- package/src/components/heading.tsx +1 -1
- package/src/components/sidebar/sidebar-directory-children.tsx +5 -8
- package/src/components/sidebar/sidebar-directory.tsx +2 -2
- package/src/components/sidebar/sidebar.tsx +2 -2
- package/src/components/text.tsx +1 -1
- package/src/components/tooltip-content.tsx +1 -1
- package/src/components/tooltip.tsx +1 -1
- package/src/components/topbar.tsx +1 -1
- package/src/contexts/emails.tsx +3 -5
- package/src/hooks/use-email-rendering-result.ts +2 -2
- package/src/utils/cn.ts +1 -1
- package/src/utils/esbuild/renderring-utilities-exporter.ts +1 -1
- package/src/utils/get-email-component.ts +6 -6
- package/src/{actions → utils}/get-emails-directory-metadata.spec.ts +1 -2
- package/src/utils/get-emails-directory-metadata.ts +119 -0
- package/src/utils/improve-error-with-sourcemap.ts +1 -1
- package/src/utils/static-node-modules-for-vm.ts +6 -6
- package/tsconfig.json +1 -6
- package/.eslintrc.js +0 -52
- package/.prettierignore +0 -3
- package/.prettierrc.js +0 -8
- package/dist/index.d.mts +0 -20
- package/dist/index.d.ts +0 -20
- package/dist/index.js +0 -96
- package/dist/index.mjs +0 -21
- package/dist/package/index.d.mts +0 -33
- package/dist/package/index.d.ts +0 -33
- package/dist/package/index.js +0 -62
- package/dist/package/index.mjs +0 -7
- package/dist/preview/.next/cache/eslint/.cache_1vyas3k +0 -1
- package/dist/preview/.next/server/chunks/420.js +0 -1
- package/dist/preview/.next/server/chunks/625.js +0 -5
- package/dist/preview/.next/static/chunks/154-69b91a0c2fd801b8.js +0 -1
- package/dist/preview/.next/static/chunks/app/layout-e1b6f1534cbbe5bd.js +0 -1
- package/dist/preview/.next/static/chunks/app/page-2c3e297e38c526ef.js +0 -1
- package/dist/preview/.next/static/chunks/app/preview/[...slug]/page-2b4988ba6daf34e1.js +0 -1
- package/dist/preview/.next/static/chunks/main-app-2c7f96205a73f128.js +0 -1
- package/src/actions/get-emails-directory-metadata.ts +0 -123
- package/src/package/body/dist/index.d.mts +0 -6
- package/src/package/body/dist/index.d.ts +0 -6
- package/src/package/body/dist/index.js +0 -79
- package/src/package/body/dist/index.mjs +0 -45
- package/src/package/button/dist/index.d.mts +0 -6
- package/src/package/button/dist/index.d.ts +0 -6
- package/src/package/button/dist/index.js +0 -252
- package/src/package/button/dist/index.mjs +0 -218
- package/src/package/code-block/dist/index.d.mts +0 -4906
- package/src/package/code-block/dist/index.d.ts +0 -4906
- package/src/package/code-block/dist/index.js +0 -18205
- package/src/package/code-block/dist/index.mjs +0 -18133
- package/src/package/code-inline/dist/index.d.mts +0 -11
- package/src/package/code-inline/dist/index.d.ts +0 -11
- package/src/package/code-inline/dist/index.js +0 -106
- package/src/package/code-inline/dist/index.mjs +0 -72
- package/src/package/column/dist/index.d.mts +0 -6
- package/src/package/column/dist/index.d.ts +0 -6
- package/src/package/column/dist/index.js +0 -79
- package/src/package/column/dist/index.mjs +0 -45
- package/src/package/components/dist/index.d.mts +0 -20
- package/src/package/components/dist/index.d.ts +0 -20
- package/src/package/components/dist/index.js +0 -62
- package/src/package/components/dist/index.mjs +0 -21
- package/src/package/container/dist/index.d.mts +0 -6
- package/src/package/container/dist/index.d.ts +0 -6
- package/src/package/container/dist/index.js +0 -93
- package/src/package/container/dist/index.mjs +0 -59
- package/src/package/font/dist/index.d.mts +0 -25
- package/src/package/font/dist/index.d.ts +0 -25
- package/src/package/font/dist/index.js +0 -55
- package/src/package/font/dist/index.mjs +0 -28
- package/src/package/head/dist/index.d.mts +0 -6
- package/src/package/head/dist/index.d.ts +0 -6
- package/src/package/head/dist/index.js +0 -83
- package/src/package/head/dist/index.mjs +0 -49
- package/src/package/heading/dist/index.d.mts +0 -43
- package/src/package/heading/dist/index.d.ts +0 -43
- package/src/package/heading/dist/index.js +0 -113
- package/src/package/heading/dist/index.mjs +0 -79
- package/src/package/hr/dist/index.d.mts +0 -6
- package/src/package/hr/dist/index.d.ts +0 -6
- package/src/package/hr/dist/index.js +0 -89
- package/src/package/hr/dist/index.mjs +0 -55
- package/src/package/html/dist/index.d.mts +0 -6
- package/src/package/html/dist/index.d.ts +0 -6
- package/src/package/html/dist/index.js +0 -79
- package/src/package/html/dist/index.mjs +0 -45
- package/src/package/img/dist/index.d.mts +0 -6
- package/src/package/img/dist/index.d.ts +0 -6
- package/src/package/img/dist/index.js +0 -94
- package/src/package/img/dist/index.mjs +0 -60
- package/src/package/link/dist/index.d.mts +0 -6
- package/src/package/link/dist/index.d.ts +0 -6
- package/src/package/link/dist/index.js +0 -90
- package/src/package/link/dist/index.mjs +0 -56
- package/src/package/markdown/dist/index.d.mts +0 -15
- package/src/package/markdown/dist/index.d.ts +0 -15
- package/src/package/markdown/dist/index.js +0 -92
- package/src/package/markdown/dist/index.mjs +0 -58
- package/src/package/preview/dist/index.d.mts +0 -12
- package/src/package/preview/dist/index.d.ts +0 -12
- package/src/package/preview/dist/index.js +0 -108
- package/src/package/preview/dist/index.mjs +0 -73
- package/src/package/render/dist/browser/index.d.mts +0 -24
- package/src/package/render/dist/browser/index.d.ts +0 -24
- package/src/package/render/dist/browser/index.js +0 -250
- package/src/package/render/dist/browser/index.mjs +0 -214
- package/src/package/render/dist/index.d.mts +0 -23
- package/src/package/render/dist/index.d.ts +0 -23
- package/src/package/render/dist/index.js +0 -768
- package/src/package/render/dist/index.mjs +0 -733
- package/src/package/render/dist/node/index.d.mts +0 -27
- package/src/package/render/dist/node/index.d.ts +0 -27
- package/src/package/render/dist/node/index.js +0 -212
- package/src/package/render/dist/node/index.mjs +0 -176
- package/src/package/row/dist/index.d.mts +0 -10
- package/src/package/row/dist/index.d.ts +0 -10
- package/src/package/row/dist/index.js +0 -93
- package/src/package/row/dist/index.mjs +0 -59
- package/src/package/section/dist/index.d.mts +0 -6
- package/src/package/section/dist/index.d.ts +0 -6
- package/src/package/section/dist/index.js +0 -93
- package/src/package/section/dist/index.mjs +0 -59
- package/src/package/tailwind/dist/index.d.ts +0 -19
- package/src/package/tailwind/dist/index.js +0 -48
- package/src/package/tailwind/dist/index.mjs +0 -17167
- package/src/package/tailwind/dist/tailwindcss/config.d.ts +0 -376
- package/src/package/tailwind/dist/tailwindcss/generated/.gitkeep +0 -0
- package/src/package/tailwind/dist/tailwindcss/generated/colors.d.ts +0 -298
- package/src/package/tailwind/dist/tailwindcss/generated/corePluginList.d.ts +0 -1
- package/src/package/tailwind/dist/tailwindcss/generated/default-theme.d.ts +0 -397
- package/src/package/tailwind/dist/tailwindcss/index.d.ts +0 -11
- package/src/package/text/dist/index.d.mts +0 -6
- package/src/package/text/dist/index.d.ts +0 -6
- package/src/package/text/dist/index.js +0 -89
- package/src/package/text/dist/index.mjs +0 -55
- /package/dist/preview/.next/static/{6K68y2QEZ1dLbv-Xhi30p → 3Ni4t_kYMdpL72HxSPHgK}/_buildManifest.js +0 -0
- /package/dist/preview/.next/static/{6K68y2QEZ1dLbv-Xhi30p → 3Ni4t_kYMdpL72HxSPHgK}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// File: /home/gabriel/Projects/
|
|
1
|
+
// File: /home/gabriel/Projects/Resend/react-email.git/tertiary/packages/react-email/src/app/layout.tsx
|
|
2
2
|
import * as entry from '../../../src/app/layout.js'
|
|
3
3
|
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// File: /home/gabriel/Projects/
|
|
1
|
+
// File: /home/gabriel/Projects/Resend/react-email.git/tertiary/packages/react-email/src/app/preview/[...slug]/page.tsx
|
|
2
2
|
import * as entry from '../../../../../src/app/preview/[...slug]/page.js'
|
|
3
3
|
import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-email",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7-canary.0",
|
|
4
4
|
"description": "A live preview of your emails right in your browser.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"email": "./dist/cli/index.js"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"chokidar": "4.0.3",
|
|
26
26
|
"commander": "11.1.0",
|
|
27
27
|
"debounce": "2.0.0",
|
|
28
|
-
"esbuild": "0.
|
|
28
|
+
"esbuild": "0.23.0",
|
|
29
29
|
"glob": "10.3.4",
|
|
30
30
|
"log-symbols": "4.1.0",
|
|
31
31
|
"mime-types": "2.1.35",
|
|
@@ -53,9 +53,6 @@
|
|
|
53
53
|
"@vercel/style-guide": "5.1.0",
|
|
54
54
|
"autoprefixer": "10.4.20",
|
|
55
55
|
"clsx": "2.1.0",
|
|
56
|
-
"eslint": "8.50.0",
|
|
57
|
-
"eslint-config-prettier": "9.0.0",
|
|
58
|
-
"eslint-config-turbo": "2.1.0",
|
|
59
56
|
"framer-motion": "12.0.0-alpha.2",
|
|
60
57
|
"postcss": "8.4.40",
|
|
61
58
|
"prism-react-renderer": "2.1.0",
|
|
@@ -72,14 +69,13 @@
|
|
|
72
69
|
"tsx": "4.9.0",
|
|
73
70
|
"typescript": "5.1.6",
|
|
74
71
|
"vitest": "1.1.3",
|
|
75
|
-
"@react-email/render": "1.0.
|
|
72
|
+
"@react-email/render": "1.0.5-canary.0"
|
|
76
73
|
},
|
|
77
74
|
"scripts": {
|
|
78
75
|
"build": "tsup-node && node build-preview-server.mjs",
|
|
79
76
|
"dev": "tsup-node --watch",
|
|
80
77
|
"test": "vitest run",
|
|
81
78
|
"test:watch": "vitest",
|
|
82
|
-
"clean": "rm -rf dist"
|
|
83
|
-
"lint": "eslint . && tsc"
|
|
79
|
+
"clean": "rm -rf dist"
|
|
84
80
|
}
|
|
85
81
|
}
|
package/postcss.config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use server';
|
|
2
|
-
import path from 'node:path';
|
|
3
2
|
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import { cache } from 'react';
|
|
5
5
|
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
6
6
|
|
|
@@ -13,11 +13,14 @@ export const getEmailPathFromSlug = cache(async (slug: string) => {
|
|
|
13
13
|
|
|
14
14
|
if (fs.existsSync(`${pathWithoutExtension}.tsx`)) {
|
|
15
15
|
return `${pathWithoutExtension}.tsx`;
|
|
16
|
-
}
|
|
16
|
+
}
|
|
17
|
+
if (fs.existsSync(`${pathWithoutExtension}.jsx`)) {
|
|
17
18
|
return `${pathWithoutExtension}.jsx`;
|
|
18
|
-
}
|
|
19
|
+
}
|
|
20
|
+
if (fs.existsSync(`${pathWithoutExtension}.ts`)) {
|
|
19
21
|
return `${pathWithoutExtension}.ts`;
|
|
20
|
-
}
|
|
22
|
+
}
|
|
23
|
+
if (fs.existsSync(`${pathWithoutExtension}.js`)) {
|
|
21
24
|
return `${pathWithoutExtension}.js`;
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
import type { EmailsDirectory } from '../utils/get-emails-directory-metadata';
|
|
4
|
+
import { getEmailsDirectoryMetadata } from '../utils/get-emails-directory-metadata';
|
|
5
|
+
|
|
6
|
+
export const getEmailsDirectoryMetadataAction = async (
|
|
7
|
+
absolutePathToEmailsDirectory: string,
|
|
8
|
+
keepFileExtensions = false,
|
|
9
|
+
isSubDirectory = false,
|
|
10
|
+
|
|
11
|
+
baseDirectoryPath = absolutePathToEmailsDirectory,
|
|
12
|
+
): Promise<EmailsDirectory | undefined> => {
|
|
13
|
+
return getEmailsDirectoryMetadata(
|
|
14
|
+
absolutePathToEmailsDirectory,
|
|
15
|
+
keepFileExtensions,
|
|
16
|
+
isSubDirectory,
|
|
17
|
+
baseDirectoryPath,
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import ora from 'ora';
|
|
5
|
-
import logSymbols from 'log-symbols';
|
|
6
4
|
import chalk from 'chalk';
|
|
5
|
+
import logSymbols from 'log-symbols';
|
|
6
|
+
import ora from 'ora';
|
|
7
7
|
import { getEmailComponent } from '../utils/get-email-component';
|
|
8
|
-
import type { ErrorObject } from '../utils/types/error-object';
|
|
9
8
|
import { improveErrorWithSourceMap } from '../utils/improve-error-with-sourcemap';
|
|
10
9
|
import { registerSpinnerAutostopping } from '../utils/register-spinner-autostopping';
|
|
10
|
+
import type { ErrorObject } from '../utils/types/error-object';
|
|
11
11
|
|
|
12
12
|
export interface RenderedEmailMetadata {
|
|
13
13
|
markup: string;
|
package/src/app/layout.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Metadata } from 'next';
|
|
2
2
|
import './globals.css';
|
|
3
|
-
import { getEmailsDirectoryMetadata } from '../actions/get-emails-directory-metadata';
|
|
4
|
-
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
5
3
|
import { EmailsProvider } from '../contexts/emails';
|
|
4
|
+
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
5
|
+
import { getEmailsDirectoryMetadata } from '../utils/get-emails-directory-metadata';
|
|
6
6
|
import { inter } from './inter';
|
|
7
7
|
|
|
8
8
|
export const metadata: Metadata = {
|
package/src/app/page.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import Link from 'next/link';
|
|
3
2
|
import Image from 'next/image';
|
|
3
|
+
import Link from 'next/link';
|
|
4
4
|
import { Button, Heading, Text } from '../components';
|
|
5
5
|
import { Shell } from '../components/shell';
|
|
6
6
|
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { Suspense } from 'react';
|
|
3
2
|
import { redirect } from 'next/navigation';
|
|
3
|
+
import { Suspense } from 'react';
|
|
4
4
|
import { getEmailPathFromSlug } from '../../../actions/get-email-path-from-slug';
|
|
5
|
-
import { getEmailsDirectoryMetadata } from '../../../actions/get-emails-directory-metadata';
|
|
6
5
|
import { renderEmailByPath } from '../../../actions/render-email-by-path';
|
|
7
6
|
import { emailsDirectoryAbsolutePath } from '../../../utils/emails-directory-absolute-path';
|
|
7
|
+
import { getEmailsDirectoryMetadata } from '../../../utils/get-emails-directory-metadata';
|
|
8
8
|
import Home from '../../page';
|
|
9
9
|
import Preview from './preview';
|
|
10
10
|
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { Toaster } from 'sonner';
|
|
6
|
-
import { useHotreload } from '../../../hooks/use-hot-reload';
|
|
7
6
|
import type { EmailRenderingResult } from '../../../actions/render-email-by-path';
|
|
8
7
|
import { CodeContainer } from '../../../components/code-container';
|
|
9
8
|
import { Shell } from '../../../components/shell';
|
|
10
9
|
import { Tooltip } from '../../../components/tooltip';
|
|
11
|
-
import { useRenderingMetadata } from '../../../hooks/use-rendering-metadata';
|
|
12
10
|
import { useEmailRenderingResult } from '../../../hooks/use-email-rendering-result';
|
|
11
|
+
import { useHotreload } from '../../../hooks/use-hot-reload';
|
|
12
|
+
import { useRenderingMetadata } from '../../../hooks/use-rendering-metadata';
|
|
13
13
|
import { RenderingError } from './rendering-error';
|
|
14
14
|
|
|
15
15
|
interface PreviewProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as SlotPrimitive from '@radix-ui/react-slot';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { unreachable } from '../utils/unreachable';
|
|
4
3
|
import { cn } from '../utils/cn';
|
|
4
|
+
import { unreachable } from '../utils/unreachable';
|
|
5
5
|
|
|
6
6
|
type ButtonElement = React.ElementRef<'button'>;
|
|
7
7
|
type RootProps = React.ComponentPropsWithoutRef<'button'>;
|
|
@@ -2,8 +2,8 @@ import { LayoutGroup, motion } from 'framer-motion';
|
|
|
2
2
|
import type { Language } from 'prism-react-renderer';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { copyTextToClipboard } from '../utils';
|
|
5
|
-
import languageMap from '../utils/language-map';
|
|
6
5
|
import { tabTransition } from '../utils/constants';
|
|
6
|
+
import languageMap from '../utils/language-map';
|
|
7
7
|
import { Code } from './code';
|
|
8
8
|
import { IconButton } from './icons/icon-button';
|
|
9
9
|
import { IconCheck } from './icons/icon-check';
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
|
|
2
1
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
2
|
+
import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
|
|
3
3
|
import Link from 'next/link';
|
|
4
4
|
import { useSearchParams } from 'next/navigation';
|
|
5
|
-
import type { EmailsDirectory } from '../../actions/get-emails-directory-metadata';
|
|
6
|
-
import { emailsDirectoryAbsolutePath } from '../../utils/emails-directory-absolute-path';
|
|
7
5
|
import { cn } from '../../utils';
|
|
6
|
+
import type { EmailsDirectory } from '../../utils/get-emails-directory-metadata';
|
|
8
7
|
import { IconFile } from '../icons/icon-file';
|
|
9
8
|
import { SidebarDirectory } from './sidebar-directory';
|
|
10
9
|
|
|
@@ -15,15 +14,13 @@ export const SidebarDirectoryChildren = (props: {
|
|
|
15
14
|
isRoot?: boolean;
|
|
16
15
|
}) => {
|
|
17
16
|
const searchParams = useSearchParams();
|
|
18
|
-
const isBaseEmailsDirectory =
|
|
19
|
-
props.emailsDirectoryMetadata.absolutePath === emailsDirectoryAbsolutePath;
|
|
20
17
|
|
|
21
18
|
return (
|
|
22
19
|
<AnimatePresence initial={false}>
|
|
23
20
|
{props.open ? (
|
|
24
21
|
<Collapsible.Content
|
|
25
22
|
asChild
|
|
26
|
-
className="relative
|
|
23
|
+
className="relative overflow-y-hidden pl-1"
|
|
27
24
|
forceMount
|
|
28
25
|
>
|
|
29
26
|
<motion.div
|
|
@@ -35,7 +32,7 @@ export const SidebarDirectoryChildren = (props: {
|
|
|
35
32
|
<div className="line absolute left-2.5 w-px h-full bg-slate-6" />
|
|
36
33
|
)}
|
|
37
34
|
|
|
38
|
-
<div className="
|
|
35
|
+
<div className="flex flex-col truncate">
|
|
39
36
|
<LayoutGroup id="sidebar">
|
|
40
37
|
{props.emailsDirectoryMetadata.subDirectories.map(
|
|
41
38
|
(subDirectory) => (
|
|
@@ -50,7 +47,7 @@ export const SidebarDirectoryChildren = (props: {
|
|
|
50
47
|
|
|
51
48
|
{props.emailsDirectoryMetadata.emailFilenames.map(
|
|
52
49
|
(emailFilename, index) => {
|
|
53
|
-
const emailSlug =
|
|
50
|
+
const emailSlug = props.isRoot
|
|
54
51
|
? emailFilename
|
|
55
52
|
: `${props.emailsDirectoryMetadata.relativePath}/${emailFilename}`;
|
|
56
53
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { cn } from '../../utils';
|
|
5
|
-
import {
|
|
5
|
+
import type { EmailsDirectory } from '../../utils/get-emails-directory-metadata';
|
|
6
6
|
import { Heading } from '../heading';
|
|
7
|
+
import { IconArrowDown } from '../icons/icon-arrow-down';
|
|
7
8
|
import { IconFolder } from '../icons/icon-folder';
|
|
8
9
|
import { IconFolderOpen } from '../icons/icon-folder-open';
|
|
9
|
-
import { IconArrowDown } from '../icons/icon-arrow-down';
|
|
10
10
|
import { SidebarDirectoryChildren } from './sidebar-directory-children';
|
|
11
11
|
|
|
12
12
|
interface SidebarDirectoryProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import * as React from 'react';
|
|
4
3
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
4
|
+
import * as React from 'react';
|
|
5
5
|
import { useEmails } from '../../contexts/emails';
|
|
6
6
|
import { cn } from '../../utils';
|
|
7
7
|
import { Logo } from '../logo';
|
|
@@ -29,7 +29,7 @@ export const Sidebar = ({
|
|
|
29
29
|
<Logo />
|
|
30
30
|
</div>
|
|
31
31
|
<nav className="p-4 flex-grow lg:pt-0 pl-0 w-screen h-[calc(100vh_-_70px)] lg:w-full lg:min-w-[275px] lg:max-w-[275px] flex flex-col overflow-y-auto">
|
|
32
|
-
<Collapsible.Root>
|
|
32
|
+
<Collapsible.Root open>
|
|
33
33
|
<React.Suspense>
|
|
34
34
|
<SidebarDirectoryChildren
|
|
35
35
|
currentEmailOpenSlug={currentEmailOpenSlug}
|
package/src/components/text.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as SlotPrimitive from '@radix-ui/react-slot';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { type As,
|
|
3
|
+
import { type As, cn, unreachable } from '../utils';
|
|
4
4
|
|
|
5
5
|
export type TextSize = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
6
6
|
export type TextColor = 'gray' | 'white';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { cn } from '../utils';
|
|
4
3
|
import { inter } from '../app/inter';
|
|
4
|
+
import { cn } from '../utils';
|
|
5
5
|
|
|
6
6
|
type ContentElement = React.ElementRef<typeof TooltipPrimitive.Content>;
|
|
7
7
|
type ContentProps = React.ComponentPropsWithoutRef<
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
2
|
-
import * as React from 'react';
|
|
2
|
+
import type * as React from 'react';
|
|
3
3
|
import { TooltipContent } from './tooltip-content';
|
|
4
4
|
|
|
5
5
|
type RootProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as ToggleGroup from '@radix-ui/react-toggle-group';
|
|
3
3
|
import { motion } from 'framer-motion';
|
|
4
|
-
import * as React from 'react';
|
|
4
|
+
import type * as React from 'react';
|
|
5
5
|
import { cn } from '../utils';
|
|
6
6
|
import { tabTransition } from '../utils/constants';
|
|
7
7
|
import { Heading } from './heading';
|
package/src/contexts/emails.tsx
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { createContext, useContext, useState } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
getEmailsDirectoryMetadata,
|
|
5
|
-
type EmailsDirectory,
|
|
6
|
-
} from '../actions/get-emails-directory-metadata';
|
|
3
|
+
import { getEmailsDirectoryMetadataAction } from '../actions/get-emails-directory-metadata-action';
|
|
7
4
|
import { useHotreload } from '../hooks/use-hot-reload';
|
|
5
|
+
import type { EmailsDirectory } from '../utils/get-emails-directory-metadata';
|
|
8
6
|
|
|
9
7
|
const EmailsContext = createContext<
|
|
10
8
|
| {
|
|
@@ -37,7 +35,7 @@ export const EmailsProvider = (props: {
|
|
|
37
35
|
// the rules of hooks
|
|
38
36
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
39
37
|
useHotreload(async () => {
|
|
40
|
-
const metadata = await
|
|
38
|
+
const metadata = await getEmailsDirectoryMetadataAction(
|
|
41
39
|
props.initialEmailsDirectoryMetadata.absolutePath,
|
|
42
40
|
);
|
|
43
41
|
if (metadata) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
+
import { getEmailPathFromSlug } from '../actions/get-email-path-from-slug';
|
|
2
3
|
import {
|
|
3
|
-
renderEmailByPath,
|
|
4
4
|
type EmailRenderingResult,
|
|
5
|
+
renderEmailByPath,
|
|
5
6
|
} from '../actions/render-email-by-path';
|
|
6
|
-
import { getEmailPathFromSlug } from '../actions/get-email-path-from-slug';
|
|
7
7
|
import { useHotreload } from './use-hot-reload';
|
|
8
8
|
|
|
9
9
|
export const useEmailRenderingResult = (
|
package/src/utils/cn.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import vm from 'node:vm';
|
|
4
|
-
import type React from 'react';
|
|
5
|
-
import { type RawSourceMap } from 'source-map-js';
|
|
6
|
-
import { type OutputFile, build, type BuildFailure } from 'esbuild';
|
|
7
4
|
import type { render } from '@react-email/render';
|
|
8
|
-
import type
|
|
9
|
-
import type
|
|
5
|
+
import { type BuildFailure, type OutputFile, build } from 'esbuild';
|
|
6
|
+
import type React from 'react';
|
|
7
|
+
import type { RawSourceMap } from 'source-map-js';
|
|
8
|
+
import { renderingUtilitiesExporter } from './esbuild/renderring-utilities-exporter';
|
|
10
9
|
import { improveErrorWithSourceMap } from './improve-error-with-sourcemap';
|
|
11
10
|
import { staticNodeModulesForVM } from './static-node-modules-for-vm';
|
|
12
|
-
import {
|
|
11
|
+
import type { EmailTemplate as EmailComponent } from './types/email-template';
|
|
12
|
+
import type { ErrorObject } from './types/error-object';
|
|
13
13
|
|
|
14
14
|
export const getEmailComponent = async (
|
|
15
15
|
emailPath: string,
|
|
@@ -4,7 +4,7 @@ import { getEmailsDirectoryMetadata } from './get-emails-directory-metadata';
|
|
|
4
4
|
test('getEmailsDirectoryMetadata on demo emails', async () => {
|
|
5
5
|
const emailsDirectoryPath = path.resolve(
|
|
6
6
|
__dirname,
|
|
7
|
-
'../../../../apps/demo/emails
|
|
7
|
+
'../../../../apps/demo/emails',
|
|
8
8
|
);
|
|
9
9
|
expect(await getEmailsDirectoryMetadata(emailsDirectoryPath)).toEqual({
|
|
10
10
|
absolutePath: emailsDirectoryPath,
|
|
@@ -18,7 +18,6 @@ test('getEmailsDirectoryMetadata on demo emails', async () => {
|
|
|
18
18
|
relativePath: 'magic-links',
|
|
19
19
|
emailFilenames: [
|
|
20
20
|
'aws-verify-email',
|
|
21
|
-
'jobaccepted-magic-link',
|
|
22
21
|
'linear-login-code',
|
|
23
22
|
'notion-magic-link',
|
|
24
23
|
'plaid-verify-identity',
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
const isFileAnEmail = (fullPath: string): boolean => {
|
|
6
|
+
const stat = fs.statSync(fullPath);
|
|
7
|
+
|
|
8
|
+
if (stat.isDirectory()) return false;
|
|
9
|
+
|
|
10
|
+
const { ext } = path.parse(fullPath);
|
|
11
|
+
|
|
12
|
+
if (!['.js', '.tsx', '.jsx'].includes(ext)) return false;
|
|
13
|
+
|
|
14
|
+
// This is to avoid a possible race condition where the file doesn't exist anymore
|
|
15
|
+
// once we are checking if it is an actual email, this couuld cause issues that
|
|
16
|
+
// would be very hard to debug and find out the why of it happening.
|
|
17
|
+
if (!fs.existsSync(fullPath)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// check with a heuristic to see if the file has at least
|
|
22
|
+
// a default export
|
|
23
|
+
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
|
24
|
+
|
|
25
|
+
return /\bexport\s+default\b/gm.test(fileContents);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export interface EmailsDirectory {
|
|
29
|
+
absolutePath: string;
|
|
30
|
+
relativePath: string;
|
|
31
|
+
directoryName: string;
|
|
32
|
+
emailFilenames: string[];
|
|
33
|
+
subDirectories: EmailsDirectory[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const mergeDirectoriesWithSubDirectories = (
|
|
37
|
+
emailsDirectoryMetadata: EmailsDirectory,
|
|
38
|
+
): EmailsDirectory => {
|
|
39
|
+
let currentResultingMergedDirectory: EmailsDirectory =
|
|
40
|
+
emailsDirectoryMetadata;
|
|
41
|
+
|
|
42
|
+
while (
|
|
43
|
+
currentResultingMergedDirectory.emailFilenames.length === 0 &&
|
|
44
|
+
currentResultingMergedDirectory.subDirectories.length === 1
|
|
45
|
+
) {
|
|
46
|
+
const onlySubDirectory = currentResultingMergedDirectory.subDirectories[0]!;
|
|
47
|
+
currentResultingMergedDirectory = {
|
|
48
|
+
...onlySubDirectory,
|
|
49
|
+
directoryName: path.join(
|
|
50
|
+
currentResultingMergedDirectory.directoryName,
|
|
51
|
+
onlySubDirectory.directoryName,
|
|
52
|
+
),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return currentResultingMergedDirectory;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const getEmailsDirectoryMetadata = async (
|
|
60
|
+
absolutePathToEmailsDirectory: string,
|
|
61
|
+
keepFileExtensions = false,
|
|
62
|
+
isSubDirectory = false,
|
|
63
|
+
|
|
64
|
+
baseDirectoryPath = absolutePathToEmailsDirectory,
|
|
65
|
+
): Promise<EmailsDirectory | undefined> => {
|
|
66
|
+
if (!fs.existsSync(absolutePathToEmailsDirectory)) return;
|
|
67
|
+
|
|
68
|
+
const dirents = await fs.promises.readdir(absolutePathToEmailsDirectory, {
|
|
69
|
+
withFileTypes: true,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const emailFilenames = dirents
|
|
73
|
+
.filter((dirent) =>
|
|
74
|
+
isFileAnEmail(path.join(absolutePathToEmailsDirectory, dirent.name)),
|
|
75
|
+
)
|
|
76
|
+
.map((dirent) =>
|
|
77
|
+
keepFileExtensions
|
|
78
|
+
? dirent.name
|
|
79
|
+
: dirent.name.replace(path.extname(dirent.name), ''),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const subDirectories = await Promise.all(
|
|
83
|
+
dirents
|
|
84
|
+
.filter(
|
|
85
|
+
(dirent) =>
|
|
86
|
+
dirent.isDirectory() &&
|
|
87
|
+
!dirent.name.startsWith('_') &&
|
|
88
|
+
dirent.name !== 'static',
|
|
89
|
+
)
|
|
90
|
+
.map((dirent) => {
|
|
91
|
+
const direntAbsolutePath = path.join(
|
|
92
|
+
absolutePathToEmailsDirectory,
|
|
93
|
+
dirent.name,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return getEmailsDirectoryMetadata(
|
|
97
|
+
direntAbsolutePath,
|
|
98
|
+
keepFileExtensions,
|
|
99
|
+
true,
|
|
100
|
+
baseDirectoryPath,
|
|
101
|
+
) as Promise<EmailsDirectory>;
|
|
102
|
+
}),
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const emailsMetadata = {
|
|
106
|
+
absolutePath: absolutePathToEmailsDirectory,
|
|
107
|
+
relativePath: path.relative(
|
|
108
|
+
baseDirectoryPath,
|
|
109
|
+
absolutePathToEmailsDirectory,
|
|
110
|
+
),
|
|
111
|
+
directoryName: absolutePathToEmailsDirectory.split(path.sep).pop()!,
|
|
112
|
+
emailFilenames,
|
|
113
|
+
subDirectories,
|
|
114
|
+
} satisfies EmailsDirectory;
|
|
115
|
+
|
|
116
|
+
return isSubDirectory
|
|
117
|
+
? mergeDirectoriesWithSubDirectories(emailsMetadata)
|
|
118
|
+
: emailsMetadata;
|
|
119
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { type RawSourceMap, SourceMapConsumer } from 'source-map-js';
|
|
2
3
|
import * as stackTraceParser from 'stacktrace-parser';
|
|
3
|
-
import { SourceMapConsumer, type RawSourceMap } from 'source-map-js';
|
|
4
4
|
import type { ErrorObject } from './types/error-object';
|
|
5
5
|
|
|
6
6
|
export const improveErrorWithSourceMap = (
|
|
@@ -48,15 +48,15 @@ import zlib from 'node:zlib';
|
|
|
48
48
|
*/
|
|
49
49
|
export const staticNodeModulesForVM = {
|
|
50
50
|
assert,
|
|
51
|
-
|
|
51
|
+
async_hooks: asyncHooks,
|
|
52
52
|
buffer,
|
|
53
|
-
|
|
53
|
+
child_process: childProcess,
|
|
54
54
|
cluster,
|
|
55
55
|
console,
|
|
56
56
|
constants,
|
|
57
57
|
crypto,
|
|
58
58
|
dgram,
|
|
59
|
-
|
|
59
|
+
diagnostics_channel: diagnosticsChannel,
|
|
60
60
|
dns,
|
|
61
61
|
domain,
|
|
62
62
|
events,
|
|
@@ -70,14 +70,14 @@ export const staticNodeModulesForVM = {
|
|
|
70
70
|
net,
|
|
71
71
|
os,
|
|
72
72
|
path,
|
|
73
|
-
|
|
73
|
+
perf_hooks: perfHooks,
|
|
74
74
|
process,
|
|
75
75
|
punycode,
|
|
76
76
|
querystring,
|
|
77
77
|
readline,
|
|
78
78
|
repl,
|
|
79
79
|
stream,
|
|
80
|
-
|
|
80
|
+
string_decoder: stringDecoder,
|
|
81
81
|
timers,
|
|
82
82
|
'timers/promises': timersPromises,
|
|
83
83
|
tls,
|
|
@@ -87,6 +87,6 @@ export const staticNodeModulesForVM = {
|
|
|
87
87
|
'util/types': utilTypes,
|
|
88
88
|
v8,
|
|
89
89
|
vm,
|
|
90
|
-
|
|
90
|
+
worker_threads: workerThreads,
|
|
91
91
|
zlib,
|
|
92
92
|
};
|
package/tsconfig.json
CHANGED
|
@@ -30,10 +30,5 @@
|
|
|
30
30
|
"outDir": "dist"
|
|
31
31
|
},
|
|
32
32
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
33
|
-
"exclude": [
|
|
34
|
-
"tsconfig.export.json",
|
|
35
|
-
".next",
|
|
36
|
-
"dist",
|
|
37
|
-
"node_modules"
|
|
38
|
-
]
|
|
33
|
+
"exclude": ["tsconfig.export.json", ".next", "dist", "node_modules"]
|
|
39
34
|
}
|