@contentstack/cli-cm-export 1.20.1 → 2.0.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +1 -1
  2. package/lib/commands/cm/stacks/export.js +15 -6
  3. package/lib/config/index.js +0 -2
  4. package/lib/export/module-exporter.js +37 -38
  5. package/lib/export/modules/assets.js +71 -14
  6. package/lib/export/modules/base-class.d.ts +17 -0
  7. package/lib/export/modules/base-class.js +45 -0
  8. package/lib/export/modules/content-types.js +30 -8
  9. package/lib/export/modules/custom-roles.js +61 -21
  10. package/lib/export/modules/entries.d.ts +2 -0
  11. package/lib/export/modules/entries.js +137 -37
  12. package/lib/export/modules/environments.js +45 -20
  13. package/lib/export/modules/extensions.js +42 -17
  14. package/lib/export/modules/global-fields.d.ts +1 -1
  15. package/lib/export/modules/global-fields.js +24 -6
  16. package/lib/export/modules/index.d.ts +1 -0
  17. package/lib/export/modules/index.js +1 -0
  18. package/lib/export/modules/labels.js +43 -16
  19. package/lib/export/modules/locales.js +31 -12
  20. package/lib/export/modules/marketplace-apps.d.ts +5 -2
  21. package/lib/export/modules/marketplace-apps.js +95 -25
  22. package/lib/export/modules/personalize.d.ts +12 -2
  23. package/lib/export/modules/personalize.js +181 -46
  24. package/lib/export/modules/stack.js +83 -28
  25. package/lib/export/modules/taxonomies.d.ts +4 -9
  26. package/lib/export/modules/taxonomies.js +123 -75
  27. package/lib/export/modules/webhooks.js +40 -17
  28. package/lib/export/modules/workflows.js +57 -20
  29. package/lib/types/default-config.d.ts +0 -2
  30. package/lib/types/index.d.ts +1 -1
  31. package/lib/utils/common-helper.d.ts +1 -2
  32. package/lib/utils/common-helper.js +1 -12
  33. package/lib/utils/constants.d.ts +147 -0
  34. package/lib/utils/constants.js +160 -0
  35. package/lib/utils/export-config-handler.js +2 -0
  36. package/lib/utils/index.d.ts +1 -0
  37. package/lib/utils/index.js +6 -1
  38. package/lib/utils/marketplace-app-helper.d.ts +1 -0
  39. package/lib/utils/marketplace-app-helper.js +21 -12
  40. package/lib/utils/progress-strategy-registry.d.ts +7 -0
  41. package/lib/utils/progress-strategy-registry.js +92 -0
  42. package/messages/index.json +4 -2
  43. package/oclif.manifest.json +1 -1
  44. package/package.json +3 -3
  45. package/lib/export/modules-js/assets.d.ts +0 -43
  46. package/lib/export/modules-js/assets.js +0 -396
  47. package/lib/export/modules-js/content-types.d.ts +0 -21
  48. package/lib/export/modules-js/content-types.js +0 -76
  49. package/lib/export/modules-js/custom-roles.d.ts +0 -21
  50. package/lib/export/modules-js/custom-roles.js +0 -76
  51. package/lib/export/modules-js/entries.d.ts +0 -18
  52. package/lib/export/modules-js/entries.js +0 -143
  53. package/lib/export/modules-js/environments.d.ts +0 -16
  54. package/lib/export/modules-js/environments.js +0 -62
  55. package/lib/export/modules-js/extensions.d.ts +0 -18
  56. package/lib/export/modules-js/extensions.js +0 -57
  57. package/lib/export/modules-js/global-fields.d.ts +0 -22
  58. package/lib/export/modules-js/global-fields.js +0 -108
  59. package/lib/export/modules-js/index.d.ts +0 -2
  60. package/lib/export/modules-js/index.js +0 -31
  61. package/lib/export/modules-js/labels.d.ts +0 -14
  62. package/lib/export/modules-js/labels.js +0 -56
  63. package/lib/export/modules-js/locales.d.ts +0 -23
  64. package/lib/export/modules-js/locales.js +0 -68
  65. package/lib/export/modules-js/marketplace-apps.d.ts +0 -21
  66. package/lib/export/modules-js/marketplace-apps.js +0 -132
  67. package/lib/export/modules-js/stack.d.ts +0 -18
  68. package/lib/export/modules-js/stack.js +0 -91
  69. package/lib/export/modules-js/webhooks.d.ts +0 -18
  70. package/lib/export/modules-js/webhooks.js +0 -60
  71. package/lib/export/modules-js/workflows.d.ts +0 -16
  72. package/lib/export/modules-js/workflows.js +0 -89
@@ -18,55 +18,131 @@ class EntriesExport extends base_class_1.default {
18
18
  this.localesFilePath = path.resolve((0, cli_utilities_2.sanitizePath)(exportConfig.data), (0, cli_utilities_2.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.locales.fileName));
19
19
  this.schemaFilePath = path.resolve((0, cli_utilities_2.sanitizePath)(exportConfig.data), (0, cli_utilities_2.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.content_types.dirName), 'schema.json');
20
20
  this.projectInstance = new cli_variants_1.ExportProjects(this.exportConfig);
21
- this.exportConfig.context.module = 'entries';
21
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.ENTRIES;
22
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.ENTRIES];
22
23
  }
23
24
  async start() {
24
25
  var _a, _b;
25
26
  try {
26
27
  cli_utilities_1.log.debug('Starting entries export process...', this.exportConfig.context);
27
- const locales = utils_1.fsUtil.readFile(this.localesFilePath);
28
- if (!Array.isArray(locales) || (locales === null || locales === void 0 ? void 0 : locales.length) === 0) {
29
- cli_utilities_1.log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context);
30
- }
31
- else {
32
- cli_utilities_1.log.debug(`Loaded ${locales === null || locales === void 0 ? void 0 : locales.length} locales from ${this.localesFilePath}`, this.exportConfig.context);
33
- }
34
- const contentTypes = utils_1.fsUtil.readFile(this.schemaFilePath);
28
+ // Initial analysis with loading spinner
29
+ const [locales, contentTypes, entryRequestOptions, totalEntriesCount, variantInfo] = await this.withLoadingSpinner('ENTRIES: Analyzing content structure and entries...', async () => {
30
+ const locales = utils_1.fsUtil.readFile(this.localesFilePath);
31
+ const contentTypes = utils_1.fsUtil.readFile(this.schemaFilePath);
32
+ if (!Array.isArray(locales) || (locales === null || locales === void 0 ? void 0 : locales.length) === 0) {
33
+ cli_utilities_1.log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context);
34
+ }
35
+ else {
36
+ cli_utilities_1.log.debug(`Loaded ${locales === null || locales === void 0 ? void 0 : locales.length} locales from ${this.localesFilePath}`, this.exportConfig.context);
37
+ }
38
+ if ((contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length) === 0) {
39
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context);
40
+ return [locales, contentTypes, [], 0, null];
41
+ }
42
+ cli_utilities_1.log.debug(`Loaded ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types from ${this.schemaFilePath}`, this.exportConfig.context);
43
+ // Create entry request objects
44
+ const entryRequestOptions = this.createRequestObjects(locales, contentTypes);
45
+ cli_utilities_1.log.debug(`Created ${entryRequestOptions.length} entry request objects for processing`, this.exportConfig.context);
46
+ // Get total entries count for better progress tracking
47
+ const totalEntriesCount = await this.getTotalEntriesCount(entryRequestOptions);
48
+ const variantInfo = await this.setupVariantExport();
49
+ return [locales, contentTypes, entryRequestOptions, totalEntriesCount, variantInfo];
50
+ });
35
51
  if ((contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length) === 0) {
36
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context);
37
52
  return;
38
53
  }
39
- cli_utilities_1.log.debug(`Loaded ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types from ${this.schemaFilePath}`, this.exportConfig.context);
40
- // NOTE Check if variant is enabled in specific stack
41
- if (this.exportConfig.personalizationEnabled) {
42
- cli_utilities_1.log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context);
43
- let project_id;
44
- try {
45
- const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey });
46
- if (project && ((_a = project[0]) === null || _a === void 0 ? void 0 : _a.uid)) {
47
- project_id = project[0].uid;
48
- this.exportVariantEntry = true;
49
- cli_utilities_1.log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context);
54
+ // Create nested progress manager
55
+ const progress = this.createNestedProgress(this.currentModuleName);
56
+ // Add sub-processes
57
+ if (totalEntriesCount > 0) {
58
+ progress.addProcess(utils_1.PROCESS_NAMES.ENTRIES, totalEntriesCount);
59
+ if (this.entriesConfig.exportVersions) {
60
+ progress.addProcess(utils_1.PROCESS_NAMES.ENTRY_VERSIONS, totalEntriesCount);
61
+ }
62
+ }
63
+ // Process entry collections
64
+ if (totalEntriesCount > 0) {
65
+ progress
66
+ .startProcess(utils_1.PROCESS_NAMES.ENTRIES)
67
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.ENTRIES].PROCESSING, utils_1.PROCESS_NAMES.ENTRIES);
68
+ for (let entryRequestOption of entryRequestOptions) {
69
+ try {
70
+ cli_utilities_1.log.debug(`Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, this.exportConfig.context);
71
+ await this.getEntries(entryRequestOption);
72
+ (_a = this.entriesFileHelper) === null || _a === void 0 ? void 0 : _a.completeFile(true);
73
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), this.exportConfig.context);
74
+ }
75
+ catch (error) {
76
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(false, `${entryRequestOption.contentType}:${entryRequestOption.locale}`, (error === null || error === void 0 ? void 0 : error.message) || utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.ENTRIES].FAILED, utils_1.PROCESS_NAMES.ENTRIES);
77
+ throw error;
50
78
  }
51
- this.variantEntries = new cli_variants_1.Export.VariantEntries(Object.assign(this.exportConfig, { project_id }));
52
79
  }
53
- catch (error) {
54
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
80
+ progress.completeProcess(utils_1.PROCESS_NAMES.ENTRIES, true);
81
+ if (this.entriesConfig.exportVersions) {
82
+ progress.completeProcess(utils_1.PROCESS_NAMES.ENTRY_VERSIONS, true);
83
+ }
84
+ if (this.exportVariantEntry && this.variantEntries) {
85
+ // Complete the variant entries export process
86
+ this.variantEntries.completeExport();
55
87
  }
56
88
  }
57
- const entryRequestOptions = this.createRequestObjects(locales, contentTypes);
58
- cli_utilities_1.log.debug(`Created ${entryRequestOptions.length} entry request objects for processing`, this.exportConfig.context);
59
- for (let entryRequestOption of entryRequestOptions) {
60
- cli_utilities_1.log.debug(`Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, this.exportConfig.context);
61
- await this.getEntries(entryRequestOption);
62
- (_b = this.entriesFileHelper) === null || _b === void 0 ? void 0 : _b.completeFile(true);
63
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), this.exportConfig.context);
64
- }
89
+ this.completeProgress(true);
65
90
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context);
66
91
  }
67
92
  catch (error) {
68
93
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
94
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Entries export failed');
95
+ }
96
+ }
97
+ async getTotalEntriesCount(entryRequestOptions) {
98
+ cli_utilities_1.log.debug('Calculating total entries count for progress tracking...', this.exportConfig.context);
99
+ const countPromises = entryRequestOptions.map(async (option) => {
100
+ const countQuery = {
101
+ locale: option.locale,
102
+ limit: 1,
103
+ include_count: true,
104
+ query: { locale: option.locale },
105
+ };
106
+ this.applyQueryFilters(countQuery, 'entries');
107
+ try {
108
+ const response = await this.stackAPIClient.contentType(option.contentType).entry().query(countQuery).find();
109
+ const count = response.count || 0;
110
+ cli_utilities_1.log.debug(`Content type ${option.contentType} (${option.locale}): ${count} entries`, this.exportConfig.context);
111
+ return count;
112
+ }
113
+ catch (error) {
114
+ cli_utilities_1.log.debug(`Failed to get count for ${option.contentType}:${option.locale}`, this.exportConfig.context);
115
+ return 0;
116
+ }
117
+ });
118
+ const results = await Promise.allSettled(countPromises);
119
+ const totalCount = results.reduce((sum, result) => {
120
+ return sum + (result.status === 'fulfilled' ? result.value : 0);
121
+ }, 0);
122
+ cli_utilities_1.log.debug(`Total entries count: ${totalCount}`, this.exportConfig.context);
123
+ return totalCount;
124
+ }
125
+ async setupVariantExport() {
126
+ var _a;
127
+ if (!this.exportConfig.personalizationEnabled) {
128
+ return null;
129
+ }
130
+ cli_utilities_1.log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context);
131
+ try {
132
+ const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey });
133
+ if (project && ((_a = project[0]) === null || _a === void 0 ? void 0 : _a.uid)) {
134
+ const project_id = project[0].uid;
135
+ this.exportVariantEntry = true;
136
+ cli_utilities_1.log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context);
137
+ this.variantEntries = new cli_variants_1.Export.VariantEntries(Object.assign(this.exportConfig, { project_id }));
138
+ return { project_id };
139
+ }
140
+ }
141
+ catch (error) {
142
+ cli_utilities_1.log.debug('Failed to setup variant export', this.exportConfig.context);
143
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
69
144
  }
145
+ return null;
70
146
  }
71
147
  createRequestObjects(locales, contentTypes) {
72
148
  if (!Array.isArray(locales) || (locales === null || locales === void 0 ? void 0 : locales.length) === 0) {
@@ -145,6 +221,11 @@ class EntriesExport extends base_class_1.default {
145
221
  }
146
222
  cli_utilities_1.log.debug(`Writing ${entriesSearchResponse.items.length} entries to file`, this.exportConfig.context);
147
223
  this.entriesFileHelper.writeIntoFile(entriesSearchResponse.items, { mapKeyVal: true });
224
+ // Track progress for individual entries
225
+ entriesSearchResponse.items.forEach((entry) => {
226
+ var _a;
227
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `entry: ${entry.uid}`, null, utils_1.PROCESS_NAMES.ENTRIES);
228
+ });
148
229
  if (this.entriesConfig.exportVersions) {
149
230
  cli_utilities_1.log.debug('Exporting entry versions is enabled', this.exportConfig.context);
150
231
  let versionedEntryPath = path.join((0, cli_utilities_2.sanitizePath)(this.entriesDirPath), (0, cli_utilities_2.sanitizePath)(options.contentType), (0, cli_utilities_2.sanitizePath)(options.locale), 'versions');
@@ -159,11 +240,21 @@ class EntriesExport extends base_class_1.default {
159
240
  // NOTE Export all base entry specific 'variant entries'
160
241
  if (this.exportVariantEntry) {
161
242
  cli_utilities_1.log.debug('Exporting variant entries for base entries', this.exportConfig.context);
162
- await this.variantEntries.exportVariantEntry({
163
- locale: options.locale,
164
- contentTypeUid: options.contentType,
165
- entries: entriesSearchResponse.items,
166
- });
243
+ try {
244
+ // Set parent progress manager for variant entries
245
+ if (this.variantEntries && typeof this.variantEntries.setParentProgressManager === 'function') {
246
+ this.variantEntries.setParentProgressManager(this.progressManager);
247
+ }
248
+ await this.variantEntries.exportVariantEntry({
249
+ locale: options.locale,
250
+ contentTypeUid: options.contentType,
251
+ entries: entriesSearchResponse.items,
252
+ });
253
+ cli_utilities_1.log.debug(`Successfully exported variant entries for ${entriesSearchResponse.items.length} entries`, this.exportConfig.context);
254
+ }
255
+ catch (error) {
256
+ cli_utilities_1.log.debug('Failed to export variant entries', this.exportConfig.context);
257
+ }
167
258
  }
168
259
  options.skip += this.entriesConfig.limit || 100;
169
260
  if (options.skip >= entriesSearchResponse.count) {
@@ -173,17 +264,26 @@ class EntriesExport extends base_class_1.default {
173
264
  cli_utilities_1.log.debug(`Continuing to fetch entries with skip: ${options.skip}`, this.exportConfig.context);
174
265
  return await this.getEntries(options);
175
266
  }
267
+ else {
268
+ cli_utilities_1.log.debug(`No entries found for content type: ${options.contentType}, locale: ${options.locale}`, this.exportConfig.context);
269
+ }
176
270
  }
177
271
  async fetchEntriesVersions(entries, options) {
178
272
  cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries`, this.exportConfig.context);
179
273
  const onSuccess = ({ response, apiData: entry }) => {
274
+ var _a;
180
275
  const versionFilePath = path.join((0, cli_utilities_2.sanitizePath)(options.versionedEntryPath), (0, cli_utilities_2.sanitizePath)(`${entry.uid}.json`));
181
276
  cli_utilities_1.log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context);
182
277
  utils_1.fsUtil.writeFile(versionFilePath, response);
278
+ // Track version progress if the process exists
279
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `version: ${entry.uid}`, null, utils_1.PROCESS_NAMES.ENTRY_VERSIONS);
183
280
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), this.exportConfig.context);
184
281
  };
185
282
  const onReject = ({ error, apiData: { uid } = undefined }) => {
283
+ var _a;
186
284
  cli_utilities_1.log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context);
285
+ // Track version failure if the process exists
286
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `version: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.ENTRY_VERSIONS].FAILED, utils_1.PROCESS_NAMES.ENTRY_VERSIONS);
187
287
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.exportConfig.context), { uid }), cli_utilities_1.messageHandler.parse('ENTRIES_EXPORT_VERSIONS_FAILED', uid));
188
288
  };
189
289
  cli_utilities_1.log.debug(`Starting concurrent calls for versioned entries with batch limit: ${this.entriesConfig.batchLimit}`, this.exportConfig.context);
@@ -13,24 +13,47 @@ class ExportEnvironments extends base_class_1.default {
13
13
  this.environments = {};
14
14
  this.environmentConfig = exportConfig.modules.environments;
15
15
  this.qs = { include_count: true };
16
- this.exportConfig.context.module = 'environments';
16
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.ENVIRONMENTS;
17
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.ENVIRONMENTS];
17
18
  }
18
19
  async start() {
19
- cli_utilities_1.log.debug('Starting environment export process...', this.exportConfig.context);
20
- this.environmentsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.environmentConfig.dirName);
21
- cli_utilities_1.log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context);
22
- await utils_1.fsUtil.makeDirectory(this.environmentsFolderPath);
23
- cli_utilities_1.log.debug('Created environments directory', this.exportConfig.context);
24
- await this.getEnvironments();
25
- cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.environments).length} environments`, this.exportConfig.context);
26
- if (this.environments === undefined || (0, isEmpty_1.default)(this.environments)) {
27
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context);
20
+ try {
21
+ cli_utilities_1.log.debug('Starting environment export process...', this.exportConfig.context);
22
+ // Setup with loading spinner
23
+ const [totalCount] = await this.withLoadingSpinner('ENVIRONMENTS: Analyzing environments...', async () => {
24
+ this.environmentsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.environmentConfig.dirName);
25
+ await utils_1.fsUtil.makeDirectory(this.environmentsFolderPath);
26
+ cli_utilities_1.log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context);
27
+ // Get count for progress tracking
28
+ const countResponse = await this.stack
29
+ .environment()
30
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
31
+ .find();
32
+ return [countResponse.count || 0];
33
+ });
34
+ if (totalCount === 0) {
35
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context);
36
+ return;
37
+ }
38
+ // Create simple progress manager with total count
39
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
40
+ progress.updateStatus('Fetching environments...');
41
+ await this.getEnvironments();
42
+ cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.environments || {}).length} environments`, this.exportConfig.context);
43
+ if (this.environments === undefined || (0, isEmpty_1.default)(this.environments)) {
44
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context);
45
+ }
46
+ else {
47
+ const environmentsFilePath = (0, node_path_1.resolve)(this.environmentsFolderPath, this.environmentConfig.fileName);
48
+ cli_utilities_1.log.debug(`Writing environments to: ${environmentsFilePath}`, this.exportConfig.context);
49
+ utils_1.fsUtil.writeFile(environmentsFilePath, this.environments);
50
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments || {}).length), this.exportConfig.context);
51
+ }
52
+ this.completeProgress(true);
28
53
  }
29
- else {
30
- const environmentsFilePath = (0, node_path_1.resolve)(this.environmentsFolderPath, this.environmentConfig.fileName);
31
- cli_utilities_1.log.debug(`Writing environments to: ${environmentsFilePath}`, this.exportConfig.context);
32
- utils_1.fsUtil.writeFile(environmentsFilePath, this.environments);
33
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), this.exportConfig.context);
54
+ catch (error) {
55
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
56
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Environments export failed');
34
57
  }
35
58
  }
36
59
  async getEnvironments(skip = 0) {
@@ -70,16 +93,18 @@ class ExportEnvironments extends base_class_1.default {
70
93
  });
71
94
  }
72
95
  sanitizeAttribs(environments) {
73
- var _a;
96
+ var _a, _b;
74
97
  cli_utilities_1.log.debug(`Sanitizing ${environments.length} environments`, this.exportConfig.context);
75
98
  for (let index = 0; index < (environments === null || environments === void 0 ? void 0 : environments.length); index++) {
76
- const extUid = environments[index].uid;
99
+ const envUID = environments[index].uid;
77
100
  const envName = (_a = environments[index]) === null || _a === void 0 ? void 0 : _a.name;
78
- cli_utilities_1.log.debug(`Processing environment: ${envName} (${extUid})`, this.exportConfig.context);
79
- this.environments[extUid] = (0, omit_1.default)(environments[index], ['ACL']);
101
+ cli_utilities_1.log.debug(`Processing environment: ${envName} (${envUID})`, this.exportConfig.context);
102
+ this.environments[envUID] = (0, omit_1.default)(environments[index], ['ACL']);
103
+ // Track progress for each environment
104
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `environment: ${envName || envUID}`);
80
105
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName), this.exportConfig.context);
81
106
  }
82
- cli_utilities_1.log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, this.exportConfig.context);
107
+ cli_utilities_1.log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments || {}).length}`, this.exportConfig.context);
83
108
  }
84
109
  }
85
110
  exports.default = ExportEnvironments;
@@ -14,24 +14,47 @@ class ExportExtensions extends base_class_1.default {
14
14
  this.extensionConfig = exportConfig.modules.extensions;
15
15
  this.qs = { include_count: true };
16
16
  this.applyQueryFilters(this.qs, 'extensions');
17
- this.exportConfig.context.module = 'extensions';
17
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.EXTENSIONS;
18
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.EXTENSIONS];
18
19
  }
19
20
  async start() {
20
- cli_utilities_1.log.debug('Starting extensions export process...', this.exportConfig.context);
21
- this.extensionsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.extensionConfig.dirName);
22
- cli_utilities_1.log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context);
23
- await utils_1.fsUtil.makeDirectory(this.extensionsFolderPath);
24
- cli_utilities_1.log.debug('Created extensions directory', this.exportConfig.context);
25
- await this.getExtensions();
26
- cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions`, this.exportConfig.context);
27
- if (this.extensions === undefined || (0, isEmpty_1.default)(this.extensions)) {
28
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context);
21
+ try {
22
+ cli_utilities_1.log.debug('Starting extensions export process...', this.exportConfig.context);
23
+ // Setup with loading spinner
24
+ const [totalCount] = await this.withLoadingSpinner('EXTENSIONS: Analyzing extensions...', async () => {
25
+ this.extensionsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.extensionConfig.dirName);
26
+ await utils_1.fsUtil.makeDirectory(this.extensionsFolderPath);
27
+ cli_utilities_1.log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context);
28
+ // Get count for progress tracking
29
+ const countResponse = await this.stack
30
+ .extension()
31
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
32
+ .find();
33
+ return [countResponse.count || 0];
34
+ });
35
+ if (totalCount === 0) {
36
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context);
37
+ return;
38
+ }
39
+ // Create simple progress manager with total count
40
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
41
+ progress.updateStatus('Fetching extensions...');
42
+ await this.getExtensions();
43
+ cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.extensions || {}).length} extensions`, this.exportConfig.context);
44
+ if (this.extensions === undefined || (0, isEmpty_1.default)(this.extensions)) {
45
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context);
46
+ }
47
+ else {
48
+ const extensionsFilePath = (0, node_path_1.resolve)(this.extensionsFolderPath, this.extensionConfig.fileName);
49
+ cli_utilities_1.log.debug(`Writing extensions to: ${extensionsFilePath}`, this.exportConfig.context);
50
+ utils_1.fsUtil.writeFile(extensionsFilePath, this.extensions);
51
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions || {}).length), this.exportConfig.context);
52
+ }
53
+ this.completeProgress(true);
29
54
  }
30
- else {
31
- const extensionsFilePath = (0, node_path_1.resolve)(this.extensionsFolderPath, this.extensionConfig.fileName);
32
- cli_utilities_1.log.debug(`Writing extensions to: ${extensionsFilePath}`, this.exportConfig.context);
33
- utils_1.fsUtil.writeFile(extensionsFilePath, this.extensions);
34
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length), this.exportConfig.context);
55
+ catch (error) {
56
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
57
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Extensions export failed');
35
58
  }
36
59
  }
37
60
  async getExtensions(skip = 0) {
@@ -71,16 +94,18 @@ class ExportExtensions extends base_class_1.default {
71
94
  });
72
95
  }
73
96
  sanitizeAttribs(extensions) {
74
- var _a;
97
+ var _a, _b;
75
98
  cli_utilities_1.log.debug(`Sanitizing ${extensions.length} extensions`, this.exportConfig.context);
76
99
  for (let index = 0; index < (extensions === null || extensions === void 0 ? void 0 : extensions.length); index++) {
77
100
  const extUid = extensions[index].uid;
78
101
  const extTitle = (_a = extensions[index]) === null || _a === void 0 ? void 0 : _a.title;
79
102
  cli_utilities_1.log.debug(`Processing extension: ${extTitle} (${extUid})`, this.exportConfig.context);
80
103
  this.extensions[extUid] = (0, omit_1.default)(extensions[index], ['SYS_ACL']);
104
+ // Track progress for each extension
105
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `extension: ${extTitle || extUid}`);
81
106
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context);
82
107
  }
83
- cli_utilities_1.log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}`, this.exportConfig.context);
108
+ cli_utilities_1.log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions || {}).length}`, this.exportConfig.context);
84
109
  }
85
110
  }
86
111
  exports.default = ExportExtensions;
@@ -1,5 +1,5 @@
1
- import { ExportConfig, ModuleClassParams } from '../../types';
2
1
  import BaseClass from './base-class';
2
+ import { ExportConfig, ModuleClassParams } from '../../types';
3
3
  export default class GlobalFieldsExport extends BaseClass {
4
4
  private stackAPIClient;
5
5
  exportConfig: ExportConfig;
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path = tslib_1.__importStar(require("path"));
5
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
6
- const utils_1 = require("../../utils");
7
6
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
7
+ const utils_1 = require("../../utils");
8
8
  class GlobalFieldsExport extends base_class_1.default {
9
9
  constructor({ exportConfig, stackAPIClient }) {
10
10
  super({ exportConfig, stackAPIClient });
@@ -20,24 +20,39 @@ class GlobalFieldsExport extends base_class_1.default {
20
20
  this.globalFieldsDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.data), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(this.globalFieldsConfig.dirName));
21
21
  this.globalFields = [];
22
22
  this.applyQueryFilters(this.qs, 'global-fields');
23
- this.exportConfig.context.module = 'global-fields';
23
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.GLOBAL_FIELDS;
24
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.GLOBAL_FIELDS];
24
25
  }
25
26
  async start() {
26
27
  try {
27
28
  cli_utilities_1.log.debug('Starting global fields export process...', this.exportConfig.context);
28
- cli_utilities_1.log.debug(`Global fields directory path: ${this.globalFieldsDirPath}`, this.exportConfig.context);
29
- await utils_1.fsUtil.makeDirectory(this.globalFieldsDirPath);
30
- cli_utilities_1.log.debug('Created global fields directory', this.exportConfig.context);
29
+ // Get global fields count and setup with loading spinner
30
+ const [totalCount] = await this.withLoadingSpinner('GLOBAL-FIELDS: Analyzing global fields...', async () => {
31
+ await utils_1.fsUtil.makeDirectory(this.globalFieldsDirPath);
32
+ const countResponse = await this.stackAPIClient
33
+ .globalField()
34
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
35
+ .find();
36
+ return [countResponse.count || 0];
37
+ });
38
+ if (totalCount === 0) {
39
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('GLOBAL_FIELDS_NOT_FOUND'), this.exportConfig.context);
40
+ return;
41
+ }
42
+ // Create simple progress manager for global fields
43
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
44
+ progress.updateStatus('Fetching global fields...');
31
45
  await this.getGlobalFields();
32
- cli_utilities_1.log.debug(`Retrieved ${this.globalFields.length} global fields`, this.exportConfig.context);
33
46
  const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName);
34
47
  cli_utilities_1.log.debug(`Writing global fields to: ${globalFieldsFilePath}`, this.exportConfig.context);
35
48
  utils_1.fsUtil.writeFile(globalFieldsFilePath, this.globalFields);
36
49
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), this.exportConfig.context);
50
+ this.completeProgress(true);
37
51
  }
38
52
  catch (error) {
39
53
  cli_utilities_1.log.debug('Error occurred during global fields export', this.exportConfig.context);
40
54
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
55
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Global fields export failed');
41
56
  }
42
57
  }
43
58
  async getGlobalFields(skip = 0) {
@@ -67,6 +82,7 @@ class GlobalFieldsExport extends base_class_1.default {
67
82
  sanitizeAttribs(globalFields) {
68
83
  cli_utilities_1.log.debug(`Sanitizing ${globalFields.length} global fields`, this.exportConfig.context);
69
84
  globalFields.forEach((globalField) => {
85
+ var _a;
70
86
  cli_utilities_1.log.debug(`Processing global field: ${globalField.uid || 'unknown'}`, this.exportConfig.context);
71
87
  for (let key in globalField) {
72
88
  if (this.globalFieldsConfig.validKeys.indexOf(key) === -1) {
@@ -74,6 +90,8 @@ class GlobalFieldsExport extends base_class_1.default {
74
90
  }
75
91
  }
76
92
  this.globalFields.push(globalField);
93
+ // Track progress for each global field
94
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `global-field: ${globalField.uid}`);
77
95
  });
78
96
  cli_utilities_1.log.debug(`Sanitization complete. Total global fields processed: ${this.globalFields.length}`, this.exportConfig.context);
79
97
  }
@@ -1,3 +1,4 @@
1
1
  import { ModuleClassParams } from '../../types';
2
+ import '../../utils/progress-strategy-registry';
2
3
  export default function startModuleExport(modulePayload: ModuleClassParams): Promise<any>;
3
4
  export { default as ExportAssets } from './assets';
@@ -29,6 +29,7 @@ var _a;
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  exports.ExportAssets = void 0;
31
31
  const cli_utilities_1 = require("@contentstack/cli-utilities");
32
+ require("../../utils/progress-strategy-registry");
32
33
  async function startModuleExport(modulePayload) {
33
34
  try {
34
35
  const { default: ModuleRunner } = await (_a = `./${modulePayload.moduleName}`, Promise.resolve().then(() => __importStar(require(_a))));
@@ -13,24 +13,47 @@ class ExportLabels extends base_class_1.default {
13
13
  this.labels = {};
14
14
  this.labelConfig = exportConfig.modules.labels;
15
15
  this.qs = { include_count: true };
16
- this.exportConfig.context.module = 'labels';
16
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.LABELS;
17
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.LABELS];
17
18
  }
18
19
  async start() {
19
- cli_utilities_1.log.debug('Starting labels export process...', this.exportConfig.context);
20
- this.labelsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.labelConfig.dirName);
21
- cli_utilities_1.log.debug(`Labels folder path: ${this.labelsFolderPath}`, this.exportConfig.context);
22
- await utils_1.fsUtil.makeDirectory(this.labelsFolderPath);
23
- cli_utilities_1.log.debug('Created labels directory', this.exportConfig.context);
24
- await this.getLabels();
25
- cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.labels).length} labels`, this.exportConfig.context);
26
- if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
27
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context);
20
+ try {
21
+ cli_utilities_1.log.debug('Starting labels export process...', this.exportConfig.context);
22
+ // Setup with loading spinner
23
+ const [totalCount] = await this.withLoadingSpinner('LABELS: Analyzing labels...', async () => {
24
+ this.labelsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.labelConfig.dirName);
25
+ await utils_1.fsUtil.makeDirectory(this.labelsFolderPath);
26
+ cli_utilities_1.log.debug(`Labels folder path: ${this.labelsFolderPath}`, this.exportConfig.context);
27
+ // Get count for progress tracking
28
+ const countResponse = await this.stack
29
+ .label()
30
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
31
+ .find();
32
+ return [countResponse.count || 0];
33
+ });
34
+ if (totalCount === 0) {
35
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context);
36
+ return;
37
+ }
38
+ // Create simple progress manager with total count
39
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
40
+ progress.updateStatus('Fetching labels...');
41
+ await this.getLabels();
42
+ cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.labels || {}).length} labels`, this.exportConfig.context);
43
+ if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
44
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context);
45
+ }
46
+ else {
47
+ const labelsFilePath = (0, node_path_1.resolve)(this.labelsFolderPath, this.labelConfig.fileName);
48
+ cli_utilities_1.log.debug(`Writing labels to: ${labelsFilePath}`, this.exportConfig.context);
49
+ utils_1.fsUtil.writeFile(labelsFilePath, this.labels);
50
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels || {}).length), this.exportConfig.context);
51
+ }
52
+ this.completeProgress(true);
28
53
  }
29
- else {
30
- const labelsFilePath = (0, node_path_1.resolve)(this.labelsFolderPath, this.labelConfig.fileName);
31
- cli_utilities_1.log.debug(`Writing labels to: ${labelsFilePath}`, this.exportConfig.context);
32
- utils_1.fsUtil.writeFile(labelsFilePath, this.labels);
33
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), this.exportConfig.context);
54
+ catch (error) {
55
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
56
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Labels export failed');
34
57
  }
35
58
  }
36
59
  async getLabels(skip = 0) {
@@ -65,12 +88,14 @@ class ExportLabels extends base_class_1.default {
65
88
  }
66
89
  })
67
90
  .catch((error) => {
91
+ var _a;
92
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, 'labels', (error === null || error === void 0 ? void 0 : error.message) || 'Failed to export labels');
68
93
  cli_utilities_1.log.debug('Error occurred while fetching labels', this.exportConfig.context);
69
94
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
70
95
  });
71
96
  }
72
97
  sanitizeAttribs(labels) {
73
- var _a;
98
+ var _a, _b;
74
99
  cli_utilities_1.log.debug(`Sanitizing ${labels.length} labels`, this.exportConfig.context);
75
100
  for (let index = 0; index < (labels === null || labels === void 0 ? void 0 : labels.length); index++) {
76
101
  const labelUid = labels[index].uid;
@@ -78,6 +103,8 @@ class ExportLabels extends base_class_1.default {
78
103
  cli_utilities_1.log.debug(`Processing label: ${labelName} (${labelUid})`, this.exportConfig.context);
79
104
  this.labels[labelUid] = (0, omit_1.default)(labels[index], this.labelConfig.invalidKeys);
80
105
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context);
106
+ // Track progress for each label
107
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `label: ${labelName}`);
81
108
  }
82
109
  cli_utilities_1.log.debug(`Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}`, this.exportConfig.context);
83
110
  }