@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
@@ -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 LocaleExport extends base_class_1.default {
9
9
  constructor({ exportConfig, stackAPIClient }) {
10
10
  super({ exportConfig, stackAPIClient });
@@ -21,26 +21,40 @@ class LocaleExport extends base_class_1.default {
21
21
  this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.data), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(this.localeConfig.dirName));
22
22
  this.locales = {};
23
23
  this.masterLocale = {};
24
- this.exportConfig.context.module = 'locales';
24
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.LOCALES;
25
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.LOCALES];
25
26
  }
26
27
  async start() {
27
28
  try {
28
29
  cli_utilities_1.log.debug('Starting locales export process...', this.exportConfig.context);
29
- cli_utilities_1.log.debug(`Locales path: ${this.localesPath}`, this.exportConfig.context);
30
- await utils_1.fsUtil.makeDirectory(this.localesPath);
31
- cli_utilities_1.log.debug('Created locales directory', this.exportConfig.context);
30
+ // Get locales count and setup with loading spinner
31
+ const [totalCount] = await this.withLoadingSpinner('LOCALES: Analyzing locales...', async () => {
32
+ await utils_1.fsUtil.makeDirectory(this.localesPath);
33
+ cli_utilities_1.log.debug(`Locales path: ${this.localesPath}`, this.exportConfig.context);
34
+ const countResponse = await this.stackAPIClient
35
+ .locale()
36
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
37
+ .find();
38
+ return [countResponse.count || 0];
39
+ });
40
+ // Create simple progress manager with total count
41
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
42
+ // Fetch locales
43
+ progress.updateStatus('Fetching locale definitions...');
32
44
  await this.getLocales();
33
- cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales`, this.exportConfig.context);
45
+ cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.locales || {}).length} locales and ${Object.keys(this.masterLocale || {}).length} master locales`, this.exportConfig.context);
34
46
  const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName);
35
47
  const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName);
36
48
  cli_utilities_1.log.debug(`Writing locales to: ${localesFilePath}`, this.exportConfig.context);
37
49
  utils_1.fsUtil.writeFile(localesFilePath, this.locales);
38
50
  cli_utilities_1.log.debug(`Writing master locale to: ${masterLocaleFilePath}`, this.exportConfig.context);
39
51
  utils_1.fsUtil.writeFile(masterLocaleFilePath, this.masterLocale);
40
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LOCALES_EXPORT_COMPLETE', Object.keys(this.locales).length, Object.keys(this.masterLocale).length), this.exportConfig.context);
52
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LOCALES_EXPORT_COMPLETE', Object.keys(this.locales || {}).length, Object.keys(this.masterLocale || {}).length), this.exportConfig.context);
53
+ this.completeProgress(true);
41
54
  }
42
55
  catch (error) {
43
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) || 'Locales export failed');
44
58
  throw error;
45
59
  }
46
60
  }
@@ -71,22 +85,27 @@ class LocaleExport extends base_class_1.default {
71
85
  sanitizeAttribs(locales) {
72
86
  cli_utilities_1.log.debug(`Sanitizing ${locales.length} locales`, this.exportConfig.context);
73
87
  locales.forEach((locale) => {
74
- var _a, _b;
88
+ var _a, _b, _c, _d;
75
89
  for (let key in locale) {
76
90
  if (this.localeConfig.requiredKeys.indexOf(key) === -1) {
77
91
  delete locale[key];
78
92
  }
79
93
  }
80
- if ((locale === null || locale === void 0 ? void 0 : locale.code) === ((_b = (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code)) {
94
+ let uid = locale.uid;
95
+ if (((_b = (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code) === (locale === null || locale === void 0 ? void 0 : locale.code)) {
81
96
  cli_utilities_1.log.debug(`Adding locale ${locale.uid} to master locale`, this.exportConfig.context);
82
- this.masterLocale[locale.uid] = locale;
97
+ this.masterLocale[uid] = locale;
98
+ // Track progress for master locale
99
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `master-locale: ${uid}`);
83
100
  }
84
101
  else {
85
102
  cli_utilities_1.log.debug(`Adding locale ${locale.uid} to regular locales`, this.exportConfig.context);
86
- this.locales[locale.uid] = locale;
103
+ this.locales[uid] = locale;
104
+ // Track progress for regular locale
105
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(true, `locale: ${uid}`);
87
106
  }
88
107
  });
89
- cli_utilities_1.log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${Object.keys(this.locales).length}`, this.exportConfig.context);
108
+ cli_utilities_1.log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale || {}).length}, Regular locales: ${Object.keys(this.locales || {}).length}`, this.exportConfig.context);
90
109
  }
91
110
  }
92
111
  exports.default = LocaleExport;
@@ -1,7 +1,8 @@
1
1
  import { Command } from '@contentstack/cli-command';
2
2
  import { NodeCrypto, ContentstackMarketplaceClient } from '@contentstack/cli-utilities';
3
+ import BaseClass from './base-class';
3
4
  import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation } from '../../types';
4
- export default class ExportMarketplaceApps {
5
+ export default class ExportMarketplaceApps extends BaseClass {
5
6
  protected marketplaceAppConfig: MarketplaceAppsConfig;
6
7
  protected installedApps: Installation[];
7
8
  developerHubBaseUrl: string;
@@ -11,8 +12,10 @@ export default class ExportMarketplaceApps {
11
12
  exportConfig: ExportConfig;
12
13
  command: Command;
13
14
  query: Record<string, any>;
14
- constructor({ exportConfig }: Omit<ModuleClassParams, 'stackAPIClient' | 'moduleName'>);
15
+ constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
15
16
  start(): Promise<void>;
17
+ setupPaths(): Promise<void>;
18
+ getAppsCount(): Promise<number>;
16
19
  /**
17
20
  * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
18
21
  * library if it is available.
@@ -9,20 +9,71 @@ const entries_1 = tslib_1.__importDefault(require("lodash/entries"));
9
9
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
10
10
  const node_path_1 = require("node:path");
11
11
  const cli_utilities_1 = require("@contentstack/cli-utilities");
12
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
12
13
  const utils_1 = require("../../utils");
13
- class ExportMarketplaceApps {
14
- constructor({ exportConfig }) {
14
+ class ExportMarketplaceApps extends base_class_1.default {
15
+ constructor({ exportConfig, stackAPIClient }) {
16
+ super({ exportConfig, stackAPIClient });
15
17
  this.installedApps = [];
16
18
  this.exportConfig = exportConfig;
17
19
  this.marketplaceAppConfig = exportConfig.modules.marketplace_apps;
18
- this.exportConfig.context.module = 'marketplace-apps';
20
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.MARKETPLACE_APPS;
21
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.MARKETPLACE_APPS];
19
22
  }
20
23
  async start() {
21
- cli_utilities_1.log.debug('Starting marketplace apps export process...', this.exportConfig.context);
22
- if (!(0, cli_utilities_1.isAuthenticated)()) {
23
- cli_utilities_1.cliux.print('WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' });
24
- return Promise.resolve();
24
+ try {
25
+ cli_utilities_1.log.debug('Starting marketplace apps export process...', this.exportConfig.context);
26
+ if (!(0, cli_utilities_1.isAuthenticated)()) {
27
+ cli_utilities_1.cliux.print('WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' });
28
+ return Promise.resolve();
29
+ }
30
+ // Initial setup and analysis with loading spinner
31
+ const [appsCount] = await this.withLoadingSpinner('MARKETPLACE-APPS: Analyzing marketplace apps...', async () => {
32
+ await this.setupPaths();
33
+ const appsCount = await this.getAppsCount();
34
+ return [appsCount];
35
+ });
36
+ if (appsCount === 0) {
37
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context);
38
+ return;
39
+ }
40
+ // Handle encryption key prompt BEFORE starting progress
41
+ if (!this.exportConfig.forceStopMarketplaceAppsPrompt) {
42
+ cli_utilities_1.log.debug('Validating security configuration before progress start', this.exportConfig.context);
43
+ cli_utilities_1.cliux.print('\n');
44
+ await (0, utils_1.askEncryptionKey)(this.exportConfig);
45
+ this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
46
+ cli_utilities_1.cliux.print('\n');
47
+ }
48
+ // Create nested progress manager
49
+ const progress = this.createNestedProgress(this.currentModuleName);
50
+ // Add processes based on what we found
51
+ progress.addProcess(utils_1.PROCESS_NAMES.FETCH_APPS, appsCount);
52
+ progress.addProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST, appsCount); // Manifests and configurations
53
+ // Fetch stack specific apps
54
+ progress
55
+ .startProcess(utils_1.PROCESS_NAMES.FETCH_APPS)
56
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_APPS].FETCHING, utils_1.PROCESS_NAMES.FETCH_APPS);
57
+ await this.exportApps();
58
+ progress.completeProcess(utils_1.PROCESS_NAMES.FETCH_APPS, true);
59
+ // Process apps (manifests and configurations)
60
+ if (this.installedApps.length > 0) {
61
+ progress
62
+ .startProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST)
63
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
64
+ await this.getAppManifestAndAppConfig();
65
+ progress.completeProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST, true);
66
+ }
67
+ this.completeProgress(true);
68
+ cli_utilities_1.log.success('Marketplace apps export completed successfully', this.exportConfig.context);
69
+ }
70
+ catch (error) {
71
+ cli_utilities_1.log.debug('Error occurred during marketplace apps export', this.exportConfig.context);
72
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
73
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Marketplace apps export failed');
25
74
  }
75
+ }
76
+ async setupPaths() {
26
77
  this.marketplaceAppPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.marketplaceAppConfig.dirName);
27
78
  cli_utilities_1.log.debug(`Marketplace apps folder path: ${this.marketplaceAppPath}`, this.exportConfig.context);
28
79
  await utils_1.fsUtil.makeDirectory(this.marketplaceAppPath);
@@ -36,30 +87,41 @@ class ExportMarketplaceApps {
36
87
  const host = this.developerHubBaseUrl.split('://').pop();
37
88
  cli_utilities_1.log.debug(`Initializing marketplace SDK with host: ${host}`, this.exportConfig.context);
38
89
  this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
39
- await this.exportApps();
40
- cli_utilities_1.log.debug('Marketplace apps export process completed', this.exportConfig.context);
90
+ }
91
+ async getAppsCount() {
92
+ var _a, _b, _c, _d, _e, _f, _g;
93
+ cli_utilities_1.log.debug('Fetching marketplace apps count...', this.exportConfig.context);
94
+ try {
95
+ const externalQuery = (_a = this.exportConfig.query) === null || _a === void 0 ? void 0 : _a.modules['marketplace-apps'];
96
+ if (externalQuery) {
97
+ if (((_c = (_b = externalQuery.app_uid) === null || _b === void 0 ? void 0 : _b.$in) === null || _c === void 0 ? void 0 : _c.length) > 0) {
98
+ this.query.app_uids = externalQuery.app_uid.$in.join(',');
99
+ }
100
+ if (((_e = (_d = externalQuery.installation_uid) === null || _d === void 0 ? void 0 : _d.$in) === null || _e === void 0 ? void 0 : _e.length) > 0) {
101
+ this.query.installation_uids = (_g = (_f = externalQuery.installation_uid) === null || _f === void 0 ? void 0 : _f.$in) === null || _g === void 0 ? void 0 : _g.join(',');
102
+ }
103
+ }
104
+ const collection = await this.appSdk
105
+ .marketplace(this.exportConfig.org_uid)
106
+ .installation()
107
+ .fetchAll(Object.assign(Object.assign({}, this.query), { limit: 1, skip: 0 }));
108
+ const count = (collection === null || collection === void 0 ? void 0 : collection.count) || 0;
109
+ cli_utilities_1.log.debug(`Total marketplace apps count: ${count}`, this.exportConfig.context);
110
+ return count;
111
+ }
112
+ catch (error) {
113
+ cli_utilities_1.log.debug('Failed to fetch marketplace apps count', this.exportConfig.context);
114
+ return 0;
115
+ }
41
116
  }
42
117
  /**
43
118
  * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
44
119
  * library if it is available.
45
120
  */
46
121
  async exportApps() {
47
- var _a, _b, _c, _d, _e, _f, _g;
48
122
  cli_utilities_1.log.debug('Starting apps export process...', this.exportConfig.context);
49
- // currently support only app_uids or installation_uids
50
- const externalQuery = (_a = this.exportConfig.query) === null || _a === void 0 ? void 0 : _a.modules['marketplace-apps'];
51
- if (externalQuery) {
52
- if (((_c = (_b = externalQuery.app_uid) === null || _b === void 0 ? void 0 : _b.$in) === null || _c === void 0 ? void 0 : _c.length) > 0) {
53
- this.query.app_uids = externalQuery.app_uid.$in.join(',');
54
- }
55
- if (((_e = (_d = externalQuery.installation_uid) === null || _d === void 0 ? void 0 : _d.$in) === null || _e === void 0 ? void 0 : _e.length) > 0) {
56
- this.query.installation_uids = (_g = (_f = externalQuery.installation_uid) === null || _f === void 0 ? void 0 : _f.$in) === null || _g === void 0 ? void 0 : _g.join(',');
57
- }
58
- }
59
123
  await this.getStackSpecificApps();
60
124
  cli_utilities_1.log.debug(`Retrieved ${this.installedApps.length} stack-specific apps`, this.exportConfig.context);
61
- await this.getAppManifestAndAppConfig();
62
- cli_utilities_1.log.debug('Completed app manifest and configuration processing', this.exportConfig.context);
63
125
  if (!this.nodeCrypto && (0, find_1.default)(this.installedApps, (app) => !(0, isEmpty_1.default)(app.configuration))) {
64
126
  cli_utilities_1.log.debug('Initializing NodeCrypto for app configuration encryption', this.exportConfig.context);
65
127
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
@@ -79,7 +141,7 @@ class ExportMarketplaceApps {
79
141
  * marketplace apps.
80
142
  */
81
143
  async getAppManifestAndAppConfig() {
82
- var _a;
144
+ var _a, _b, _c;
83
145
  if ((0, isEmpty_1.default)(this.installedApps)) {
84
146
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context);
85
147
  }
@@ -94,11 +156,13 @@ class ExportMarketplaceApps {
94
156
  for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
95
157
  cli_utilities_1.log.debug(`Processing app configurations: ${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}`, this.exportConfig.context);
96
158
  await this.getAppConfigurations(+index, app);
159
+ // Track progress for each app processed
160
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `app: ${((_c = app.manifest) === null || _c === void 0 ? void 0 : _c.name) || app.uid}`, null, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
97
161
  }
98
162
  const marketplaceAppsFilePath = (0, node_path_1.resolve)(this.marketplaceAppPath, this.marketplaceAppConfig.fileName);
99
163
  cli_utilities_1.log.debug(`Writing marketplace apps to: ${marketplaceAppsFilePath}`, this.exportConfig.context);
100
164
  utils_1.fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps);
101
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), this.exportConfig.context);
165
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps || {}).length), this.exportConfig.context);
102
166
  }
103
167
  }
104
168
  /**
@@ -147,12 +211,13 @@ class ExportMarketplaceApps {
147
211
  .installation(appInstallation.uid)
148
212
  .installationData()
149
213
  .then(async (result) => {
214
+ var _a;
150
215
  const { data, error } = result;
151
216
  if ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration')) {
152
217
  cli_utilities_1.log.debug(`Found configuration data for app: ${app}`, this.exportConfig.context);
153
218
  if (!this.nodeCrypto && ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration'))) {
154
- cli_utilities_1.log.debug(`Initializing NodeCrypto for app: ${app}`, this.exportConfig.context);
155
219
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
220
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
156
221
  }
157
222
  if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.configuration)) {
158
223
  cli_utilities_1.log.debug(`Encrypting configuration for app: ${app}`, this.exportConfig.context);
@@ -204,6 +269,11 @@ class ExportMarketplaceApps {
204
269
  return false;
205
270
  }));
206
271
  cli_utilities_1.log.debug(`Processed ${installation.length} app installations`, this.exportConfig.context);
272
+ // Track progress for each app fetched
273
+ installation.forEach((app) => {
274
+ var _a, _b;
275
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `app: ${((_b = app.manifest) === null || _b === void 0 ? void 0 : _b.name) || app.uid}`, null, utils_1.PROCESS_NAMES.FETCH_APPS);
276
+ });
207
277
  this.installedApps = this.installedApps.concat(installation);
208
278
  if (count - (skip + 50) > 0) {
209
279
  cli_utilities_1.log.debug(`Continuing to fetch apps with skip: ${skip + 50}`, this.exportConfig.context);
@@ -1,11 +1,21 @@
1
1
  import { AnyProperty } from '@contentstack/cli-variants';
2
+ import BaseClass from './base-class';
2
3
  import { ModuleClassParams, ExportConfig } from '../../types';
3
- export default class ExportPersonalize {
4
+ export default class ExportPersonalize extends BaseClass {
4
5
  exportConfig: ExportConfig;
5
6
  personalizeConfig: {
6
7
  dirName: string;
7
8
  baseURL: Record<string, string>;
8
9
  } & AnyProperty;
9
- constructor({ exportConfig }: ModuleClassParams);
10
+ private readonly moduleInstanceMapper;
11
+ private readonly moduleDisplayMapper;
12
+ constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
10
13
  start(): Promise<void>;
14
+ private validatePersonalizeSetup;
15
+ private validateProjectConnectivity;
16
+ private getPersonalizeModuleCount;
17
+ private addProjectProcess;
18
+ private addModuleProcesses;
19
+ private exportProjects;
20
+ private exportModules;
11
21
  }
@@ -1,70 +1,205 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
3
4
  const cli_variants_1 = require("@contentstack/cli-variants");
4
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
5
- class ExportPersonalize {
6
- constructor({ exportConfig }) {
6
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
7
+ const utils_1 = require("../../utils");
8
+ class ExportPersonalize extends base_class_1.default {
9
+ constructor({ exportConfig, stackAPIClient }) {
10
+ super({ exportConfig, stackAPIClient });
11
+ this.moduleInstanceMapper = {
12
+ events: cli_variants_1.ExportEvents,
13
+ attributes: cli_variants_1.ExportAttributes,
14
+ audiences: cli_variants_1.ExportAudiences,
15
+ experiences: cli_variants_1.ExportExperiences,
16
+ };
17
+ this.moduleDisplayMapper = {
18
+ events: utils_1.PROCESS_NAMES.PERSONALIZE_EVENTS,
19
+ attributes: utils_1.PROCESS_NAMES.PERSONALIZE_ATTRIBUTES,
20
+ audiences: utils_1.PROCESS_NAMES.PERSONALIZE_AUDIENCES,
21
+ experiences: utils_1.PROCESS_NAMES.PERSONALIZE_EXPERIENCES,
22
+ };
7
23
  this.exportConfig = exportConfig;
8
24
  this.personalizeConfig = exportConfig.modules.personalize;
9
- this.exportConfig.context.module = 'personalize';
25
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.PERSONALIZE;
26
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.PERSONALIZE];
10
27
  }
11
28
  async start() {
12
29
  try {
13
30
  cli_utilities_1.log.debug('Starting personalize export process...', this.exportConfig.context);
14
- if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) {
15
- cli_utilities_1.log.debug(`Personalize URL not set for region: ${this.exportConfig.region.name}`, this.exportConfig.context);
16
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context);
17
- this.exportConfig.personalizationEnabled = false;
18
- return;
19
- }
20
- if (this.exportConfig.management_token) {
21
- cli_utilities_1.log.debug('Management token detected, skipping personalize export', this.exportConfig.context);
22
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context);
23
- this.exportConfig.personalizationEnabled = false;
31
+ const [canProceed, projectCount, moduleCount] = await this.withLoadingSpinner('PERSONALIZE: Analyzing personalization configuration and connectivity...', async () => {
32
+ // Step 1: Basic validation (URL, tokens)
33
+ const basicValidation = this.validatePersonalizeSetup();
34
+ if (!basicValidation) {
35
+ return [false, 0, 0];
36
+ }
37
+ // Step 2: Check actual project connectivity
38
+ const projectCount = await this.validateProjectConnectivity();
39
+ if (projectCount === 0) {
40
+ cli_utilities_1.log.info('No Personalize Project connected with the given stack', this.exportConfig.context);
41
+ this.exportConfig.personalizationEnabled = false;
42
+ return [false, 0, 0];
43
+ }
44
+ // Step 3: Get module count only if projects exist
45
+ const moduleCount = this.getPersonalizeModuleCount();
46
+ cli_utilities_1.log.debug(`Personalize validation - canProceed: true, projectCount: ${projectCount}, moduleCount: ${moduleCount}`, this.exportConfig.context);
47
+ // Enable personalization since we have connected projects
48
+ this.exportConfig.personalizationEnabled = true;
49
+ return [true, projectCount, moduleCount];
50
+ });
51
+ if (!canProceed) {
24
52
  return;
25
53
  }
26
- cli_utilities_1.log.debug('Starting projects export for personalization...', this.exportConfig.context);
27
- await new cli_variants_1.ExportProjects(this.exportConfig).start();
28
- if (this.exportConfig.personalizationEnabled) {
29
- cli_utilities_1.log.debug('Personalization is enabled, processing personalize modules...', this.exportConfig.context);
30
- const moduleMapper = {
31
- events: new cli_variants_1.ExportEvents(this.exportConfig),
32
- attributes: new cli_variants_1.ExportAttributes(this.exportConfig),
33
- audiences: new cli_variants_1.ExportAudiences(this.exportConfig),
34
- experiences: new cli_variants_1.ExportExperiences(this.exportConfig),
35
- };
36
- const order = this.exportConfig.modules.personalize
37
- .exportOrder;
38
- cli_utilities_1.log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context);
39
- for (const module of order) {
40
- cli_utilities_1.log.debug(`Processing personalize module: ${module}`, this.exportConfig.context);
41
- if (moduleMapper[module]) {
42
- cli_utilities_1.log.debug(`Starting export for module: ${module}`, this.exportConfig.context);
43
- await moduleMapper[module].start();
44
- cli_utilities_1.log.debug(`Completed export for module: ${module}`, this.exportConfig.context);
45
- }
46
- else {
47
- cli_utilities_1.log.debug(`Module not implemented: ${module}`, this.exportConfig.context);
48
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context);
49
- }
54
+ cli_utilities_1.log.debug(`Creating personalize progress with projectCount: ${projectCount}, moduleCount: ${moduleCount}`, this.exportConfig.context);
55
+ const progress = this.createNestedProgress(this.currentModuleName);
56
+ this.addProjectProcess(progress, projectCount);
57
+ this.addModuleProcesses(progress, moduleCount);
58
+ try {
59
+ await this.exportProjects(progress);
60
+ if (moduleCount > 0) {
61
+ cli_utilities_1.log.debug('Processing personalize modules...', this.exportConfig.context);
62
+ await this.exportModules(progress);
50
63
  }
51
- cli_utilities_1.log.debug('Completed all personalize module exports', this.exportConfig.context);
64
+ else {
65
+ cli_utilities_1.log.debug('No personalize modules configured for processing', this.exportConfig.context);
66
+ }
67
+ this.completeProgress(true);
68
+ cli_utilities_1.log.success('Personalize export completed successfully', this.exportConfig.context);
52
69
  }
53
- else {
54
- cli_utilities_1.log.debug('Personalization is disabled, skipping personalize module exports', this.exportConfig.context);
70
+ catch (moduleError) {
71
+ if (moduleError === 'Forbidden') {
72
+ cli_utilities_1.log.debug('Personalize access forbidden, personalization not enabled', this.exportConfig.context);
73
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context);
74
+ this.exportConfig.personalizationEnabled = false;
75
+ this.completeProgress(true); // considered successful even if skipped
76
+ }
77
+ else {
78
+ cli_utilities_1.log.debug('Error occurred during personalize module processing', this.exportConfig.context);
79
+ this.completeProgress(false, (moduleError === null || moduleError === void 0 ? void 0 : moduleError.message) || 'Personalize module processing failed');
80
+ throw moduleError;
81
+ }
55
82
  }
56
83
  }
57
84
  catch (error) {
58
- if (error === 'Forbidden') {
59
- cli_utilities_1.log.debug('Personalize access forbidden, personalization not enabled', this.exportConfig.context);
60
- cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context);
85
+ cli_utilities_1.log.debug('Error occurred during personalize export', this.exportConfig.context);
86
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
87
+ this.exportConfig.personalizationEnabled = false;
88
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Personalize export failed');
89
+ }
90
+ }
91
+ validatePersonalizeSetup() {
92
+ if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) {
93
+ cli_utilities_1.log.debug(`Personalize URL not set for region: ${this.exportConfig.region.name}`, this.exportConfig.context);
94
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context);
95
+ this.exportConfig.personalizationEnabled = false;
96
+ return false;
97
+ }
98
+ if (this.exportConfig.management_token) {
99
+ cli_utilities_1.log.debug('Management token detected, skipping personalize export', this.exportConfig.context);
100
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context);
101
+ this.exportConfig.personalizationEnabled = false;
102
+ return false;
103
+ }
104
+ return true;
105
+ }
106
+ async validateProjectConnectivity() {
107
+ try {
108
+ // Create a temporary ExportProjects instance to check connectivity
109
+ const tempProjectsExporter = new cli_variants_1.ExportProjects(this.exportConfig);
110
+ // Initialize and fetch projects
111
+ await tempProjectsExporter.init();
112
+ // talisman-ignore-line
113
+ const projectsData = await tempProjectsExporter.projects({ connectedStackApiKey: this.exportConfig.apiKey });
114
+ const projectCount = (projectsData === null || projectsData === void 0 ? void 0 : projectsData.length) || 0;
115
+ cli_utilities_1.log.debug(`Found ${projectCount} connected projects`, this.exportConfig.context);
116
+ return projectCount;
117
+ }
118
+ catch (error) {
119
+ cli_utilities_1.log.debug(`Error checking project connectivity: ${error}`, this.exportConfig.context);
120
+ return 0;
121
+ }
122
+ }
123
+ getPersonalizeModuleCount() {
124
+ var _a, _b;
125
+ const order = (_b = (_a = this.exportConfig.modules) === null || _a === void 0 ? void 0 : _a.personalize) === null || _b === void 0 ? void 0 : _b.exportOrder;
126
+ return Array.isArray(order) ? order.length : 0;
127
+ }
128
+ addProjectProcess(progress, projectCount) {
129
+ progress.addProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS, projectCount);
130
+ cli_utilities_1.log.debug(`Added ${utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS} process with count: ${projectCount}`, this.exportConfig.context);
131
+ }
132
+ addModuleProcesses(progress, moduleCount) {
133
+ if (moduleCount > 0) {
134
+ // talisman-ignore-start
135
+ const order = this.exportConfig.modules.personalize
136
+ .exportOrder;
137
+ // talisman-ignore-end
138
+ cli_utilities_1.log.debug(`Adding ${order.length} personalize module processes: ${order.join(', ')}`, this.exportConfig.context);
139
+ for (const module of order) {
140
+ const processName = this.moduleDisplayMapper[module];
141
+ progress.addProcess(processName, 1);
142
+ cli_utilities_1.log.debug(`Added ${processName} process to personalize progress`, this.exportConfig.context);
143
+ }
144
+ }
145
+ else {
146
+ cli_utilities_1.log.debug('No personalize modules to add to progress', this.exportConfig.context);
147
+ }
148
+ }
149
+ async exportProjects(progress) {
150
+ progress
151
+ .startProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS)
152
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS].EXPORTING, utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS);
153
+ cli_utilities_1.log.debug('Starting projects export for personalization...', this.exportConfig.context);
154
+ const projectsExporter = new cli_variants_1.ExportProjects(this.exportConfig);
155
+ projectsExporter.setParentProgressManager(progress);
156
+ await projectsExporter.start();
157
+ progress.completeProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS, true);
158
+ }
159
+ async exportModules(progress) {
160
+ var _a, _b, _c;
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
+ // talisman-ignore-start
167
+ const order = this.exportConfig.modules.personalize
168
+ .exportOrder;
169
+ // talisman-ignore-end
170
+ cli_utilities_1.log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context);
171
+ for (const module of order) {
172
+ cli_utilities_1.log.debug(`Processing personalize module: ${module}`, this.exportConfig.context);
173
+ const processName = this.moduleDisplayMapper[module];
174
+ const ModuleClass = this.moduleInstanceMapper[module];
175
+ if (ModuleClass) {
176
+ progress
177
+ .startProcess(processName)
178
+ .updateStatus(((_a = utils_1.PROCESS_STATUS[processName]) === null || _a === void 0 ? void 0 : _a.EXPORTING) || `Exporting ${module}...`, processName);
179
+ cli_utilities_1.log.debug(`Starting export for module: ${module}`, this.exportConfig.context);
180
+ if (this.exportConfig.personalizationEnabled) {
181
+ const exporter = new ModuleClass(this.exportConfig);
182
+ exporter.setParentProgressManager(progress);
183
+ await exporter.start();
184
+ progress.completeProcess(processName, true);
185
+ cli_utilities_1.log.debug(`Completed export for module: ${module}`, this.exportConfig.context);
186
+ }
187
+ else {
188
+ cli_utilities_1.log.debug(`Skipping ${module} - personalization not enabled`, this.exportConfig.context);
189
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `${module} skipped (no project)`, null, processName);
190
+ progress.completeProcess(processName, true);
191
+ cli_utilities_1.log.info(`Skipped ${module} export - no personalize project found`, this.exportConfig.context);
192
+ }
61
193
  }
62
194
  else {
63
- cli_utilities_1.log.debug('Error occurred during personalize export', this.exportConfig.context);
64
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
195
+ cli_utilities_1.log.debug(`Module not implemented: ${module}`, this.exportConfig.context);
196
+ progress.startProcess(processName).updateStatus(`Module not implemented: ${module}`, processName);
197
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `module: ${module}`, 'Module not implemented', processName);
198
+ progress.completeProcess(processName, false);
199
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context);
65
200
  }
66
- this.exportConfig.personalizationEnabled = false;
67
201
  }
202
+ cli_utilities_1.log.debug('Completed all personalize module processing', this.exportConfig.context);
68
203
  }
69
204
  }
70
205
  exports.default = ExportPersonalize;