payload-plugin-newsletter 0.20.0 → 0.20.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-plugin-newsletter",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "Complete newsletter management plugin for Payload CMS with subscriber management, magic link authentication, and email service integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,24 +8,24 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": {
12
- "types": "./dist/index.d.ts",
13
- "default": "./dist/index.js"
14
- },
15
- "require": {
16
- "types": "./dist/index.d.cts",
17
- "default": "./dist/index.cjs"
18
- }
11
+ "import": "./dist/server.js",
12
+ "types": "./dist/server.d.ts"
13
+ },
14
+ "./server": {
15
+ "import": "./dist/server.js",
16
+ "types": "./dist/server.d.ts"
19
17
  },
20
18
  "./client": {
21
- "import": {
22
- "types": "./dist/client.d.ts",
23
- "default": "./dist/client.js"
24
- },
25
- "require": {
26
- "types": "./dist/client.d.cts",
27
- "default": "./dist/client.cjs"
28
- }
19
+ "import": "./dist/client.js",
20
+ "types": "./dist/client.d.ts"
21
+ },
22
+ "./admin": {
23
+ "import": "./dist/admin.js",
24
+ "types": "./dist/admin.d.ts"
25
+ },
26
+ "./components": {
27
+ "import": "./dist/admin.js",
28
+ "types": "./dist/admin.d.ts"
29
29
  },
30
30
  "./types": {
31
31
  "import": {
@@ -37,16 +37,6 @@
37
37
  "default": "./dist/types.cjs"
38
38
  }
39
39
  },
40
- "./components": {
41
- "import": {
42
- "types": "./dist/components.d.ts",
43
- "default": "./dist/components.js"
44
- },
45
- "require": {
46
- "types": "./dist/components.d.cts",
47
- "default": "./dist/components.cjs"
48
- }
49
- },
50
40
  "./utils": {
51
41
  "import": {
52
42
  "types": "./dist/utils.d.ts",
@@ -1,74 +0,0 @@
1
- # ESM/CJS Module Resolution Fix Summary
2
-
3
- ## Changes Made
4
-
5
- ### 1. **Added tsup Build Tool**
6
- - Added `tsup` v8.3.5 to devDependencies for proper ESM/CJS dual package support
7
- - Created `tsup.config.ts` with configuration for building both ESM and CJS outputs
8
-
9
- ### 2. **Updated package.json**
10
- - Changed entry points from source files (`./src/`) to built files (`./dist/`)
11
- - Added proper exports configuration with both ESM and CJS support:
12
- - ESM files: `.js` extension with `.d.ts` types
13
- - CJS files: `.cjs` extension with `.d.cts` types
14
- - Updated build scripts to use tsup
15
- - Added `module` field pointing to ESM entry
16
-
17
- ### 3. **Updated tsconfig.json**
18
- - Changed `moduleResolution` from "bundler" to "node" for better compatibility
19
-
20
- ### 4. **Created Build Script**
21
- - Added `build-and-commit.sh` for easy building and verification
22
-
23
- ## File Structure After Build
24
-
25
- ```
26
- dist/
27
- ├── index.js # ESM main entry
28
- ├── index.cjs # CJS main entry
29
- ├── index.d.ts # TypeScript definitions
30
- ├── index.d.cts # CJS TypeScript definitions
31
- ├── client.js # ESM client export
32
- ├── client.cjs # CJS client export
33
- ├── client.d.ts # Client TypeScript definitions
34
- ├── client.d.cts # CJS Client TypeScript definitions
35
- ├── types.js # ESM types export
36
- ├── types.cjs # CJS types export
37
- ├── types.d.ts # Types TypeScript definitions
38
- ├── types.d.cts # CJS Types TypeScript definitions
39
- ├── components.js # ESM components export
40
- ├── components.cjs # CJS components export
41
- ├── components.d.ts # Components TypeScript definitions
42
- └── components.d.cts # CJS Components TypeScript definitions
43
- ```
44
-
45
- ## How to Build and Publish
46
-
47
- 1. **Install dependencies**: `bun install`
48
- 2. **Build the package**: `bun run build`
49
- 3. **Test locally**: Link the package to test in your project
50
- 4. **Publish**: `npm publish` (dist files will be included automatically)
51
-
52
- ## Benefits
53
-
54
- 1. **Proper ESM Support**: Next.js apps using `"type": "module"` can now import the package without issues
55
- 2. **CJS Compatibility**: Still works with CommonJS projects
56
- 3. **TypeScript Support**: Proper type definitions for both module systems
57
- 4. **Clean Exports**: Clear separation of server/client code with proper exports
58
- 5. **Future Proof**: Ready for the ESM-first ecosystem
59
-
60
- ## Testing the Fix
61
-
62
- To test in your ContentQuant project:
63
- 1. Build the plugin: `bun run build`
64
- 2. Link locally: `npm link` in plugin directory
65
- 3. Link in project: `npm link payload-plugin-newsletter` in ContentQuant
66
- 4. Import and use normally
67
-
68
- ## Next Steps
69
-
70
- 1. Run `./build-and-commit.sh` to build the package
71
- 2. Test the built package locally
72
- 3. Commit changes with message: "fix: add tsup build system for proper ESM/CJS dual package support"
73
- 4. Push to repository
74
- 5. Publish new version to npm
@@ -1,201 +0,0 @@
1
- # Email Preview Customization Task
2
-
3
- ## Overview
4
- The email preview in the plugin currently wraps all content in a default email template, which conflicts with custom email templates that users might implement. We need to make the preview customizable so users can control how their emails are rendered in the preview.
5
-
6
- ## Problem
7
- - The plugin's `EmailPreview.tsx` always wraps content with `wrapInTemplate: true` (line 54)
8
- - This causes styling differences between the preview and what's actually sent to email providers
9
- - Users who implement custom email templates see inconsistent previews
10
-
11
- ## Required Changes
12
-
13
- ### 1. Update Type Definitions (`src/types/index.ts`)
14
-
15
- Add email preview customization options to the `BroadcastCustomizations` interface:
16
-
17
- ```typescript
18
- export interface BroadcastCustomizations {
19
- // ... existing fields ...
20
-
21
- /**
22
- * Email preview customization options
23
- */
24
- emailPreview?: {
25
- /**
26
- * Whether to wrap preview content in default email template
27
- * @default true
28
- */
29
- wrapInTemplate?: boolean
30
-
31
- /**
32
- * Custom wrapper function for preview content
33
- * Receives the converted HTML and should return wrapped HTML
34
- */
35
- customWrapper?: (content: string, options?: {
36
- subject?: string
37
- preheader?: string
38
- }) => string | Promise<string>
39
-
40
- /**
41
- * Custom preview component to replace the default one entirely
42
- * If provided, this component will be used instead of the default EmailPreview
43
- */
44
- customPreviewComponent?: string // Path to custom component for import map
45
- }
46
- }
47
- ```
48
-
49
- ### 2. Update Email Preview Component (`src/components/Broadcasts/EmailPreview.tsx`)
50
-
51
- Modify the component to use the customization options:
52
-
53
- 1. Import the plugin config (you'll need to pass it through props or context)
54
- 2. Update the `convertContent` function (around line 42) to respect customization options:
55
-
56
- ```typescript
57
- // Around line 51-54, replace:
58
- const emailHtml = await convertToEmailSafeHtml(content, {
59
- wrapInTemplate: true,
60
- preheader,
61
- })
62
-
63
- // With:
64
- const emailHtml = await convertToEmailSafeHtml(content, {
65
- wrapInTemplate: pluginConfig?.customizations?.broadcasts?.emailPreview?.wrapInTemplate ?? true,
66
- preheader,
67
- customWrapper: pluginConfig?.customizations?.broadcasts?.emailPreview?.customWrapper,
68
- })
69
- ```
70
-
71
- ### 3. Update Email Safe HTML Utility (`src/utils/emailSafeHtml.ts`)
72
-
73
- Modify the `convertToEmailSafeHtml` function to support custom wrapper:
74
-
75
- 1. Add `customWrapper` to the options interface (around line 36):
76
- ```typescript
77
- options?: {
78
- wrapInTemplate?: boolean
79
- preheader?: string
80
- mediaUrl?: string
81
- customBlockConverter?: (node: any, mediaUrl?: string) => Promise<string>
82
- payload?: any
83
- populateFields?: string[] | ((blockType: string) => string[])
84
- customWrapper?: (content: string, options?: { preheader?: string }) => string | Promise<string>
85
- }
86
- ```
87
-
88
- 2. Update the wrapping logic (around line 54-57):
89
- ```typescript
90
- // Optionally wrap in email template
91
- if (options?.wrapInTemplate) {
92
- if (options.customWrapper) {
93
- return await Promise.resolve(options.customWrapper(sanitizedHtml, { preheader: options.preheader }))
94
- }
95
- return wrapInEmailTemplate(sanitizedHtml, options.preheader)
96
- }
97
- ```
98
-
99
- ### 4. Update Email Preview Field (`src/components/Broadcasts/EmailPreviewField.tsx`)
100
-
101
- Pass the plugin config to the EmailPreview component. You'll need to:
102
-
103
- 1. Import and use a context or prop to get the plugin config
104
- 2. Pass it to the EmailPreview component (around line 158):
105
-
106
- ```typescript
107
- <EmailPreview
108
- content={fields.content?.value as SerializedEditorState || null}
109
- subject={fields.subject?.value as string || 'Email Subject'}
110
- preheader={fields.preheader?.value as string}
111
- mode={previewMode}
112
- onValidation={handleValidation}
113
- pluginConfig={pluginConfig} // Add this
114
- />
115
- ```
116
-
117
- ### 5. Create Plugin Config Context (`src/contexts/PluginConfigContext.tsx`) - NEW FILE
118
-
119
- Create a context to pass plugin config throughout the component tree:
120
-
121
- ```typescript
122
- import React, { createContext, useContext } from 'react'
123
- import type { NewsletterPluginConfig } from '../types'
124
-
125
- const PluginConfigContext = createContext<NewsletterPluginConfig | null>(null)
126
-
127
- export const PluginConfigProvider: React.FC<{
128
- config: NewsletterPluginConfig
129
- children: React.ReactNode
130
- }> = ({ config, children }) => {
131
- return (
132
- <PluginConfigContext.Provider value={config}>
133
- {children}
134
- </PluginConfigContext.Provider>
135
- )
136
- }
137
-
138
- export const usePluginConfig = () => {
139
- const config = useContext(PluginConfigContext)
140
- if (!config) {
141
- throw new Error('usePluginConfig must be used within PluginConfigProvider')
142
- }
143
- return config
144
- }
145
- ```
146
-
147
- ### 6. Update Broadcasts Collection (`src/collections/Broadcasts.ts`)
148
-
149
- Wrap the admin UI components with the PluginConfigProvider. This is more complex and might require modifying how components are initialized.
150
-
151
- ## Testing Instructions
152
-
153
- 1. Create a test configuration that uses custom email preview:
154
- ```typescript
155
- newsletterPlugin({
156
- customizations: {
157
- broadcasts: {
158
- emailPreview: {
159
- wrapInTemplate: false,
160
- // Or with custom wrapper:
161
- customWrapper: async (content, { preheader }) => {
162
- return `<div class="my-custom-wrapper">${content}</div>`
163
- }
164
- }
165
- }
166
- }
167
- })
168
- ```
169
-
170
- 2. Verify that:
171
- - Default behavior (with template) still works when no customization is provided
172
- - Setting `wrapInTemplate: false` shows raw content without wrapper
173
- - Custom wrapper function is called and applied correctly
174
- - Preview matches what's sent to email providers
175
-
176
- ## Backward Compatibility
177
-
178
- - Default behavior must remain unchanged (wrap in template)
179
- - All customization options should be optional
180
- - Existing installations should work without any configuration changes
181
-
182
- ## Additional Considerations
183
-
184
- 1. **Custom Preview Component**: The `customPreviewComponent` option would allow complete replacement of the preview component, but this is a more complex feature that could be added later.
185
-
186
- 2. **Preview Context**: Consider passing additional context to the custom wrapper like:
187
- - Current user
188
- - Broadcast metadata
189
- - Provider configuration
190
-
191
- 3. **Documentation**: Update the plugin README with examples of how to use these new customization options.
192
-
193
- ## Implementation Order
194
-
195
- 1. Start with type definitions
196
- 2. Update emailSafeHtml utility
197
- 3. Modify EmailPreview component
198
- 4. Test with various configurations
199
- 5. Add documentation
200
-
201
- This approach provides maximum flexibility while maintaining backward compatibility and clean architecture.