@contentstack/cli-cm-import 1.25.0 → 1.26.0

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 (38) hide show
  1. package/README.md +3 -3
  2. package/lib/commands/cm/stacks/import.d.ts +1 -0
  3. package/lib/commands/cm/stacks/import.js +33 -12
  4. package/lib/import/module-importer.js +1 -1
  5. package/lib/import/modules/assets.d.ts +1 -1
  6. package/lib/import/modules/assets.js +93 -39
  7. package/lib/import/modules/base-class.js +11 -3
  8. package/lib/import/modules/content-types.js +79 -28
  9. package/lib/import/modules/custom-roles.js +95 -19
  10. package/lib/import/modules/entries.js +128 -57
  11. package/lib/import/modules/environments.js +48 -14
  12. package/lib/import/modules/extensions.js +78 -16
  13. package/lib/import/modules/global-fields.js +86 -19
  14. package/lib/import/modules/labels.d.ts +4 -4
  15. package/lib/import/modules/labels.js +60 -18
  16. package/lib/import/modules/locales.js +63 -20
  17. package/lib/import/modules/marketplace-apps.js +160 -31
  18. package/lib/import/modules/personalize.js +33 -7
  19. package/lib/import/modules/stack.js +5 -0
  20. package/lib/import/modules/taxonomies.js +52 -13
  21. package/lib/import/modules/variant-entries.js +21 -3
  22. package/lib/import/modules/webhooks.js +44 -12
  23. package/lib/import/modules/workflows.js +65 -21
  24. package/lib/types/import-config.d.ts +3 -1
  25. package/lib/types/index.d.ts +22 -0
  26. package/lib/utils/asset-helper.js +24 -1
  27. package/lib/utils/backup-handler.js +15 -1
  28. package/lib/utils/common-helper.js +41 -16
  29. package/lib/utils/content-type-helper.js +35 -2
  30. package/lib/utils/entries-helper.js +24 -2
  31. package/lib/utils/extension-helper.js +35 -1
  32. package/lib/utils/global-field-helper.js +1 -1
  33. package/lib/utils/import-config-handler.js +21 -0
  34. package/lib/utils/login-handler.js +8 -4
  35. package/lib/utils/marketplace-app-helper.js +50 -11
  36. package/lib/utils/taxonomies-helper.js +22 -4
  37. package/oclif.manifest.json +2 -2
  38. package/package.json +5 -5
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
4
4
  const node_path_1 = require("node:path");
5
5
  const values_1 = tslib_1.__importDefault(require("lodash/values"));
6
6
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
7
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
8
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
8
9
  const utils_1 = require("../../utils");
9
10
  class ImportTaxonomies extends base_class_1.default {
@@ -13,6 +14,7 @@ class ImportTaxonomies extends base_class_1.default {
13
14
  this.failedTaxonomies = {};
14
15
  this.createdTerms = {};
15
16
  this.failedTerms = {};
17
+ this.importConfig.context.module = 'taxonomies';
16
18
  this.taxonomiesConfig = importConfig.modules.taxonomies;
17
19
  this.taxonomiesMapperDirPath = (0, node_path_1.join)(importConfig.backupDir, 'mapper', 'taxonomies');
18
20
  this.termsMapperDirPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'terms');
@@ -27,23 +29,30 @@ class ImportTaxonomies extends base_class_1.default {
27
29
  * @returns {Promise<void>} Promise<void>
28
30
  */
29
31
  async start() {
30
- (0, utils_1.log)(this.importConfig, 'Migrating taxonomies...', 'info');
32
+ cli_utilities_1.log.debug('Checking for taxonomies folder existence', this.importConfig.context);
31
33
  //Step1 check folder exists or not
32
34
  if (utils_1.fileHelper.fileExistsSync(this.taxonomiesFolderPath)) {
35
+ cli_utilities_1.log.debug(`Found taxonomies folder: ${this.taxonomiesFolderPath}`, this.importConfig.context);
33
36
  this.taxonomies = utils_1.fsUtil.readFile((0, node_path_1.join)(this.taxonomiesFolderPath, 'taxonomies.json'), true);
37
+ const taxonomyCount = Object.keys(this.taxonomies || {}).length;
38
+ cli_utilities_1.log.debug(`Loaded ${taxonomyCount} taxonomy items from file`, this.importConfig.context);
34
39
  }
35
40
  else {
36
- (0, utils_1.log)(this.importConfig, `No Taxonomies Found! - '${this.taxonomiesFolderPath}'`, 'info');
41
+ cli_utilities_1.log.info(`No Taxonomies Found! - '${this.taxonomiesFolderPath}'`, this.importConfig.context);
37
42
  return;
38
43
  }
39
44
  //Step 2 create taxonomies & terms mapper directory
45
+ cli_utilities_1.log.debug('Creating mapper directories', this.importConfig.context);
40
46
  await utils_1.fsUtil.makeDirectory(this.taxonomiesMapperDirPath);
41
47
  await utils_1.fsUtil.makeDirectory(this.termsMapperDirPath);
48
+ cli_utilities_1.log.debug('Created taxonomies and terms mapper directories', this.importConfig.context);
42
49
  // Step 3 import taxonomies
50
+ cli_utilities_1.log.debug('Starting taxonomies import', this.importConfig.context);
43
51
  await this.importTaxonomies();
44
52
  //Step 4 create taxonomy & related terms success & failure file
53
+ cli_utilities_1.log.debug('Creating success and failure files', this.importConfig.context);
45
54
  this.createSuccessAndFailedFile();
46
- (0, utils_1.log)(this.importConfig, 'Taxonomies imported successfully!', 'success');
55
+ cli_utilities_1.log.success('Taxonomies imported successfully!', this.importConfig.context);
47
56
  }
48
57
  /**
49
58
  * create taxonomy and enter success & failure related data into taxonomies mapper file
@@ -52,38 +61,49 @@ class ImportTaxonomies extends base_class_1.default {
52
61
  * @returns {Promise<any>} Promise<any>
53
62
  */
54
63
  async importTaxonomies() {
64
+ cli_utilities_1.log.debug('Validating taxonomies data', this.importConfig.context);
55
65
  if (this.taxonomies === undefined || (0, isEmpty_1.default)(this.taxonomies)) {
56
- (0, utils_1.log)(this.importConfig, 'No Taxonomies Found!', 'info');
66
+ cli_utilities_1.log.info('No Taxonomies Found!', this.importConfig.context);
57
67
  return;
58
68
  }
59
69
  const apiContent = (0, values_1.default)(this.taxonomies);
70
+ cli_utilities_1.log.debug(`Starting to import ${apiContent.length} taxonomies`, this.importConfig.context);
60
71
  const onSuccess = ({ apiData }) => {
61
- var _a;
72
+ var _a, _b;
62
73
  const taxonomyUID = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _a === void 0 ? void 0 : _a.uid;
74
+ const taxonomyName = (_b = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _b === void 0 ? void 0 : _b.name;
75
+ const termsCount = Object.keys((apiData === null || apiData === void 0 ? void 0 : apiData.terms) || {}).length;
63
76
  this.createdTaxonomies[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy;
64
77
  this.createdTerms[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.terms;
65
- (0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' imported successfully!`, 'success');
78
+ cli_utilities_1.log.success(`Taxonomy '${taxonomyUID}' imported successfully!`, this.importConfig.context);
79
+ cli_utilities_1.log.debug(`Created taxonomy '${taxonomyName}' with ${termsCount} terms`, this.importConfig.context);
80
+ cli_utilities_1.log.debug(`Taxonomy details: ${JSON.stringify({ uid: taxonomyUID, name: taxonomyName, termsCount })}`, this.importConfig.context);
66
81
  };
67
82
  const onReject = ({ error, apiData }) => {
68
- var _a, _b, _c;
83
+ var _a, _b, _c, _d;
69
84
  const taxonomyUID = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _a === void 0 ? void 0 : _a.uid;
85
+ const taxonomyName = (_b = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _b === void 0 ? void 0 : _b.name;
86
+ cli_utilities_1.log.debug(`Taxonomy '${taxonomyUID}' failed to import`, this.importConfig.context);
70
87
  if ((error === null || error === void 0 ? void 0 : error.status) === 409 && (error === null || error === void 0 ? void 0 : error.statusText) === 'Conflict') {
71
- (0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' already exists!`, 'info');
88
+ cli_utilities_1.log.info(`Taxonomy '${taxonomyUID}' already exists!`, this.importConfig.context);
89
+ cli_utilities_1.log.debug(`Adding existing taxonomy '${taxonomyUID}' to created list`, this.importConfig.context);
72
90
  this.createdTaxonomies[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy;
73
91
  this.createdTerms[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.terms;
74
92
  }
75
93
  else {
94
+ cli_utilities_1.log.debug(`Adding taxonomy '${taxonomyUID}' to failed list`, this.importConfig.context);
76
95
  if ((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message)) {
77
- const errorMsg = (error === null || error === void 0 ? void 0 : error.errorMessage) || ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.taxonomy) || ((_c = error === null || error === void 0 ? void 0 : error.errors) === null || _c === void 0 ? void 0 : _c.term) || (error === null || error === void 0 ? void 0 : error.message);
78
- (0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' failed to be import! ${errorMsg}`, 'error');
96
+ const errorMsg = (error === null || error === void 0 ? void 0 : error.errorMessage) || ((_c = error === null || error === void 0 ? void 0 : error.errors) === null || _c === void 0 ? void 0 : _c.taxonomy) || ((_d = error === null || error === void 0 ? void 0 : error.errors) === null || _d === void 0 ? void 0 : _d.term) || (error === null || error === void 0 ? void 0 : error.message);
97
+ cli_utilities_1.log.error(`Taxonomy '${taxonomyUID}' failed to be import! ${errorMsg}`, this.importConfig.context);
79
98
  }
80
99
  else {
81
- (0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
100
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { taxonomyUID }), `Taxonomy '${taxonomyUID}' failed to import`);
82
101
  }
83
102
  this.failedTaxonomies[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy;
84
103
  this.failedTerms[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.terms;
85
104
  }
86
105
  };
106
+ cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
87
107
  await this.makeConcurrentCall({
88
108
  apiContent,
89
109
  processName: 'import taxonomies',
@@ -96,6 +116,7 @@ class ImportTaxonomies extends base_class_1.default {
96
116
  },
97
117
  concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
98
118
  }, undefined, false);
119
+ cli_utilities_1.log.debug('Taxonomies import process completed', this.importConfig.context);
99
120
  }
100
121
  /**
101
122
  * @method serializeTaxonomy
@@ -104,13 +125,19 @@ class ImportTaxonomies extends base_class_1.default {
104
125
  */
105
126
  serializeTaxonomy(apiOptions) {
106
127
  const { apiData } = apiOptions;
107
- const filePath = (0, node_path_1.join)(this.taxonomiesFolderPath, `${apiData === null || apiData === void 0 ? void 0 : apiData.uid}.json`);
128
+ const taxonomyUID = apiData === null || apiData === void 0 ? void 0 : apiData.uid;
129
+ const filePath = (0, node_path_1.join)(this.taxonomiesFolderPath, `${taxonomyUID}.json`);
130
+ cli_utilities_1.log.debug(`Serializing taxonomy: ${taxonomyUID}`, this.importConfig.context);
131
+ cli_utilities_1.log.debug(`Looking for taxonomy file: ${filePath}`, this.importConfig.context);
108
132
  if (utils_1.fileHelper.fileExistsSync(filePath)) {
109
133
  const taxonomyDetails = utils_1.fsUtil.readFile(filePath, true);
134
+ cli_utilities_1.log.debug(`Successfully loaded taxonomy details from ${filePath}`, this.importConfig.context);
135
+ const termCount = Object.keys((taxonomyDetails === null || taxonomyDetails === void 0 ? void 0 : taxonomyDetails.terms) || {}).length;
136
+ cli_utilities_1.log.debug(`Taxonomy has ${termCount} term entries`, this.importConfig.context);
110
137
  apiOptions.apiData = { filePath, taxonomy: taxonomyDetails === null || taxonomyDetails === void 0 ? void 0 : taxonomyDetails.taxonomy, terms: taxonomyDetails === null || taxonomyDetails === void 0 ? void 0 : taxonomyDetails.terms };
111
138
  }
112
139
  else {
113
- (0, utils_1.log)(this.importConfig, `No such file - ${filePath}`, 'error');
140
+ cli_utilities_1.log.debug(`File does not exist for taxonomy: ${taxonomyUID}`, this.importConfig.context);
114
141
  apiOptions.apiData = undefined;
115
142
  }
116
143
  return apiOptions;
@@ -121,17 +148,29 @@ class ImportTaxonomies extends base_class_1.default {
121
148
  * @method createSuccessAndFailedFile
122
149
  */
123
150
  createSuccessAndFailedFile() {
151
+ var _a, _b, _c, _d;
152
+ cli_utilities_1.log.debug('Creating success and failed files for taxonomies and terms', this.importConfig.context);
153
+ const createdTaxCount = (_a = Object.keys(this.createdTaxonomies)) === null || _a === void 0 ? void 0 : _a.length;
154
+ const failedTaxCount = (_b = Object.keys(this.failedTaxonomies)) === null || _b === void 0 ? void 0 : _b.length;
155
+ const createdTermsCount = (_c = Object.keys(this.createdTerms)) === null || _c === void 0 ? void 0 : _c.length;
156
+ const failedTermsCount = (_d = Object.keys(this.failedTerms)) === null || _d === void 0 ? void 0 : _d.length;
157
+ cli_utilities_1.log.debug(`Summary - Created taxonomies: ${createdTaxCount}, Failed taxonomies: ${failedTaxCount}`, this.importConfig.context);
158
+ cli_utilities_1.log.debug(`Summary - Created terms: ${createdTermsCount}, Failed terms: ${failedTermsCount}`, this.importConfig.context);
124
159
  if (this.createdTaxonomies !== undefined && !(0, isEmpty_1.default)(this.createdTaxonomies)) {
125
160
  utils_1.fsUtil.writeFile(this.taxSuccessPath, this.createdTaxonomies);
161
+ cli_utilities_1.log.debug(`Written ${createdTaxCount} successful taxonomies to file: ${this.taxSuccessPath}`, this.importConfig.context);
126
162
  }
127
163
  if (this.failedTaxonomies !== undefined && !(0, isEmpty_1.default)(this.failedTaxonomies)) {
128
164
  utils_1.fsUtil.writeFile(this.taxFailsPath, this.failedTaxonomies);
165
+ cli_utilities_1.log.debug(`Written ${failedTaxCount} failed taxonomies to file: ${this.taxFailsPath}`, this.importConfig.context);
129
166
  }
130
167
  if (this.createdTerms !== undefined && !(0, isEmpty_1.default)(this.createdTerms)) {
131
168
  utils_1.fsUtil.writeFile(this.termsSuccessPath, this.createdTerms);
169
+ cli_utilities_1.log.debug(`Written successful terms for ${createdTermsCount} taxonomies to file: ${this.termsSuccessPath}`, this.importConfig.context);
132
170
  }
133
171
  if (this.failedTerms !== undefined && !(0, isEmpty_1.default)(this.failedTerms)) {
134
172
  utils_1.fsUtil.writeFile(this.termsFailsPath, this.failedTerms);
173
+ cli_utilities_1.log.debug(`Written failed terms for ${failedTermsCount} taxonomies to file: ${this.termsFailsPath}`, this.importConfig.context);
135
174
  }
136
175
  }
137
176
  }
@@ -8,6 +8,7 @@ const utils_1 = require("../../utils");
8
8
  class ImportVarientEntries {
9
9
  constructor({ importConfig }) {
10
10
  this.config = importConfig;
11
+ this.config.context.module = 'variant-entries';
11
12
  this.personalize = importConfig.modules.personalize;
12
13
  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');
13
14
  }
@@ -17,9 +18,18 @@ class ImportVarientEntries {
17
18
  */
18
19
  async start() {
19
20
  try {
21
+ cli_utilities_1.log.debug(`Reading project mapper from: ${this.projectMapperFilePath}`, this.config.context);
22
+ if (!utils_1.fileHelper.fileExistsSync(this.projectMapperFilePath)) {
23
+ cli_utilities_1.log.debug('Project mapper file does not exist', this.config.context);
24
+ cli_utilities_1.log.info('Skipping entry variants import because no personalize project mapper found.', this.config.context);
25
+ return;
26
+ }
20
27
  const project = utils_1.fsUtil.readFile(this.projectMapperFilePath);
28
+ cli_utilities_1.log.debug(`Project data loaded: ${JSON.stringify(project)}`, this.config.context);
21
29
  if (project && project.uid) {
30
+ cli_utilities_1.log.debug(`Found personalize project: ${project.uid}`, this.config.context);
22
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);
23
33
  const helpers = {
24
34
  lookUpTerms: utils_1.lookUpTerms,
25
35
  lookupAssets: utils_1.lookupAssets,
@@ -27,14 +37,22 @@ class ImportVarientEntries {
27
37
  lookupExtension: utils_1.lookupExtension,
28
38
  restoreJsonRteEntryRefs: utils_1.restoreJsonRteEntryRefs,
29
39
  };
30
- await new cli_variants_1.Import.VariantEntries(Object.assign(this.config, { helpers })).import();
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);
31
48
  }
32
49
  else {
33
- (0, utils_1.log)(this.config, 'Skipping entry variants import because no personalize project is linked.', 'info');
50
+ 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);
34
52
  }
35
53
  }
36
54
  catch (error) {
37
- (0, utils_1.log)(this.config, error, 'error');
55
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.config.context));
38
56
  }
39
57
  }
40
58
  }
@@ -4,11 +4,13 @@ const tslib_1 = require("tslib");
4
4
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
5
  const values_1 = tslib_1.__importDefault(require("lodash/values"));
6
6
  const node_path_1 = require("node:path");
7
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
8
  const utils_1 = require("../../utils");
8
9
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
9
10
  class ImportWebhooks extends base_class_1.default {
10
11
  constructor({ importConfig, stackAPIClient }) {
11
12
  super({ importConfig, stackAPIClient });
13
+ this.importConfig.context.module = 'webhooks';
12
14
  this.webhooksConfig = importConfig.modules.webhooks;
13
15
  this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'webhooks');
14
16
  this.webhooksFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.webhooksConfig.dirName);
@@ -25,54 +27,76 @@ class ImportWebhooks extends base_class_1.default {
25
27
  * @returns {Promise<void>} Promise<void>
26
28
  */
27
29
  async start() {
28
- var _a, _b;
29
- (0, utils_1.log)(this.importConfig, 'Migrating webhooks', 'info');
30
+ var _a, _b, _c;
31
+ cli_utilities_1.log.debug('Checking for webhooks folder existence', this.importConfig.context);
30
32
  //Step1 check folder exists or not
31
33
  if (utils_1.fileHelper.fileExistsSync(this.webhooksFolderPath)) {
32
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);
33
38
  }
34
39
  else {
35
- (0, utils_1.log)(this.importConfig, `No Webhooks Found - '${this.webhooksFolderPath}'`, 'info');
40
+ cli_utilities_1.log.info(`No Webhooks Found - '${this.webhooksFolderPath}'`, this.importConfig.context);
36
41
  return;
37
42
  }
38
43
  //create webhooks in mapper directory
44
+ cli_utilities_1.log.debug('Creating webhooks mapper directory', this.importConfig.context);
39
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);
40
48
  this.webhookUidMapper = utils_1.fileHelper.fileExistsSync(this.webhookUidMapperPath)
41
49
  ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhookUidMapperPath), true)
42
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);
43
59
  await this.importWebhooks();
44
- if ((_a = this.createdWebhooks) === null || _a === void 0 ? void 0 : _a.length) {
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) {
45
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);
46
64
  }
47
- if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
65
+ if ((_c = this.failedWebhooks) === null || _c === void 0 ? void 0 : _c.length) {
48
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);
49
68
  }
50
- (0, utils_1.log)(this.importConfig, 'Webhooks have been imported successfully!', 'success');
69
+ cli_utilities_1.log.success('Webhooks have been imported successfully!', this.importConfig.context);
51
70
  }
52
71
  async importWebhooks() {
72
+ cli_utilities_1.log.debug('Validating webhooks data', this.importConfig.context);
53
73
  if (this.webhooks === undefined || (0, isEmpty_1.default)(this.webhooks)) {
54
- (0, utils_1.log)(this.importConfig, 'No Webhook Found', 'info');
74
+ cli_utilities_1.log.info('No Webhook Found', this.importConfig.context);
55
75
  return;
56
76
  }
57
77
  const apiContent = (0, values_1.default)(this.webhooks);
78
+ cli_utilities_1.log.debug(`Starting to import ${apiContent.length} webhooks`, this.importConfig.context);
58
79
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
59
80
  this.createdWebhooks.push(response);
60
81
  this.webhookUidMapper[uid] = response.uid;
61
- (0, utils_1.log)(this.importConfig, `Webhook '${name}' imported successfully`, 'success');
82
+ cli_utilities_1.log.success(`Webhook '${name}' imported successfully`, this.importConfig.context);
83
+ cli_utilities_1.log.debug(`Webhook UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
62
84
  utils_1.fsUtil.writeFile(this.webhookUidMapperPath, this.webhookUidMapper);
63
85
  };
64
86
  const onReject = ({ error, apiData }) => {
65
87
  var _a;
66
88
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
67
- const { name } = apiData;
89
+ const { name, uid } = apiData;
90
+ cli_utilities_1.log.debug(`Webhook '${name}' (${uid}) failed to import`, this.importConfig.context);
68
91
  if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
69
- (0, utils_1.log)(this.importConfig, `Webhook '${name}' already exists`, 'info');
92
+ cli_utilities_1.log.info(`Webhook '${name}' already exists`, this.importConfig.context);
70
93
  }
71
94
  else {
72
95
  this.failedWebhooks.push(apiData);
73
- (0, utils_1.log)(this.importConfig, `Webhook '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
96
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { webhookName: name }), `Webhook '${name}' failed to import`);
74
97
  }
75
98
  };
99
+ cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
76
100
  await this.makeConcurrentCall({
77
101
  apiContent,
78
102
  processName: 'create webhooks',
@@ -85,6 +109,7 @@ class ImportWebhooks extends base_class_1.default {
85
109
  },
86
110
  concurrencyLimit: this.importConfig.fetchConcurrency || 1,
87
111
  }, undefined, false);
112
+ cli_utilities_1.log.debug('Webhook import process completed', this.importConfig.context);
88
113
  }
89
114
  /**
90
115
  * @method serializeWebhooks
@@ -93,13 +118,20 @@ class ImportWebhooks extends base_class_1.default {
93
118
  */
94
119
  serializeWebhooks(apiOptions) {
95
120
  const { apiData: webhook } = apiOptions;
121
+ cli_utilities_1.log.debug(`Serializing webhook: ${webhook.name} (${webhook.uid})`, this.importConfig.context);
96
122
  if (this.webhookUidMapper.hasOwnProperty(webhook.uid)) {
97
- (0, utils_1.log)(this.importConfig, `Webhook '${webhook.name}' already exists. Skipping it to avoid duplicates!`, 'info');
123
+ cli_utilities_1.log.info(`Webhook '${webhook.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
124
+ cli_utilities_1.log.debug(`Skipping webhook serialization for: ${webhook.uid}`, this.importConfig.context);
98
125
  apiOptions.entity = undefined;
99
126
  }
100
127
  else {
128
+ cli_utilities_1.log.debug(`Processing webhook status configuration`, this.importConfig.context);
101
129
  if (this.importConfig.importWebhookStatus === 'disable' || this.importConfig.importWebhookStatus !== 'current') {
102
130
  webhook.disabled = true;
131
+ cli_utilities_1.log.debug(`Webhook '${webhook.name}' will be imported as disabled`, this.importConfig.context);
132
+ }
133
+ else {
134
+ cli_utilities_1.log.debug(`Webhook '${webhook.name}' will be imported with current status`, this.importConfig.context);
103
135
  }
104
136
  apiOptions.apiData = webhook;
105
137
  }
@@ -12,9 +12,11 @@ const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
12
12
  const findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex"));
13
13
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
14
14
  const utils_1 = require("../../utils");
15
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
15
16
  class ImportWorkflows extends base_class_1.default {
16
17
  constructor({ importConfig, stackAPIClient }) {
17
18
  super({ importConfig, stackAPIClient });
19
+ this.importConfig.context.module = 'workflows';
18
20
  this.workflowsConfig = importConfig.modules.workflows;
19
21
  this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'workflows');
20
22
  this.workflowsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.workflowsConfig.dirName);
@@ -32,89 +34,130 @@ class ImportWorkflows extends base_class_1.default {
32
34
  * @returns {Promise<void>} Promise<void>
33
35
  */
34
36
  async start() {
35
- var _a, _b;
36
- (0, utils_1.log)(this.importConfig, 'Migrating workflows', 'info');
37
+ var _a, _b, _c;
38
+ cli_utilities_1.log.debug('Checking for workflows folder existence', this.importConfig.context);
37
39
  //Step1 check folder exists or not
38
40
  if (utils_1.fileHelper.fileExistsSync(this.workflowsFolderPath)) {
41
+ cli_utilities_1.log.debug(`Found workflows folder: ${this.workflowsFolderPath}`, this.importConfig.context);
39
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);
40
45
  }
41
46
  else {
42
- (0, utils_1.log)(this.importConfig, `No Workflows Found - '${this.workflowsFolderPath}'`, 'info');
47
+ cli_utilities_1.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
43
48
  return;
44
49
  }
45
50
  //create workflows in mapper directory
51
+ cli_utilities_1.log.debug('Creating workflows mapper directory', this.importConfig.context);
46
52
  await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
53
+ cli_utilities_1.log.debug('Loading existing workflow UID mappings', this.importConfig.context);
47
54
  this.workflowUidMapper = utils_1.fileHelper.fileExistsSync(this.workflowUidMapperPath)
48
55
  ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowUidMapperPath), true)
49
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
+ }
50
64
  if (this.workflows === undefined || (0, isEmpty_1.default)(this.workflows)) {
51
- (0, utils_1.log)(this.importConfig, 'No Workflow Found', 'info');
65
+ cli_utilities_1.log.info('No Workflow Found', this.importConfig.context);
52
66
  return;
53
67
  }
54
68
  //fetch all roles
69
+ cli_utilities_1.log.debug('Fetching all roles for workflow processing', this.importConfig.context);
55
70
  await this.getRoles();
71
+ cli_utilities_1.log.debug('Starting workflow import process', this.importConfig.context);
56
72
  await this.importWorkflows();
57
- if ((_a = this.createdWorkflows) === null || _a === void 0 ? void 0 : _a.length) {
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) {
58
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);
59
77
  }
60
- if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
78
+ if ((_c = this.failedWebhooks) === null || _c === void 0 ? void 0 : _c.length) {
61
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);
62
81
  }
63
- (0, utils_1.log)(this.importConfig, 'Workflows have been imported successfully!', 'success');
82
+ cli_utilities_1.log.success('Workflows have been imported successfully!', this.importConfig.context);
64
83
  }
65
84
  async getRoles() {
85
+ cli_utilities_1.log.debug('Fetching roles from stack', this.importConfig.context);
66
86
  const roles = await this.stack
67
87
  .role()
68
88
  .fetchAll()
69
- .then((data) => data)
70
- .catch((err) => (0, utils_1.log)(this.importConfig, `Failed to fetch roles. ${(0, utils_1.formatError)(err)}`, 'error'));
89
+ .then((data) => {
90
+ var _a;
91
+ cli_utilities_1.log.debug(`Successfully fetched ${((_a = data === null || data === void 0 ? void 0 : data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} roles`, this.importConfig.context);
92
+ return data;
93
+ })
94
+ .catch((err) => {
95
+ cli_utilities_1.log.debug('Error fetching roles', this.importConfig.context);
96
+ (0, cli_utilities_1.handleAndLogError)(err, Object.assign({}, this.importConfig.context));
97
+ });
71
98
  for (const role of (roles === null || roles === void 0 ? void 0 : roles.items) || []) {
72
99
  this.roleNameMap[role.name] = role.uid;
100
+ cli_utilities_1.log.debug(`Role mapping: ${role.name} → ${role.uid}`, this.importConfig.context);
73
101
  }
102
+ const roleCount = Object.keys(this.roleNameMap || {}).length;
103
+ cli_utilities_1.log.debug(`Created role name data for ${roleCount} roles`, this.importConfig.context);
74
104
  }
75
105
  async importWorkflows() {
106
+ cli_utilities_1.log.debug('Validating workflows data', this.importConfig.context);
76
107
  const apiContent = (0, values_1.default)(this.workflows);
77
108
  const oldWorkflows = (0, cloneDeep_1.default)((0, values_1.default)(this.workflows));
109
+ cli_utilities_1.log.debug(`Starting to import ${apiContent.length} workflows`, this.importConfig.context);
78
110
  //check and create custom roles if not exists
111
+ cli_utilities_1.log.debug('Checking and creating custom roles if needed', this.importConfig.context);
79
112
  for (const workflow of (0, values_1.default)(this.workflows)) {
80
113
  if (!this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
114
+ cli_utilities_1.log.debug(`Processing custom roles for workflow: ${workflow.name}`, this.importConfig.context);
81
115
  await this.createCustomRoleIfNotExists(workflow);
82
116
  }
117
+ else {
118
+ cli_utilities_1.log.debug(`Workflow ${workflow.name} already exists, skipping custom role creation`, this.importConfig.context);
119
+ }
83
120
  }
84
121
  const onSuccess = async ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
85
122
  var _a;
123
+ cli_utilities_1.log.debug(`Workflow '${name}' imported successfully, processing next available stages`, this.importConfig.context);
86
124
  const oldWorkflowStages = (_a = (0, find_1.default)(oldWorkflows, { uid })) === null || _a === void 0 ? void 0 : _a.workflow_stages;
87
125
  if (!(0, isEmpty_1.default)((0, filter_1.default)(oldWorkflowStages, ({ next_available_stages }) => !(0, isEmpty_1.default)(next_available_stages)))) {
126
+ cli_utilities_1.log.debug(`Updating next available stages for workflow '${name}'`, this.importConfig.context);
88
127
  let updateRresponse = await this.updateNextAvailableStagesUid(response, response.workflow_stages, oldWorkflowStages).catch((error) => {
89
- (0, utils_1.log)(this.importConfig, `Workflow '${name}' update failed.`, 'error');
90
- (0, utils_1.log)(this.importConfig, error, 'error');
128
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Workflow '${name}' update failed`);
91
129
  });
92
- if (updateRresponse)
130
+ if (updateRresponse) {
93
131
  response = updateRresponse;
132
+ cli_utilities_1.log.debug(`Successfully updated next available stages for workflow '${name}'`, this.importConfig.context);
133
+ }
94
134
  }
95
135
  this.createdWorkflows.push(response);
96
136
  this.workflowUidMapper[uid] = response.uid;
97
- (0, utils_1.log)(this.importConfig, `Workflow '${name}' imported successfully`, 'success');
137
+ cli_utilities_1.log.success(`Workflow '${name}' imported successfully`, this.importConfig.context);
138
+ cli_utilities_1.log.debug(`Workflow UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
98
139
  utils_1.fsUtil.writeFile(this.workflowUidMapperPath, this.workflowUidMapper);
99
140
  };
100
141
  const onReject = ({ error, apiData }) => {
101
142
  var _a, _b;
102
143
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
103
- const { name } = apiData;
144
+ const { name, uid } = apiData;
145
+ cli_utilities_1.log.debug(`Workflow '${name}' (${uid}) failed to import`, this.importConfig.context);
104
146
  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']);
105
147
  if (workflowExists) {
106
- (0, utils_1.log)(this.importConfig, `Workflow '${name}' already exists`, 'info');
148
+ cli_utilities_1.log.info(`Workflow '${name}' already exists`, this.importConfig.context);
107
149
  }
108
150
  else {
109
151
  this.failedWebhooks.push(apiData);
110
152
  if (error.errors['workflow_stages.0.users']) {
111
- (0, utils_1.log)(this.importConfig, "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.", 'error');
153
+ 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);
112
154
  }
113
155
  else {
114
- (0, utils_1.log)(this.importConfig, `Workflow '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
156
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Workflow '${name}' failed to be import`);
115
157
  }
116
158
  }
117
159
  };
160
+ cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
118
161
  await this.makeConcurrentCall({
119
162
  apiContent,
120
163
  processName: 'create workflows',
@@ -127,6 +170,7 @@ class ImportWorkflows extends base_class_1.default {
127
170
  },
128
171
  concurrencyLimit: this.importConfig.fetchConcurrency || 1,
129
172
  }, undefined, false);
173
+ cli_utilities_1.log.debug('Workflows import process completed', this.importConfig.context);
130
174
  }
131
175
  updateNextAvailableStagesUid(workflow, newWorkflowStages, oldWorkflowStages) {
132
176
  newWorkflowStages = (0, map_1.default)(newWorkflowStages, (newStage, index) => {
@@ -147,7 +191,7 @@ class ImportWorkflows extends base_class_1.default {
147
191
  name: workflow.name,
148
192
  branches: workflow.branches,
149
193
  workflow_stages: newWorkflowStages,
150
- content_types: workflow.content_types
194
+ content_types: workflow.content_types,
151
195
  });
152
196
  return updateWorkflow.update();
153
197
  }
@@ -159,12 +203,12 @@ class ImportWorkflows extends base_class_1.default {
159
203
  serializeWorkflows(apiOptions) {
160
204
  let { apiData: workflow } = apiOptions;
161
205
  if (this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
162
- (0, utils_1.log)(this.importConfig, `Workflow '${workflow.name}' already exists. Skipping it to avoid duplicates!`, 'info');
206
+ cli_utilities_1.log.info(`Workflow '${workflow.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
163
207
  apiOptions.entity = undefined;
164
208
  }
165
209
  else {
166
210
  if (workflow.admin_users !== undefined) {
167
- (0, utils_1.log)(this.importConfig, chalk_1.default.yellow('We are skipping import of `Workflow superuser(s)` from workflow'), 'info');
211
+ cli_utilities_1.log.info(chalk_1.default.yellow('We are skipping import of `Workflow superuser(s)` from workflow'), this.importConfig.context);
168
212
  delete workflow.admin_users;
169
213
  }
170
214
  // One branch is required to create workflow.
@@ -189,7 +233,7 @@ class ImportWorkflows extends base_class_1.default {
189
233
  this.roleNameMap[name] = response === null || response === void 0 ? void 0 : response.uid;
190
234
  };
191
235
  const onReject = ({ error, apiData: { name } = { name: '' } }) => {
192
- (0, utils_1.log)(this.importConfig, `Failed to create custom roles '${name}'.${(0, utils_1.formatError)(error)}`, 'error');
236
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Failed to create custom roles '${name}'`);
193
237
  };
194
238
  const workflowStages = workflow.workflow_stages;
195
239
  let stageIndex = 0;
@@ -1,4 +1,4 @@
1
- import { Modules, Region } from '.';
1
+ import { Context, Modules, Region } from '.';
2
2
  import DefaultConfig from './default-config';
3
3
  export interface ExternalConfig {
4
4
  source_stack?: string;
@@ -9,6 +9,7 @@ export interface ExternalConfig {
9
9
  password?: string;
10
10
  }
11
11
  export default interface ImportConfig extends DefaultConfig, ExternalConfig {
12
+ authenticationMethod?: string;
12
13
  skipAssetsPublish?: boolean;
13
14
  skipEntriesPublish?: boolean;
14
15
  cliLogsPath: string;
@@ -54,6 +55,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
54
55
  region: Region;
55
56
  personalizeProjectName?: string;
56
57
  'exclude-global-modules': false;
58
+ context: Context;
57
59
  }
58
60
  type branch = {
59
61
  uid: string;
@@ -71,6 +71,17 @@ 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
+ }
74
85
  export { default as DefaultConfig } from './default-config';
75
86
  export { default as ImportConfig } from './import-config';
76
87
  export * from './entries';
@@ -80,3 +91,14 @@ export type ExtensionType = {
80
91
  scope: Record<string, unknown>;
81
92
  title: string;
82
93
  };
94
+ export interface Context {
95
+ command: string;
96
+ module: string;
97
+ userId: string | undefined;
98
+ email: string | undefined;
99
+ sessionId: string | undefined;
100
+ clientId?: string | undefined;
101
+ apiKey: string;
102
+ orgId: string;
103
+ authenticationMethod?: string;
104
+ }