1+ import cloneDeep from 'lodash/cloneDeep' ;
12import omit from 'lodash/omit' ;
23import keys from 'lodash/keys' ;
34import isEmpty from 'lodash/isEmpty' ;
@@ -16,8 +17,12 @@ import {
1617import { ModuleClassParams , ExportConfig } from '../../types' ;
1718
1819export default class ExportTaxonomies extends BaseClass {
20+ private static readonly PUBLISH_DETAILS_DEFAULT_LOCALE = '_default' ;
21+
1922 private taxonomies : Record < string , Record < string , string > > ;
2023 private taxonomiesByLocale : Record < string , Set < string > > ;
24+ /** List API `publish_details` keyed by non-localized bucket or locale code, then taxonomy uid */
25+ private publishDetailsByLocale : Record < string , Record < string , unknown > > ;
2126 private taxonomiesConfig : ExportConfig [ 'modules' ] [ 'taxonomies' ] ;
2227 private isLocaleBasedExportSupported : boolean = true ; // Flag to track if locale-based export is supported
2328 private qs : {
@@ -39,6 +44,7 @@ export default class ExportTaxonomies extends BaseClass {
3944 super ( { exportConfig, stackAPIClient } ) ;
4045 this . taxonomies = { } ;
4146 this . taxonomiesByLocale = { } ;
47+ this . publishDetailsByLocale = { } ;
4248 this . taxonomiesConfig = exportConfig . modules . taxonomies ;
4349 this . qs = {
4450 include_count : true ,
@@ -143,6 +149,7 @@ export default class ExportTaxonomies extends BaseClass {
143149 log . debug ( 'Falling back to legacy export (non-localized)' , this . exportConfig . context ) ;
144150 this . taxonomies = { } ;
145151 this . taxonomiesByLocale = { } ;
152+ this . publishDetailsByLocale = { } ;
146153 } else {
147154 log . debug ( 'Localization enabled, proceeding with locale-based export' , this . exportConfig . context ) ;
148155 }
@@ -330,11 +337,21 @@ export default class ExportTaxonomies extends BaseClass {
330337 log . debug ( `Processing ${ taxonomies . length } taxonomies${ localeInfo } ` , this . exportConfig . context ) ;
331338
332339 for ( const taxonomy of taxonomies ) {
340+ const taxonomyRow = taxonomy as Record < string , unknown > ;
333341 const taxonomyUID = taxonomy . uid ;
334342 const taxonomyName = taxonomy . name ;
335343
336344 log . debug ( `Processing taxonomy: ${ taxonomyName } (${ taxonomyUID } )${ localeInfo } ` , this . exportConfig . context ) ;
337345
346+ // Store list API publish_details for merge into per-uid export files (per locale or default bucket)
347+ if ( taxonomyRow . publish_details != null ) {
348+ const bucket = localeCode ?? ExportTaxonomies . PUBLISH_DETAILS_DEFAULT_LOCALE ;
349+ if ( ! this . publishDetailsByLocale [ bucket ] ) {
350+ this . publishDetailsByLocale [ bucket ] = { } ;
351+ }
352+ this . publishDetailsByLocale [ bucket ] [ taxonomyUID ] = taxonomyRow . publish_details ;
353+ }
354+
338355 // Store taxonomy metadata (only once per taxonomy)
339356 if ( ! this . taxonomies [ taxonomyUID ] ) {
340357 this . taxonomies [ taxonomyUID ] = omit ( taxonomy , this . taxonomiesConfig . invalidKeys ) ;
@@ -374,8 +391,9 @@ export default class ExportTaxonomies extends BaseClass {
374391 const onSuccess = ( { response, uid } : any ) => {
375392 const taxonomyName = this . taxonomies [ uid ] ?. name ;
376393 const filePath = pResolve ( exportFolderPath , `${ uid } .json` ) ;
394+ const merged = this . mergeListPublishDetailsIntoExportPayload ( response , uid , localeCode ) ;
377395 log . debug ( `Writing detailed taxonomy data to: ${ filePath } ` , this . exportConfig . context ) ;
378- fsUtil . writeFile ( filePath , response ) ;
396+ fsUtil . writeFile ( filePath , merged ) ;
379397
380398 // Track progress for each exported taxonomy
381399 this . progressManager ?. tick (
@@ -463,6 +481,60 @@ export default class ExportTaxonomies extends BaseClass {
463481 return localesToExport ;
464482 }
465483
484+ /**
485+ * List `find` may include `publish_details` while `export` may not; we copy list data into the
486+ * written file when export omits or has an empty `taxonomy.publish_details`.
487+ */
488+ private getListPublishDetailsForExport ( taxonomyUid : string , localeCode ?: string ) : unknown | undefined {
489+ const bucket = localeCode ?? ExportTaxonomies . PUBLISH_DETAILS_DEFAULT_LOCALE ;
490+ return this . publishDetailsByLocale [ bucket ] ?. [ taxonomyUid ] ;
491+ }
492+
493+ private isPublishDetailsValueEmpty ( publishDetails : unknown ) : boolean {
494+ if ( publishDetails == null ) {
495+ return true ;
496+ }
497+ if ( Array . isArray ( publishDetails ) ) {
498+ return publishDetails . length === 0 ;
499+ }
500+ if ( typeof publishDetails === 'object' ) {
501+ return Object . keys ( publishDetails as object ) . length === 0 ;
502+ }
503+ return false ;
504+ }
505+
506+ private mergeListPublishDetailsIntoExportPayload (
507+ response : any ,
508+ taxonomyUid : string ,
509+ localeCode ?: string ,
510+ ) : any {
511+ const fromList = this . getListPublishDetailsForExport ( taxonomyUid , localeCode ) ;
512+ if ( fromList == null ) {
513+ return response ;
514+ }
515+
516+ const merged = cloneDeep ( response ) ;
517+ const applyToTaxonomyObject = ( tax : Record < string , unknown > | undefined | null ) => {
518+ if ( ! tax || typeof tax !== 'object' ) {
519+ return ;
520+ }
521+ if ( this . isPublishDetailsValueEmpty ( tax . publish_details ) ) {
522+ tax . publish_details = fromList ;
523+ }
524+ } ;
525+
526+ if ( merged && typeof merged === 'object' && 'taxonomy' in merged && ( merged as any ) . taxonomy ) {
527+ applyToTaxonomyObject ( ( merged as any ) . taxonomy ) ;
528+ return merged ;
529+ }
530+
531+ log . debug (
532+ 'Taxonomy export response has no taxonomy object; skipping publish_details merge from list' ,
533+ this . exportConfig . context ,
534+ ) ;
535+ return merged ;
536+ }
537+
466538 private isLocalePlanLimitationError ( error : any ) : boolean {
467539 return (
468540 error ?. status === 403 &&
0 commit comments