payload-wordpress-migrator 0.0.22
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/LICENSE +21 -0
- package/README.md +586 -0
- package/dist/components/BeforeDashboardClient.d.ts +14 -0
- package/dist/components/BeforeDashboardClient.js +225 -0
- package/dist/components/BeforeDashboardClient.js.map +1 -0
- package/dist/components/BeforeDashboardClient.module.css +175 -0
- package/dist/components/BeforeDashboardServer.d.ts +1 -0
- package/dist/components/BeforeDashboardServer.js +29 -0
- package/dist/components/BeforeDashboardServer.js.map +1 -0
- package/dist/components/ContentTypeSelect.d.ts +4 -0
- package/dist/components/ContentTypeSelect.js +147 -0
- package/dist/components/ContentTypeSelect.js.map +1 -0
- package/dist/components/FieldMappingConfiguration.d.ts +5 -0
- package/dist/components/FieldMappingConfiguration.js +361 -0
- package/dist/components/FieldMappingConfiguration.js.map +1 -0
- package/dist/components/FieldMappingConfiguration.module.css +75 -0
- package/dist/components/MigrationDashboardClient.d.ts +6 -0
- package/dist/components/MigrationDashboardClient.js +49 -0
- package/dist/components/MigrationDashboardClient.js.map +1 -0
- package/dist/components/MigrationDashboardClient.module.css +749 -0
- package/dist/components/SimpleFieldMapping.d.ts +5 -0
- package/dist/components/SimpleFieldMapping.js +437 -0
- package/dist/components/SimpleFieldMapping.js.map +1 -0
- package/dist/components/dashboard/JobActionButtons.d.ts +8 -0
- package/dist/components/dashboard/JobActionButtons.js +91 -0
- package/dist/components/dashboard/JobActionButtons.js.map +1 -0
- package/dist/components/dashboard/JobsTable.d.ts +6 -0
- package/dist/components/dashboard/JobsTable.js +86 -0
- package/dist/components/dashboard/JobsTable.js.map +1 -0
- package/dist/components/dashboard/LogViewer.d.ts +3 -0
- package/dist/components/dashboard/LogViewer.js +35 -0
- package/dist/components/dashboard/LogViewer.js.map +1 -0
- package/dist/components/dashboard/SiteConfigPanel.d.ts +12 -0
- package/dist/components/dashboard/SiteConfigPanel.js +205 -0
- package/dist/components/dashboard/SiteConfigPanel.js.map +1 -0
- package/dist/components/dashboard/StatsOverview.d.ts +5 -0
- package/dist/components/dashboard/StatsOverview.js +72 -0
- package/dist/components/dashboard/StatsOverview.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +7 -0
- package/dist/components/dashboard/index.js +7 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/types.d.ts +46 -0
- package/dist/components/dashboard/types.js +2 -0
- package/dist/components/dashboard/types.js.map +1 -0
- package/dist/components/dashboard/useMigrationDashboard.d.ts +15 -0
- package/dist/components/dashboard/useMigrationDashboard.js +584 -0
- package/dist/components/dashboard/useMigrationDashboard.js.map +1 -0
- package/dist/exports/client.d.ts +4 -0
- package/dist/exports/client.js +5 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +2 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +443 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/content/blocks.d.ts +6 -0
- package/dist/utils/content/blocks.js +93 -0
- package/dist/utils/content/blocks.js.map +1 -0
- package/dist/utils/content/fieldMapping.d.ts +9 -0
- package/dist/utils/content/fieldMapping.js +218 -0
- package/dist/utils/content/fieldMapping.js.map +1 -0
- package/dist/utils/content/index.d.ts +4 -0
- package/dist/utils/content/index.js +4 -0
- package/dist/utils/content/index.js.map +1 -0
- package/dist/utils/content/transformer.d.ts +5 -0
- package/dist/utils/content/transformer.js +323 -0
- package/dist/utils/content/transformer.js.map +1 -0
- package/dist/utils/endpoints/handlers.d.ts +9 -0
- package/dist/utils/endpoints/handlers.js +201 -0
- package/dist/utils/endpoints/handlers.js.map +1 -0
- package/dist/utils/endpoints/index.d.ts +2 -0
- package/dist/utils/endpoints/index.js +2 -0
- package/dist/utils/endpoints/index.js.map +1 -0
- package/dist/utils/fields/analyzer.d.ts +7 -0
- package/dist/utils/fields/analyzer.js +502 -0
- package/dist/utils/fields/analyzer.js.map +1 -0
- package/dist/utils/fields/index.d.ts +2 -0
- package/dist/utils/fields/index.js +2 -0
- package/dist/utils/fields/index.js.map +1 -0
- package/dist/utils/helpers/auth.d.ts +9 -0
- package/dist/utils/helpers/auth.js +50 -0
- package/dist/utils/helpers/auth.js.map +1 -0
- package/dist/utils/helpers/cache.d.ts +11 -0
- package/dist/utils/helpers/cache.js +47 -0
- package/dist/utils/helpers/cache.js.map +1 -0
- package/dist/utils/helpers/concurrency.d.ts +2 -0
- package/dist/utils/helpers/concurrency.js +26 -0
- package/dist/utils/helpers/concurrency.js.map +1 -0
- package/dist/utils/helpers/index.d.ts +8 -0
- package/dist/utils/helpers/index.js +8 -0
- package/dist/utils/helpers/index.js.map +1 -0
- package/dist/utils/helpers/objectHelpers.d.ts +3 -0
- package/dist/utils/helpers/objectHelpers.js +22 -0
- package/dist/utils/helpers/objectHelpers.js.map +1 -0
- package/dist/utils/helpers/rateLimiter.d.ts +10 -0
- package/dist/utils/helpers/rateLimiter.js +29 -0
- package/dist/utils/helpers/rateLimiter.js.map +1 -0
- package/dist/utils/helpers/responses.d.ts +3 -0
- package/dist/utils/helpers/responses.js +23 -0
- package/dist/utils/helpers/responses.js.map +1 -0
- package/dist/utils/helpers/wpHelpers.d.ts +6 -0
- package/dist/utils/helpers/wpHelpers.js +29 -0
- package/dist/utils/helpers/wpHelpers.js.map +1 -0
- package/dist/utils/lexical/constants.d.ts +37 -0
- package/dist/utils/lexical/constants.js +58 -0
- package/dist/utils/lexical/constants.js.map +1 -0
- package/dist/utils/lexical/htmlParser.d.ts +20 -0
- package/dist/utils/lexical/htmlParser.js +253 -0
- package/dist/utils/lexical/htmlParser.js.map +1 -0
- package/dist/utils/lexical/htmlToLexicalConverter.d.ts +55 -0
- package/dist/utils/lexical/htmlToLexicalConverter.js +999 -0
- package/dist/utils/lexical/htmlToLexicalConverter.js.map +1 -0
- package/dist/utils/lexical/index.d.ts +5 -0
- package/dist/utils/lexical/index.js +4 -0
- package/dist/utils/lexical/index.js.map +1 -0
- package/dist/utils/lexical/nodeFactories.d.ts +21 -0
- package/dist/utils/lexical/nodeFactories.js +91 -0
- package/dist/utils/lexical/nodeFactories.js.map +1 -0
- package/dist/utils/lexical/preprocessor.d.ts +4 -0
- package/dist/utils/lexical/preprocessor.js +302 -0
- package/dist/utils/lexical/preprocessor.js.map +1 -0
- package/dist/utils/media/download.d.ts +7 -0
- package/dist/utils/media/download.js +85 -0
- package/dist/utils/media/download.js.map +1 -0
- package/dist/utils/media/extraction.d.ts +12 -0
- package/dist/utils/media/extraction.js +58 -0
- package/dist/utils/media/extraction.js.map +1 -0
- package/dist/utils/media/import.d.ts +7 -0
- package/dist/utils/media/import.js +146 -0
- package/dist/utils/media/import.js.map +1 -0
- package/dist/utils/media/index.d.ts +6 -0
- package/dist/utils/media/index.js +6 -0
- package/dist/utils/media/index.js.map +1 -0
- package/dist/utils/media/upload.d.ts +4 -0
- package/dist/utils/media/upload.js +46 -0
- package/dist/utils/media/upload.js.map +1 -0
- package/dist/utils/media/validation.d.ts +8 -0
- package/dist/utils/media/validation.js +60 -0
- package/dist/utils/media/validation.js.map +1 -0
- package/dist/utils/migration/index.d.ts +3 -0
- package/dist/utils/migration/index.js +3 -0
- package/dist/utils/migration/index.js.map +1 -0
- package/dist/utils/migration/jobCrud.d.ts +4 -0
- package/dist/utils/migration/jobCrud.js +380 -0
- package/dist/utils/migration/jobCrud.js.map +1 -0
- package/dist/utils/migration/orchestrator.d.ts +5 -0
- package/dist/utils/migration/orchestrator.js +756 -0
- package/dist/utils/migration/orchestrator.js.map +1 -0
- package/dist/utils/types.d.ts +201 -0
- package/dist/utils/types.js +14 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/wordpress/client.d.ts +61 -0
- package/dist/utils/wordpress/client.js +365 -0
- package/dist/utils/wordpress/client.js.map +1 -0
- package/dist/utils/wordpress/index.d.ts +2 -0
- package/dist/utils/wordpress/index.js +2 -0
- package/dist/utils/wordpress/index.js.map +1 -0
- package/dist/utils/wordpressApi.d.ts +11 -0
- package/dist/utils/wordpressApi.js +25 -0
- package/dist/utils/wordpressApi.js.map +1 -0
- package/package.json +155 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Brightscout
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
# Payload WordPress Migrator Plugin
|
|
2
|
+
|
|
3
|
+
A comprehensive PayloadCMS plugin for WordPress migration - migrate and manage WordPress content directly in your Payload admin dashboard with a powerful React-based interface.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- 📊 **Interactive Migration Dashboard**: Real-time progress tracking with a modern React interface
|
|
8
|
+
- 🔄 **WordPress API Integration**: Secure REST API connectivity with application password authentication
|
|
9
|
+
- 📋 **Smart Job Management**: Create, monitor, pause, resume, and retry migration jobs
|
|
10
|
+
- 🎯 **Content Type Discovery**: Automatic detection of posts, pages, media, categories, and custom post types
|
|
11
|
+
- 🔗 **Advanced Field Mapping**: Visual field mapping interface with dot-notation support
|
|
12
|
+
- 🖼️ **Intelligent Media Migration**: Auto-import featured images and content media with duplicate detection
|
|
13
|
+
- 🧱 **Gutenberg to Lexical**: Convert WordPress blocks to PayloadCMS Lexical format
|
|
14
|
+
- ⚡ **Performance Optimized**: Configurable batch processing with background job execution
|
|
15
|
+
- 🔄 **Resume & Retry**: Intelligent job recovery with progress preservation
|
|
16
|
+
- 🔒 **Production Ready**: Comprehensive error handling and SSL certificate management
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# npm
|
|
22
|
+
npm install payload-wordpress-migrator
|
|
23
|
+
|
|
24
|
+
# yarn
|
|
25
|
+
yarn add payload-wordpress-migrator
|
|
26
|
+
|
|
27
|
+
# pnpm
|
|
28
|
+
pnpm add payload-wordpress-migrator
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 🚀 Quick Start
|
|
32
|
+
|
|
33
|
+
### Basic Setup
|
|
34
|
+
|
|
35
|
+
Add the plugin to your Payload config:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { buildConfig } from 'payload'
|
|
39
|
+
import { payloadWordPressMigrator } from 'payload-wordpress-migrator'
|
|
40
|
+
|
|
41
|
+
export default buildConfig({
|
|
42
|
+
// ... your existing config
|
|
43
|
+
plugins: [
|
|
44
|
+
payloadWordPressMigrator({
|
|
45
|
+
wpSiteUrl: process.env.WORDPRESS_API_URL,
|
|
46
|
+
wpUsername: process.env.WORDPRESS_USERNAME,
|
|
47
|
+
wpPassword: process.env.WORDPRESS_APP_PASSWORD,
|
|
48
|
+
collections: {
|
|
49
|
+
posts: { wpPostType: 'post', enableBlocks: true },
|
|
50
|
+
pages: { wpPostType: 'page', enableBlocks: true },
|
|
51
|
+
media: { wpPostType: 'media' },
|
|
52
|
+
},
|
|
53
|
+
enableMediaDownload: true,
|
|
54
|
+
migrationBatchSize: 25,
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Environment Variables
|
|
61
|
+
|
|
62
|
+
Add these to your `.env` file:
|
|
63
|
+
|
|
64
|
+
```env
|
|
65
|
+
WORDPRESS_API_URL=https://your-wordpress-site.com
|
|
66
|
+
WORDPRESS_USERNAME=your-username
|
|
67
|
+
WORDPRESS_APP_PASSWORD=your-application-password
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### WordPress Setup
|
|
71
|
+
|
|
72
|
+
#### Application Password Setup
|
|
73
|
+
|
|
74
|
+
1. In WordPress admin, go to **Users** → **Profile**
|
|
75
|
+
2. Scroll down to **Application Passwords**
|
|
76
|
+
3. Enter a name (e.g., "Payload Migration")
|
|
77
|
+
4. Click **Add New Application Password**
|
|
78
|
+
5. Copy the generated password (save it securely)
|
|
79
|
+
6. Use this password as `WORDPRESS_APP_PASSWORD`
|
|
80
|
+
|
|
81
|
+
#### REST API Requirements
|
|
82
|
+
|
|
83
|
+
- WordPress 5.6+ (for Application Passwords)
|
|
84
|
+
- REST API enabled (default in most installations)
|
|
85
|
+
- User with appropriate permissions for content access
|
|
86
|
+
|
|
87
|
+
### Configuration Options
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
type PayloadWordPressMigratorConfig = {
|
|
91
|
+
// WordPress Connection
|
|
92
|
+
wpSiteUrl?: string // WordPress site URL
|
|
93
|
+
wpUsername?: string // WordPress username
|
|
94
|
+
wpPassword?: string // WordPress application password
|
|
95
|
+
|
|
96
|
+
// Collection Configuration
|
|
97
|
+
collections?: Partial<Record<CollectionSlug, WordPressCollectionMapping>>
|
|
98
|
+
|
|
99
|
+
// Plugin Control
|
|
100
|
+
disabled?: boolean // Disable plugin functionality
|
|
101
|
+
disableDashboard?: boolean // Disable dashboard UI
|
|
102
|
+
|
|
103
|
+
// Performance Settings
|
|
104
|
+
migrationBatchSize?: number // Batch size (default: 10)
|
|
105
|
+
enableAutoSync?: boolean // Auto-sync on startup
|
|
106
|
+
|
|
107
|
+
// Media Migration
|
|
108
|
+
enableMediaDownload?: boolean // Download actual files (default: false)
|
|
109
|
+
maxMediaFileSize?: number // Max file size in bytes (default: 10MB)
|
|
110
|
+
allowedMediaTypes?: string[] // Allowed MIME types
|
|
111
|
+
allowSelfSignedCerts?: boolean // Allow self-signed SSL (dev only)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
type WordPressCollectionMapping = {
|
|
115
|
+
wpPostType: string // WordPress content type
|
|
116
|
+
fieldMapping?: Record<string, string> // Custom field mapping
|
|
117
|
+
enableBlocks?: boolean // Convert Gutenberg blocks
|
|
118
|
+
customFields?: string[] // ACF field names to migrate
|
|
119
|
+
importContentMedia?: boolean // Auto-import content images
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 📋 Plugin Architecture
|
|
124
|
+
|
|
125
|
+
The plugin creates the following collections and components in your PayloadCMS instance:
|
|
126
|
+
|
|
127
|
+
### Collections Added
|
|
128
|
+
|
|
129
|
+
1. **`wordpress-migration`**: Core collection for managing migration jobs
|
|
130
|
+
- Job configuration and status tracking
|
|
131
|
+
- Progress monitoring with detailed logs
|
|
132
|
+
- Built-in dashboard interface
|
|
133
|
+
|
|
134
|
+
2. **Enhanced Target Collections**: Automatically adds WordPress metadata fields to configured collections:
|
|
135
|
+
- `migratedFromWordPress.wpPostId`: Original WordPress post ID
|
|
136
|
+
- `migratedFromWordPress.wpPostType`: WordPress content type
|
|
137
|
+
- `migratedFromWordPress.migrationDate`: Migration timestamp
|
|
138
|
+
|
|
139
|
+
### UI Components
|
|
140
|
+
|
|
141
|
+
- **Migration Dashboard**: React-based interface with real-time updates
|
|
142
|
+
- **WordPress Site Configuration**: Secure credential management with localStorage persistence
|
|
143
|
+
- **Content Type Selector**: Dynamic dropdown populated from WordPress API discovery
|
|
144
|
+
- **Field Mapping Interface**: Visual field mapping with source/destination field analysis
|
|
145
|
+
- **Job Monitor**: Live progress tracking with success/failure metrics
|
|
146
|
+
|
|
147
|
+
### API Endpoints
|
|
148
|
+
|
|
149
|
+
The plugin adds these endpoints to your PayloadCMS API:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
POST /api/wordpress/test-connection # Test WordPress connectivity
|
|
153
|
+
GET /api/wordpress/migration-summary # Dashboard data with caching
|
|
154
|
+
POST /api/wordpress/discover-content # Content type discovery
|
|
155
|
+
GET /api/wordpress/migration-jobs # Job status retrieval
|
|
156
|
+
POST /api/wordpress/migration-jobs # Start migration jobs
|
|
157
|
+
PUT /api/wordpress/migration-jobs # Pause/resume jobs
|
|
158
|
+
DELETE /api/wordpress/migration-jobs # Delete jobs
|
|
159
|
+
POST /api/wordpress/content-fields # Analyze WordPress fields
|
|
160
|
+
GET /api/collections/:slug/fields # Analyze PayloadCMS fields
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 🎯 Content Migration Features
|
|
164
|
+
|
|
165
|
+
### Supported Content Types
|
|
166
|
+
|
|
167
|
+
| Content Type | Features | Notes |
|
|
168
|
+
| --------------------- | ------------------------------------------------------- | --------------------------------- |
|
|
169
|
+
| **Posts** | ✅ Content, metadata, categories, tags, featured images | Full Gutenberg block conversion |
|
|
170
|
+
| **Pages** | ✅ Content, metadata, featured images, custom fields | Hierarchical structure support |
|
|
171
|
+
| **Media** | ✅ File downloads, metadata, alt text, captions | MIME type filtering & size limits |
|
|
172
|
+
| **Categories** | ✅ Names, descriptions, hierarchy, counts | Taxonomy relationships |
|
|
173
|
+
| **Tags** | ✅ Names, descriptions, post associations | Tag cloud support |
|
|
174
|
+
| **Users** | ✅ User data, roles, capabilities, avatars | Permission mapping |
|
|
175
|
+
| **Custom Post Types** | ✅ Auto-discovery, custom fields, metadata | ACF integration |
|
|
176
|
+
|
|
177
|
+
### Advanced Content Processing
|
|
178
|
+
|
|
179
|
+
- **HTML to Lexical Conversion**: Sophisticated converter handles complex HTML structures
|
|
180
|
+
- **Gutenberg Block Processing**: Converts blocks to PayloadCMS block format
|
|
181
|
+
- **ACF Field Migration**: Automatic Advanced Custom Fields detection and migration
|
|
182
|
+
- **Media Auto-Import**: Scans content for WordPress media URLs and imports automatically
|
|
183
|
+
- **Relationship Preservation**: Maintains post-category, post-tag, and other relationships
|
|
184
|
+
|
|
185
|
+
## 🖼️ Media Migration
|
|
186
|
+
|
|
187
|
+
### Migration Modes
|
|
188
|
+
|
|
189
|
+
The plugin supports two modes for media migration:
|
|
190
|
+
|
|
191
|
+
1. **Metadata Only** (default): Migrates media titles, descriptions, alt text, and URLs
|
|
192
|
+
2. **Full File Migration**: Downloads files from WordPress and uploads them to PayloadCMS
|
|
193
|
+
|
|
194
|
+
### Enabling Media File Migration
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
payloadWordPressMigrator({
|
|
198
|
+
enableMediaDownload: true, // Enable file downloads
|
|
199
|
+
maxMediaFileSize: 50 * 1024 * 1024, // 50MB limit
|
|
200
|
+
allowedMediaTypes: [
|
|
201
|
+
'image/jpeg',
|
|
202
|
+
'image/png',
|
|
203
|
+
'image/gif',
|
|
204
|
+
'image/webp',
|
|
205
|
+
'application/pdf',
|
|
206
|
+
'video/mp4',
|
|
207
|
+
],
|
|
208
|
+
allowSelfSignedCerts: true, // For development only
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Auto-Import Features
|
|
213
|
+
|
|
214
|
+
#### Featured Image Auto-Import
|
|
215
|
+
|
|
216
|
+
- Automatically detects and imports featured images using WordPress `_embed` data
|
|
217
|
+
- Fallback support when `_embed` data is unavailable
|
|
218
|
+
- Creates PayloadCMS media records with actual file downloads
|
|
219
|
+
- Links imported media to posts/pages via `featuredImage` field
|
|
220
|
+
|
|
221
|
+
#### Content Media Auto-Import
|
|
222
|
+
|
|
223
|
+
- Scans HTML content for WordPress media URLs (`wp-content/uploads`)
|
|
224
|
+
- Downloads and imports images referenced in post/page content
|
|
225
|
+
- Preserves alt text and title attributes
|
|
226
|
+
- Smart duplicate detection to avoid re-importing existing files
|
|
227
|
+
|
|
228
|
+
#### MediaBlock Conversion
|
|
229
|
+
|
|
230
|
+
When migrating content with `enableMediaDownload: true`, the plugin now converts HTML `<img>` tags to proper PayloadCMS MediaBlocks:
|
|
231
|
+
|
|
232
|
+
- **HTML Images → MediaBlocks**: Converts inline images to structured MediaBlock components
|
|
233
|
+
- **Media Import Integration**: Automatically downloads and links media files to MediaBlocks
|
|
234
|
+
- **Rich Editor Support**: MediaBlocks display properly in PayloadCMS Lexical editor
|
|
235
|
+
- **Frontend Rendering**: Works seamlessly with PayloadCMS RichText component
|
|
236
|
+
- **Metadata Preservation**: Maintains alt text, titles, and dimensions for accessibility
|
|
237
|
+
|
|
238
|
+
#### Configuration Example
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
collections: {
|
|
242
|
+
posts: {
|
|
243
|
+
wpPostType: 'post',
|
|
244
|
+
importContentMedia: true, // Enable content media auto-import
|
|
245
|
+
},
|
|
246
|
+
media: {
|
|
247
|
+
wpPostType: 'media' // Required for media storage
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
enableMediaDownload: true // Required for auto-import
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Migration Workflow Options
|
|
254
|
+
|
|
255
|
+
1. **Recommended**: Migrate posts/pages only - media will be auto-imported
|
|
256
|
+
2. **Alternative**: Migrate media first, then posts/pages (avoids duplicates)
|
|
257
|
+
|
|
258
|
+
### Performance Considerations
|
|
259
|
+
|
|
260
|
+
- Files processed in configurable batches to prevent memory issues
|
|
261
|
+
- Large files streamed to minimize memory usage
|
|
262
|
+
- Failed downloads don't stop the entire migration process
|
|
263
|
+
- Media auto-import runs in parallel for optimal performance
|
|
264
|
+
- Smart duplicate detection prevents re-importing existing media
|
|
265
|
+
|
|
266
|
+
## 🔧 Advanced Configuration
|
|
267
|
+
|
|
268
|
+
### Complete Configuration Example
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { buildConfig } from 'payload'
|
|
272
|
+
import { payloadWordPressMigrator } from 'payload-wordpress-migrator'
|
|
273
|
+
|
|
274
|
+
export default buildConfig({
|
|
275
|
+
plugins: [
|
|
276
|
+
payloadWordPressMigrator({
|
|
277
|
+
// WordPress Connection
|
|
278
|
+
wpSiteUrl: process.env.WORDPRESS_API_URL,
|
|
279
|
+
wpUsername: process.env.WORDPRESS_USERNAME,
|
|
280
|
+
wpPassword: process.env.WORDPRESS_APP_PASSWORD,
|
|
281
|
+
|
|
282
|
+
// Collection Configuration
|
|
283
|
+
collections: {
|
|
284
|
+
posts: {
|
|
285
|
+
wpPostType: 'post',
|
|
286
|
+
enableBlocks: true,
|
|
287
|
+
importContentMedia: true,
|
|
288
|
+
customFields: ['_yoast_wpseo_title', '_yoast_wpseo_metadesc'],
|
|
289
|
+
fieldMapping: {
|
|
290
|
+
'title.rendered': 'title',
|
|
291
|
+
'content.rendered': 'content',
|
|
292
|
+
'excerpt.rendered': 'excerpt',
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
pages: {
|
|
296
|
+
wpPostType: 'page',
|
|
297
|
+
enableBlocks: true,
|
|
298
|
+
importContentMedia: true,
|
|
299
|
+
disableHtmlConversion: false, // Enable HTML to Lexical conversion
|
|
300
|
+
},
|
|
301
|
+
media: {
|
|
302
|
+
wpPostType: 'media',
|
|
303
|
+
},
|
|
304
|
+
categories: {
|
|
305
|
+
wpPostType: 'category',
|
|
306
|
+
},
|
|
307
|
+
products: {
|
|
308
|
+
// Custom post type example
|
|
309
|
+
wpPostType: 'product',
|
|
310
|
+
enableBlocks: false,
|
|
311
|
+
customFields: ['_price', '_stock_status', '_featured'],
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
|
|
315
|
+
// Performance & Batch Settings
|
|
316
|
+
migrationBatchSize: 25,
|
|
317
|
+
enableAutoSync: false,
|
|
318
|
+
|
|
319
|
+
// Media Configuration
|
|
320
|
+
enableMediaDownload: true,
|
|
321
|
+
maxMediaFileSize: 50 * 1024 * 1024, // 50MB
|
|
322
|
+
allowedMediaTypes: [
|
|
323
|
+
'image/jpeg',
|
|
324
|
+
'image/png',
|
|
325
|
+
'image/gif',
|
|
326
|
+
'image/webp',
|
|
327
|
+
'image/svg+xml',
|
|
328
|
+
'application/pdf',
|
|
329
|
+
'video/mp4',
|
|
330
|
+
'video/webm',
|
|
331
|
+
'audio/mpeg',
|
|
332
|
+
],
|
|
333
|
+
|
|
334
|
+
// Development Settings
|
|
335
|
+
allowSelfSignedCerts: process.env.NODE_ENV === 'development',
|
|
336
|
+
|
|
337
|
+
// Plugin Control
|
|
338
|
+
disabled: false,
|
|
339
|
+
disableDashboard: false,
|
|
340
|
+
}),
|
|
341
|
+
],
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Field Mapping Configuration
|
|
346
|
+
|
|
347
|
+
The plugin supports sophisticated field mapping with dot notation:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
fieldMapping: {
|
|
351
|
+
// WordPress field path → PayloadCMS field path
|
|
352
|
+
'title.rendered': 'title',
|
|
353
|
+
'content.rendered': 'content',
|
|
354
|
+
'meta._yoast_wpseo_title': 'seo.title',
|
|
355
|
+
'acf.hero_image': 'hero.image',
|
|
356
|
+
'custom_field_name': 'mappedField'
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## 🎛️ Migration Dashboard
|
|
361
|
+
|
|
362
|
+
The plugin provides a comprehensive React-based dashboard accessible at `/admin/collections/wordpress-migration`:
|
|
363
|
+
|
|
364
|
+
### Dashboard Features
|
|
365
|
+
|
|
366
|
+
- **Site Configuration**: Secure WordPress credentials management
|
|
367
|
+
- **Content Discovery**: Automatic scan and analysis of available content
|
|
368
|
+
- **Job Creation**: Visual job setup with field mapping interface
|
|
369
|
+
- **Real-time Monitoring**: Live progress updates with success/failure metrics
|
|
370
|
+
- **Job Controls**: Start, pause, resume, retry operations
|
|
371
|
+
- **Error Reporting**: Detailed logs and error analysis
|
|
372
|
+
|
|
373
|
+
### Dashboard Screenshots
|
|
374
|
+
|
|
375
|
+
The interface includes:
|
|
376
|
+
|
|
377
|
+
1. **Configuration Panel**: WordPress site setup and testing
|
|
378
|
+
2. **Content Overview**: Discovered content types with item counts
|
|
379
|
+
3. **Job Management**: Active and completed migration jobs
|
|
380
|
+
4. **Progress Tracking**: Visual progress bars with detailed statistics
|
|
381
|
+
5. **Log Viewer**: Real-time migration logs and error reporting
|
|
382
|
+
|
|
383
|
+
## 🔌 Programmatic API
|
|
384
|
+
|
|
385
|
+
The plugin exports utilities that can be used outside the dashboard for scripted or custom migrations.
|
|
386
|
+
|
|
387
|
+
### WordPress Client
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { WordPressClient } from 'payload-wordpress-migrator/dist/utils/wordpress/index.js'
|
|
391
|
+
|
|
392
|
+
const client = new WordPressClient({
|
|
393
|
+
wpSiteUrl: 'https://example.com',
|
|
394
|
+
wpUsername: 'admin',
|
|
395
|
+
wpPassword: 'xxxx xxxx xxxx xxxx',
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
// Discover available content types
|
|
399
|
+
const contentTypes = await client.discoverContent()
|
|
400
|
+
|
|
401
|
+
// Fetch fields for a specific content type
|
|
402
|
+
const fields = await client.fetchContentFields('post')
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Content Transformation
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { transformWordPressContent } from 'payload-wordpress-migrator/dist/utils/content/index.js'
|
|
409
|
+
|
|
410
|
+
const payloadData = await transformWordPressContent(
|
|
411
|
+
wpItem, // WordPress REST API item
|
|
412
|
+
'post', // Content type
|
|
413
|
+
jobConfig, // Job configuration (batchSize, enableBlocks, fieldMapping)
|
|
414
|
+
payload, // Payload instance
|
|
415
|
+
pluginOptions // Plugin config
|
|
416
|
+
)
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### HTML to Lexical Conversion
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
import { convertHtmlToLexical } from 'payload-wordpress-migrator/dist/utils/lexical/index.js'
|
|
423
|
+
|
|
424
|
+
const lexicalContent = convertHtmlToLexical('<p>Hello <strong>world</strong></p>')
|
|
425
|
+
// Returns a Lexical root node ready for PayloadCMS rich text fields
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Field Mapping
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
import { applyFieldMapping } from 'payload-wordpress-migrator/dist/utils/content/index.js'
|
|
432
|
+
|
|
433
|
+
const mappedData = await applyFieldMapping(
|
|
434
|
+
payloadData, // Transformed Payload data
|
|
435
|
+
wpItem, // Original WordPress item
|
|
436
|
+
fieldMapping, // { fieldMappings: [{ sourceField, destinationField }] }
|
|
437
|
+
payload // Payload instance (needed for relationship ID conversion)
|
|
438
|
+
)
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
> **Note:** These utilities are imported from internal paths (`dist/utils/...`). The public package exports (`payload-wordpress-migrator`) expose only the plugin function and types. Internal APIs may change between minor versions.
|
|
442
|
+
|
|
443
|
+
## 🛠️ Development & Extension
|
|
444
|
+
|
|
445
|
+
### Plugin Structure
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
src/
|
|
449
|
+
├── components/ # React UI components
|
|
450
|
+
│ ├── dashboard/ # Dashboard sub-components
|
|
451
|
+
│ │ ├── SiteConfigPanel.tsx # WordPress connection form
|
|
452
|
+
│ │ ├── StatsOverview.tsx # Summary stat cards
|
|
453
|
+
│ │ ├── JobsTable.tsx # Migration jobs table
|
|
454
|
+
│ │ ├── JobActionButtons.tsx # Per-job action buttons
|
|
455
|
+
│ │ ├── LogViewer.tsx # Combined log display
|
|
456
|
+
│ │ ├── useMigrationDashboard.ts # State, effects, and handlers
|
|
457
|
+
│ │ └── types.ts # Dashboard-specific types
|
|
458
|
+
│ ├── MigrationDashboardClient.tsx # Dashboard composition shell
|
|
459
|
+
│ ├── ContentTypeSelect.tsx # Content type picker
|
|
460
|
+
│ ├── FieldMappingConfiguration.tsx # Field mapper
|
|
461
|
+
│ └── SimpleFieldMapping.tsx # Simple mapping UI
|
|
462
|
+
├── utils/
|
|
463
|
+
│ ├── wordpress/client.ts # WordPress REST API client
|
|
464
|
+
│ ├── migration/orchestrator.ts # Job execution engine
|
|
465
|
+
│ ├── content/transformer.ts # WP → Payload content transform
|
|
466
|
+
│ ├── lexical/htmlToLexicalConverter.ts # HTML → Lexical conversion
|
|
467
|
+
│ └── ... # Media, fields, helpers, endpoints
|
|
468
|
+
└── index.ts # Plugin entry point
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Error Handling
|
|
472
|
+
|
|
473
|
+
The plugin provides comprehensive error handling:
|
|
474
|
+
|
|
475
|
+
- **Connection Errors**: WordPress API connectivity issues
|
|
476
|
+
- **Authentication Errors**: Invalid credentials or permissions
|
|
477
|
+
- **Content Errors**: Malformed content or missing fields
|
|
478
|
+
- **Media Errors**: Download failures or file size limits
|
|
479
|
+
- **Database Errors**: PayloadCMS creation failures
|
|
480
|
+
|
|
481
|
+
## 📊 Migration Best Practices
|
|
482
|
+
|
|
483
|
+
### Pre-Migration Checklist
|
|
484
|
+
|
|
485
|
+
1. **✅ WordPress Setup**
|
|
486
|
+
- Generate application password
|
|
487
|
+
- Verify REST API access
|
|
488
|
+
- Check user permissions
|
|
489
|
+
- Test SSL certificate
|
|
490
|
+
|
|
491
|
+
2. **✅ PayloadCMS Configuration**
|
|
492
|
+
- Configure target collections
|
|
493
|
+
- Set up field mappings
|
|
494
|
+
- Test media collection setup
|
|
495
|
+
- Verify storage configuration
|
|
496
|
+
|
|
497
|
+
3. **✅ Content Analysis**
|
|
498
|
+
- Run content discovery scan
|
|
499
|
+
- Review field mapping options
|
|
500
|
+
- Identify custom post types
|
|
501
|
+
- Plan migration sequence
|
|
502
|
+
|
|
503
|
+
### Migration Strategy
|
|
504
|
+
|
|
505
|
+
**Recommended Migration Order:**
|
|
506
|
+
|
|
507
|
+
1. **Categories & Tags** (establishes taxonomy)
|
|
508
|
+
2. **Media Files** (creates media library)
|
|
509
|
+
3. **Pages** (static content first)
|
|
510
|
+
4. **Posts** (blog content with relationships)
|
|
511
|
+
5. **Users** (author information)
|
|
512
|
+
6. **Custom Post Types** (specialized content)
|
|
513
|
+
|
|
514
|
+
**Performance Optimization:**
|
|
515
|
+
|
|
516
|
+
- Start with smaller batch sizes (10-25) for initial testing
|
|
517
|
+
- Increase batch size (50-100) for production migrations
|
|
518
|
+
- Monitor memory usage during large media migrations
|
|
519
|
+
- Use resume functionality for interrupted migrations
|
|
520
|
+
|
|
521
|
+
### Troubleshooting
|
|
522
|
+
|
|
523
|
+
| Problem | Cause | Solution |
|
|
524
|
+
|---------|-------|----------|
|
|
525
|
+
| **"Authentication failed"** | Wrong credentials, or REST API disabled | Verify you're using an **Application Password** (not your login password). Confirm the REST API is accessible at `https://your-site.com/wp-json/` |
|
|
526
|
+
| **Content types not discovered** | WordPress permalinks set to "Plain" | In WordPress Admin > Settings > Permalinks, switch to any structure other than "Plain" |
|
|
527
|
+
| **Custom post types not found** | CPT not exposed to REST API | Add `'show_in_rest' => true` to your `register_post_type()` call |
|
|
528
|
+
| **SSL certificate errors** | Self-signed or expired certificate | Set `allowSelfSignedCerts: true` for development. In production, use a valid certificate |
|
|
529
|
+
| **Media download fails** | WordPress behind CDN or firewall | Ensure media file URLs (`wp-content/uploads/...`) are accessible from the server running Payload |
|
|
530
|
+
| **`"The following path cannot be queried: migratedFromWordPress"`** | Target collection not in plugin config | Add the collection to the `collections` option so the metadata fields get injected |
|
|
531
|
+
| **Large migration runs out of memory** | Batch size too high for available RAM | Reduce `migrationBatchSize` (try 5) and `migrationConcurrency` (set to 1) |
|
|
532
|
+
| **Lexical content looks wrong** | HTML conversion edge case | Set `disableHtmlConversion: true` on the collection mapping as a workaround, and report the specific HTML that fails |
|
|
533
|
+
| **Duplicate items after resume** | `migratedFromWordPress.wpPostId` field missing | Ensure the collection is listed in the plugin `collections` config — the field is auto-added |
|
|
534
|
+
| **ACF fields not migrated** | Field mapping not configured | Add ACF field names to `customFields` in the collection mapping, or configure explicit `fieldMapping` in the job |
|
|
535
|
+
| **`"MIME type not allowed"` or `"File too large"`** | Media file exceeds limits | Expand `allowedMediaTypes` and increase `maxMediaFileSize` in plugin config |
|
|
536
|
+
|
|
537
|
+
## 🔧 Technical Requirements
|
|
538
|
+
|
|
539
|
+
- **Node.js**: ^18.20.2 || >=20.9.0
|
|
540
|
+
- **PayloadCMS**: ^3.29.0
|
|
541
|
+
- **Package Manager**: pnpm ^9 || ^10
|
|
542
|
+
- **WordPress**: 5.6+ with REST API enabled
|
|
543
|
+
- **Memory**: 512MB+ recommended for media migrations
|
|
544
|
+
- **Storage**: Adequate space for media file imports
|
|
545
|
+
|
|
546
|
+
## 📈 Performance Considerations
|
|
547
|
+
|
|
548
|
+
- **Batch Processing**: Configurable batch sizes prevent memory overflow
|
|
549
|
+
- **Background Jobs**: Non-blocking migration execution
|
|
550
|
+
- **Progress Persistence**: Resume interrupted migrations
|
|
551
|
+
- **Memory Management**: Efficient file streaming for large media
|
|
552
|
+
- **Cache Management**: Intelligent caching with invalidation
|
|
553
|
+
- **Parallel Processing**: Concurrent media imports for optimal speed
|
|
554
|
+
|
|
555
|
+
## 🤝 Contributing
|
|
556
|
+
|
|
557
|
+
We welcome contributions! Areas for enhancement:
|
|
558
|
+
|
|
559
|
+
- Additional content type support
|
|
560
|
+
- Enhanced field mapping UI
|
|
561
|
+
- Performance optimizations
|
|
562
|
+
- Advanced content transformations
|
|
563
|
+
- Integration tests
|
|
564
|
+
- Documentation improvements
|
|
565
|
+
|
|
566
|
+
## 📝 License
|
|
567
|
+
|
|
568
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
569
|
+
|
|
570
|
+
## 🎯 Roadmap
|
|
571
|
+
|
|
572
|
+
- [ ] WordPress multisite support
|
|
573
|
+
- [ ] Advanced Custom Fields Pro support
|
|
574
|
+
- [ ] WooCommerce product migration
|
|
575
|
+
- [ ] Automated testing suite
|
|
576
|
+
- [ ] Docker development environment
|
|
577
|
+
- [ ] Migration templates and presets
|
|
578
|
+
- [ ] Webhook integration for real-time sync
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
**Author**: [Igor Abdulovic](mailto:igor.abdulovic@brightscout.com) at [Brightscout](https://brightscout.com)
|
|
583
|
+
|
|
584
|
+
**Repository**: [GitHub](https://github.com/Brightscout/payload-wordpress-migrator)
|
|
585
|
+
|
|
586
|
+
**Issues**: [GitHub Issues](https://github.com/Brightscout/payload-wordpress-migrator/issues)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type HubSpotForm = {
|
|
2
|
+
guid: string;
|
|
3
|
+
name: string;
|
|
4
|
+
stats: {
|
|
5
|
+
conversionRate: number;
|
|
6
|
+
submissions: number;
|
|
7
|
+
views: number;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
type BeforeDashboardClientProps = {
|
|
11
|
+
forms: HubSpotForm[];
|
|
12
|
+
};
|
|
13
|
+
export declare const BeforeDashboardClient: ({ forms: initialForms }: BeforeDashboardClientProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|