@@ -124,7 +124,7 @@ function getLastUid(uid : string) {
124124 return uid ?. split ?.( '.' ) ?. [ uid ?. split ?.( '.' ) ?. length - 1 ] ;
125125}
126126
127- async function createSchema ( fields : any , blockJson : any , title : string , uid : string , assetData : any ) {
127+ async function createSchema ( fields : any , blockJson : any , title : string , uid : string , assetData : any , duplicateBlockMappings ?: Record < string , string > ) {
128128 const schema : any = {
129129 title : title ,
130130 uid : uid ,
@@ -162,16 +162,37 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st
162162 const blockName = ( block ?. attrs ?. metadata ?. name ?. toLowerCase ( ) || getFieldName ( block ?. blockName ?. toLowerCase ( ) ) ) ;
163163
164164 // Find which modular block child this block matches
165- const matchingChildField = fields . find ( ( childField : any ) => {
165+ let matchingChildField = fields . find ( ( childField : any ) => {
166166 const fieldName = childField ?. otherCmsField ?. toLowerCase ( ) ;
167167
168168 return ( childField ?. contentstackFieldType !== 'modular_blocks_child' ) && ( blockName === fieldName )
169169 } ) ;
170170
171- const matchingModularBlockChild = modularBlockChildren . find ( ( childField : any ) => {
171+ let matchingModularBlockChild = modularBlockChildren . find ( ( childField : any ) => {
172172 const fieldName = childField ?. otherCmsField ?. toLowerCase ( ) ;
173173 return blockName === fieldName
174174 } ) ;
175+
176+ // Fallback: if no direct match, check duplicate block mappings
177+ if ( ! matchingModularBlockChild && duplicateBlockMappings ) {
178+ const mappedName = duplicateBlockMappings [ blockName ] ;
179+
180+ if ( mappedName ) {
181+
182+ matchingModularBlockChild = modularBlockChildren . find ( ( childField : any ) => {
183+ const fieldName = childField ?. otherCmsField ?. toLowerCase ( ) ;
184+ return mappedName === fieldName ;
185+ } ) ;
186+
187+ //if (!matchingChildField) {
188+ matchingChildField = fields . find ( ( childField : any ) => {
189+ const fieldName = childField ?. otherCmsField ?. toLowerCase ( ) ;
190+ return ( childField ?. contentstackFieldType !== 'modular_blocks_child' ) && ( mappedName === fieldName ) ;
191+ } ) ;
192+
193+ // }
194+ }
195+ }
175196
176197 //if (matchingChildField) {
177198 // Process innerBlocks (children) if they exist
@@ -186,12 +207,13 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st
186207 const childField = fields . find ( ( f : any ) => {
187208 const fUid = f ?. contentstackFieldUid || '' ;
188209 const fOtherCmsField = f ?. otherCmsType ?. toLowerCase ( ) ;
189- const childBlockName = ( child ?. attrs ?. metadata ?. name ?. toLowerCase ( ) || getFieldName ( child ?. blockName ?. toLowerCase ( ) ) ) ;
190- // Check if this field belongs to the modular_blocks_child and matches the block name
210+ const childBlockName = matchingChildField ? matchingChildField ?. otherCmsField ?. toLowerCase ( ) : ( child ?. attrs ?. metadata ?. name ?. toLowerCase ( ) || getFieldName ( child ?. blockName ?. toLowerCase ( ) ) ) ;
211+ const childKey = getLastUid ( f ?. contentstackFieldUid ) ;
212+ const alreadyPopulated = childrenObject [ childKey ] !== undefined && childrenObject [ childKey ] !== null ;
191213 return fUid . startsWith ( childFieldUid + '.' ) &&
192- ( fOtherCmsField === childBlockName ) && ! childrenObject [ getLastUid ( f ?. contentstackFieldUid ) ] ?. length ;
214+ ( fOtherCmsField === childBlockName ) && ( ! alreadyPopulated || f ?. advanced ?. multiple === true ) ;
193215 } ) ;
194-
216+
195217 if ( childField ) {
196218 const childKey = getLastUid ( childField ?. contentstackFieldUid ) ;
197219
@@ -218,6 +240,7 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st
218240 childrenObject [ childKey ] = [ formattedChild ] ;
219241 }
220242 } else {
243+
221244 formattedChild && ( childrenObject [ childKey ] = formattedChild ) ;
222245 }
223246 }
@@ -228,7 +251,13 @@ async function createSchema(fields: any, blockJson : any, title: string, uid: st
228251 } ) ;
229252
230253 // Add the block to the modular blocks array with the child field's UID as the key
231- Object . keys ( childrenObject ) . length > 0 && modularBlocksArray . push ( { [ getLastUid ( matchingModularBlockChild ?. contentstackFieldUid ) ] : childrenObject } ) ;
254+ if ( Object ?. keys ( childrenObject ) ?. length > 0 ) {
255+ modularBlocksArray . push ( { [ getLastUid ( matchingModularBlockChild ?. contentstackFieldUid ) ] : childrenObject } ) ;
256+ } else if ( getLastUid ( matchingModularBlockChild ?. contentstackFieldUid ) && matchingChildField ) {
257+ // Fallback: inner blocks didn't match child fields (e.g., duplicate-mapped block with different inner block types)
258+ const formattedBlock = formatChildByType ( block , matchingChildField , assetData ) ;
259+ formattedBlock && modularBlocksArray . push ( { [ getLastUid ( matchingModularBlockChild ?. contentstackFieldUid ) ] : { [ getLastUid ( matchingChildField ?. contentstackFieldUid ) ] : formattedBlock } } ) ;
260+ }
232261 } else if ( getLastUid ( matchingModularBlockChild ?. contentstackFieldUid ) && matchingChildField ) {
233262 // Handle blocks with no inner blocks - format the block itself
234263 const formattedBlock = formatChildByType ( block , matchingChildField , assetData ) ;
@@ -389,9 +418,17 @@ function formatChildByType(child: any, field: any, assetData: any) {
389418 formatted = Boolean ( child ?. attrs [ attrKey ] ) ;
390419 break ;
391420
392- case 'json' :
393- formatted = child ?. blockName ? RteJsonConverter ( formatted ?? child ?. innerHTML ) : RteJsonConverter ( formatted ?? child ) ;
421+ case 'json' : {
422+ let htmlContent = formatted ;
423+ if ( ! htmlContent && child ?. innerBlocks ?. length > 0 ) {
424+ htmlContent = collectHtmlFromInnerBlocks ( child ) ;
425+ }
426+ if ( ! htmlContent ) {
427+ htmlContent = child ?. blockName ? child ?. innerHTML : child ;
428+ }
429+ formatted = RteJsonConverter ( htmlContent ) ;
394430 break ;
431+ }
395432
396433 case 'html' :
397434 formatted = child ?. blockName ? formatted ?? child ?. innerHTML : `<p>${ child } </p>` ;
@@ -471,7 +508,7 @@ const extractTermsReference = (terms: any) => {
471508 const termReference = termArray ?. filter ( ( term : any ) => term ?. attributes ?. domain !== 'category' ) ;
472509 return termReference ;
473510}
474- async function saveEntry ( fields : any , entry : any , file_path : string , assetData : any , categories : any , master_locale : string , destinationStackId : string , project : any , allTerms : any ) {
511+ async function saveEntry ( fields : any , entry : any , file_path : string , assetData : any , categories : any , master_locale : string , destinationStackId : string , project : any , allTerms : any , duplicateBlockMappings ?: Record < string , string > ) {
475512 const locale = getLocale ( master_locale , project ) ;
476513 const mapperKeys = project ?. mapperKeys || { } ;
477514 const authorsCtName = mapperKeys [ MIGRATION_DATA_CONFIG . AUTHORS_DIR_NAME ] ? mapperKeys [ MIGRATION_DATA_CONFIG . AUTHORS_DIR_NAME ] : MIGRATION_DATA_CONFIG . AUTHORS_DIR_NAME ;
@@ -544,10 +581,11 @@ async function saveEntry(fields: any, entry: any, file_path: string, assetData
544581 const contentEncoded = $ ( xmlItem ) ?. find ( "content\\:encoded" ) ?. text ( ) || '' ;
545582 const blocksJson = await setupWordPressBlocks ( contentEncoded ) ;
546583 customLogger ( project ?. id , destinationStackId , 'info' , `Processed blocks for entry ${ uid } ` ) ;
547- //await writeFileAsync(`${uid}.json`, JSON.stringify(blocksJson, null, 4), 4);
584+
585+
548586
549587 // Pass individual content to createSchema
550- entryData [ uid ] = await createSchema ( fields , blocksJson , item ?. title , uid , assetData ) ;
588+ entryData [ uid ] = await createSchema ( fields , blocksJson , item ?. title , uid , assetData , duplicateBlockMappings ) ;
551589 const categoryReference = extractCategoryReference ( item ?. [ 'category' ] ) ;
552590 if ( categoryReference ?. length > 0 ) {
553591 entryData [ uid ] [ 'taxonomies' ] = taxonomies ;
@@ -586,6 +624,7 @@ async function createEntry(file_path: string, packagePath: string, destinationSt
586624 const entriesJsonData = JSON . parse ( Jsondata ) ;
587625 const entries = entriesJsonData ?. rss ?. channel ?. [ "item" ] ;
588626 const categories = entriesJsonData ?. rss ?. channel ?. [ "wp:category" ] ;
627+ const allCategories = Array ?. isArray ( categories ) ? categories : ( categories ? [ categories ] : [ ] ) ;
589628
590629 const authorsData = entriesJsonData ?. rss ?. channel ?. [ "wp:author" ] ;
591630 const authors = Array ?. isArray ( authorsData ) ? authorsData : [ authorsData ] ;
@@ -669,15 +708,8 @@ async function createEntry(file_path: string, packagePath: string, destinationSt
669708 const entry = entries ?. filter ( ( entry : any ) => {
670709 return entry ?. [ 'wp:post_type' ] ?. toLowerCase ( ) === contentTypeUid ;
671710 } ) ;
672-
673- // for (const [type, items] of Object.entries(groupedByType)) {
674- // if (Array.isArray(items) && items.length > 0) {
675- // await extractItems(items,file_path);
676- // } else {
677- // console.log(`No ${type} found to extract`);
678- // }
679- // }
680- const content = await saveEntry ( contentType ?. fieldMapping , entry , file_path , assetData , categories , master_locale , destinationStackId , project , allTerms ) || { } ;
711+
712+ const content = await saveEntry ( contentType ?. fieldMapping , entry , file_path , assetData , allCategories , master_locale , destinationStackId , project , allTerms , contentType ?. duplicateBlockMappings ) || { } ;
681713
682714 const filePath = path . join ( postFolderPath , `${ locale } .json` ) ;
683715 await writeFileAsync ( filePath , content , 4 ) ;
@@ -696,7 +728,9 @@ async function createTaxonomy(file_path: string, packagePath: string, destinatio
696728
697729 const Jsondata = await fs . promises . readFile ( packagePath , "utf8" ) ;
698730 const xmlData = await fs . promises . readFile ( file_path , "utf8" ) ;
699- const categoriesJsonData = JSON . parse ( Jsondata ) ?. rss ?. channel ?. [ "wp:category" ] || JSON . parse ( Jsondata ) ?. channel ?. [ "wp:category" ] || [ ] ;
731+ const categoriesData = JSON . parse ( Jsondata ) ?. rss ?. channel ?. [ "wp:category" ] || JSON . parse ( Jsondata ) ?. channel ?. [ "wp:category" ] ;
732+ const categoriesJsonData = Array ?. isArray ( categoriesData ) ? categoriesData : ( categoriesData ? [ categoriesData ] : [ ] ) ;
733+
700734 if ( categoriesJsonData ?. length > 0 ) {
701735 const allTaxonomies : any = { }
702736 for ( const category of categoriesJsonData ) {
0 commit comments