promote-email-templates 0.0.3 → 0.0.4
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/dist/index.d.mts +0 -8
- package/dist/index.d.ts +0 -8
- package/dist/index.js +3 -7
- package/dist/index.mjs +3 -7
- package/package.json +1 -1
- package/.react-email/.eslintrc.js +0 -52
- package/.react-email/.prettierignore +0 -3
- package/.react-email/.prettierrc.js +0 -8
- package/.react-email/license.md +0 -7
- package/.react-email/next.config.js +0 -36
- package/.react-email/package.json +0 -1
- package/.react-email/postcss.config.js +0 -8
- package/.react-email/readme.md +0 -44
- package/.react-email/src/actions/get-email-path-from-slug.ts +0 -26
- package/.react-email/src/actions/get-emails-directory-metadata.spec.ts +0 -73
- package/.react-email/src/actions/get-emails-directory-metadata.ts +0 -91
- package/.react-email/src/actions/render-email-by-path.tsx +0 -59
- package/.react-email/src/app/favicon.ico +0 -0
- package/.react-email/src/app/globals.css +0 -35
- package/.react-email/src/app/inter.ts +0 -7
- package/.react-email/src/app/layout.tsx +0 -36
- package/.react-email/src/app/logo.png +0 -0
- package/.react-email/src/app/page.tsx +0 -47
- package/.react-email/src/app/preview/[...slug]/page.tsx +0 -65
- package/.react-email/src/app/preview/[...slug]/preview.tsx +0 -141
- package/.react-email/src/app/preview/[...slug]/rendering-error.tsx +0 -40
- package/.react-email/src/components/button.tsx +0 -90
- package/.react-email/src/components/code-container.tsx +0 -145
- package/.react-email/src/components/code.tsx +0 -112
- package/.react-email/src/components/heading.tsx +0 -113
- package/.react-email/src/components/icons/icon-arrow-down.tsx +0 -16
- package/.react-email/src/components/icons/icon-base.tsx +0 -24
- package/.react-email/src/components/icons/icon-button.tsx +0 -23
- package/.react-email/src/components/icons/icon-check.tsx +0 -19
- package/.react-email/src/components/icons/icon-clipboard.tsx +0 -40
- package/.react-email/src/components/icons/icon-download.tsx +0 -19
- package/.react-email/src/components/icons/icon-file.tsx +0 -19
- package/.react-email/src/components/icons/icon-folder-open.tsx +0 -19
- package/.react-email/src/components/icons/icon-folder.tsx +0 -18
- package/.react-email/src/components/icons/icon-hide-sidebar.tsx +0 -23
- package/.react-email/src/components/icons/icon-monitor.tsx +0 -19
- package/.react-email/src/components/icons/icon-phone.tsx +0 -26
- package/.react-email/src/components/icons/icon-source.tsx +0 -19
- package/.react-email/src/components/index.ts +0 -7
- package/.react-email/src/components/logo.tsx +0 -64
- package/.react-email/src/components/send.tsx +0 -135
- package/.react-email/src/components/shell.tsx +0 -115
- package/.react-email/src/components/sidebar/index.ts +0 -1
- package/.react-email/src/components/sidebar/sidebar-directory-children.tsx +0 -134
- package/.react-email/src/components/sidebar/sidebar-directory.tsx +0 -106
- package/.react-email/src/components/sidebar/sidebar.tsx +0 -45
- package/.react-email/src/components/text.tsx +0 -99
- package/.react-email/src/components/tooltip-content.tsx +0 -32
- package/.react-email/src/components/tooltip.tsx +0 -19
- package/.react-email/src/components/topbar.tsx +0 -161
- package/.react-email/src/contexts/emails.tsx +0 -127
- package/.react-email/src/hooks/use-hot-reload.ts +0 -35
- package/.react-email/src/hooks/use-rendering-metadata.ts +0 -36
- package/.react-email/src/utils/cn.ts +0 -6
- package/.react-email/src/utils/constants.ts +0 -6
- package/.react-email/src/utils/copy-text-to-clipboard.ts +0 -7
- package/.react-email/src/utils/emails-directory-absolute-path.ts +0 -34
- package/.react-email/src/utils/get-email-component.ts +0 -108
- package/.react-email/src/utils/improve-error-with-sourcemap.ts +0 -55
- package/.react-email/src/utils/index.ts +0 -5
- package/.react-email/src/utils/language-map.ts +0 -7
- package/.react-email/src/utils/static-node-modules-for-vm.ts +0 -92
- package/.react-email/src/utils/types/as.ts +0 -26
- package/.react-email/src/utils/types/email-template.ts +0 -8
- package/.react-email/src/utils/types/error-object.ts +0 -11
- package/.react-email/src/utils/types/hot-reload-change.ts +0 -6
- package/.react-email/src/utils/types/hot-reload-event.ts +0 -6
- package/.react-email/src/utils/unreachable.ts +0 -8
- package/.react-email/tailwind.config.ts +0 -94
package/dist/index.d.mts
CHANGED
|
@@ -183,11 +183,9 @@ interface NewJobApplicationsReceivedBrandProps {
|
|
|
183
183
|
campaign: {
|
|
184
184
|
name: string;
|
|
185
185
|
description: string;
|
|
186
|
-
photo: string;
|
|
187
186
|
};
|
|
188
187
|
job: {
|
|
189
188
|
id: string;
|
|
190
|
-
createdAt: string;
|
|
191
189
|
jobCommission: string;
|
|
192
190
|
};
|
|
193
191
|
jobApplication: {
|
|
@@ -205,12 +203,10 @@ interface NewJobApplicationUnapprovedCreatorProps {
|
|
|
205
203
|
creator: {
|
|
206
204
|
name: string;
|
|
207
205
|
email: string;
|
|
208
|
-
photo: string;
|
|
209
206
|
};
|
|
210
207
|
campaign: {
|
|
211
208
|
name: string;
|
|
212
209
|
description: string;
|
|
213
|
-
photo: string;
|
|
214
210
|
};
|
|
215
211
|
jobApplication: {
|
|
216
212
|
id: string;
|
|
@@ -460,11 +456,9 @@ declare namespace NewJobApplicationsReceivedBrand {
|
|
|
460
456
|
campaign: {
|
|
461
457
|
name: string;
|
|
462
458
|
description: string;
|
|
463
|
-
photo: string;
|
|
464
459
|
};
|
|
465
460
|
job: {
|
|
466
461
|
id: string;
|
|
467
|
-
createdAt: string;
|
|
468
462
|
jobCommission: string;
|
|
469
463
|
};
|
|
470
464
|
jobApplication: {
|
|
@@ -568,12 +562,10 @@ declare namespace NewJobApplicationUnapprovedCreator {
|
|
|
568
562
|
creator: {
|
|
569
563
|
name: string;
|
|
570
564
|
email: string;
|
|
571
|
-
photo: string;
|
|
572
565
|
};
|
|
573
566
|
campaign: {
|
|
574
567
|
name: string;
|
|
575
568
|
description: string;
|
|
576
|
-
photo: string;
|
|
577
569
|
};
|
|
578
570
|
jobApplication: {
|
|
579
571
|
id: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -183,11 +183,9 @@ interface NewJobApplicationsReceivedBrandProps {
|
|
|
183
183
|
campaign: {
|
|
184
184
|
name: string;
|
|
185
185
|
description: string;
|
|
186
|
-
photo: string;
|
|
187
186
|
};
|
|
188
187
|
job: {
|
|
189
188
|
id: string;
|
|
190
|
-
createdAt: string;
|
|
191
189
|
jobCommission: string;
|
|
192
190
|
};
|
|
193
191
|
jobApplication: {
|
|
@@ -205,12 +203,10 @@ interface NewJobApplicationUnapprovedCreatorProps {
|
|
|
205
203
|
creator: {
|
|
206
204
|
name: string;
|
|
207
205
|
email: string;
|
|
208
|
-
photo: string;
|
|
209
206
|
};
|
|
210
207
|
campaign: {
|
|
211
208
|
name: string;
|
|
212
209
|
description: string;
|
|
213
|
-
photo: string;
|
|
214
210
|
};
|
|
215
211
|
jobApplication: {
|
|
216
212
|
id: string;
|
|
@@ -460,11 +456,9 @@ declare namespace NewJobApplicationsReceivedBrand {
|
|
|
460
456
|
campaign: {
|
|
461
457
|
name: string;
|
|
462
458
|
description: string;
|
|
463
|
-
photo: string;
|
|
464
459
|
};
|
|
465
460
|
job: {
|
|
466
461
|
id: string;
|
|
467
|
-
createdAt: string;
|
|
468
462
|
jobCommission: string;
|
|
469
463
|
};
|
|
470
464
|
jobApplication: {
|
|
@@ -568,12 +562,10 @@ declare namespace NewJobApplicationUnapprovedCreator {
|
|
|
568
562
|
creator: {
|
|
569
563
|
name: string;
|
|
570
564
|
email: string;
|
|
571
|
-
photo: string;
|
|
572
565
|
};
|
|
573
566
|
campaign: {
|
|
574
567
|
name: string;
|
|
575
568
|
description: string;
|
|
576
|
-
photo: string;
|
|
577
569
|
};
|
|
578
570
|
jobApplication: {
|
|
579
571
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -885,12 +885,10 @@ NewJobApplicationsReceivedBrand.PreviewProps = {
|
|
|
885
885
|
},
|
|
886
886
|
campaign: {
|
|
887
887
|
name: "Megas at\xE9 Dormir",
|
|
888
|
-
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
889
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/8c52bb92-4a8b-472f-89cb-0428b90b8b74.jpg"
|
|
888
|
+
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
890
889
|
},
|
|
891
890
|
job: {
|
|
892
891
|
id: "1",
|
|
893
|
-
createdAt: "20 de Agosto, 2021",
|
|
894
892
|
jobCommission: "1000"
|
|
895
893
|
},
|
|
896
894
|
jobApplication: {
|
|
@@ -1190,13 +1188,11 @@ function NewJobApplicationUnapprovedCreator(props) {
|
|
|
1190
1188
|
NewJobApplicationUnapprovedCreator.PreviewProps = {
|
|
1191
1189
|
creator: {
|
|
1192
1190
|
name: "K\xE1tia Vanessa",
|
|
1193
|
-
email: "katia@example.com"
|
|
1194
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/creator-photo.jpg"
|
|
1191
|
+
email: "katia@example.com"
|
|
1195
1192
|
},
|
|
1196
1193
|
campaign: {
|
|
1197
1194
|
name: "Megas at\xE9 Dormir",
|
|
1198
|
-
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
1199
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/campaign-photo.jpg"
|
|
1195
|
+
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
1200
1196
|
},
|
|
1201
1197
|
jobApplication: {
|
|
1202
1198
|
id: "1",
|
package/dist/index.mjs
CHANGED
|
@@ -828,12 +828,10 @@ NewJobApplicationsReceivedBrand.PreviewProps = {
|
|
|
828
828
|
},
|
|
829
829
|
campaign: {
|
|
830
830
|
name: "Megas at\xE9 Dormir",
|
|
831
|
-
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
832
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/8c52bb92-4a8b-472f-89cb-0428b90b8b74.jpg"
|
|
831
|
+
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
833
832
|
},
|
|
834
833
|
job: {
|
|
835
834
|
id: "1",
|
|
836
|
-
createdAt: "20 de Agosto, 2021",
|
|
837
835
|
jobCommission: "1000"
|
|
838
836
|
},
|
|
839
837
|
jobApplication: {
|
|
@@ -1133,13 +1131,11 @@ function NewJobApplicationUnapprovedCreator(props) {
|
|
|
1133
1131
|
NewJobApplicationUnapprovedCreator.PreviewProps = {
|
|
1134
1132
|
creator: {
|
|
1135
1133
|
name: "K\xE1tia Vanessa",
|
|
1136
|
-
email: "katia@example.com"
|
|
1137
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/creator-photo.jpg"
|
|
1134
|
+
email: "katia@example.com"
|
|
1138
1135
|
},
|
|
1139
1136
|
campaign: {
|
|
1140
1137
|
name: "Megas at\xE9 Dormir",
|
|
1141
|
-
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
1142
|
-
photo: "https://s3.us-east-2.amazonaws.com/promote-mz.com/images/campaign-photo.jpg"
|
|
1138
|
+
description: "Ganhe megas s\xF3 por publicar uma foto com a Vodacom"
|
|
1143
1139
|
},
|
|
1144
1140
|
jobApplication: {
|
|
1145
1141
|
id: "1",
|
package/package.json
CHANGED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const { resolve } = require('node:path');
|
|
2
|
-
|
|
3
|
-
const project = resolve(process.cwd(), './tsconfig.json');
|
|
4
|
-
|
|
5
|
-
/** @type {import('eslint').ESLint.ConfigData} */
|
|
6
|
-
module.exports = {
|
|
7
|
-
extends: [
|
|
8
|
-
"@vercel/style-guide/eslint/node",
|
|
9
|
-
"@vercel/style-guide/eslint/browser",
|
|
10
|
-
"@vercel/style-guide/eslint/typescript",
|
|
11
|
-
"@vercel/style-guide/eslint/react",
|
|
12
|
-
"@vercel/style-guide/eslint/next",
|
|
13
|
-
"eslint-config-turbo",
|
|
14
|
-
]
|
|
15
|
-
.map(require.resolve)
|
|
16
|
-
.concat(["eslint-config-prettier"]),
|
|
17
|
-
parserOptions: {
|
|
18
|
-
project,
|
|
19
|
-
},
|
|
20
|
-
globals: {
|
|
21
|
-
React: true,
|
|
22
|
-
JSX: true,
|
|
23
|
-
},
|
|
24
|
-
settings: {
|
|
25
|
-
"import/resolver": {
|
|
26
|
-
typescript: {
|
|
27
|
-
project,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
ignorePatterns: ['cli/', 'cli/index.mjs', "node_modules/", "dist/"],
|
|
32
|
-
rules: {
|
|
33
|
-
"@next/next/no-img-element": "off",
|
|
34
|
-
"@typescript-eslint/explicit-function-return-type": "off",
|
|
35
|
-
"import/no-default-export": "off",
|
|
36
|
-
"jsx-a11y/no-autofocus": "off",
|
|
37
|
-
"no-alert": "off",
|
|
38
|
-
"react/no-array-index-key": "off",
|
|
39
|
-
"react/function-component-definition": [
|
|
40
|
-
2,
|
|
41
|
-
{
|
|
42
|
-
namedComponents: "arrow-function",
|
|
43
|
-
unnamedComponents: "arrow-function",
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
'import/no-cycle': 'off',
|
|
47
|
-
'import/no-extraneous-dependencies': 'off',
|
|
48
|
-
'turbo/no-undeclared-env-vars': 'off',
|
|
49
|
-
'eslint-comments/require-description': 'off',
|
|
50
|
-
'no-console': 'off',
|
|
51
|
-
},
|
|
52
|
-
};
|
package/.react-email/license.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Copyright 2024 Plus Five Five, Inc
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
-
|
|
5
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const path = require('path');
|
|
3
|
-
/** @type {import('next').NextConfig} */
|
|
4
|
-
module.exports = {
|
|
5
|
-
env: {
|
|
6
|
-
...{"NEXT_PUBLIC_EMAILS_DIR_RELATIVE_PATH":"./emails","NEXT_PUBLIC_CLI_PACKAGE_LOCATION":"PLACEHOLDER","NEXT_PUBLIC_OS_PATH_SEPARATOR":"/","NEXT_PUBLIC_USER_PROJECT_LOCATION":"PLACEHOLDER","NEXT_PUBLIC_IS_BUILDING":"true"},
|
|
7
|
-
NEXT_PUBLIC_USER_PROJECT_LOCATION: path.resolve(process.cwd(), '../'),
|
|
8
|
-
NEXT_PUBLIC_CLI_PACKAGE_LOCATION: process.cwd(),
|
|
9
|
-
},
|
|
10
|
-
// this is needed so that the code for building emails works properly
|
|
11
|
-
webpack: (
|
|
12
|
-
/** @type {import('webpack').Configuration & { externals: string[] }} */
|
|
13
|
-
config,
|
|
14
|
-
{ isServer }
|
|
15
|
-
) => {
|
|
16
|
-
if (isServer) {
|
|
17
|
-
config.externals.push('esbuild');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return config;
|
|
21
|
-
},
|
|
22
|
-
typescript: {
|
|
23
|
-
ignoreBuildErrors: true
|
|
24
|
-
},
|
|
25
|
-
eslint: {
|
|
26
|
-
ignoreDuringBuilds: true
|
|
27
|
-
},
|
|
28
|
-
experimental: {
|
|
29
|
-
webpackBuildWorker: true,
|
|
30
|
-
serverComponentsExternalPackages: [
|
|
31
|
-
'@react-email/components',
|
|
32
|
-
'@react-email/render',
|
|
33
|
-
'@react-email/tailwind',
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"name":"react-email","version":"2.1.0","description":"A live preview of your emails right in your browser.","bin":{"email":"./cli/index.js"},"license":"MIT","repository":{"type":"git","url":"https://github.com/resend/react-email.git","directory":"packages/react-email"},"keywords":["react","email"],"engines":{"node":">=18.0.0"},"dependencies":{"@radix-ui/colors":"1.0.1","@radix-ui/react-collapsible":"1.0.3","@radix-ui/react-popover":"1.0.6","@radix-ui/react-slot":"1.0.2","@radix-ui/react-toggle-group":"1.0.4","@radix-ui/react-tooltip":"1.0.6","@react-email/components":"0.0.15","@react-email/render":"0.0.12","@swc/core":"1.3.101","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","@types/webpack":"5.28.5","autoprefixer":"10.4.14","chalk":"4.1.2","chokidar":"3.5.3","clsx":"2.1.0","commander":"11.1.0","debounce":"2.0.0","esbuild":"0.19.11","eslint-config-prettier":"9.0.0","eslint-config-turbo":"1.10.12","framer-motion":"10.17.4","glob":"10.3.4","log-symbols":"4.1.0","mime-types":"2.1.35","next":"14.1.0","normalize-path":"3.0.0","ora":"5.4.1","postcss":"8.4.35","prism-react-renderer":"2.1.0","react":"^18.2.0","react-dom":"^18.2.0","shelljs":"0.8.5","socket.io":"4.7.3","socket.io-client":"4.7.3","sonner":"1.3.1","source-map-js":"1.0.2","stacktrace-parser":"0.1.10","tailwind-merge":"2.2.0","tailwindcss":"3.4.0","tree-cli":"0.6.7","typescript":"5.1.6","sharp":"0.33.2"},"devDependencies":{"@types/fs-extra":"11.0.1","@types/mime-types":"2.1.4","@types/node":"18.0.0","@types/normalize-path":"3.0.2","@types/shelljs":"0.8.15","@vercel/style-guide":"5.1.0","eslint":"8.50.0","tsup":"7.2.0","tsx":"4.7.0","vitest":"1.1.3","watch":"1.0.2"},"scripts":{"build":"next build","dev":"tsup --watch","test":"vitest run","clean":"rm -rf dist","lint":"eslint . && tsc","start":"next start"}}
|
package/.react-email/readme.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
3
|
-
<div align="center"><strong>React Email</strong></div>
|
|
4
|
-
<div align="center">The next generation of writing emails.<br />High-quality, unstyled components for creating emails.</div>
|
|
5
|
-
<br />
|
|
6
|
-
<div align="center">
|
|
7
|
-
<a href="https://react.email">Website</a>
|
|
8
|
-
<span> · </span>
|
|
9
|
-
<a href="https://github.com/resend/react-email">GitHub</a>
|
|
10
|
-
<span> · </span>
|
|
11
|
-
<a href="https://react.email/discord">Discord</a>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
## Getting started
|
|
15
|
-
|
|
16
|
-
To get started, open a new shell and run:
|
|
17
|
-
|
|
18
|
-
```sh
|
|
19
|
-
npx create-email
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
This will create a new folder called `emails` with a few email templates.
|
|
23
|
-
|
|
24
|
-
## Commands
|
|
25
|
-
|
|
26
|
-
### `email dev`
|
|
27
|
-
|
|
28
|
-
Starts a local development server that will watch your files and automatically rebuild your email when you make changes.
|
|
29
|
-
|
|
30
|
-
```sh
|
|
31
|
-
npx react-email dev
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### `email export`
|
|
35
|
-
|
|
36
|
-
Generates the plain HTML files of your emails into a `out` directory.
|
|
37
|
-
|
|
38
|
-
```sh
|
|
39
|
-
npx react-email export
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## License
|
|
43
|
-
|
|
44
|
-
MIT License
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use server';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
5
|
-
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
7
|
-
export const getEmailPathFromSlug = async (slug: string) => {
|
|
8
|
-
if (['.tsx', '.jsx', '.js'].includes(path.extname(slug)))
|
|
9
|
-
return path.join(emailsDirectoryAbsolutePath, slug);
|
|
10
|
-
|
|
11
|
-
const pathWithoutExtension = path.join(emailsDirectoryAbsolutePath, slug);
|
|
12
|
-
|
|
13
|
-
if (fs.existsSync(`${pathWithoutExtension}.tsx`)) {
|
|
14
|
-
return `${pathWithoutExtension}.tsx`;
|
|
15
|
-
} else if (fs.existsSync(`${pathWithoutExtension}.jsx`)) {
|
|
16
|
-
return `${pathWithoutExtension}.jsx`;
|
|
17
|
-
} else if (fs.existsSync(`${pathWithoutExtension}.js`)) {
|
|
18
|
-
return `${pathWithoutExtension}.jsx`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
throw new Error(
|
|
22
|
-
`Could not find your email file based on the slug by guessing the file extension. Tried .tsx, .jsx and .js.
|
|
23
|
-
|
|
24
|
-
This is most likely not an issue with the preview server. It most likely is that the email doesn't exist.`,
|
|
25
|
-
);
|
|
26
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { getEmailsDirectoryMetadata } from './get-emails-directory-metadata';
|
|
3
|
-
|
|
4
|
-
test('getEmailsDirectoryMetadata on demo emails', async () => {
|
|
5
|
-
const emailsDirectoryPath = path.resolve(
|
|
6
|
-
__dirname,
|
|
7
|
-
'../../../../apps/demo/emails/',
|
|
8
|
-
);
|
|
9
|
-
expect(await getEmailsDirectoryMetadata(emailsDirectoryPath)).toEqual({
|
|
10
|
-
absolutePath: emailsDirectoryPath,
|
|
11
|
-
directoryName: 'emails',
|
|
12
|
-
emailFilenames: [],
|
|
13
|
-
subDirectories: [
|
|
14
|
-
{
|
|
15
|
-
absolutePath: `${emailsDirectoryPath}/magic-links`,
|
|
16
|
-
directoryName: 'magic-links',
|
|
17
|
-
emailFilenames: [
|
|
18
|
-
'aws-verify-email',
|
|
19
|
-
'linear-login-code',
|
|
20
|
-
'notion-magic-link',
|
|
21
|
-
'plaid-verify-identity',
|
|
22
|
-
'raycast-magic-link',
|
|
23
|
-
'slack-confirm',
|
|
24
|
-
],
|
|
25
|
-
subDirectories: [],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
absolutePath: `${emailsDirectoryPath}/newsletters`,
|
|
29
|
-
directoryName: 'newsletters',
|
|
30
|
-
emailFilenames: [
|
|
31
|
-
'codepen-challengers',
|
|
32
|
-
'google-play-policy-update',
|
|
33
|
-
'stack-overflow-tips',
|
|
34
|
-
],
|
|
35
|
-
subDirectories: [],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
absolutePath: `${emailsDirectoryPath}/notifications`,
|
|
39
|
-
directoryName: 'notifications',
|
|
40
|
-
emailFilenames: [
|
|
41
|
-
'github-access-token',
|
|
42
|
-
'vercel-invite-user',
|
|
43
|
-
'yelp-recent-login',
|
|
44
|
-
],
|
|
45
|
-
subDirectories: [],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
absolutePath: `${emailsDirectoryPath}/receipts`,
|
|
49
|
-
directoryName: 'receipts',
|
|
50
|
-
emailFilenames: ['apple-receipt', 'nike-receipt'],
|
|
51
|
-
subDirectories: [],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
absolutePath: `${emailsDirectoryPath}/reset-password`,
|
|
55
|
-
directoryName: 'reset-password',
|
|
56
|
-
emailFilenames: ['dropbox-reset-password', 'twitch-reset-password'],
|
|
57
|
-
subDirectories: [],
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
absolutePath: `${emailsDirectoryPath}/reviews`,
|
|
61
|
-
directoryName: 'reviews',
|
|
62
|
-
emailFilenames: ['airbnb-review', 'amazon-review'],
|
|
63
|
-
subDirectories: [],
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
absolutePath: `${emailsDirectoryPath}/welcome`,
|
|
67
|
-
directoryName: 'welcome',
|
|
68
|
-
emailFilenames: ['koala-welcome', 'netlify-welcome', 'stripe-welcome'],
|
|
69
|
-
subDirectories: [],
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
});
|
|
73
|
-
});
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
'use server';
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
|
|
6
|
-
const isFileAnEmail = (fullPath: string): boolean => {
|
|
7
|
-
const stat = fs.statSync(fullPath);
|
|
8
|
-
|
|
9
|
-
if (stat.isDirectory()) return false;
|
|
10
|
-
|
|
11
|
-
const { ext } = path.parse(fullPath);
|
|
12
|
-
|
|
13
|
-
if (!['.js', '.tsx', '.jsx'].includes(ext)) return false;
|
|
14
|
-
|
|
15
|
-
// check with a heuristic to see if the file has at least
|
|
16
|
-
// a default export
|
|
17
|
-
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
|
18
|
-
|
|
19
|
-
return /\bexport\s+default\b/gm.test(fileContents);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export interface EmailsDirectory {
|
|
23
|
-
absolutePath: string;
|
|
24
|
-
directoryName: string;
|
|
25
|
-
emailFilenames: string[];
|
|
26
|
-
subDirectories: EmailsDirectory[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const mergeDirectoriesWithSubDirectories = (
|
|
30
|
-
emailsDirectoryMetadata: EmailsDirectory,
|
|
31
|
-
): EmailsDirectory => {
|
|
32
|
-
let currentResultingMergedDirectory: EmailsDirectory =
|
|
33
|
-
emailsDirectoryMetadata;
|
|
34
|
-
|
|
35
|
-
while (
|
|
36
|
-
currentResultingMergedDirectory.emailFilenames.length === 0 &&
|
|
37
|
-
currentResultingMergedDirectory.subDirectories.length === 1
|
|
38
|
-
) {
|
|
39
|
-
const onlySubDirectory = currentResultingMergedDirectory.subDirectories[0]!;
|
|
40
|
-
currentResultingMergedDirectory = {
|
|
41
|
-
subDirectories: onlySubDirectory.subDirectories,
|
|
42
|
-
emailFilenames: onlySubDirectory.emailFilenames,
|
|
43
|
-
absolutePath: onlySubDirectory.absolutePath,
|
|
44
|
-
directoryName: path.join(
|
|
45
|
-
currentResultingMergedDirectory.directoryName,
|
|
46
|
-
onlySubDirectory.directoryName,
|
|
47
|
-
),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return currentResultingMergedDirectory;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const getEmailsDirectoryMetadata = async (
|
|
55
|
-
absolutePathToEmailsDirectory: string,
|
|
56
|
-
): Promise<EmailsDirectory | undefined> => {
|
|
57
|
-
if (!fs.existsSync(absolutePathToEmailsDirectory)) return;
|
|
58
|
-
|
|
59
|
-
const dirents = await fs.promises.readdir(absolutePathToEmailsDirectory, {
|
|
60
|
-
withFileTypes: true,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const emailFilenames = dirents
|
|
64
|
-
.filter((dirent) =>
|
|
65
|
-
isFileAnEmail(path.join(absolutePathToEmailsDirectory, dirent.name)),
|
|
66
|
-
)
|
|
67
|
-
.map((dirent) => dirent.name.replace(path.extname(dirent.name), ''));
|
|
68
|
-
|
|
69
|
-
const subDirectories = await Promise.all(
|
|
70
|
-
dirents
|
|
71
|
-
.filter(
|
|
72
|
-
(dirent) =>
|
|
73
|
-
dirent.isDirectory() &&
|
|
74
|
-
!dirent.name.startsWith('_') &&
|
|
75
|
-
dirent.name !== 'static',
|
|
76
|
-
)
|
|
77
|
-
.map(
|
|
78
|
-
(dirent) =>
|
|
79
|
-
getEmailsDirectoryMetadata(
|
|
80
|
-
path.join(absolutePathToEmailsDirectory, dirent.name),
|
|
81
|
-
) as Promise<EmailsDirectory>,
|
|
82
|
-
),
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
return mergeDirectoriesWithSubDirectories({
|
|
86
|
-
absolutePath: absolutePathToEmailsDirectory,
|
|
87
|
-
directoryName: absolutePathToEmailsDirectory.split(path.sep).pop()!,
|
|
88
|
-
emailFilenames,
|
|
89
|
-
subDirectories,
|
|
90
|
-
});
|
|
91
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
'use server';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import { renderAsync } from '@react-email/render';
|
|
4
|
-
import { getEmailComponent } from '../utils/get-email-component';
|
|
5
|
-
import type { ErrorObject } from '../utils/types/error-object';
|
|
6
|
-
import { improveErrorWithSourceMap } from '../utils/improve-error-with-sourcemap';
|
|
7
|
-
|
|
8
|
-
export interface RenderedEmailMetadata {
|
|
9
|
-
markup: string;
|
|
10
|
-
plainText: string;
|
|
11
|
-
reactMarkup: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type EmailRenderingResult =
|
|
15
|
-
| RenderedEmailMetadata
|
|
16
|
-
| {
|
|
17
|
-
error: ErrorObject;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const renderEmailByPath = async (
|
|
21
|
-
emailPath: string,
|
|
22
|
-
): Promise<EmailRenderingResult> => {
|
|
23
|
-
const result = await getEmailComponent(emailPath);
|
|
24
|
-
|
|
25
|
-
if ('error' in result) {
|
|
26
|
-
return { error: result.error };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const { emailComponent: Email, sourceMapToOriginalFile } = result;
|
|
30
|
-
|
|
31
|
-
const previewProps = Email.PreviewProps || {};
|
|
32
|
-
const EmailComponent = Email as React.FC;
|
|
33
|
-
try {
|
|
34
|
-
const markup = await renderAsync(<EmailComponent {...previewProps} />, {
|
|
35
|
-
pretty: true,
|
|
36
|
-
});
|
|
37
|
-
const plainText = await renderAsync(<EmailComponent {...previewProps} />, {
|
|
38
|
-
plainText: true,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const reactMarkup = await fs.promises.readFile(emailPath, 'utf-8');
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
markup,
|
|
45
|
-
plainText,
|
|
46
|
-
reactMarkup,
|
|
47
|
-
};
|
|
48
|
-
} catch (exception) {
|
|
49
|
-
const error = exception as Error;
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
error: improveErrorWithSourceMap(
|
|
53
|
-
error,
|
|
54
|
-
emailPath,
|
|
55
|
-
sourceMapToOriginalFile,
|
|
56
|
-
),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
};
|
|
Binary file
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
@tailwind base;
|
|
2
|
-
@tailwind components;
|
|
3
|
-
@tailwind utilities;
|
|
4
|
-
|
|
5
|
-
:root {
|
|
6
|
-
--foreground-rgb: 0, 0, 0;
|
|
7
|
-
--background-start-rgb: 214, 219, 220;
|
|
8
|
-
--background-end-rgb: 255, 255, 255;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@media (prefers-color-scheme: dark) {
|
|
12
|
-
:root {
|
|
13
|
-
--foreground-rgb: 255, 255, 255;
|
|
14
|
-
--background-start-rgb: 0, 0, 0;
|
|
15
|
-
--background-end-rgb: 0, 0, 0;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
body {
|
|
20
|
-
color: rgb(var(--foreground-rgb));
|
|
21
|
-
background: linear-gradient(
|
|
22
|
-
to bottom,
|
|
23
|
-
transparent,
|
|
24
|
-
rgb(var(--background-end-rgb))
|
|
25
|
-
)
|
|
26
|
-
rgb(var(--background-start-rgb));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.popup-open iframe {
|
|
30
|
-
pointer-events: none;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
nav > div > div > .line {
|
|
34
|
-
display: none;
|
|
35
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Metadata } from 'next';
|
|
2
|
-
import './globals.css';
|
|
3
|
-
import { getEmailsDirectoryMetadata } from '../actions/get-emails-directory-metadata';
|
|
4
|
-
import { emailsDirectoryAbsolutePath } from '../utils/emails-directory-absolute-path';
|
|
5
|
-
import { EmailsProvider } from '../contexts/emails';
|
|
6
|
-
import { inter } from './inter';
|
|
7
|
-
|
|
8
|
-
export const metadata: Metadata = {
|
|
9
|
-
title: 'React Email',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const RootLayout = async ({ children }: { children: React.ReactNode }) => {
|
|
13
|
-
const emailsDirectoryMetadata = await getEmailsDirectoryMetadata(
|
|
14
|
-
emailsDirectoryAbsolutePath,
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
if (typeof emailsDirectoryMetadata === 'undefined') {
|
|
18
|
-
throw new Error(
|
|
19
|
-
`Could not find the emails directory specified under ${emailsDirectoryAbsolutePath}!`,
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<html lang="en">
|
|
25
|
-
<body className={inter.className}>
|
|
26
|
-
<EmailsProvider
|
|
27
|
-
initialEmailsDirectoryMetadata={emailsDirectoryMetadata}
|
|
28
|
-
>
|
|
29
|
-
{children}
|
|
30
|
-
</EmailsProvider>
|
|
31
|
-
</body>
|
|
32
|
-
</html>
|
|
33
|
-
);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export default RootLayout;
|