Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ fileignoreconfig:
checksum: 0dbf0a6bc447206260b8acd41b85781d60ca50c948bb3ca62f444f97d64d1fb2
- filename: packages/contentstack-utilities/src/interfaces/index.ts
checksum: d0b0042e643ce0c0489b86f15f3b64f60a837c2ae928b6275028e5e0184b0a7a
- filename: packages/contentstack-variants/src/import/attribute.ts
checksum: 03e764ee2032c44d9493f2be194f91a2337026b7fd8037df90240327e6bcaabb
- filename: packages/contentstack-variants/src/import/audiences.ts
checksum: f24697ef86e928bb4d16f93c021b647639cc344a7f02463d79d69f9434ebed56
- filename: packages/contentstack-variants/src/import/events.ts
checksum: 6cb014b5518ffe204a9f894ad801c05e2ef91a1692049168f74dd12a224363c4
- filename: packages/contentstack-import/src/import/modules/personalize.ts
checksum: 1311a613177160637e21b3983b281b384c2cb15837d001a398b67afef30a393a
version: "1.0"
7 changes: 3 additions & 4 deletions packages/contentstack-import/src/import/modules/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,7 @@ export default class EntriesImport extends BaseClass {
progress.completeProcess('Reference Updates', true);

// Step 5: Restore content types
progress
.startProcess('CT Restoration')
.updateStatus('Restoring content type references...', 'CT Restoration');
progress.startProcess('CT Restoration').updateStatus('Restoring content type references...', 'CT Restoration');
await this.enableMandatoryCTReferences();
progress.completeProcess('CT Restoration', true);

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

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

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

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

Expand Down
10 changes: 5 additions & 5 deletions packages/contentstack-import/src/import/modules/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ export default class ImportExtensions extends BaseClass {
this.updateUidExtension();

if (this.importConfig.replaceExisting && this.existingExtensions.length > 0) {
progress.addProcess('Update', this.existingExtensions.length);
progress.startProcess('Update').updateStatus('Updating existing extensions...', 'Update');
progress.addProcess('Replace existing', this.existingExtensions.length);
progress.startProcess('Replace existing').updateStatus('Updating existing extensions...', 'Replace existing');
await this.replaceExtensions();
progress.completeProcess('Update', true);
progress.completeProcess('Replace existing', true);
}

await this.processExtensionResults();
Expand Down Expand Up @@ -167,7 +167,7 @@ export default class ImportExtensions extends BaseClass {
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }: any) => {
this.extSuccess.push(response);
this.extUidMapper[uid] = response.uid;
this.progressManager?.tick(true, `extension: ${title || uid} (updated)`, null, 'Update');
this.progressManager?.tick(true, `extension: ${title || uid} (updated)`, null, 'Replace existing');
log.success(`Extension '${title}' updated successfully`, this.importConfig.context);
log.debug(`Extension update completed: ${title} (${uid})`, this.importConfig.context);
fsUtil.writeFile(this.extUidMapperPath, this.extUidMapper);
Expand All @@ -180,7 +180,7 @@ export default class ImportExtensions extends BaseClass {
false,
`extension: ${title || uid}`,
error?.message || 'Failed to update extension',
'Update',
'Replace existing',
);
log.debug(`Extension '${title}' update failed`, this.importConfig.context);
handleAndLogError(error, { ...this.importConfig.context, title }, `Extension '${title}' failed to be updated`);
Expand Down
14 changes: 7 additions & 7 deletions packages/contentstack-import/src/import/modules/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,7 @@ export default class ImportLocales extends BaseClass {
};

const onReject = ({ error, apiData: { uid, code } = undefined }: any) => {
this.progressManager?.tick(
false,
`locale: ${code}`,
error?.message || 'Failed to create locale',
'Create',
);
this.progressManager?.tick(false, `locale: ${code}`, error?.message || 'Failed to create locale', 'Create');
if (error?.errorCode === 247) {
log.info(formatError(error), this.config.context);
} else {
Expand Down Expand Up @@ -164,10 +159,12 @@ export default class ImportLocales extends BaseClass {
const onSuccess = ({ response = {}, apiData: { uid, code } = undefined }: any) => {
log.info(`Updated locale: '${code}'`, this.config.context);
log.debug(`Locale update completed for: ${code}`, this.config.context);
this.progressManager?.tick(true, `locale: ${code}`, null, 'Update');
fsUtil.writeFile(this.langSuccessPath, this.createdLocales);
};

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

this.tickProgress(true, message);
log.debug(`Master Locale language codes do not match. Source: ${sourceCode}, Target: ${targetCode}`, this.config.context);
log.debug(
`Master Locale language codes do not match. Source: ${sourceCode}, Target: ${targetCode}`,
this.config.context,
);
}

private async handleNameMismatch(source: Record<string, any>, target: Record<string, any>): Promise<void> {
Expand Down
133 changes: 69 additions & 64 deletions packages/contentstack-import/src/import/modules/personalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ export default class ImportPersonalize extends BaseClass {
private config: ImportConfig;
public personalizeConfig: ImportConfig['modules']['personalize'];

private readonly moduleDisplayMapper = {
events: 'Events',
attributes: 'Attributes',
audiences: 'Audiences',
experiences: 'Experiences',
};

constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
this.config = importConfig;
Expand All @@ -29,30 +36,23 @@ export default class ImportPersonalize extends BaseClass {
}

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

if (this.personalizeConfig.importData && modulesCount > 0) {
progress.addProcess('Personalize data import', modulesCount);
}
this.addProjectProcess(progress);
this.addModuleProcesses(progress, modulesCount);

// Step 1: Import personalize project
progress.startProcess('Project Import').updateStatus('Importing personalize project...', 'Project Import');
log.info('Starting personalize project import', this.config.context);
await this.importPersonalizeProject(progress);
progress.completeProcess('Project Import', true);
await this.importProjects(progress);

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

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

private async importPersonalizeProject(parentProgress: any): Promise<void> {
log.debug('Starting personalize project import', this.config.context);
log.debug(`Base URL: ${this.personalizeConfig.baseURL[this.config.region.name]}`, this.config.context);
private addProjectProcess(progress: any) {
progress.addProcess('Projects', 1);
log.debug('Added Projects process to personalize progress', this.config.context);
}

private addModuleProcesses(progress: any, moduleCount: number) {
if (moduleCount > 0) {
const order: (keyof typeof this.moduleDisplayMapper)[] = this.personalizeConfig
.importOrder as (keyof typeof this.moduleDisplayMapper)[];

// Create project instance and set parent progress manager
const projectInstance = new Import.Project(this.config);
if (projectInstance.setParentProgressManager) {
projectInstance.setParentProgressManager(parentProgress);
log.debug(`Adding ${order.length} personalize module processes: ${order.join(', ')}`, this.config.context);

for (const module of order) {
const processName = this.moduleDisplayMapper[module];
progress.addProcess(processName, 1);
log.debug(`Added ${processName} process to personalize progress`, this.config.context);
}
} else {
log.debug('No personalize modules to add to progress', this.config.context);
}
}

private async importProjects(progress: any): Promise<void> {
progress.startProcess('Projects').updateStatus('Importing personalization projects...', 'Projects');
log.debug('Starting projects import for personalization...', this.config.context);

const projectInstance = new Import.Project(this.config);
projectInstance.setParentProgressManager(progress);
await projectInstance.import();

parentProgress?.tick(true, 'personalize project', null, 'Project Import');
log.debug('Personalize project import completed', this.config.context);
progress.completeProcess('Projects', true);
}

private async importPersonalizeData(parentProgress: any): Promise<void> {
log.debug('Personalize data import is enabled', this.config.context);

private async importModules(progress: any): Promise<void> {
const moduleMapper = {
events: Import.Events,
audiences: Import.Audiences,
Expand All @@ -92,46 +107,36 @@ export default class ImportPersonalize extends BaseClass {

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

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

for (const module of order) {
log.debug(`Starting import for personalize module: ${module}`, this.config.context);
const Module = moduleMapper[module];

if (!Module) {
parentProgress?.tick(
false,
`module: ${module}`,
'Module not found in moduleMapper',
'Personalize data import',
);
log.debug(`Module ${module} not found in moduleMapper`, this.config.context);
continue;
}

try {
log.debug(`Creating instance of ${module} module`, this.config.context);
const moduleInstance = new Module(this.config);

// Set parent progress manager for sub-module
if (moduleInstance.setParentProgressManager) {
moduleInstance.setParentProgressManager(parentProgress);
log.debug(`Processing personalize module: ${module}`, this.config.context);
const processName = this.moduleDisplayMapper[module];
const ModuleClass = moduleMapper[module];

if (ModuleClass) {
progress.startProcess(processName).updateStatus(`Importing ${module}...`, processName);
log.debug(`Starting import for module: ${module}`, this.config.context);

if (this.personalizeConfig.importData) {
const importer = new ModuleClass(this.config);
importer.setParentProgressManager(progress);
await importer.import();

progress.completeProcess(processName, true);
log.debug(`Completed import for module: ${module}`, this.config.context);
} else {
log.debug(`Skipping ${module} - personalization not enabled`, this.config.context);
this.progressManager?.tick(true, `${module} skipped (no project)`, null, processName);
progress.completeProcess(processName, true);
log.info(`Skipped ${module} import - no personalize project found`, this.config.context);
}

log.debug(`Importing ${module} module`, this.config.context);
await moduleInstance.import();

parentProgress?.tick(true, `module: ${module}`, null, 'Personalize data import');
log.success(`Successfully imported personalize module: ${module}`, this.config.context);
} catch (error) {
parentProgress?.tick(
false,
`module: ${module}`,
(error as any)?.message || 'Import failed',
'Personalize data import',
);
log.debug(`Failed to import personalize module: ${module} - ${(error as any)?.message}`, this.config.context);
handleAndLogError(error, { ...this.config.context, module });
} else {
log.debug(`Module not implemented: ${module}`, this.config.context);
progress.startProcess(processName).updateStatus(`Module not implemented: ${module}`, processName);
this.progressManager?.tick(false, `module: ${module}`, 'Module not implemented', processName);
progress.completeProcess(processName, false);
log.info(`Module not implemented: ${module}`, this.config.context);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-import/src/import/modules/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class ImportStack extends BaseClass {
constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
this.importConfig.context.module = 'stack';
this.currentModuleName = 'Stack Settings';
this.currentModuleName = 'Stack';
this.stackSettingsPath = join(this.importConfig.backupDir, 'stack', 'settings.json');
this.envUidMapperPath = join(this.importConfig.backupDir, 'mapper', 'environments', 'uid-mapping.json');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class ImportTaxonomies extends BaseClass {
this.createSuccessAndFailedFile();

this.completeProgress(true);
log.success('Taxonomies imported successfully!', this.importConfig.context);
log.success('Taxonomies imported successfully!', this.importConfig.context);
} catch (error) {
this.completeProgress(false, error?.message || 'Taxonomies import failed');
handleAndLogError(error, { ...this.importConfig.context });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class ImportVariantEntries extends BaseClass {
return;
}

const progress = this.createSimpleProgress(this.currentModuleName, 1);
const progress = this.createSimpleProgress(this.currentModuleName);

progress.updateStatus('Importing variant entries...');
log.info('Starting variant entries import process', this.config.context);
Expand Down
10 changes: 3 additions & 7 deletions packages/contentstack-import/src/import/modules/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class ImportWebhooks extends BaseClass {
const [webhooksCount] = await this.analyzeWebhooks();

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

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

this.completeProgress(true);
log.success('Webhooks have been imported successfully!', this.importConfig.context);
log.success('Webhooks have been imported successfully!', this.importConfig.context);
} catch (error) {
this.completeProgress(false, error?.message || 'Webhooks import failed');
handleAndLogError(error, { ...this.importConfig.context });
Expand Down Expand Up @@ -95,11 +95,7 @@ export default class ImportWebhooks extends BaseClass {
log.info(`Webhook '${name}' already exists`, this.importConfig.context);
} else {
this.failedWebhooks.push(apiData);
this.progressManager?.tick(
false,
`webhook: ${name || uid}`,
error?.message || 'Failed to import webhook',
);
this.progressManager?.tick(false, `webhook: ${name || uid}`, error?.message || 'Failed to import webhook');
handleAndLogError(
error,
{ ...this.importConfig.context, webhookName: name },
Expand Down
Loading