@ainsleydev/payload-helper 0.0.39 โ 0.1.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/README.md +163 -0
- package/dist/admin/components/Icon.d.ts +16 -0
- package/dist/admin/components/Icon.js +26 -0
- package/dist/admin/components/Icon.js.map +1 -0
- package/dist/cli/bin.js +20 -0
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/preview-emails.d.ts +5 -0
- package/dist/cli/commands/preview-emails.js +123 -0
- package/dist/cli/commands/preview-emails.js.map +1 -0
- package/dist/email/ForgotPasswordEmail.d.ts +38 -0
- package/dist/email/ForgotPasswordEmail.js +61 -0
- package/dist/email/ForgotPasswordEmail.js.map +1 -0
- package/dist/email/ForgotPasswordEmail.test.d.ts +1 -0
- package/dist/email/ForgotPasswordEmail.test.js +202 -0
- package/dist/email/ForgotPasswordEmail.test.js.map +1 -0
- package/dist/email/VerifyAccountEmail.d.ts +38 -0
- package/dist/email/VerifyAccountEmail.js +61 -0
- package/dist/email/VerifyAccountEmail.js.map +1 -0
- package/dist/email/VerifyAccountEmail.test.d.ts +1 -0
- package/dist/email/VerifyAccountEmail.test.js +212 -0
- package/dist/email/VerifyAccountEmail.test.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/plugin/admin.d.ts +10 -0
- package/dist/plugin/admin.js +50 -0
- package/dist/plugin/admin.js.map +1 -0
- package/dist/plugin/email.d.ts +10 -0
- package/dist/plugin/email.js +98 -0
- package/dist/plugin/email.js.map +1 -0
- package/dist/plugin/email.test.js +265 -0
- package/dist/plugin/email.test.js.map +1 -0
- package/dist/types.d.ts +147 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/package.json +28 -15
- package/dist/plugin/logo.d.ts +0 -6
- package/dist/plugin/logo.js +0 -26
- package/dist/plugin/logo.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,169 @@ Payload Helper is a project designed to extend and enhance functionality for Pay
|
|
|
4
4
|
project includes custom configurations, scripts, and utilities to streamline development and content
|
|
5
5
|
management processes.
|
|
6
6
|
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @ainsleydev/payload-helper
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @ainsleydev/payload-helper
|
|
13
|
+
# or
|
|
14
|
+
yarn add @ainsleydev/payload-helper
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
Add the plugin to your Payload configuration:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { payloadHelper } from '@ainsleydev/payload-helper'
|
|
23
|
+
|
|
24
|
+
export default buildConfig({
|
|
25
|
+
plugins: [
|
|
26
|
+
payloadHelper({
|
|
27
|
+
siteName: 'My Site',
|
|
28
|
+
admin: {
|
|
29
|
+
logo: {
|
|
30
|
+
path: '/images/logo-light.svg',
|
|
31
|
+
darkModePath: '/images/logo-dark.svg',
|
|
32
|
+
width: 150,
|
|
33
|
+
height: 40,
|
|
34
|
+
alt: 'My Site Logo',
|
|
35
|
+
className: 'custom-logo-class',
|
|
36
|
+
},
|
|
37
|
+
icon: {
|
|
38
|
+
path: '/images/icon-light.svg',
|
|
39
|
+
darkModePath: '/images/icon-dark.svg',
|
|
40
|
+
width: 120,
|
|
41
|
+
height: 120,
|
|
42
|
+
alt: 'My Site Icon',
|
|
43
|
+
className: 'custom-icon-class',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
### Admin configuration
|
|
54
|
+
|
|
55
|
+
The `admin` object contains configuration for admin UI customisation:
|
|
56
|
+
|
|
57
|
+
#### Logo configuration
|
|
58
|
+
|
|
59
|
+
The logo appears in the navigation area of the Payload admin dashboard.
|
|
60
|
+
|
|
61
|
+
- `path` (required): Path to the logo image file
|
|
62
|
+
- `darkModePath` (optional): Path to the logo for dark mode
|
|
63
|
+
- `width` (optional): Logo width in pixels (default: 150)
|
|
64
|
+
- `height` (optional): Logo height in pixels (default: 40)
|
|
65
|
+
- `alt` (optional): Alt text for the logo (defaults to siteName)
|
|
66
|
+
- `className` (optional): Custom CSS class name
|
|
67
|
+
|
|
68
|
+
#### Icon configuration
|
|
69
|
+
|
|
70
|
+
The icon appears in the top left corner of the Payload admin dashboard.
|
|
71
|
+
|
|
72
|
+
- `path` (required): Path to the icon image file
|
|
73
|
+
- `darkModePath` (optional): Path to the icon for dark mode
|
|
74
|
+
- `width` (optional): Icon width in pixels (default: 120)
|
|
75
|
+
- `height` (optional): Icon height in pixels (default: 120)
|
|
76
|
+
- `alt` (optional): Alt text for the icon (defaults to siteName)
|
|
77
|
+
- `className` (optional): Custom CSS class name
|
|
78
|
+
|
|
79
|
+
### Web server configuration
|
|
80
|
+
|
|
81
|
+
Configure cache invalidation for your web server:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
payloadHelper({
|
|
85
|
+
siteName: 'My Site',
|
|
86
|
+
webServer: {
|
|
87
|
+
apiKey: 'your-api-key',
|
|
88
|
+
baseURL: 'https://your-site.com',
|
|
89
|
+
cacheEndpoint: '/api/cache/purge',
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Email configuration
|
|
95
|
+
|
|
96
|
+
Configure branded email templates for Payload authentication flows. Automatically applies to all collections with `auth` enabled.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
payloadHelper({
|
|
100
|
+
siteName: 'My Site',
|
|
101
|
+
email: {
|
|
102
|
+
frontEndUrl: 'https://your-site.com', // Optional, defaults to Payload's serverURL
|
|
103
|
+
theme: {
|
|
104
|
+
branding: {
|
|
105
|
+
companyName: 'My Company',
|
|
106
|
+
logoUrl: 'https://your-site.com/logo.png',
|
|
107
|
+
},
|
|
108
|
+
colours: {
|
|
109
|
+
background: {
|
|
110
|
+
accent: '#ff5043',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
forgotPassword: {
|
|
115
|
+
heading: 'Reset your password',
|
|
116
|
+
bodyText: 'Click the button below to reset your password.',
|
|
117
|
+
buttonText: 'Reset Password',
|
|
118
|
+
},
|
|
119
|
+
verifyAccount: {
|
|
120
|
+
heading: 'Welcome aboard',
|
|
121
|
+
bodyText: 'Please verify your email address.',
|
|
122
|
+
buttonText: 'Verify Email',
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Previewing emails
|
|
129
|
+
|
|
130
|
+
Preview your emails with your actual branding directly from your Payload configuration:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx payload-helper preview-emails
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This command will:
|
|
137
|
+
- Read your `payload.config.ts` to extract your email theme configuration
|
|
138
|
+
- Generate preview templates with your actual branding
|
|
139
|
+
- Launch a preview server at http://localhost:3000
|
|
140
|
+
|
|
141
|
+
You can optionally specify a custom port:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx payload-helper preview-emails --port 3001
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The preview will show both ForgotPassword and VerifyAccount emails using your configured theme, frontEndUrl, and content overrides.
|
|
148
|
+
|
|
149
|
+
## Utilities
|
|
150
|
+
|
|
151
|
+
### Environment Variables
|
|
152
|
+
|
|
153
|
+
The package exports an `env` utility object that provides access to environment variables required by Payload Helper.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { env } from '@ainsleydev/payload-helper'
|
|
157
|
+
|
|
158
|
+
// Access environment variables
|
|
159
|
+
const spaces = {
|
|
160
|
+
key: env.DO_SPACES_KEY,
|
|
161
|
+
secret: env.DO_SPACES_SECRET,
|
|
162
|
+
endpoint: env.DO_SPACES_ENDPOINT,
|
|
163
|
+
region: env.DO_SPACES_REGION,
|
|
164
|
+
bucket: env.DO_SPACES_BUCKET,
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Note:** When using ESM modules, always import utilities from the main package entry point as shown above. Direct imports to subpaths (e.g., `@ainsleydev/payload-helper/dist/util/env`) are not supported.
|
|
169
|
+
|
|
7
170
|
## Open Source
|
|
8
171
|
|
|
9
172
|
ainsley.dev permits the use of any HTML, SCSS and Javascript found within the repository for use
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { AdminIconConfig } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the Icon component.
|
|
5
|
+
*/
|
|
6
|
+
export type IconProps = {
|
|
7
|
+
config: AdminIconConfig;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Icon component that displays a configurable icon with theme support.
|
|
11
|
+
* The icon appears in the top left corner of the Payload dashboard.
|
|
12
|
+
*
|
|
13
|
+
* @param {IconProps} props - Component props containing icon configuration
|
|
14
|
+
* @returns {React.ReactElement} Icon component
|
|
15
|
+
*/
|
|
16
|
+
export declare const Icon: React.FC<IconProps>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useTheme } from '@payloadcms/ui';
|
|
4
|
+
// @ts-expect-error - next/image is a peer dependency and will be available in consumer projects
|
|
5
|
+
import Image from 'next/image';
|
|
6
|
+
/**
|
|
7
|
+
* Icon component that displays a configurable icon with theme support.
|
|
8
|
+
* The icon appears in the top left corner of the Payload dashboard.
|
|
9
|
+
*
|
|
10
|
+
* @param {IconProps} props - Component props containing icon configuration
|
|
11
|
+
* @returns {React.ReactElement} Icon component
|
|
12
|
+
*/ export const Icon = ({ config })=>{
|
|
13
|
+
const { theme } = useTheme();
|
|
14
|
+
const imagePath = theme === 'light' || !config.darkModePath ? config.path : config.darkModePath;
|
|
15
|
+
return /*#__PURE__*/ _jsx("figure", {
|
|
16
|
+
className: config.className ? config.className : undefined,
|
|
17
|
+
children: /*#__PURE__*/ _jsx(Image, {
|
|
18
|
+
src: imagePath,
|
|
19
|
+
alt: config.alt || 'Icon',
|
|
20
|
+
width: config.width || 120,
|
|
21
|
+
height: config.height || 120
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=Icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/components/Icon.tsx"],"sourcesContent":["'use client';\n\nimport { useTheme } from '@payloadcms/ui';\n// @ts-expect-error - next/image is a peer dependency and will be available in consumer projects\nimport Image from 'next/image';\nimport type React from 'react';\nimport type { AdminIconConfig } from '../../types.js';\n\n/**\n * Props for the Icon component.\n */\nexport type IconProps = {\n\tconfig: AdminIconConfig;\n};\n\n/**\n * Icon component that displays a configurable icon with theme support.\n * The icon appears in the top left corner of the Payload dashboard.\n *\n * @param {IconProps} props - Component props containing icon configuration\n * @returns {React.ReactElement} Icon component\n */\nexport const Icon: React.FC<IconProps> = ({ config }) => {\n\tconst { theme } = useTheme();\n\tconst imagePath = theme === 'light' || !config.darkModePath ? config.path : config.darkModePath;\n\n\treturn (\n\t\t<figure className={config.className ? config.className : undefined}>\n\t\t\t<Image\n\t\t\t\tsrc={imagePath}\n\t\t\t\talt={config.alt || 'Icon'}\n\t\t\t\twidth={config.width || 120}\n\t\t\t\theight={config.height || 120}\n\t\t\t/>\n\t\t</figure>\n\t);\n};\n"],"names":["useTheme","Image","Icon","config","theme","imagePath","darkModePath","path","figure","className","undefined","src","alt","width","height"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,QAAQ,iBAAiB;AAC1C,gGAAgG;AAChG,OAAOC,WAAW,aAAa;AAW/B;;;;;;CAMC,GACD,OAAO,MAAMC,OAA4B,CAAC,EAAEC,MAAM,EAAE;IACnD,MAAM,EAAEC,KAAK,EAAE,GAAGJ;IAClB,MAAMK,YAAYD,UAAU,WAAW,CAACD,OAAOG,YAAY,GAAGH,OAAOI,IAAI,GAAGJ,OAAOG,YAAY;IAE/F,qBACC,KAACE;QAAOC,WAAWN,OAAOM,SAAS,GAAGN,OAAOM,SAAS,GAAGC;kBACxD,cAAA,KAACT;YACAU,KAAKN;YACLO,KAAKT,OAAOS,GAAG,IAAI;YACnBC,OAAOV,OAAOU,KAAK,IAAI;YACvBC,QAAQX,OAAOW,MAAM,IAAI;;;AAI7B,EAAE"}
|
package/dist/cli/bin.js
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
2
4
|
import { Command } from 'commander';
|
|
5
|
+
import { getPayload } from 'payload';
|
|
6
|
+
import { previewEmails } from './commands/preview-emails.js';
|
|
3
7
|
const program = new Command();
|
|
8
|
+
const filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const dirname = path.dirname(filename);
|
|
4
10
|
program.command('generate-types').description('Generate JSON schema types for Payload CMS');
|
|
11
|
+
program.command('preview-emails').description('Preview email templates with your Payload configuration').option('-p, --port <number>', 'Port to run preview server on', '3000').action(async (options)=>{
|
|
12
|
+
const payload = await getPayloadInstance();
|
|
13
|
+
await previewEmails({
|
|
14
|
+
payload,
|
|
15
|
+
port: Number.parseInt(options.port, 10)
|
|
16
|
+
});
|
|
17
|
+
});
|
|
5
18
|
export const bin = async ()=>{
|
|
6
19
|
await program.parseAsync(process.argv);
|
|
7
20
|
};
|
|
21
|
+
const getPayloadInstance = async ()=>{
|
|
22
|
+
const configPath = path.join(process.cwd(), 'src/payload.config.ts');
|
|
23
|
+
const config = (await import(configPath)).default;
|
|
24
|
+
return await getPayload({
|
|
25
|
+
config
|
|
26
|
+
});
|
|
27
|
+
};
|
|
8
28
|
|
|
9
29
|
//# sourceMappingURL=bin.js.map
|
package/dist/cli/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/cli/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport { type Payload, getPayload } from 'payload';\nimport { previewEmails } from './commands/preview-emails.js';\n\nconst program = new Command();\nconst filename = fileURLToPath(import.meta.url);\nconst dirname = path.dirname(filename);\n\nprogram.command('generate-types').description('Generate JSON schema types for Payload CMS');\nprogram\n\t.command('preview-emails')\n\t.description('Preview email templates with your Payload configuration')\n\t.option('-p, --port <number>', 'Port to run preview server on', '3000')\n\t.action(async (options) => {\n\t\tconst payload = await getPayloadInstance();\n\n\t\tawait previewEmails({\n\t\t\tpayload,\n\t\t\tport: Number.parseInt(options.port, 10),\n\t\t});\n\t});\n\nexport const bin = async () => {\n\tawait program.parseAsync(process.argv);\n};\n\nconst getPayloadInstance = async (): Promise<Payload> => {\n\tconst configPath = path.join(process.cwd(), 'src/payload.config.ts');\n\tconst config = (await import(configPath)).default;\n\n\treturn await getPayload({ config });\n};\n"],"names":["path","fileURLToPath","Command","getPayload","previewEmails","program","filename","url","dirname","command","description","option","action","options","payload","getPayloadInstance","port","Number","parseInt","bin","parseAsync","process","argv","configPath","join","cwd","config","default"],"mappings":";AAEA,OAAOA,UAAU,YAAY;AAC7B,SAASC,aAAa,QAAQ,WAAW;AACzC,SAASC,OAAO,QAAQ,YAAY;AACpC,SAAuBC,UAAU,QAAQ,UAAU;AACnD,SAASC,aAAa,QAAQ,+BAA+B;AAE7D,MAAMC,UAAU,IAAIH;AACpB,MAAMI,WAAWL,cAAc,YAAYM,GAAG;AAC9C,MAAMC,UAAUR,KAAKQ,OAAO,CAACF;AAE7BD,QAAQI,OAAO,CAAC,kBAAkBC,WAAW,CAAC;AAC9CL,QACEI,OAAO,CAAC,kBACRC,WAAW,CAAC,2DACZC,MAAM,CAAC,uBAAuB,iCAAiC,QAC/DC,MAAM,CAAC,OAAOC;IACd,MAAMC,UAAU,MAAMC;IAEtB,MAAMX,cAAc;QACnBU;QACAE,MAAMC,OAAOC,QAAQ,CAACL,QAAQG,IAAI,EAAE;IACrC;AACD;AAED,OAAO,MAAMG,MAAM;IAClB,MAAMd,QAAQe,UAAU,CAACC,QAAQC,IAAI;AACtC,EAAE;AAEF,MAAMP,qBAAqB;IAC1B,MAAMQ,aAAavB,KAAKwB,IAAI,CAACH,QAAQI,GAAG,IAAI;IAC5C,MAAMC,SAAS,AAAC,CAAA,MAAM,MAAM,CAACH,WAAU,EAAGI,OAAO;IAEjD,OAAO,MAAMxB,WAAW;QAAEuB;IAAO;AAClC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
/**
|
|
7
|
+
* Escapes a string for safe use in template literals.
|
|
8
|
+
*/ const escapeForTemplate = (str)=>{
|
|
9
|
+
return str.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$');
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves the email configuration from the Payload config.
|
|
13
|
+
*/ const getEmailConfig = (payload)=>{
|
|
14
|
+
const custom = payload.config.custom;
|
|
15
|
+
const payloadHelperOptions = custom?.payloadHelperOptions;
|
|
16
|
+
return payloadHelperOptions?.email;
|
|
17
|
+
};
|
|
18
|
+
export const previewEmails = async (options)=>{
|
|
19
|
+
const port = options.port || 3000;
|
|
20
|
+
const payload = options.payload;
|
|
21
|
+
console.log(chalk.blue('๐ Looking for email configuration...'));
|
|
22
|
+
// Get email config from stored plugin options
|
|
23
|
+
const emailConfig = getEmailConfig(payload);
|
|
24
|
+
if (!emailConfig) {
|
|
25
|
+
console.log(chalk.yellow('โ ๏ธ No email configuration found'));
|
|
26
|
+
console.log(chalk.yellow(' Make sure you have configured email in your payloadHelper plugin:\n'));
|
|
27
|
+
console.log(chalk.cyan(` payloadHelper({
|
|
28
|
+
email: {
|
|
29
|
+
theme: { /* ... */ },
|
|
30
|
+
frontEndUrl: 'https://yoursite.com',
|
|
31
|
+
}
|
|
32
|
+
})`));
|
|
33
|
+
console.log(chalk.yellow('\n Using default theme for email previews'));
|
|
34
|
+
} else {
|
|
35
|
+
console.log(chalk.green('โ Found email configuration'));
|
|
36
|
+
}
|
|
37
|
+
// Create temp directory for preview files
|
|
38
|
+
const tempDir = join(tmpdir(), `payload-helper-preview-${Date.now()}-${process.pid}`);
|
|
39
|
+
mkdirSync(tempDir, {
|
|
40
|
+
recursive: true
|
|
41
|
+
});
|
|
42
|
+
console.log(chalk.blue('๐ Generating preview templates...'));
|
|
43
|
+
// Extract theme and frontEndUrl
|
|
44
|
+
const themeConfig = emailConfig?.theme ? JSON.stringify(emailConfig.theme, null, 2) : '{}';
|
|
45
|
+
const frontEndUrl = emailConfig?.frontEndUrl || 'https://yoursite.com';
|
|
46
|
+
// Safely escape the frontEndUrl for use in template strings
|
|
47
|
+
const escapedFrontEndUrl = escapeForTemplate(frontEndUrl);
|
|
48
|
+
// Generate ForgotPassword preview
|
|
49
|
+
const forgotPasswordContent = emailConfig?.forgotPassword ? JSON.stringify(emailConfig.forgotPassword, null, 3) : 'undefined';
|
|
50
|
+
const forgotPasswordPreview = `import { renderEmail } from '@ainsleydev/email-templates';
|
|
51
|
+
import { ForgotPasswordEmail } from '@ainsleydev/payload-helper';
|
|
52
|
+
|
|
53
|
+
export default async function render() {
|
|
54
|
+
return renderEmail({
|
|
55
|
+
component: ForgotPasswordEmail,
|
|
56
|
+
props: {
|
|
57
|
+
user: { firstName: 'John', email: 'john@example.com' },
|
|
58
|
+
resetUrl: \`${escapedFrontEndUrl}/admin/reset/token123\`,
|
|
59
|
+
content: ${forgotPasswordContent},
|
|
60
|
+
},
|
|
61
|
+
theme: ${themeConfig},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
// Generate VerifyAccount preview
|
|
66
|
+
const verifyAccountContent = emailConfig?.verifyAccount ? JSON.stringify(emailConfig.verifyAccount, null, 3) : 'undefined';
|
|
67
|
+
const verifyAccountPreview = `import { renderEmail } from '@ainsleydev/email-templates';
|
|
68
|
+
import { VerifyAccountEmail } from '@ainsleydev/payload-helper';
|
|
69
|
+
|
|
70
|
+
export default async function render() {
|
|
71
|
+
return renderEmail({
|
|
72
|
+
component: VerifyAccountEmail,
|
|
73
|
+
props: {
|
|
74
|
+
user: { firstName: 'John', email: 'john@example.com' },
|
|
75
|
+
verifyUrl: \`${escapedFrontEndUrl}/admin/verify/token123\`,
|
|
76
|
+
content: ${verifyAccountContent},
|
|
77
|
+
},
|
|
78
|
+
theme: ${themeConfig},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
82
|
+
// Write preview files
|
|
83
|
+
writeFileSync(join(tempDir, 'forgot-password-email-preview.tsx'), forgotPasswordPreview);
|
|
84
|
+
writeFileSync(join(tempDir, 'verify-account-email-preview.tsx'), verifyAccountPreview);
|
|
85
|
+
console.log(chalk.green('โ Preview templates generated'));
|
|
86
|
+
console.log(chalk.blue(`๐ Starting preview server on http://localhost:${port}...`));
|
|
87
|
+
// Launch email-templates preview
|
|
88
|
+
const previewProcess = spawn('npx', [
|
|
89
|
+
'email-templates',
|
|
90
|
+
'preview',
|
|
91
|
+
tempDir,
|
|
92
|
+
`--port=${port}`
|
|
93
|
+
], {
|
|
94
|
+
stdio: 'inherit',
|
|
95
|
+
shell: true
|
|
96
|
+
});
|
|
97
|
+
// Cleanup on exit
|
|
98
|
+
const cleanup = ()=>{
|
|
99
|
+
console.log(chalk.blue('\n๐งน Cleaning up...'));
|
|
100
|
+
try {
|
|
101
|
+
rmSync(tempDir, {
|
|
102
|
+
recursive: true,
|
|
103
|
+
force: true
|
|
104
|
+
});
|
|
105
|
+
console.log(chalk.green('โ Cleanup complete'));
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(chalk.red('โ Error during cleanup:'), error);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
previewProcess.on('exit', (code)=>{
|
|
111
|
+
cleanup();
|
|
112
|
+
process.exit(code || 0);
|
|
113
|
+
});
|
|
114
|
+
// Handle Ctrl+C
|
|
115
|
+
process.on('SIGINT', ()=>{
|
|
116
|
+
previewProcess.kill('SIGINT');
|
|
117
|
+
});
|
|
118
|
+
process.on('SIGTERM', ()=>{
|
|
119
|
+
previewProcess.kill('SIGTERM');
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=preview-emails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/preview-emails.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport { mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport chalk from 'chalk';\nimport type { Payload } from 'payload';\nimport type { PayloadHelperPluginConfig } from '../../types.js';\n\n/**\n * Escapes a string for safe use in template literals.\n */\nconst escapeForTemplate = (str: string): string => {\n\treturn str.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$/g, '\\\\$');\n};\n\n/**\n * Retrieves the email configuration from the Payload config.\n */\nconst getEmailConfig = (payload: Payload): PayloadHelperPluginConfig['email'] | undefined => {\n\tconst custom = payload.config.custom as Record<string, unknown> | undefined;\n\tconst payloadHelperOptions = custom?.payloadHelperOptions as\n\t\t| PayloadHelperPluginConfig\n\t\t| undefined;\n\treturn payloadHelperOptions?.email;\n};\n\nexport const previewEmails = async (options: { payload: Payload; port?: number }) => {\n\tconst port = options.port || 3000;\n\tconst payload = options.payload;\n\n\tconsole.log(chalk.blue('๐ Looking for email configuration...'));\n\n\t// Get email config from stored plugin options\n\tconst emailConfig = getEmailConfig(payload);\n\n\tif (!emailConfig) {\n\t\tconsole.log(chalk.yellow('โ ๏ธ No email configuration found'));\n\t\tconsole.log(\n\t\t\tchalk.yellow(' Make sure you have configured email in your payloadHelper plugin:\\n'),\n\t\t);\n\t\tconsole.log(\n\t\t\tchalk.cyan(` payloadHelper({\n email: {\n theme: { /* ... */ },\n frontEndUrl: 'https://yoursite.com',\n }\n })`),\n\t\t);\n\t\tconsole.log(chalk.yellow('\\n Using default theme for email previews'));\n\t} else {\n\t\tconsole.log(chalk.green('โ Found email configuration'));\n\t}\n\n\t// Create temp directory for preview files\n\tconst tempDir = join(tmpdir(), `payload-helper-preview-${Date.now()}-${process.pid}`);\n\tmkdirSync(tempDir, { recursive: true });\n\n\tconsole.log(chalk.blue('๐ Generating preview templates...'));\n\n\t// Extract theme and frontEndUrl\n\tconst themeConfig = emailConfig?.theme ? JSON.stringify(emailConfig.theme, null, 2) : '{}';\n\tconst frontEndUrl = emailConfig?.frontEndUrl || 'https://yoursite.com';\n\n\t// Safely escape the frontEndUrl for use in template strings\n\tconst escapedFrontEndUrl = escapeForTemplate(frontEndUrl);\n\n\t// Generate ForgotPassword preview\n\tconst forgotPasswordContent = emailConfig?.forgotPassword\n\t\t? JSON.stringify(emailConfig.forgotPassword, null, 3)\n\t\t: 'undefined';\n\n\tconst forgotPasswordPreview = `import { renderEmail } from '@ainsleydev/email-templates';\nimport { ForgotPasswordEmail } from '@ainsleydev/payload-helper';\n\nexport default async function render() {\n\treturn renderEmail({\n\t\tcomponent: ForgotPasswordEmail,\n\t\tprops: {\n\t\t\tuser: { firstName: 'John', email: 'john@example.com' },\n\t\t\tresetUrl: \\`${escapedFrontEndUrl}/admin/reset/token123\\`,\n\t\t\tcontent: ${forgotPasswordContent},\n\t\t},\n\t\ttheme: ${themeConfig},\n\t});\n}\n`;\n\n\t// Generate VerifyAccount preview\n\tconst verifyAccountContent = emailConfig?.verifyAccount\n\t\t? JSON.stringify(emailConfig.verifyAccount, null, 3)\n\t\t: 'undefined';\n\n\tconst verifyAccountPreview = `import { renderEmail } from '@ainsleydev/email-templates';\nimport { VerifyAccountEmail } from '@ainsleydev/payload-helper';\n\nexport default async function render() {\n\treturn renderEmail({\n\t\tcomponent: VerifyAccountEmail,\n\t\tprops: {\n\t\t\tuser: { firstName: 'John', email: 'john@example.com' },\n\t\t\tverifyUrl: \\`${escapedFrontEndUrl}/admin/verify/token123\\`,\n\t\t\tcontent: ${verifyAccountContent},\n\t\t},\n\t\ttheme: ${themeConfig},\n\t});\n}\n`;\n\n\t// Write preview files\n\twriteFileSync(join(tempDir, 'forgot-password-email-preview.tsx'), forgotPasswordPreview);\n\twriteFileSync(join(tempDir, 'verify-account-email-preview.tsx'), verifyAccountPreview);\n\n\tconsole.log(chalk.green('โ Preview templates generated'));\n\tconsole.log(chalk.blue(`๐ Starting preview server on http://localhost:${port}...`));\n\n\t// Launch email-templates preview\n\tconst previewProcess = spawn('npx', ['email-templates', 'preview', tempDir, `--port=${port}`], {\n\t\tstdio: 'inherit',\n\t\tshell: true,\n\t});\n\n\t// Cleanup on exit\n\tconst cleanup = () => {\n\t\tconsole.log(chalk.blue('\\n๐งน Cleaning up...'));\n\t\ttry {\n\t\t\trmSync(tempDir, { recursive: true, force: true });\n\t\t\tconsole.log(chalk.green('โ Cleanup complete'));\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.red('โ Error during cleanup:'), error);\n\t\t}\n\t};\n\n\tpreviewProcess.on('exit', (code) => {\n\t\tcleanup();\n\t\tprocess.exit(code || 0);\n\t});\n\n\t// Handle Ctrl+C\n\tprocess.on('SIGINT', () => {\n\t\tpreviewProcess.kill('SIGINT');\n\t});\n\n\tprocess.on('SIGTERM', () => {\n\t\tpreviewProcess.kill('SIGTERM');\n\t});\n};\n"],"names":["spawn","mkdirSync","rmSync","writeFileSync","tmpdir","join","chalk","escapeForTemplate","str","replace","getEmailConfig","payload","custom","config","payloadHelperOptions","email","previewEmails","options","port","console","log","blue","emailConfig","yellow","cyan","green","tempDir","Date","now","process","pid","recursive","themeConfig","theme","JSON","stringify","frontEndUrl","escapedFrontEndUrl","forgotPasswordContent","forgotPassword","forgotPasswordPreview","verifyAccountContent","verifyAccount","verifyAccountPreview","previewProcess","stdio","shell","cleanup","force","error","red","on","code","exit","kill"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { EmailTheme } from '@ainsleydev/email-templates';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the ForgotPasswordEmail component.
|
|
5
|
+
*/
|
|
6
|
+
export interface ForgotPasswordEmailProps {
|
|
7
|
+
/**
|
|
8
|
+
* The email theme (required by renderEmail).
|
|
9
|
+
*/
|
|
10
|
+
theme: EmailTheme;
|
|
11
|
+
/**
|
|
12
|
+
* The user object containing user information.
|
|
13
|
+
*/
|
|
14
|
+
user: {
|
|
15
|
+
firstName?: string;
|
|
16
|
+
email?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The URL for resetting the password.
|
|
20
|
+
*/
|
|
21
|
+
resetUrl: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional content overrides.
|
|
24
|
+
*/
|
|
25
|
+
content?: {
|
|
26
|
+
previewText?: string;
|
|
27
|
+
heading?: string;
|
|
28
|
+
bodyText?: string;
|
|
29
|
+
buttonText?: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Email template for password reset requests in Payload CMS.
|
|
34
|
+
*
|
|
35
|
+
* @param props - The component props
|
|
36
|
+
* @returns The rendered email component
|
|
37
|
+
*/
|
|
38
|
+
export declare const ForgotPasswordEmail: ({ theme, user, resetUrl, content, }: ForgotPasswordEmailProps) => React.JSX.Element;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BaseEmail, Button, Heading, Section, Text } from '@ainsleydev/email-templates';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Email template for password reset requests in Payload CMS.
|
|
6
|
+
*
|
|
7
|
+
* @param props - The component props
|
|
8
|
+
* @returns The rendered email component
|
|
9
|
+
*/ export const ForgotPasswordEmail = ({ theme, user, resetUrl, content })=>{
|
|
10
|
+
const userName = user.firstName || user.email || 'there';
|
|
11
|
+
const previewText = content?.previewText || 'Reset your password';
|
|
12
|
+
const heading = content?.heading || `Hello, ${userName}!`;
|
|
13
|
+
const bodyText = content?.bodyText || 'We received a request to reset your password, please click the button below. If you did not request a password reset, you can safely ignore this email.';
|
|
14
|
+
const buttonText = content?.buttonText || 'Reset Password';
|
|
15
|
+
return /*#__PURE__*/ _jsxs(BaseEmail, {
|
|
16
|
+
theme: theme,
|
|
17
|
+
previewText: previewText,
|
|
18
|
+
children: [
|
|
19
|
+
/*#__PURE__*/ _jsx(Heading, {
|
|
20
|
+
style: {
|
|
21
|
+
color: theme.colours.text.heading,
|
|
22
|
+
fontSize: '24px',
|
|
23
|
+
fontWeight: 'bold',
|
|
24
|
+
marginBottom: '20px'
|
|
25
|
+
},
|
|
26
|
+
children: heading
|
|
27
|
+
}),
|
|
28
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
29
|
+
style: {
|
|
30
|
+
color: theme.colours.text.body,
|
|
31
|
+
fontSize: '16px',
|
|
32
|
+
lineHeight: '24px',
|
|
33
|
+
marginBottom: '30px'
|
|
34
|
+
},
|
|
35
|
+
children: bodyText
|
|
36
|
+
}),
|
|
37
|
+
/*#__PURE__*/ _jsx(Section, {
|
|
38
|
+
style: {
|
|
39
|
+
textAlign: 'center',
|
|
40
|
+
marginBottom: '30px'
|
|
41
|
+
},
|
|
42
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
43
|
+
href: resetUrl,
|
|
44
|
+
style: {
|
|
45
|
+
backgroundColor: theme.colours.background.accent,
|
|
46
|
+
color: theme.colours.text.heading,
|
|
47
|
+
padding: '12px 32px',
|
|
48
|
+
borderRadius: '5px',
|
|
49
|
+
fontSize: '16px',
|
|
50
|
+
fontWeight: 'bold',
|
|
51
|
+
textDecoration: 'none',
|
|
52
|
+
display: 'inline-block'
|
|
53
|
+
},
|
|
54
|
+
children: buttonText
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=ForgotPasswordEmail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/email/ForgotPasswordEmail.tsx"],"sourcesContent":["import { BaseEmail, Button, Heading, Section, Text } from '@ainsleydev/email-templates';\nimport type { EmailTheme } from '@ainsleydev/email-templates';\nimport * as React from 'react';\n\n/**\n * Props for the ForgotPasswordEmail component.\n */\nexport interface ForgotPasswordEmailProps {\n\t/**\n\t * The email theme (required by renderEmail).\n\t */\n\ttheme: EmailTheme;\n\n\t/**\n\t * The user object containing user information.\n\t */\n\tuser: {\n\t\tfirstName?: string;\n\t\temail?: string;\n\t};\n\n\t/**\n\t * The URL for resetting the password.\n\t */\n\tresetUrl: string;\n\n\t/**\n\t * Optional content overrides.\n\t */\n\tcontent?: {\n\t\tpreviewText?: string;\n\t\theading?: string;\n\t\tbodyText?: string;\n\t\tbuttonText?: string;\n\t};\n}\n\n/**\n * Email template for password reset requests in Payload CMS.\n *\n * @param props - The component props\n * @returns The rendered email component\n */\nexport const ForgotPasswordEmail = ({\n\ttheme,\n\tuser,\n\tresetUrl,\n\tcontent,\n}: ForgotPasswordEmailProps) => {\n\tconst userName = user.firstName || user.email || 'there';\n\tconst previewText = content?.previewText || 'Reset your password';\n\tconst heading = content?.heading || `Hello, ${userName}!`;\n\tconst bodyText =\n\t\tcontent?.bodyText ||\n\t\t'We received a request to reset your password, please click the button below. If you did not request a password reset, you can safely ignore this email.';\n\tconst buttonText = content?.buttonText || 'Reset Password';\n\n\treturn (\n\t\t<BaseEmail theme={theme} previewText={previewText}>\n\t\t\t<Heading\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: theme.colours.text.heading,\n\t\t\t\t\tfontSize: '24px',\n\t\t\t\t\tfontWeight: 'bold',\n\t\t\t\t\tmarginBottom: '20px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{heading}\n\t\t\t</Heading>\n\t\t\t<Text\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: theme.colours.text.body,\n\t\t\t\t\tfontSize: '16px',\n\t\t\t\t\tlineHeight: '24px',\n\t\t\t\t\tmarginBottom: '30px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{bodyText}\n\t\t\t</Text>\n\t\t\t<Section style={{ textAlign: 'center', marginBottom: '30px' }}>\n\t\t\t\t<Button\n\t\t\t\t\thref={resetUrl}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackgroundColor: theme.colours.background.accent,\n\t\t\t\t\t\tcolor: theme.colours.text.heading,\n\t\t\t\t\t\tpadding: '12px 32px',\n\t\t\t\t\t\tborderRadius: '5px',\n\t\t\t\t\t\tfontSize: '16px',\n\t\t\t\t\t\tfontWeight: 'bold',\n\t\t\t\t\t\ttextDecoration: 'none',\n\t\t\t\t\t\tdisplay: 'inline-block',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{buttonText}\n\t\t\t\t</Button>\n\t\t\t</Section>\n\t\t</BaseEmail>\n\t);\n};\n"],"names":["BaseEmail","Button","Heading","Section","Text","React","ForgotPasswordEmail","theme","user","resetUrl","content","userName","firstName","email","previewText","heading","bodyText","buttonText","style","color","colours","text","fontSize","fontWeight","marginBottom","body","lineHeight","textAlign","href","backgroundColor","background","accent","padding","borderRadius","textDecoration","display"],"mappings":";AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,IAAI,QAAQ,8BAA8B;AAExF,YAAYC,WAAW,QAAQ;AAmC/B;;;;;CAKC,GACD,OAAO,MAAMC,sBAAsB,CAAC,EACnCC,KAAK,EACLC,IAAI,EACJC,QAAQ,EACRC,OAAO,EACmB;IAC1B,MAAMC,WAAWH,KAAKI,SAAS,IAAIJ,KAAKK,KAAK,IAAI;IACjD,MAAMC,cAAcJ,SAASI,eAAe;IAC5C,MAAMC,UAAUL,SAASK,WAAW,CAAC,OAAO,EAAEJ,SAAS,CAAC,CAAC;IACzD,MAAMK,WACLN,SAASM,YACT;IACD,MAAMC,aAAaP,SAASO,cAAc;IAE1C,qBACC,MAACjB;QAAUO,OAAOA;QAAOO,aAAaA;;0BACrC,KAACZ;gBACAgB,OAAO;oBACNC,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACN,OAAO;oBACjCO,UAAU;oBACVC,YAAY;oBACZC,cAAc;gBACf;0BAECT;;0BAEF,KAACX;gBACAc,OAAO;oBACNC,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACI,IAAI;oBAC9BH,UAAU;oBACVI,YAAY;oBACZF,cAAc;gBACf;0BAECR;;0BAEF,KAACb;gBAAQe,OAAO;oBAAES,WAAW;oBAAUH,cAAc;gBAAO;0BAC3D,cAAA,KAACvB;oBACA2B,MAAMnB;oBACNS,OAAO;wBACNW,iBAAiBtB,MAAMa,OAAO,CAACU,UAAU,CAACC,MAAM;wBAChDZ,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACN,OAAO;wBACjCiB,SAAS;wBACTC,cAAc;wBACdX,UAAU;wBACVC,YAAY;wBACZW,gBAAgB;wBAChBC,SAAS;oBACV;8BAEClB;;;;;AAKN,EAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|