Skip to content

Commit 0e2eeb2

Browse files
committed
feat: Integrated CLIProgressManager and SummaryManager in personalize & variant-entries
1 parent 1cf7b5e commit 0e2eeb2

18 files changed

Lines changed: 701 additions & 363 deletions

File tree

packages/contentstack-import/src/import/modules/entries.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,7 @@ export default class EntriesImport extends BaseClass {
149149
progress.completeProcess('Reference Updates', true);
150150

151151
// Step 5: Restore content types
152-
progress
153-
.startProcess('CT Restoration')
154-
.updateStatus('Restoring content type references...', 'CT Restoration');
152+
progress.startProcess('CT Restoration').updateStatus('Restoring content type references...', 'CT Restoration');
155153
await this.enableMandatoryCTReferences();
156154
progress.completeProcess('CT Restoration', true);
157155

@@ -523,6 +521,7 @@ export default class EntriesImport extends BaseClass {
523521
log.debug(`Found content type schema for ${cTUid}`, this.importConfig.context);
524522

525523
const onSuccess = ({ response, apiData: entry, additionalInfo }: any) => {
524+
this.progressManager?.tick(true, `${entry?.title} - ${entry?.uid}`, null, 'Create');
526525
if (additionalInfo[entry.uid]?.isLocalized) {
527526
let oldUid = additionalInfo[entry.uid].entryOldUid;
528527
this.entriesForVariant.push({ content_type: cTUid, entry_uid: oldUid, locale });
@@ -556,6 +555,7 @@ export default class EntriesImport extends BaseClass {
556555

557556
const onReject = ({ error, apiData: entry, additionalInfo }: any) => {
558557
const { title, uid } = entry;
558+
this.progressManager?.tick(false, `${title} - ${uid}`, 'Error while creating entries', 'Create');
559559
this.entriesForVariant = this.entriesForVariant.filter(
560560
(item) => !(item.locale === locale && item.entry_uid === uid),
561561
);
@@ -613,7 +613,6 @@ export default class EntriesImport extends BaseClass {
613613

614614
entriesCreateFileHelper?.completeFile(true);
615615
existingEntriesFileHelper?.completeFile(true);
616-
this.progressManager?.tick(true, `${cTUid} - ${locale}`, null, 'Create');
617616
log.success(`Created entries for content type ${cTUid} in locale ${locale}`, this.importConfig.context);
618617
}
619618

packages/contentstack-import/src/import/modules/extensions.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ export default class ImportExtensions extends BaseClass {
7171
this.updateUidExtension();
7272

7373
if (this.importConfig.replaceExisting && this.existingExtensions.length > 0) {
74-
progress.addProcess('Update', this.existingExtensions.length);
75-
progress.startProcess('Update').updateStatus('Updating existing extensions...', 'Update');
74+
progress.addProcess('Replace existing', this.existingExtensions.length);
75+
progress.startProcess('Replace existing').updateStatus('Updating existing extensions...', 'Replace existing');
7676
await this.replaceExtensions();
77-
progress.completeProcess('Update', true);
77+
progress.completeProcess('Replace existing', true);
7878
}
7979

8080
await this.processExtensionResults();
@@ -167,7 +167,7 @@ export default class ImportExtensions extends BaseClass {
167167
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }: any) => {
168168
this.extSuccess.push(response);
169169
this.extUidMapper[uid] = response.uid;
170-
this.progressManager?.tick(true, `extension: ${title || uid} (updated)`, null, 'Update');
170+
this.progressManager?.tick(true, `extension: ${title || uid} (updated)`, null, 'Replace existing');
171171
log.success(`Extension '${title}' updated successfully`, this.importConfig.context);
172172
log.debug(`Extension update completed: ${title} (${uid})`, this.importConfig.context);
173173
fsUtil.writeFile(this.extUidMapperPath, this.extUidMapper);
@@ -180,7 +180,7 @@ export default class ImportExtensions extends BaseClass {
180180
false,
181181
`extension: ${title || uid}`,
182182
error?.message || 'Failed to update extension',
183-
'Update',
183+
'Replace existing',
184184
);
185185
log.debug(`Extension '${title}' update failed`, this.importConfig.context);
186186
handleAndLogError(error, { ...this.importConfig.context, title }, `Extension '${title}' failed to be updated`);

packages/contentstack-import/src/import/modules/locales.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,7 @@ export default class ImportLocales extends BaseClass {
130130
};
131131

132132
const onReject = ({ error, apiData: { uid, code } = undefined }: any) => {
133-
this.progressManager?.tick(
134-
false,
135-
`locale: ${code}`,
136-
error?.message || 'Failed to create locale',
137-
'Create',
138-
);
133+
this.progressManager?.tick(false, `locale: ${code}`, error?.message || 'Failed to create locale', 'Create');
139134
if (error?.errorCode === 247) {
140135
log.info(formatError(error), this.config.context);
141136
} else {
@@ -164,10 +159,12 @@ export default class ImportLocales extends BaseClass {
164159
const onSuccess = ({ response = {}, apiData: { uid, code } = undefined }: any) => {
165160
log.info(`Updated locale: '${code}'`, this.config.context);
166161
log.debug(`Locale update completed for: ${code}`, this.config.context);
162+
this.progressManager?.tick(true, `locale: ${code}`, null, 'Update');
167163
fsUtil.writeFile(this.langSuccessPath, this.createdLocales);
168164
};
169165

170166
const onReject = ({ error, apiData: { uid, code } = undefined }: any) => {
167+
this.progressManager?.tick(false, `locale: ${code}`, 'Failed to update locale', 'Update');
171168
log.error(`Language '${code}' failed to update`, this.config.context);
172169
handleAndLogError(error, { ...this.config.context, code });
173170
fsUtil.writeFile(this.langFailsPath, this.failedLocales);
@@ -304,7 +301,10 @@ export default class ImportLocales extends BaseClass {
304301
const message = `master locale: codes differ (${sourceCode} vs ${targetCode})`;
305302

306303
this.tickProgress(true, message);
307-
log.debug(`Master Locale language codes do not match. Source: ${sourceCode}, Target: ${targetCode}`, this.config.context);
304+
log.debug(
305+
`Master Locale language codes do not match. Source: ${sourceCode}, Target: ${targetCode}`,
306+
this.config.context,
307+
);
308308
}
309309

310310
private async handleNameMismatch(source: Record<string, any>, target: Record<string, any>): Promise<void> {

packages/contentstack-import/src/import/modules/personalize.ts

Lines changed: 69 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export default class ImportPersonalize extends BaseClass {
77
private config: ImportConfig;
88
public personalizeConfig: ImportConfig['modules']['personalize'];
99

10+
private readonly moduleDisplayMapper = {
11+
events: 'Events',
12+
attributes: 'Attributes',
13+
audiences: 'Audiences',
14+
experiences: 'Experiences',
15+
};
16+
1017
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
1118
super({ importConfig, stackAPIClient });
1219
this.config = importConfig;
@@ -29,30 +36,23 @@ export default class ImportPersonalize extends BaseClass {
2936
}
3037

3138
const progress = this.createNestedProgress(this.currentModuleName);
32-
progress.addProcess('Project Import', 1);
3339

34-
if (this.personalizeConfig.importData && modulesCount > 0) {
35-
progress.addProcess('Personalize data import', modulesCount);
36-
}
40+
this.addProjectProcess(progress);
41+
this.addModuleProcesses(progress, modulesCount);
3742

3843
// Step 1: Import personalize project
39-
progress.startProcess('Project Import').updateStatus('Importing personalize project...', 'Project Import');
40-
log.info('Starting personalize project import', this.config.context);
41-
await this.importPersonalizeProject(progress);
42-
progress.completeProcess('Project Import', true);
44+
await this.importProjects(progress);
4345

4446
// Step 2: Import personalize data modules (if enabled)
4547
if (this.personalizeConfig.importData && modulesCount > 0) {
46-
progress
47-
.startProcess('Personalize data import')
48-
.updateStatus('Importing personalize data modules...', 'Personalize data import');
49-
log.info('Starting personalize data import', this.config.context);
50-
await this.importPersonalizeData(progress);
51-
progress.completeProcess('Personalize data import', true);
48+
log.debug('Processing personalize modules...', this.config.context);
49+
await this.importModules(progress);
50+
} else {
51+
log.debug('No personalize modules configured for processing', this.config.context);
5252
}
5353

5454
this.completeProgress(true);
55-
log.success('Personalize import completed successfully', this.config.context)
55+
log.success('Personalize import completed successfully', this.config.context);
5656
} catch (error) {
5757
this.personalizeConfig.importData = false; // Stop personalize import if project creation fails
5858
this.completeProgress(false, (error as any)?.message || 'Personalize import failed');
@@ -64,25 +64,40 @@ export default class ImportPersonalize extends BaseClass {
6464
}
6565
}
6666

67-
private async importPersonalizeProject(parentProgress: any): Promise<void> {
68-
log.debug('Starting personalize project import', this.config.context);
69-
log.debug(`Base URL: ${this.personalizeConfig.baseURL[this.config.region.name]}`, this.config.context);
67+
private addProjectProcess(progress: any) {
68+
progress.addProcess('Projects', 1);
69+
log.debug('Added Projects process to personalize progress', this.config.context);
70+
}
71+
72+
private addModuleProcesses(progress: any, moduleCount: number) {
73+
if (moduleCount > 0) {
74+
const order: (keyof typeof this.moduleDisplayMapper)[] = this.personalizeConfig
75+
.importOrder as (keyof typeof this.moduleDisplayMapper)[];
7076

71-
// Create project instance and set parent progress manager
72-
const projectInstance = new Import.Project(this.config);
73-
if (projectInstance.setParentProgressManager) {
74-
projectInstance.setParentProgressManager(parentProgress);
77+
log.debug(`Adding ${order.length} personalize module processes: ${order.join(', ')}`, this.config.context);
78+
79+
for (const module of order) {
80+
const processName = this.moduleDisplayMapper[module];
81+
progress.addProcess(processName, 1);
82+
log.debug(`Added ${processName} process to personalize progress`, this.config.context);
83+
}
84+
} else {
85+
log.debug('No personalize modules to add to progress', this.config.context);
7586
}
87+
}
88+
89+
private async importProjects(progress: any): Promise<void> {
90+
progress.startProcess('Projects').updateStatus('Importing personalization projects...', 'Projects');
91+
log.debug('Starting projects import for personalization...', this.config.context);
7692

93+
const projectInstance = new Import.Project(this.config);
94+
projectInstance.setParentProgressManager(progress);
7795
await projectInstance.import();
7896

79-
parentProgress?.tick(true, 'personalize project', null, 'Project Import');
80-
log.debug('Personalize project import completed', this.config.context);
97+
progress.completeProcess('Projects', true);
8198
}
8299

83-
private async importPersonalizeData(parentProgress: any): Promise<void> {
84-
log.debug('Personalize data import is enabled', this.config.context);
85-
100+
private async importModules(progress: any): Promise<void> {
86101
const moduleMapper = {
87102
events: Import.Events,
88103
audiences: Import.Audiences,
@@ -92,46 +107,36 @@ export default class ImportPersonalize extends BaseClass {
92107

93108
const order: (keyof typeof moduleMapper)[] = this.personalizeConfig.importOrder as (keyof typeof moduleMapper)[];
94109

95-
log.debug(`Processing ${order.length} personalize modules in order: ${order.join(', ')}`, this.config.context);
110+
log.debug(`Personalize import order: ${order.join(', ')}`, this.config.context);
96111

97112
for (const module of order) {
98-
log.debug(`Starting import for personalize module: ${module}`, this.config.context);
99-
const Module = moduleMapper[module];
100-
101-
if (!Module) {
102-
parentProgress?.tick(
103-
false,
104-
`module: ${module}`,
105-
'Module not found in moduleMapper',
106-
'Personalize data import',
107-
);
108-
log.debug(`Module ${module} not found in moduleMapper`, this.config.context);
109-
continue;
110-
}
111-
112-
try {
113-
log.debug(`Creating instance of ${module} module`, this.config.context);
114-
const moduleInstance = new Module(this.config);
115-
116-
// Set parent progress manager for sub-module
117-
if (moduleInstance.setParentProgressManager) {
118-
moduleInstance.setParentProgressManager(parentProgress);
113+
log.debug(`Processing personalize module: ${module}`, this.config.context);
114+
const processName = this.moduleDisplayMapper[module];
115+
const ModuleClass = moduleMapper[module];
116+
117+
if (ModuleClass) {
118+
progress.startProcess(processName).updateStatus(`Importing ${module}...`, processName);
119+
log.debug(`Starting import for module: ${module}`, this.config.context);
120+
121+
if (this.personalizeConfig.importData) {
122+
const importer = new ModuleClass(this.config);
123+
importer.setParentProgressManager(progress);
124+
await importer.import();
125+
126+
progress.completeProcess(processName, true);
127+
log.debug(`Completed import for module: ${module}`, this.config.context);
128+
} else {
129+
log.debug(`Skipping ${module} - personalization not enabled`, this.config.context);
130+
this.progressManager?.tick(true, `${module} skipped (no project)`, null, processName);
131+
progress.completeProcess(processName, true);
132+
log.info(`Skipped ${module} import - no personalize project found`, this.config.context);
119133
}
120-
121-
log.debug(`Importing ${module} module`, this.config.context);
122-
await moduleInstance.import();
123-
124-
parentProgress?.tick(true, `module: ${module}`, null, 'Personalize data import');
125-
log.success(`Successfully imported personalize module: ${module}`, this.config.context);
126-
} catch (error) {
127-
parentProgress?.tick(
128-
false,
129-
`module: ${module}`,
130-
(error as any)?.message || 'Import failed',
131-
'Personalize data import',
132-
);
133-
log.debug(`Failed to import personalize module: ${module} - ${(error as any)?.message}`, this.config.context);
134-
handleAndLogError(error, { ...this.config.context, module });
134+
} else {
135+
log.debug(`Module not implemented: ${module}`, this.config.context);
136+
progress.startProcess(processName).updateStatus(`Module not implemented: ${module}`, processName);
137+
this.progressManager?.tick(false, `module: ${module}`, 'Module not implemented', processName);
138+
progress.completeProcess(processName, false);
139+
log.info(`Module not implemented: ${module}`, this.config.context);
135140
}
136141
}
137142

packages/contentstack-import/src/import/modules/stack.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default class ImportStack extends BaseClass {
1313
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
1414
super({ importConfig, stackAPIClient });
1515
this.importConfig.context.module = 'stack';
16-
this.currentModuleName = 'Stack Settings';
16+
this.currentModuleName = 'Stack';
1717
this.stackSettingsPath = join(this.importConfig.backupDir, 'stack', 'settings.json');
1818
this.envUidMapperPath = join(this.importConfig.backupDir, 'mapper', 'environments', 'uid-mapping.json');
1919
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default class ImportTaxonomies extends BaseClass {
5858
this.createSuccessAndFailedFile();
5959

6060
this.completeProgress(true);
61-
log.success('Taxonomies imported successfully!', this.importConfig.context);
61+
log.success('Taxonomies imported successfully!', this.importConfig.context);
6262
} catch (error) {
6363
this.completeProgress(false, error?.message || 'Taxonomies import failed');
6464
handleAndLogError(error, { ...this.importConfig.context });

packages/contentstack-import/src/import/modules/variant-entries.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default class ImportVariantEntries extends BaseClass {
4848
return;
4949
}
5050

51-
const progress = this.createSimpleProgress(this.currentModuleName, 1);
51+
const progress = this.createSimpleProgress(this.currentModuleName);
5252

5353
progress.updateStatus('Importing variant entries...');
5454
log.info('Starting variant entries import process', this.config.context);

packages/contentstack-import/src/import/modules/webhooks.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default class ImportWebhooks extends BaseClass {
4646
const [webhooksCount] = await this.analyzeWebhooks();
4747

4848
if (webhooksCount === 0) {
49-
log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
49+
log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
5050
return;
5151
}
5252

@@ -59,7 +59,7 @@ export default class ImportWebhooks extends BaseClass {
5959
this.processWebhookResults();
6060

6161
this.completeProgress(true);
62-
log.success('Webhooks have been imported successfully!', this.importConfig.context);
62+
log.success('Webhooks have been imported successfully!', this.importConfig.context);
6363
} catch (error) {
6464
this.completeProgress(false, error?.message || 'Webhooks import failed');
6565
handleAndLogError(error, { ...this.importConfig.context });
@@ -95,11 +95,7 @@ export default class ImportWebhooks extends BaseClass {
9595
log.info(`Webhook '${name}' already exists`, this.importConfig.context);
9696
} else {
9797
this.failedWebhooks.push(apiData);
98-
this.progressManager?.tick(
99-
false,
100-
`webhook: ${name || uid}`,
101-
error?.message || 'Failed to import webhook',
102-
);
98+
this.progressManager?.tick(false, `webhook: ${name || uid}`, error?.message || 'Failed to import webhook');
10399
handleAndLogError(
104100
error,
105101
{ ...this.importConfig.context, webhookName: name },

0 commit comments

Comments
 (0)