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.
Files changed (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +586 -0
  3. package/dist/components/BeforeDashboardClient.d.ts +14 -0
  4. package/dist/components/BeforeDashboardClient.js +225 -0
  5. package/dist/components/BeforeDashboardClient.js.map +1 -0
  6. package/dist/components/BeforeDashboardClient.module.css +175 -0
  7. package/dist/components/BeforeDashboardServer.d.ts +1 -0
  8. package/dist/components/BeforeDashboardServer.js +29 -0
  9. package/dist/components/BeforeDashboardServer.js.map +1 -0
  10. package/dist/components/ContentTypeSelect.d.ts +4 -0
  11. package/dist/components/ContentTypeSelect.js +147 -0
  12. package/dist/components/ContentTypeSelect.js.map +1 -0
  13. package/dist/components/FieldMappingConfiguration.d.ts +5 -0
  14. package/dist/components/FieldMappingConfiguration.js +361 -0
  15. package/dist/components/FieldMappingConfiguration.js.map +1 -0
  16. package/dist/components/FieldMappingConfiguration.module.css +75 -0
  17. package/dist/components/MigrationDashboardClient.d.ts +6 -0
  18. package/dist/components/MigrationDashboardClient.js +49 -0
  19. package/dist/components/MigrationDashboardClient.js.map +1 -0
  20. package/dist/components/MigrationDashboardClient.module.css +749 -0
  21. package/dist/components/SimpleFieldMapping.d.ts +5 -0
  22. package/dist/components/SimpleFieldMapping.js +437 -0
  23. package/dist/components/SimpleFieldMapping.js.map +1 -0
  24. package/dist/components/dashboard/JobActionButtons.d.ts +8 -0
  25. package/dist/components/dashboard/JobActionButtons.js +91 -0
  26. package/dist/components/dashboard/JobActionButtons.js.map +1 -0
  27. package/dist/components/dashboard/JobsTable.d.ts +6 -0
  28. package/dist/components/dashboard/JobsTable.js +86 -0
  29. package/dist/components/dashboard/JobsTable.js.map +1 -0
  30. package/dist/components/dashboard/LogViewer.d.ts +3 -0
  31. package/dist/components/dashboard/LogViewer.js +35 -0
  32. package/dist/components/dashboard/LogViewer.js.map +1 -0
  33. package/dist/components/dashboard/SiteConfigPanel.d.ts +12 -0
  34. package/dist/components/dashboard/SiteConfigPanel.js +205 -0
  35. package/dist/components/dashboard/SiteConfigPanel.js.map +1 -0
  36. package/dist/components/dashboard/StatsOverview.d.ts +5 -0
  37. package/dist/components/dashboard/StatsOverview.js +72 -0
  38. package/dist/components/dashboard/StatsOverview.js.map +1 -0
  39. package/dist/components/dashboard/index.d.ts +7 -0
  40. package/dist/components/dashboard/index.js +7 -0
  41. package/dist/components/dashboard/index.js.map +1 -0
  42. package/dist/components/dashboard/types.d.ts +46 -0
  43. package/dist/components/dashboard/types.js +2 -0
  44. package/dist/components/dashboard/types.js.map +1 -0
  45. package/dist/components/dashboard/useMigrationDashboard.d.ts +15 -0
  46. package/dist/components/dashboard/useMigrationDashboard.js +584 -0
  47. package/dist/components/dashboard/useMigrationDashboard.js.map +1 -0
  48. package/dist/exports/client.d.ts +4 -0
  49. package/dist/exports/client.js +5 -0
  50. package/dist/exports/client.js.map +1 -0
  51. package/dist/exports/rsc.d.ts +1 -0
  52. package/dist/exports/rsc.js +2 -0
  53. package/dist/exports/rsc.js.map +1 -0
  54. package/dist/index.d.ts +101 -0
  55. package/dist/index.js +443 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/utils/content/blocks.d.ts +6 -0
  58. package/dist/utils/content/blocks.js +93 -0
  59. package/dist/utils/content/blocks.js.map +1 -0
  60. package/dist/utils/content/fieldMapping.d.ts +9 -0
  61. package/dist/utils/content/fieldMapping.js +218 -0
  62. package/dist/utils/content/fieldMapping.js.map +1 -0
  63. package/dist/utils/content/index.d.ts +4 -0
  64. package/dist/utils/content/index.js +4 -0
  65. package/dist/utils/content/index.js.map +1 -0
  66. package/dist/utils/content/transformer.d.ts +5 -0
  67. package/dist/utils/content/transformer.js +323 -0
  68. package/dist/utils/content/transformer.js.map +1 -0
  69. package/dist/utils/endpoints/handlers.d.ts +9 -0
  70. package/dist/utils/endpoints/handlers.js +201 -0
  71. package/dist/utils/endpoints/handlers.js.map +1 -0
  72. package/dist/utils/endpoints/index.d.ts +2 -0
  73. package/dist/utils/endpoints/index.js +2 -0
  74. package/dist/utils/endpoints/index.js.map +1 -0
  75. package/dist/utils/fields/analyzer.d.ts +7 -0
  76. package/dist/utils/fields/analyzer.js +502 -0
  77. package/dist/utils/fields/analyzer.js.map +1 -0
  78. package/dist/utils/fields/index.d.ts +2 -0
  79. package/dist/utils/fields/index.js +2 -0
  80. package/dist/utils/fields/index.js.map +1 -0
  81. package/dist/utils/helpers/auth.d.ts +9 -0
  82. package/dist/utils/helpers/auth.js +50 -0
  83. package/dist/utils/helpers/auth.js.map +1 -0
  84. package/dist/utils/helpers/cache.d.ts +11 -0
  85. package/dist/utils/helpers/cache.js +47 -0
  86. package/dist/utils/helpers/cache.js.map +1 -0
  87. package/dist/utils/helpers/concurrency.d.ts +2 -0
  88. package/dist/utils/helpers/concurrency.js +26 -0
  89. package/dist/utils/helpers/concurrency.js.map +1 -0
  90. package/dist/utils/helpers/index.d.ts +8 -0
  91. package/dist/utils/helpers/index.js +8 -0
  92. package/dist/utils/helpers/index.js.map +1 -0
  93. package/dist/utils/helpers/objectHelpers.d.ts +3 -0
  94. package/dist/utils/helpers/objectHelpers.js +22 -0
  95. package/dist/utils/helpers/objectHelpers.js.map +1 -0
  96. package/dist/utils/helpers/rateLimiter.d.ts +10 -0
  97. package/dist/utils/helpers/rateLimiter.js +29 -0
  98. package/dist/utils/helpers/rateLimiter.js.map +1 -0
  99. package/dist/utils/helpers/responses.d.ts +3 -0
  100. package/dist/utils/helpers/responses.js +23 -0
  101. package/dist/utils/helpers/responses.js.map +1 -0
  102. package/dist/utils/helpers/wpHelpers.d.ts +6 -0
  103. package/dist/utils/helpers/wpHelpers.js +29 -0
  104. package/dist/utils/helpers/wpHelpers.js.map +1 -0
  105. package/dist/utils/lexical/constants.d.ts +37 -0
  106. package/dist/utils/lexical/constants.js +58 -0
  107. package/dist/utils/lexical/constants.js.map +1 -0
  108. package/dist/utils/lexical/htmlParser.d.ts +20 -0
  109. package/dist/utils/lexical/htmlParser.js +253 -0
  110. package/dist/utils/lexical/htmlParser.js.map +1 -0
  111. package/dist/utils/lexical/htmlToLexicalConverter.d.ts +55 -0
  112. package/dist/utils/lexical/htmlToLexicalConverter.js +999 -0
  113. package/dist/utils/lexical/htmlToLexicalConverter.js.map +1 -0
  114. package/dist/utils/lexical/index.d.ts +5 -0
  115. package/dist/utils/lexical/index.js +4 -0
  116. package/dist/utils/lexical/index.js.map +1 -0
  117. package/dist/utils/lexical/nodeFactories.d.ts +21 -0
  118. package/dist/utils/lexical/nodeFactories.js +91 -0
  119. package/dist/utils/lexical/nodeFactories.js.map +1 -0
  120. package/dist/utils/lexical/preprocessor.d.ts +4 -0
  121. package/dist/utils/lexical/preprocessor.js +302 -0
  122. package/dist/utils/lexical/preprocessor.js.map +1 -0
  123. package/dist/utils/media/download.d.ts +7 -0
  124. package/dist/utils/media/download.js +85 -0
  125. package/dist/utils/media/download.js.map +1 -0
  126. package/dist/utils/media/extraction.d.ts +12 -0
  127. package/dist/utils/media/extraction.js +58 -0
  128. package/dist/utils/media/extraction.js.map +1 -0
  129. package/dist/utils/media/import.d.ts +7 -0
  130. package/dist/utils/media/import.js +146 -0
  131. package/dist/utils/media/import.js.map +1 -0
  132. package/dist/utils/media/index.d.ts +6 -0
  133. package/dist/utils/media/index.js +6 -0
  134. package/dist/utils/media/index.js.map +1 -0
  135. package/dist/utils/media/upload.d.ts +4 -0
  136. package/dist/utils/media/upload.js +46 -0
  137. package/dist/utils/media/upload.js.map +1 -0
  138. package/dist/utils/media/validation.d.ts +8 -0
  139. package/dist/utils/media/validation.js +60 -0
  140. package/dist/utils/media/validation.js.map +1 -0
  141. package/dist/utils/migration/index.d.ts +3 -0
  142. package/dist/utils/migration/index.js +3 -0
  143. package/dist/utils/migration/index.js.map +1 -0
  144. package/dist/utils/migration/jobCrud.d.ts +4 -0
  145. package/dist/utils/migration/jobCrud.js +380 -0
  146. package/dist/utils/migration/jobCrud.js.map +1 -0
  147. package/dist/utils/migration/orchestrator.d.ts +5 -0
  148. package/dist/utils/migration/orchestrator.js +756 -0
  149. package/dist/utils/migration/orchestrator.js.map +1 -0
  150. package/dist/utils/types.d.ts +201 -0
  151. package/dist/utils/types.js +14 -0
  152. package/dist/utils/types.js.map +1 -0
  153. package/dist/utils/wordpress/client.d.ts +61 -0
  154. package/dist/utils/wordpress/client.js +365 -0
  155. package/dist/utils/wordpress/client.js.map +1 -0
  156. package/dist/utils/wordpress/index.d.ts +2 -0
  157. package/dist/utils/wordpress/index.js +2 -0
  158. package/dist/utils/wordpress/index.js.map +1 -0
  159. package/dist/utils/wordpressApi.d.ts +11 -0
  160. package/dist/utils/wordpressApi.js +25 -0
  161. package/dist/utils/wordpressApi.js.map +1 -0
  162. 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 {};