@contentstack/cli-cm-import 1.28.0 → 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 (87) hide show
  1. package/README.md +5 -7
  2. package/lib/commands/cm/stacks/import.d.ts +2 -0
  3. package/lib/commands/cm/stacks/import.js +46 -11
  4. package/lib/config/index.js +0 -1
  5. package/lib/import/module-importer.d.ts +2 -2
  6. package/lib/import/module-importer.js +9 -25
  7. package/lib/import/modules/assets.d.ts +6 -0
  8. package/lib/import/modules/assets.js +102 -25
  9. package/lib/import/modules/base-class.d.ts +17 -0
  10. package/lib/import/modules/base-class.js +45 -0
  11. package/lib/import/modules/content-types.d.ts +7 -10
  12. package/lib/import/modules/content-types.js +132 -68
  13. package/lib/import/modules/custom-roles.d.ts +6 -2
  14. package/lib/import/modules/custom-roles.js +80 -69
  15. package/lib/import/modules/entries.d.ts +7 -0
  16. package/lib/import/modules/entries.js +278 -163
  17. package/lib/import/modules/environments.d.ts +3 -0
  18. package/lib/import/modules/environments.js +69 -38
  19. package/lib/import/modules/extensions.d.ts +3 -0
  20. package/lib/import/modules/extensions.js +99 -64
  21. package/lib/import/modules/global-fields.d.ts +8 -1
  22. package/lib/import/modules/global-fields.js +123 -63
  23. package/lib/import/modules/index.d.ts +1 -0
  24. package/lib/import/modules/index.js +1 -0
  25. package/lib/import/modules/labels.d.ts +3 -0
  26. package/lib/import/modules/labels.js +104 -54
  27. package/lib/import/modules/locales.d.ts +15 -4
  28. package/lib/import/modules/locales.js +194 -94
  29. package/lib/import/modules/marketplace-apps.d.ts +6 -3
  30. package/lib/import/modules/marketplace-apps.js +177 -102
  31. package/lib/import/modules/personalize.d.ts +11 -4
  32. package/lib/import/modules/personalize.js +138 -47
  33. package/lib/import/modules/stack.d.ts +6 -0
  34. package/lib/import/modules/stack.js +71 -27
  35. package/lib/import/modules/taxonomies.d.ts +4 -2
  36. package/lib/import/modules/taxonomies.js +60 -46
  37. package/lib/import/modules/variant-entries.d.ts +7 -4
  38. package/lib/import/modules/variant-entries.js +76 -35
  39. package/lib/import/modules/webhooks.d.ts +3 -0
  40. package/lib/import/modules/webhooks.js +71 -40
  41. package/lib/import/modules/workflows.d.ts +3 -0
  42. package/lib/import/modules/workflows.js +98 -48
  43. package/lib/types/default-config.d.ts +0 -1
  44. package/lib/types/import-config.d.ts +0 -1
  45. package/lib/types/index.d.ts +1 -12
  46. package/lib/utils/backup-handler.js +1 -2
  47. package/lib/utils/constants.d.ts +243 -0
  48. package/lib/utils/constants.js +264 -0
  49. package/lib/utils/import-config-handler.js +2 -7
  50. package/lib/utils/import-path-resolver.d.ts +1 -1
  51. package/lib/utils/import-path-resolver.js +5 -5
  52. package/lib/utils/index.d.ts +1 -1
  53. package/lib/utils/index.js +6 -2
  54. package/lib/utils/marketplace-app-helper.js +3 -8
  55. package/lib/utils/progress-strategy-registry.d.ts +7 -0
  56. package/lib/utils/progress-strategy-registry.js +72 -0
  57. package/lib/utils/setup-branch.js +1 -1
  58. package/oclif.manifest.json +2 -2
  59. package/package.json +2 -2
  60. package/lib/import/modules-js/assets.d.ts +0 -33
  61. package/lib/import/modules-js/assets.js +0 -428
  62. package/lib/import/modules-js/content-types.d.ts +0 -34
  63. package/lib/import/modules-js/content-types.js +0 -204
  64. package/lib/import/modules-js/custom-roles.d.ts +0 -15
  65. package/lib/import/modules-js/custom-roles.js +0 -143
  66. package/lib/import/modules-js/entries.d.ts +0 -54
  67. package/lib/import/modules-js/entries.js +0 -1280
  68. package/lib/import/modules-js/environments.d.ts +0 -13
  69. package/lib/import/modules-js/environments.js +0 -85
  70. package/lib/import/modules-js/extensions.d.ts +0 -18
  71. package/lib/import/modules-js/extensions.js +0 -86
  72. package/lib/import/modules-js/global-fields.d.ts +0 -13
  73. package/lib/import/modules-js/global-fields.js +0 -106
  74. package/lib/import/modules-js/index.d.ts +0 -1
  75. package/lib/import/modules-js/index.js +0 -33
  76. package/lib/import/modules-js/labels.d.ts +0 -20
  77. package/lib/import/modules-js/labels.js +0 -148
  78. package/lib/import/modules-js/locales.d.ts +0 -24
  79. package/lib/import/modules-js/locales.js +0 -196
  80. package/lib/import/modules-js/marketplace-apps.d.ts +0 -63
  81. package/lib/import/modules-js/marketplace-apps.js +0 -429
  82. package/lib/import/modules-js/webhooks.d.ts +0 -17
  83. package/lib/import/modules-js/webhooks.js +0 -85
  84. package/lib/import/modules-js/workflows.d.ts +0 -19
  85. package/lib/import/modules-js/workflows.js +0 -170
  86. package/lib/utils/log.d.ts +0 -12
  87. package/lib/utils/log.js +0 -31
@@ -2,58 +2,99 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path_1 = tslib_1.__importDefault(require("path"));
5
- const cli_variants_1 = require("@contentstack/cli-variants");
6
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
6
+ const cli_variants_1 = require("@contentstack/cli-variants");
7
7
  const utils_1 = require("../../utils");
8
- class ImportVarientEntries {
9
- constructor({ importConfig }) {
8
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
9
+ class ImportVariantEntries extends base_class_1.default {
10
+ constructor({ importConfig, stackAPIClient }) {
11
+ super({ importConfig, stackAPIClient });
10
12
  this.config = importConfig;
11
- this.config.context.module = 'variant-entries';
13
+ this.config.context.module = utils_1.MODULE_CONTEXTS.VARIANT_ENTRIES;
14
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.VARIANT_ENTRIES];
12
15
  this.personalize = importConfig.modules.personalize;
13
16
  this.projectMapperFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalize.dirName), 'projects', 'projects.json');
14
17
  }
15
18
  /**
16
- * The `start` function in TypeScript is an asynchronous method that conditionally imports data using
17
- * helper methods and logs any errors encountered.
19
+ * @method start
20
+ * @returns {Promise<void>} Promise<void>
18
21
  */
19
22
  async start() {
20
23
  try {
24
+ cli_utilities_1.log.debug('Starting variant entries import process...', this.config.context);
25
+ const [hasProject] = await this.analyzeVariantEntries();
26
+ if (!hasProject) {
27
+ cli_utilities_1.log.info('No variant entries found to import', this.config.context);
28
+ return;
29
+ }
30
+ const progress = this.createNestedProgress(this.currentModuleName);
31
+ // Add the variant entries process that will be managed by the actual VariantEntries class
32
+ progress.addProcess(utils_1.PROCESS_NAMES.VARIANT_ENTRIES_IMPORT, 0); // Start with 0, will be updated dynamically
33
+ progress.startProcess(utils_1.PROCESS_NAMES.VARIANT_ENTRIES_IMPORT);
34
+ progress.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.VARIANT_ENTRIES_IMPORT].IMPORTING, utils_1.PROCESS_NAMES.VARIANT_ENTRIES_IMPORT);
35
+ cli_utilities_1.log.info('Starting variant entries import process', this.config.context);
36
+ await this.importVariantEntries();
37
+ this.completeProgress(true);
38
+ cli_utilities_1.log.success('Variant entries imported successfully', this.config.context);
39
+ }
40
+ catch (error) {
41
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Variant entries import failed');
42
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.config.context));
43
+ }
44
+ }
45
+ async importVariantEntries() {
46
+ var _a;
47
+ const project = utils_1.fsUtil.readFile(this.projectMapperFilePath);
48
+ cli_utilities_1.log.debug(`Project data loaded: ${JSON.stringify(project)}`, this.config.context);
49
+ if (project && project.uid) {
50
+ cli_utilities_1.log.debug(`Found personalize project: ${project.uid}`, this.config.context);
51
+ this.config.modules.personalize.project_id = project.uid;
52
+ cli_utilities_1.log.debug('Initializing helper methods for variant entries import', this.config.context);
53
+ const helpers = {
54
+ lookUpTerms: utils_1.lookUpTerms,
55
+ lookupAssets: utils_1.lookupAssets,
56
+ lookupEntries: utils_1.lookupEntries,
57
+ lookupExtension: utils_1.lookupExtension,
58
+ restoreJsonRteEntryRefs: utils_1.restoreJsonRteEntryRefs,
59
+ };
60
+ cli_utilities_1.log.debug('Helper methods initialized successfully', this.config.context);
61
+ const helperTypes = Object.keys(helpers || {}).join(', ');
62
+ cli_utilities_1.log.debug(`Helper method types available: ${helperTypes}`, this.config.context);
63
+ cli_utilities_1.log.debug('Creating VariantEntries instance', this.config.context);
64
+ const variantEntriesImporter = new cli_variants_1.Import.VariantEntries(Object.assign(this.config, { helpers }));
65
+ variantEntriesImporter.setParentProgressManager(this.progressManager);
66
+ cli_utilities_1.log.debug('Starting variant entries import', this.config.context);
67
+ await variantEntriesImporter.import();
68
+ // this.progressManager?.tick(true, 'variant entries import completed', null, PROCESS_NAMES.VARIANT_ENTRIES_IMPORT);
69
+ cli_utilities_1.log.debug('Variant entries import completed successfully', this.config.context);
70
+ }
71
+ else {
72
+ cli_utilities_1.log.debug('No valid project found in mapper file', this.config.context);
73
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, 'variant entries import', 'No personalize project linked', utils_1.PROCESS_NAMES.VARIANT_ENTRIES_IMPORT);
74
+ cli_utilities_1.log.info('Skipping entry variants import because no personalize project is linked.', this.config.context);
75
+ }
76
+ }
77
+ async analyzeVariantEntries() {
78
+ return this.withLoadingSpinner('VARIANT ENTRIES: Analyzing import data...', async () => {
21
79
  cli_utilities_1.log.debug(`Reading project mapper from: ${this.projectMapperFilePath}`, this.config.context);
22
80
  if (!utils_1.fileHelper.fileExistsSync(this.projectMapperFilePath)) {
23
81
  cli_utilities_1.log.debug('Project mapper file does not exist', this.config.context);
24
82
  cli_utilities_1.log.info('Skipping entry variants import because no personalize project mapper found.', this.config.context);
25
- return;
83
+ return [false, 0];
26
84
  }
27
85
  const project = utils_1.fsUtil.readFile(this.projectMapperFilePath);
28
- cli_utilities_1.log.debug(`Project data loaded: ${JSON.stringify(project)}`, this.config.context);
29
- if (project && project.uid) {
30
- cli_utilities_1.log.debug(`Found personalize project: ${project.uid}`, this.config.context);
31
- this.config.modules.personalize.project_id = project.uid;
32
- cli_utilities_1.log.debug('Initializing helper methods for variant entries import', this.config.context);
33
- const helpers = {
34
- lookUpTerms: utils_1.lookUpTerms,
35
- lookupAssets: utils_1.lookupAssets,
36
- lookupEntries: utils_1.lookupEntries,
37
- lookupExtension: utils_1.lookupExtension,
38
- restoreJsonRteEntryRefs: utils_1.restoreJsonRteEntryRefs,
39
- };
40
- cli_utilities_1.log.debug('Helper methods initialized successfully', this.config.context);
41
- const helperTypes = Object.keys(helpers || {}).join(', ');
42
- cli_utilities_1.log.debug(`Helper method types available: ${helperTypes}`, this.config.context);
43
- cli_utilities_1.log.debug('Creating VariantEntries instance', this.config.context);
44
- const variantEntriesImporter = new cli_variants_1.Import.VariantEntries(Object.assign(this.config, { helpers }));
45
- cli_utilities_1.log.debug('Starting variant entries import', this.config.context);
46
- await variantEntriesImporter.import();
47
- cli_utilities_1.log.success('Variant entries imported successfully', this.config.context);
48
- }
49
- else {
86
+ const hasValidProject = !!(project && project.uid);
87
+ if (!hasValidProject) {
50
88
  cli_utilities_1.log.debug('No valid project found in mapper file', this.config.context);
51
- cli_utilities_1.log.info('Skipping entry variants import because no personalize project is linked.', this.config.context);
89
+ return [false, 0];
52
90
  }
53
- }
54
- catch (error) {
55
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.config.context));
56
- }
91
+ // Basic validation - check if data file exists
92
+ const dataFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'entries', 'data-for-variant-entry.json');
93
+ const hasVariantData = utils_1.fileHelper.fileExistsSync(dataFilePath);
94
+ cli_utilities_1.log.debug(`Found valid personalize project: ${project.uid} with variant data: ${hasVariantData}`, this.config.context);
95
+ // Return 0 count - let the variant module update it dynamically
96
+ return [hasValidProject && hasVariantData, 0];
97
+ });
57
98
  }
58
99
  }
59
- exports.default = ImportVarientEntries;
100
+ exports.default = ImportVariantEntries;
@@ -24,4 +24,7 @@ export default class ImportWebhooks extends BaseClass {
24
24
  * @returns {ApiOptions} ApiOptions
25
25
  */
26
26
  serializeWebhooks(apiOptions: ApiOptions): ApiOptions;
27
+ private analyzeWebhooks;
28
+ private prepareWebhookMapper;
29
+ private processWebhookResults;
27
30
  }
@@ -10,7 +10,8 @@ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
10
10
  class ImportWebhooks extends base_class_1.default {
11
11
  constructor({ importConfig, stackAPIClient }) {
12
12
  super({ importConfig, stackAPIClient });
13
- this.importConfig.context.module = 'webhooks';
13
+ this.importConfig.context.module = utils_1.MODULE_CONTEXTS.WEBHOOKS;
14
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.WEBHOOKS];
14
15
  this.webhooksConfig = importConfig.modules.webhooks;
15
16
  this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'webhooks');
16
17
  this.webhooksFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.webhooksConfig.dirName);
@@ -27,46 +28,25 @@ class ImportWebhooks extends base_class_1.default {
27
28
  * @returns {Promise<void>} Promise<void>
28
29
  */
29
30
  async start() {
30
- var _a, _b, _c;
31
- cli_utilities_1.log.debug('Checking for webhooks folder existence', this.importConfig.context);
32
- //Step1 check folder exists or not
33
- if (utils_1.fileHelper.fileExistsSync(this.webhooksFolderPath)) {
34
- this.webhooks = utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhooksFolderPath, 'webhooks.json'), true);
35
- cli_utilities_1.log.debug(`Found webhooks folder: ${this.webhooksFolderPath}`, this.importConfig.context);
36
- const webhookCount = Object.keys(this.webhooks || {}).length;
37
- cli_utilities_1.log.debug(`Loaded ${webhookCount} webhook items from file`, this.importConfig.context);
38
- }
39
- else {
40
- cli_utilities_1.log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
41
- return;
42
- }
43
- //create webhooks in mapper directory
44
- cli_utilities_1.log.debug('Creating webhooks mapper directory', this.importConfig.context);
45
- await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
46
- cli_utilities_1.log.debug('Created webhooks mapper directory', this.importConfig.context);
47
- cli_utilities_1.log.debug('Loading existing webhook UID mappings', this.importConfig.context);
48
- this.webhookUidMapper = utils_1.fileHelper.fileExistsSync(this.webhookUidMapperPath)
49
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhookUidMapperPath), true)
50
- : {};
51
- if (((_a = Object.keys(this.webhookUidMapper)) === null || _a === void 0 ? void 0 : _a.length) > 0) {
52
- const webhookUidCount = Object.keys(this.webhookUidMapper || {}).length;
53
- cli_utilities_1.log.debug(`Loaded existing webhook UID data: ${webhookUidCount} items`, this.importConfig.context);
54
- }
55
- else {
56
- cli_utilities_1.log.debug('No existing webhook UID mappings found', this.importConfig.context);
57
- }
58
- cli_utilities_1.log.debug('Starting webhook import process', this.importConfig.context);
59
- await this.importWebhooks();
60
- cli_utilities_1.log.debug('Processing webhook import results', this.importConfig.context);
61
- if ((_b = this.createdWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
62
- utils_1.fsUtil.writeFile(this.createdWebhooksPath, this.createdWebhooks);
63
- cli_utilities_1.log.debug(`Written ${this.createdWebhooks.length} successful webhooks to file`, this.importConfig.context);
31
+ try {
32
+ cli_utilities_1.log.debug('Starting webhooks import process...', this.importConfig.context);
33
+ const [webhooksCount] = await this.analyzeWebhooks();
34
+ if (webhooksCount === 0) {
35
+ cli_utilities_1.log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
36
+ return;
37
+ }
38
+ const progress = this.createSimpleProgress(this.currentModuleName, webhooksCount);
39
+ await this.prepareWebhookMapper();
40
+ progress.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT].IMPORTING);
41
+ await this.importWebhooks();
42
+ this.processWebhookResults();
43
+ this.completeProgress(true);
44
+ cli_utilities_1.log.success('Webhooks have been imported successfully!', this.importConfig.context);
64
45
  }
65
- if ((_c = this.failedWebhooks) === null || _c === void 0 ? void 0 : _c.length) {
66
- utils_1.fsUtil.writeFile(this.failedWebhooksPath, this.failedWebhooks);
67
- cli_utilities_1.log.debug(`Written ${this.failedWebhooks.length} failed webhooks to file`, this.importConfig.context);
46
+ catch (error) {
47
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Webhooks import failed');
48
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
68
49
  }
69
- cli_utilities_1.log.success('Webhooks have been imported successfully!', this.importConfig.context);
70
50
  }
71
51
  async importWebhooks() {
72
52
  cli_utilities_1.log.debug('Validating webhooks data', this.importConfig.context);
@@ -77,22 +57,26 @@ class ImportWebhooks extends base_class_1.default {
77
57
  const apiContent = (0, values_1.default)(this.webhooks);
78
58
  cli_utilities_1.log.debug(`Starting to import ${apiContent.length} webhooks`, this.importConfig.context);
79
59
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
60
+ var _a;
80
61
  this.createdWebhooks.push(response);
81
62
  this.webhookUidMapper[uid] = response.uid;
63
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `webhook: ${name || uid}`, null, utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT);
82
64
  cli_utilities_1.log.success(`Webhook '${name}' imported successfully`, this.importConfig.context);
83
65
  cli_utilities_1.log.debug(`Webhook UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
84
66
  utils_1.fsUtil.writeFile(this.webhookUidMapperPath, this.webhookUidMapper);
85
67
  };
86
68
  const onReject = ({ error, apiData }) => {
87
- var _a;
69
+ var _a, _b, _c;
88
70
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
89
71
  const { name, uid } = apiData;
90
72
  cli_utilities_1.log.debug(`Webhook '${name}' (${uid}) failed to import`, this.importConfig.context);
91
73
  if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
74
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `webhook: ${name || uid} (already exists)`, null, utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT);
92
75
  cli_utilities_1.log.info(`Webhook '${name}' already exists`, this.importConfig.context);
93
76
  }
94
77
  else {
95
78
  this.failedWebhooks.push(apiData);
79
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `webhook: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT].FAILED, utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT);
96
80
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { webhookName: name }), `Webhook '${name}' failed to import`);
97
81
  }
98
82
  };
@@ -117,11 +101,13 @@ class ImportWebhooks extends base_class_1.default {
117
101
  * @returns {ApiOptions} ApiOptions
118
102
  */
119
103
  serializeWebhooks(apiOptions) {
104
+ var _a;
120
105
  const { apiData: webhook } = apiOptions;
121
106
  cli_utilities_1.log.debug(`Serializing webhook: ${webhook.name} (${webhook.uid})`, this.importConfig.context);
122
107
  if (this.webhookUidMapper.hasOwnProperty(webhook.uid)) {
123
108
  cli_utilities_1.log.info(`Webhook '${webhook.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
124
109
  cli_utilities_1.log.debug(`Skipping webhook serialization for: ${webhook.uid}`, this.importConfig.context);
110
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `webhook: ${webhook.name} (skipped - already exists)`, null, utils_1.PROCESS_NAMES.WEBHOOKS_IMPORT);
125
111
  apiOptions.entity = undefined;
126
112
  }
127
113
  else {
@@ -137,5 +123,50 @@ class ImportWebhooks extends base_class_1.default {
137
123
  }
138
124
  return apiOptions;
139
125
  }
126
+ async analyzeWebhooks() {
127
+ return this.withLoadingSpinner('WEBHOOKS: Analyzing import data...', async () => {
128
+ cli_utilities_1.log.debug('Checking for webhooks folder existence', this.importConfig.context);
129
+ if (!utils_1.fileHelper.fileExistsSync(this.webhooksFolderPath)) {
130
+ cli_utilities_1.log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
131
+ return [0];
132
+ }
133
+ cli_utilities_1.log.debug(`Found webhooks folder: ${this.webhooksFolderPath}`, this.importConfig.context);
134
+ this.webhooks = utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhooksFolderPath, 'webhooks.json'), true);
135
+ if (!this.webhooks) {
136
+ cli_utilities_1.log.info(`No webhooks found in file - '${(0, node_path_1.join)(this.webhooksFolderPath, 'webhooks.json')}'`, this.importConfig.context);
137
+ return [0];
138
+ }
139
+ const count = Object.keys(this.webhooks || {}).length;
140
+ cli_utilities_1.log.debug(`Loaded ${count} webhook items from file`, this.importConfig.context);
141
+ return [count];
142
+ });
143
+ }
144
+ async prepareWebhookMapper() {
145
+ cli_utilities_1.log.debug('Creating webhooks mapper directory', this.importConfig.context);
146
+ await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
147
+ cli_utilities_1.log.debug('Loading existing webhook UID mappings', this.importConfig.context);
148
+ this.webhookUidMapper = utils_1.fileHelper.fileExistsSync(this.webhookUidMapperPath)
149
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhookUidMapperPath), true) || {}
150
+ : {};
151
+ const count = Object.keys(this.webhookUidMapper || {}).length;
152
+ if (count > 0) {
153
+ cli_utilities_1.log.debug(`Loaded existing webhook UID data: ${count} items`, this.importConfig.context);
154
+ }
155
+ else {
156
+ cli_utilities_1.log.debug('No existing webhook UID mappings found', this.importConfig.context);
157
+ }
158
+ }
159
+ processWebhookResults() {
160
+ var _a, _b;
161
+ cli_utilities_1.log.debug('Processing webhook import results', this.importConfig.context);
162
+ if ((_a = this.createdWebhooks) === null || _a === void 0 ? void 0 : _a.length) {
163
+ utils_1.fsUtil.writeFile(this.createdWebhooksPath, this.createdWebhooks);
164
+ cli_utilities_1.log.debug(`Written ${this.createdWebhooks.length} successful webhooks to file`, this.importConfig.context);
165
+ }
166
+ if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
167
+ utils_1.fsUtil.writeFile(this.failedWebhooksPath, this.failedWebhooks);
168
+ cli_utilities_1.log.debug(`Written ${this.failedWebhooks.length} failed webhooks to file`, this.importConfig.context);
169
+ }
170
+ }
140
171
  }
141
172
  exports.default = ImportWebhooks;
@@ -39,4 +39,7 @@ export default class ImportWorkflows extends BaseClass {
39
39
  stageIndex: number;
40
40
  roleData: any;
41
41
  }): void;
42
+ private analyzeWorkflows;
43
+ private prepareWorkflowMapper;
44
+ private processWorkflowResults;
42
45
  }
@@ -10,13 +10,14 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
10
10
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
11
11
  const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
12
12
  const findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex"));
13
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
13
14
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
14
15
  const utils_1 = require("../../utils");
15
- const cli_utilities_1 = require("@contentstack/cli-utilities");
16
16
  class ImportWorkflows extends base_class_1.default {
17
17
  constructor({ importConfig, stackAPIClient }) {
18
18
  super({ importConfig, stackAPIClient });
19
- this.importConfig.context.module = 'workflows';
19
+ this.importConfig.context.module = utils_1.MODULE_CONTEXTS.WORKFLOWS;
20
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.WORKFLOWS];
20
21
  this.workflowsConfig = importConfig.modules.workflows;
21
22
  this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'workflows');
22
23
  this.workflowsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.workflowsConfig.dirName);
@@ -34,52 +35,39 @@ class ImportWorkflows extends base_class_1.default {
34
35
  * @returns {Promise<void>} Promise<void>
35
36
  */
36
37
  async start() {
37
- var _a, _b, _c;
38
- cli_utilities_1.log.debug('Checking for workflows folder existence', this.importConfig.context);
39
- //Step1 check folder exists or not
40
- if (utils_1.fileHelper.fileExistsSync(this.workflowsFolderPath)) {
41
- cli_utilities_1.log.debug(`Found workflows folder: ${this.workflowsFolderPath}`, this.importConfig.context);
42
- this.workflows = utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName), true);
43
- const workflowCount = Object.keys(this.workflows || {}).length;
44
- cli_utilities_1.log.debug(`Loaded ${workflowCount} workflow items from file`, this.importConfig.context);
45
- }
46
- else {
47
- cli_utilities_1.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
48
- return;
49
- }
50
- //create workflows in mapper directory
51
- cli_utilities_1.log.debug('Creating workflows mapper directory', this.importConfig.context);
52
- await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
53
- cli_utilities_1.log.debug('Loading existing workflow UID mappings', this.importConfig.context);
54
- this.workflowUidMapper = utils_1.fileHelper.fileExistsSync(this.workflowUidMapperPath)
55
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowUidMapperPath), true)
56
- : {};
57
- if (((_a = Object.keys(this.workflowUidMapper)) === null || _a === void 0 ? void 0 : _a.length) > 0) {
58
- const workflowUidCount = Object.keys(this.workflowUidMapper || {}).length;
59
- cli_utilities_1.log.debug(`Loaded existing workflow UID data: ${workflowUidCount} items`, this.importConfig.context);
60
- }
61
- else {
62
- cli_utilities_1.log.debug('No existing workflow UID mappings found', this.importConfig.context);
63
- }
64
- if (this.workflows === undefined || (0, isEmpty_1.default)(this.workflows)) {
65
- cli_utilities_1.log.info('No Workflow Found', this.importConfig.context);
66
- return;
67
- }
68
- //fetch all roles
69
- cli_utilities_1.log.debug('Fetching all roles for workflow processing', this.importConfig.context);
70
- await this.getRoles();
71
- cli_utilities_1.log.debug('Starting workflow import process', this.importConfig.context);
72
- await this.importWorkflows();
73
- cli_utilities_1.log.debug('Processing workflow import results', this.importConfig.context);
74
- if ((_b = this.createdWorkflows) === null || _b === void 0 ? void 0 : _b.length) {
75
- utils_1.fsUtil.writeFile(this.createdWorkflowsPath, this.createdWorkflows);
76
- cli_utilities_1.log.debug(`Written ${this.createdWorkflows.length} successful workflows to file`, this.importConfig.context);
38
+ try {
39
+ cli_utilities_1.log.debug('Starting workflows import process...', this.importConfig.context);
40
+ const [workflowsCount] = await this.analyzeWorkflows();
41
+ if (workflowsCount === 0) {
42
+ cli_utilities_1.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
43
+ return;
44
+ }
45
+ const progress = this.createNestedProgress(this.currentModuleName);
46
+ progress.addProcess(utils_1.PROCESS_NAMES.GET_ROLES, 1);
47
+ progress.addProcess(utils_1.PROCESS_NAMES.WORKFLOWS_CREATE, workflowsCount);
48
+ await this.prepareWorkflowMapper();
49
+ // Step 1: Fetch and setup roles
50
+ progress
51
+ .startProcess(utils_1.PROCESS_NAMES.GET_ROLES)
52
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.GET_ROLES].FETCHING, utils_1.PROCESS_NAMES.GET_ROLES);
53
+ cli_utilities_1.log.info('Fetching all roles for workflow processing', this.importConfig.context);
54
+ await this.getRoles();
55
+ progress.completeProcess(utils_1.PROCESS_NAMES.GET_ROLES, true);
56
+ // Step 2: Import workflows
57
+ progress
58
+ .startProcess(utils_1.PROCESS_NAMES.WORKFLOWS_CREATE)
59
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.WORKFLOWS_CREATE].IMPORTING, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
60
+ cli_utilities_1.log.info('Starting workflows import process', this.importConfig.context);
61
+ await this.importWorkflows();
62
+ progress.completeProcess(utils_1.PROCESS_NAMES.WORKFLOWS_CREATE, true);
63
+ this.processWorkflowResults();
64
+ this.completeProgress(true);
65
+ cli_utilities_1.log.success('Workflows have been imported successfully!', this.importConfig.context);
77
66
  }
78
- if ((_c = this.failedWebhooks) === null || _c === void 0 ? void 0 : _c.length) {
79
- utils_1.fsUtil.writeFile(this.failedWorkflowsPath, this.failedWebhooks);
80
- cli_utilities_1.log.debug(`Written ${this.failedWebhooks.length} failed workflows to file`, this.importConfig.context);
67
+ catch (error) {
68
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Workflows import failed');
69
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
81
70
  }
82
- cli_utilities_1.log.success('Workflows have been imported successfully!', this.importConfig.context);
83
71
  }
84
72
  async getRoles() {
85
73
  cli_utilities_1.log.debug('Fetching roles from stack', this.importConfig.context);
@@ -119,12 +107,14 @@ class ImportWorkflows extends base_class_1.default {
119
107
  }
120
108
  }
121
109
  const onSuccess = async ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
122
- var _a;
110
+ var _a, _b;
123
111
  cli_utilities_1.log.debug(`Workflow '${name}' imported successfully, processing next available stages`, this.importConfig.context);
124
112
  const oldWorkflowStages = (_a = (0, find_1.default)(oldWorkflows, { uid })) === null || _a === void 0 ? void 0 : _a.workflow_stages;
125
113
  if (!(0, isEmpty_1.default)((0, filter_1.default)(oldWorkflowStages, ({ next_available_stages }) => !(0, isEmpty_1.default)(next_available_stages)))) {
126
114
  cli_utilities_1.log.debug(`Updating next available stages for workflow '${name}'`, this.importConfig.context);
127
115
  let updateRresponse = await this.updateNextAvailableStagesUid(response, response.workflow_stages, oldWorkflowStages).catch((error) => {
116
+ var _a;
117
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `workflow: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to update next available stages', utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
128
118
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Workflow '${name}' update failed`);
129
119
  });
130
120
  if (updateRresponse) {
@@ -134,21 +124,24 @@ class ImportWorkflows extends base_class_1.default {
134
124
  }
135
125
  this.createdWorkflows.push(response);
136
126
  this.workflowUidMapper[uid] = response.uid;
127
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `workflow: ${name || uid}`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
137
128
  cli_utilities_1.log.success(`Workflow '${name}' imported successfully`, this.importConfig.context);
138
129
  cli_utilities_1.log.debug(`Workflow UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
139
130
  utils_1.fsUtil.writeFile(this.workflowUidMapperPath, this.workflowUidMapper);
140
131
  };
141
132
  const onReject = ({ error, apiData }) => {
142
- var _a, _b;
133
+ var _a, _b, _c, _d;
143
134
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
144
135
  const { name, uid } = apiData;
145
136
  cli_utilities_1.log.debug(`Workflow '${name}' (${uid}) failed to import`, this.importConfig.context);
146
137
  const workflowExists = ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) || ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b['workflow.name']);
147
138
  if (workflowExists) {
139
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `workflow: ${name || uid} (already exists)`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
148
140
  cli_utilities_1.log.info(`Workflow '${name}' already exists`, this.importConfig.context);
149
141
  }
150
142
  else {
151
143
  this.failedWebhooks.push(apiData);
144
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(false, `workflow: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to import workflow', utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
152
145
  if (error.errors['workflow_stages.0.users']) {
153
146
  cli_utilities_1.log.error("Failed to import Workflows as you've specified certain roles in the Stage transition and access rules section. We currently don't import roles to the stack.", this.importConfig.context);
154
147
  }
@@ -201,9 +194,13 @@ class ImportWorkflows extends base_class_1.default {
201
194
  * @returns {ApiOptions} ApiOptions
202
195
  */
203
196
  serializeWorkflows(apiOptions) {
197
+ var _a;
204
198
  let { apiData: workflow } = apiOptions;
199
+ cli_utilities_1.log.debug(`Serializing workflow: ${workflow.name} (${workflow.uid})`, this.importConfig.context);
205
200
  if (this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
206
201
  cli_utilities_1.log.info(`Workflow '${workflow.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
202
+ cli_utilities_1.log.debug(`Skipping workflow serialization for: ${workflow.uid}`, this.importConfig.context);
203
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `workflow: ${workflow.name} (skipped - already exists)`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
207
204
  apiOptions.entity = undefined;
208
205
  }
209
206
  else {
@@ -221,6 +218,7 @@ class ImportWorkflows extends base_class_1.default {
221
218
  stage.next_available_stages = ['$all'];
222
219
  }
223
220
  }
221
+ cli_utilities_1.log.debug(`Workflow serialization completed: ${workflow.name}`, this.importConfig.context);
224
222
  apiOptions.apiData = workflow;
225
223
  }
226
224
  return apiOptions;
@@ -231,8 +229,10 @@ class ImportWorkflows extends base_class_1.default {
231
229
  const { name } = apiData;
232
230
  this.updateRoleData({ workflowUid, stageIndex, roleData: apiData });
233
231
  this.roleNameMap[name] = response === null || response === void 0 ? void 0 : response.uid;
232
+ cli_utilities_1.log.debug(`Custom role '${name}' created successfully for workflow`, this.importConfig.context);
234
233
  };
235
234
  const onReject = ({ error, apiData: { name } = { name: '' } }) => {
235
+ cli_utilities_1.log.debug(`Custom role '${name}' creation failed`, this.importConfig.context);
236
236
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Failed to create custom roles '${name}'`);
237
237
  };
238
238
  const workflowStages = workflow.workflow_stages;
@@ -243,6 +243,7 @@ class ImportWorkflows extends base_class_1.default {
243
243
  }
244
244
  if ((_h = (_g = (_f = stage === null || stage === void 0 ? void 0 : stage.SYS_ACL) === null || _f === void 0 ? void 0 : _f.roles) === null || _g === void 0 ? void 0 : _g.uids) === null || _h === void 0 ? void 0 : _h.length) {
245
245
  const apiContent = stage.SYS_ACL.roles.uids;
246
+ cli_utilities_1.log.debug(`Creating ${apiContent.length} custom roles for workflow stage ${stageIndex}`, this.importConfig.context);
246
247
  await this.makeConcurrentCall({
247
248
  apiContent,
248
249
  processName: 'create custom role',
@@ -267,6 +268,7 @@ class ImportWorkflows extends base_class_1.default {
267
268
  */
268
269
  serializeCustomRoles(apiOptions) {
269
270
  let { apiData: roleData, additionalInfo: { workflowUid, stageIndex }, } = apiOptions;
271
+ cli_utilities_1.log.debug(`Serializing custom role: ${roleData.name}`, this.importConfig.context);
270
272
  if (!this.roleNameMap[roleData.name]) {
271
273
  // rules.branch is required to create custom roles.
272
274
  const branchRuleExists = (0, find_1.default)(roleData.rules, (rule) => rule.module === 'branch');
@@ -276,10 +278,12 @@ class ImportWorkflows extends base_class_1.default {
276
278
  branches: ['main'],
277
279
  acl: { read: true },
278
280
  });
281
+ cli_utilities_1.log.debug(`Added branch rule to custom role: ${roleData.name}`, this.importConfig.context);
279
282
  }
280
283
  apiOptions = roleData;
281
284
  }
282
285
  else {
286
+ cli_utilities_1.log.debug(`Custom role '${roleData.name}' already exists, skipping creation`, this.importConfig.context);
283
287
  apiOptions.entity = undefined;
284
288
  this.updateRoleData({ workflowUid, stageIndex, roleData });
285
289
  }
@@ -291,6 +295,52 @@ class ImportWorkflows extends base_class_1.default {
291
295
  const roles = workflowStage[stageIndex].SYS_ACL.roles.uids;
292
296
  const index = (0, findIndex_1.default)(roles, ['uid', roleData.uid]);
293
297
  roles[index >= 0 ? index : roles.length] = this.roleNameMap[roleData.name];
298
+ cli_utilities_1.log.debug(`Updated role data for workflow ${workflowUid}, stage ${stageIndex}`, this.importConfig.context);
299
+ }
300
+ async analyzeWorkflows() {
301
+ return this.withLoadingSpinner('WORKFLOWS: Analyzing import data...', async () => {
302
+ cli_utilities_1.log.debug('Checking for workflows folder existence', this.importConfig.context);
303
+ if (!utils_1.fileHelper.fileExistsSync(this.workflowsFolderPath)) {
304
+ cli_utilities_1.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
305
+ return [0];
306
+ }
307
+ cli_utilities_1.log.debug(`Found workflows folder: ${this.workflowsFolderPath}`, this.importConfig.context);
308
+ this.workflows = utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName), true);
309
+ if (!this.workflows || (0, isEmpty_1.default)(this.workflows)) {
310
+ cli_utilities_1.log.info(`No workflows found in file - '${(0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName)}'`, this.importConfig.context);
311
+ return [0];
312
+ }
313
+ const count = Object.keys(this.workflows || {}).length;
314
+ cli_utilities_1.log.debug(`Loaded ${count} workflow items from file`, this.importConfig.context);
315
+ return [count];
316
+ });
317
+ }
318
+ async prepareWorkflowMapper() {
319
+ cli_utilities_1.log.debug('Creating workflows mapper directory', this.importConfig.context);
320
+ await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
321
+ cli_utilities_1.log.debug('Loading existing workflow UID mappings', this.importConfig.context);
322
+ this.workflowUidMapper = utils_1.fileHelper.fileExistsSync(this.workflowUidMapperPath)
323
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowUidMapperPath), true) || {}
324
+ : {};
325
+ const count = Object.keys(this.workflowUidMapper || {}).length;
326
+ if (count > 0) {
327
+ cli_utilities_1.log.debug(`Loaded existing workflow UID data: ${count} items`, this.importConfig.context);
328
+ }
329
+ else {
330
+ cli_utilities_1.log.debug('No existing workflow UID mappings found', this.importConfig.context);
331
+ }
332
+ }
333
+ processWorkflowResults() {
334
+ var _a, _b;
335
+ cli_utilities_1.log.debug('Processing workflow import results', this.importConfig.context);
336
+ if ((_a = this.createdWorkflows) === null || _a === void 0 ? void 0 : _a.length) {
337
+ utils_1.fsUtil.writeFile(this.createdWorkflowsPath, this.createdWorkflows);
338
+ cli_utilities_1.log.debug(`Written ${this.createdWorkflows.length} successful workflows to file`, this.importConfig.context);
339
+ }
340
+ if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
341
+ utils_1.fsUtil.writeFile(this.failedWorkflowsPath, this.failedWebhooks);
342
+ cli_utilities_1.log.debug(`Written ${this.failedWebhooks.length} failed workflows to file`, this.importConfig.context);
343
+ }
294
344
  }
295
345
  }
296
346
  exports.default = ImportWorkflows;
@@ -183,7 +183,6 @@ export default interface DefaultConfig {
183
183
  getEncryptionKeyMaxRetry: number;
184
184
  createBackupDir?: string;
185
185
  overwriteSupportedModules: string[];
186
- onlyTSModules: string[];
187
186
  auditConfig?: {
188
187
  noLog?: boolean;
189
188
  skipConfirm?: boolean;
@@ -48,7 +48,6 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
48
48
  authtoken?: string;
49
49
  destinationStackName?: string;
50
50
  org_uid?: string;
51
- contentVersion: number;
52
51
  replaceExisting?: boolean;
53
52
  skipExisting?: boolean;
54
53
  skipAudit?: boolean;
@@ -71,17 +71,6 @@ export interface TaxonomiesConfig {
71
71
  fileName: string;
72
72
  dependencies?: Modules[];
73
73
  }
74
- export interface Context {
75
- command: string;
76
- module: string;
77
- userId: string | undefined;
78
- email: string | undefined;
79
- sessionId: string | undefined;
80
- clientId?: string | undefined;
81
- apiKey: string;
82
- orgId: string;
83
- authenticationMethod?: string;
84
- }
85
74
  export { default as DefaultConfig } from './default-config';
86
75
  export { default as ImportConfig } from './import-config';
87
76
  export * from './entries';
@@ -95,7 +84,7 @@ export interface Context {
95
84
  command: string;
96
85
  module: string;
97
86
  userId: string | undefined;
98
- email: string | undefined;
87
+ email?: string | undefined;
99
88
  sessionId: string | undefined;
100
89
  clientId?: string | undefined;
101
90
  apiKey: string;