Skip to content

Commit 651fb20

Browse files
Merge branch 'v2-dev' into fix/DX-8552
2 parents 56da1a3 + 8f53ebf commit 651fb20

17 files changed

Lines changed: 852 additions & 42 deletions

File tree

packages/contentstack-export/src/export/modules/taxonomies.ts

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import cloneDeep from 'lodash/cloneDeep';
12
import omit from 'lodash/omit';
23
import keys from 'lodash/keys';
34
import isEmpty from 'lodash/isEmpty';
@@ -16,19 +17,25 @@ import {
1617
import { ModuleClassParams, ExportConfig } from '../../types';
1718

1819
export 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: {
2429
include_count: boolean;
30+
include_publish_details: boolean;
2531
skip: number;
2632
asc?: string;
2733
limit: number;
2834
locale?: string;
2935
branch?: string;
3036
include_fallback?: boolean;
3137
fallback_locale?: string;
38+
query?: Record<string, unknown>;
3239
};
3340
public taxonomiesFolderPath: string;
3441
private localesFilePath: string;
@@ -37,8 +44,14 @@ export default class ExportTaxonomies extends BaseClass {
3744
super({ exportConfig, stackAPIClient });
3845
this.taxonomies = {};
3946
this.taxonomiesByLocale = {};
47+
this.publishDetailsByLocale = {};
4048
this.taxonomiesConfig = exportConfig.modules.taxonomies;
41-
this.qs = { include_count: true, limit: this.taxonomiesConfig.limit || 100, skip: 0 };
49+
this.qs = {
50+
include_count: true,
51+
include_publish_details: true,
52+
limit: this.taxonomiesConfig.limit || 100,
53+
skip: 0,
54+
};
4255

4356
this.applyQueryFilters(this.qs, 'taxonomies');
4457
this.exportConfig.context.module = MODULE_CONTEXTS.TAXONOMIES;
@@ -136,6 +149,7 @@ export default class ExportTaxonomies extends BaseClass {
136149
log.debug('Falling back to legacy export (non-localized)', this.exportConfig.context);
137150
this.taxonomies = {};
138151
this.taxonomiesByLocale = {};
152+
this.publishDetailsByLocale = {};
139153
} else {
140154
log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context);
141155
}
@@ -323,11 +337,21 @@ export default class ExportTaxonomies extends BaseClass {
323337
log.debug(`Processing ${taxonomies.length} taxonomies${localeInfo}`, this.exportConfig.context);
324338

325339
for (const taxonomy of taxonomies) {
340+
const taxonomyRow = taxonomy as Record<string, unknown>;
326341
const taxonomyUID = taxonomy.uid;
327342
const taxonomyName = taxonomy.name;
328343

329344
log.debug(`Processing taxonomy: ${taxonomyName} (${taxonomyUID})${localeInfo}`, this.exportConfig.context);
330345

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+
331355
// Store taxonomy metadata (only once per taxonomy)
332356
if (!this.taxonomies[taxonomyUID]) {
333357
this.taxonomies[taxonomyUID] = omit(taxonomy, this.taxonomiesConfig.invalidKeys);
@@ -367,8 +391,9 @@ export default class ExportTaxonomies extends BaseClass {
367391
const onSuccess = ({ response, uid }: any) => {
368392
const taxonomyName = this.taxonomies[uid]?.name;
369393
const filePath = pResolve(exportFolderPath, `${uid}.json`);
394+
const merged = this.mergeListPublishDetailsIntoExportPayload(response, uid, localeCode);
370395
log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context);
371-
fsUtil.writeFile(filePath, response);
396+
fsUtil.writeFile(filePath, merged);
372397

373398
// Track progress for each exported taxonomy
374399
this.progressManager?.tick(
@@ -456,6 +481,60 @@ export default class ExportTaxonomies extends BaseClass {
456481
return localesToExport;
457482
}
458483

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+
459538
private isLocalePlanLimitationError(error: any): boolean {
460539
return (
461540
error?.status === 403 &&

0 commit comments

Comments
 (0)