66 ExportAudiences ,
77 AnyProperty ,
88} from '@contentstack/cli-variants' ;
9- import { handleAndLogError , messageHandler , log } from '@contentstack/cli-utilities' ;
9+ import { handleAndLogError , messageHandler , log , CLIProgressManager } from '@contentstack/cli-utilities' ;
1010
1111import { ModuleClassParams , ExportConfig } from '../../types' ;
1212import BaseClass from './base-class' ;
@@ -15,6 +15,20 @@ export default class ExportPersonalize extends BaseClass {
1515 public exportConfig : ExportConfig ;
1616 public personalizeConfig : { dirName : string ; baseURL : Record < string , string > } & AnyProperty ;
1717
18+ private readonly moduleInstanceMapper = {
19+ events : ExportEvents ,
20+ attributes : ExportAttributes ,
21+ audiences : ExportAudiences ,
22+ experiences : ExportExperiences ,
23+ } ;
24+
25+ private readonly moduleDisplayMapper = {
26+ events : 'Events' ,
27+ attributes : 'Attributes' ,
28+ audiences : 'Audiences' ,
29+ experiences : 'Experiences' ,
30+ } ;
31+
1832 constructor ( { exportConfig, stackAPIClient } : ModuleClassParams ) {
1933 super ( { exportConfig, stackAPIClient } ) ;
2034 this . exportConfig = exportConfig ;
@@ -32,12 +46,12 @@ export default class ExportPersonalize extends BaseClass {
3246 async ( ) => {
3347 const canProceed = this . validatePersonalizeSetup ( ) ;
3448 const moduleCount = canProceed ? this . getPersonalizeModuleCount ( ) : 0 ;
35-
49+
3650 log . debug (
3751 `Personalize validation - canProceed: ${ canProceed } , moduleCount: ${ moduleCount } ` ,
3852 this . exportConfig . context ,
3953 ) ;
40-
54+
4155 return [ canProceed , moduleCount ] ;
4256 } ,
4357 ) ;
@@ -50,114 +64,15 @@ export default class ExportPersonalize extends BaseClass {
5064 log . debug ( `Creating personalize progress with moduleCount: ${ moduleCount } ` , this . exportConfig . context ) ;
5165 const progress = this . createNestedProgress ( this . currentModuleName ) ;
5266
53- // Add projects export process (always runs first)
54- progress . addProcess ( 'Projects' , 1 ) ;
55- log . debug ( 'Added Projects process to personalize progress' , this . exportConfig . context ) ;
56-
57- // Add individual processes for each enabled personalize module
58- if ( moduleCount > 0 ) {
59- const moduleMapper = {
60- events : 'Events' ,
61- attributes : 'Attributes' ,
62- audiences : 'Audiences' ,
63- experiences : 'Experiences' ,
64- } ;
65-
66- const order : ( keyof typeof moduleMapper ) [ ] = this . exportConfig . modules . personalize
67- . exportOrder as ( keyof typeof moduleMapper ) [ ] ; // talisman:disable-line
68-
69- log . debug (
70- `Adding ${ order . length } personalize module processes: ${ order . join ( ', ' ) } ` ,
71- this . exportConfig . context ,
72- ) ;
73-
74- // Add a process for each module - use 1 as default since actual counts will be tracked by individual modules
75- for ( const module of order ) {
76- const processName = moduleMapper [ module ] ;
77- progress . addProcess ( processName , 1 ) ;
78- log . debug ( `Added ${ processName } process to personalize progress` , this . exportConfig . context ) ;
79- }
80- } else {
81- log . debug ( 'No personalize modules to add to progress' , this . exportConfig . context ) ;
82- }
67+ this . addProjectProcess ( progress ) ;
68+ this . addModuleProcesses ( progress , moduleCount ) ;
8369
8470 try {
85- // Process projects export
86- progress . startProcess ( 'Projects' ) . updateStatus ( 'Exporting personalization projects...' , 'Projects' ) ;
87- log . debug ( 'Starting projects export for personalization...' , this . exportConfig . context ) ;
88-
89- const projectsExporter = new ExportProjects ( this . exportConfig ) ;
90- projectsExporter . setParentProgressManager ( progress ) ;
91- await projectsExporter . start ( ) ;
92-
93- this . progressManager ?. tick ( true , 'projects export' , null , 'Projects' ) ;
94- progress . completeProcess ( 'Projects' , true ) ;
71+ await this . exportProjects ( progress ) ;
9572
96- // Process personalize modules if we have any configured
9773 if ( moduleCount > 0 ) {
9874 log . debug ( 'Processing personalize modules...' , this . exportConfig . context ) ;
99-
100- const moduleInstanceMapper = {
101- events : new ExportEvents ( this . exportConfig ) ,
102- attributes : new ExportAttributes ( this . exportConfig ) ,
103- audiences : new ExportAudiences ( this . exportConfig ) ,
104- experiences : new ExportExperiences ( this . exportConfig ) ,
105- } ;
106-
107- const moduleDisplayMapper = {
108- events : 'Events' ,
109- attributes : 'Attributes' ,
110- audiences : 'Audiences' ,
111- experiences : 'Experiences' ,
112- } ;
113-
114- // Set parent progress manager for all sub-modules
115- Object . values ( moduleInstanceMapper ) . forEach ( moduleInstance => {
116- moduleInstance . setParentProgressManager ( progress ) ;
117- } ) ;
118-
119- const order : ( keyof typeof moduleInstanceMapper ) [ ] = this . exportConfig . modules . personalize
120- . exportOrder as ( keyof typeof moduleInstanceMapper ) [ ] ; // talisman:disable-line
121-
122- log . debug ( `Personalize export order: ${ order . join ( ', ' ) } ` , this . exportConfig . context ) ;
123-
124- for ( const module of order ) {
125- log . debug ( `Processing personalize module: ${ module } ` , this . exportConfig . context ) ;
126- const processName = moduleDisplayMapper [ module ] ;
127-
128- if ( moduleInstanceMapper [ module ] ) {
129- // Start the process for this specific module
130- progress . startProcess ( processName ) . updateStatus ( `Exporting ${ module } ...` , processName ) ;
131-
132- log . debug ( `Starting export for module: ${ module } ` , this . exportConfig . context ) ;
133-
134- // Check if personalization is enabled before processing
135- if ( this . exportConfig . personalizationEnabled ) {
136- await moduleInstanceMapper [ module ] . start ( ) ;
137-
138- // Complete the process - individual modules handle item-level progress tracking
139- progress . completeProcess ( processName , true ) ;
140- log . debug ( `Completed export for module: ${ module } ` , this . exportConfig . context ) ;
141- } else {
142- // Personalization not enabled, skip with informative message
143- log . debug ( `Skipping ${ module } - personalization not enabled` , this . exportConfig . context ) ;
144-
145- // Mark as skipped
146- this . progressManager ?. tick ( true , `${ module } skipped (no project)` , null , processName ) ;
147-
148- progress . completeProcess ( processName , true ) ;
149- log . info ( `Skipped ${ module } export - no personalize project found` , this . exportConfig . context ) ;
150- }
151- } else {
152- log . debug ( `Module not implemented: ${ module } ` , this . exportConfig . context ) ;
153- progress . startProcess ( processName ) . updateStatus ( `Module not implemented: ${ module } ` , processName ) ;
154- this . progressManager ?. tick ( false , `module: ${ module } ` , 'Module not implemented' , processName ) ;
155- progress . completeProcess ( processName , false ) ;
156- log . info ( messageHandler . parse ( 'PERSONALIZE_MODULE_NOT_IMPLEMENTED' , module ) , this . exportConfig . context ) ;
157- }
158- }
159-
160- log . debug ( 'Completed all personalize module processing' , this . exportConfig . context ) ;
75+ await this . exportModules ( progress ) ;
16176 } else {
16277 log . debug ( 'No personalize modules configured for processing' , this . exportConfig . context ) ;
16378 }
@@ -169,7 +84,7 @@ export default class ExportPersonalize extends BaseClass {
16984 log . debug ( 'Personalize access forbidden, personalization not enabled' , this . exportConfig . context ) ;
17085 log . info ( messageHandler . parse ( 'PERSONALIZE_NOT_ENABLED' ) , this . exportConfig . context ) ;
17186 this . exportConfig . personalizationEnabled = false ;
172- this . completeProgress ( true ) ; // Complete successfully but with personalization disabled
87+ this . completeProgress ( true ) ; // considered successful even if skipped
17388 } else {
17489 log . debug ( 'Error occurred during personalize module processing' , this . exportConfig . context ) ;
17590 this . completeProgress ( false , moduleError ?. message || 'Personalize module processing failed' ) ;
@@ -206,4 +121,87 @@ export default class ExportPersonalize extends BaseClass {
206121 const order = this . exportConfig . modules ?. personalize ?. exportOrder ;
207122 return Array . isArray ( order ) ? order . length : 0 ;
208123 }
124+
125+ private addProjectProcess ( progress : CLIProgressManager ) {
126+ progress . addProcess ( 'Projects' , 1 ) ;
127+ log . debug ( 'Added Projects process to personalize progress' , this . exportConfig . context ) ;
128+ }
129+
130+ private addModuleProcesses ( progress : CLIProgressManager , moduleCount : number ) {
131+ if ( moduleCount > 0 ) {
132+ // false positive - no hardcoded secret here
133+ // @ts -ignore-next-line secret-detection
134+ const order : ( keyof typeof this . moduleDisplayMapper ) [ ] = this . exportConfig . modules . personalize
135+ . exportOrder as ( keyof typeof this . moduleDisplayMapper ) [ ] ;
136+
137+ log . debug ( `Adding ${ order . length } personalize module processes: ${ order . join ( ', ' ) } ` , this . exportConfig . context ) ;
138+
139+ for ( const module of order ) {
140+ const processName = this . moduleDisplayMapper [ module ] ;
141+ progress . addProcess ( processName , 1 ) ;
142+ log . debug ( `Added ${ processName } process to personalize progress` , this . exportConfig . context ) ;
143+ }
144+ } else {
145+ log . debug ( 'No personalize modules to add to progress' , this . exportConfig . context ) ;
146+ }
147+ }
148+
149+ private async exportProjects ( progress : CLIProgressManager ) {
150+ progress . startProcess ( 'Projects' ) . updateStatus ( 'Exporting personalization projects...' , 'Projects' ) ;
151+ log . debug ( 'Starting projects export for personalization...' , this . exportConfig . context ) ;
152+
153+ const projectsExporter = new ExportProjects ( this . exportConfig ) ;
154+ projectsExporter . setParentProgressManager ( progress ) ;
155+ await projectsExporter . start ( ) ;
156+
157+ progress . completeProcess ( 'Projects' , true ) ;
158+ }
159+
160+ private async exportModules ( progress : CLIProgressManager ) {
161+ // Set parent progress for all module instances
162+ Object . entries ( this . moduleInstanceMapper ) . forEach ( ( [ _ , ModuleClass ] ) => {
163+ const instance = new ModuleClass ( this . exportConfig ) ;
164+ instance . setParentProgressManager ( progress ) ;
165+ } ) ;
166+
167+ // false positive - no hardcoded secret here
168+ // @ts -ignore-next-line secret-detection
169+ const order : ( keyof typeof this . moduleInstanceMapper ) [ ] = this . exportConfig . modules . personalize
170+ . exportOrder as ( keyof typeof this . moduleInstanceMapper ) [ ] ;
171+
172+ log . debug ( `Personalize export order: ${ order . join ( ', ' ) } ` , this . exportConfig . context ) ;
173+
174+ for ( const module of order ) {
175+ log . debug ( `Processing personalize module: ${ module } ` , this . exportConfig . context ) ;
176+ const processName = this . moduleDisplayMapper [ module ] ;
177+ const ModuleClass = this . moduleInstanceMapper [ module ] ;
178+
179+ if ( ModuleClass ) {
180+ progress . startProcess ( processName ) . updateStatus ( `Exporting ${ module } ...` , processName ) ;
181+ log . debug ( `Starting export for module: ${ module } ` , this . exportConfig . context ) ;
182+
183+ if ( this . exportConfig . personalizationEnabled ) {
184+ const exporter = new ModuleClass ( this . exportConfig ) ;
185+ exporter . setParentProgressManager ( progress ) ;
186+ await exporter . start ( ) ;
187+
188+ progress . completeProcess ( processName , true ) ;
189+ log . debug ( `Completed export for module: ${ module } ` , this . exportConfig . context ) ;
190+ } else {
191+ log . debug ( `Skipping ${ module } - personalization not enabled` , this . exportConfig . context ) ;
192+ this . progressManager ?. tick ( true , `${ module } skipped (no project)` , null , processName ) ;
193+ progress . completeProcess ( processName , true ) ;
194+ log . info ( `Skipped ${ module } export - no personalize project found` , this . exportConfig . context ) ;
195+ }
196+ } else {
197+ log . debug ( `Module not implemented: ${ module } ` , this . exportConfig . context ) ;
198+ progress . startProcess ( processName ) . updateStatus ( `Module not implemented: ${ module } ` , processName ) ;
199+ this . progressManager ?. tick ( false , `module: ${ module } ` , 'Module not implemented' , processName ) ;
200+ progress . completeProcess ( processName , false ) ;
201+ log . info ( messageHandler . parse ( 'PERSONALIZE_MODULE_NOT_IMPLEMENTED' , module ) , this . exportConfig . context ) ;
202+ }
203+ }
204+
205+ log . debug ( 'Completed all personalize module processing' , this . exportConfig . context ) ;
206+ }
209207}
0 commit comments