@contentstack/cli-cm-import 1.25.1 → 1.26.1

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 (36) 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 +39 -12
  4. package/lib/import/module-importer.js +20 -3
  5. package/lib/import/modules/assets.d.ts +1 -1
  6. package/lib/import/modules/assets.js +93 -39
  7. package/lib/import/modules/content-types.js +76 -31
  8. package/lib/import/modules/custom-roles.js +95 -19
  9. package/lib/import/modules/entries.js +128 -57
  10. package/lib/import/modules/environments.js +48 -14
  11. package/lib/import/modules/extensions.js +78 -16
  12. package/lib/import/modules/global-fields.js +85 -20
  13. package/lib/import/modules/labels.d.ts +4 -4
  14. package/lib/import/modules/labels.js +60 -18
  15. package/lib/import/modules/locales.js +63 -20
  16. package/lib/import/modules/marketplace-apps.js +160 -31
  17. package/lib/import/modules/personalize.js +33 -7
  18. package/lib/import/modules/stack.js +5 -0
  19. package/lib/import/modules/taxonomies.js +52 -13
  20. package/lib/import/modules/variant-entries.js +21 -3
  21. package/lib/import/modules/webhooks.js +44 -12
  22. package/lib/import/modules/workflows.js +65 -21
  23. package/lib/types/import-config.d.ts +3 -1
  24. package/lib/types/index.d.ts +22 -0
  25. package/lib/utils/asset-helper.js +24 -1
  26. package/lib/utils/backup-handler.js +15 -1
  27. package/lib/utils/common-helper.js +41 -16
  28. package/lib/utils/content-type-helper.js +35 -2
  29. package/lib/utils/entries-helper.js +24 -2
  30. package/lib/utils/extension-helper.js +35 -1
  31. package/lib/utils/import-config-handler.js +21 -0
  32. package/lib/utils/login-handler.js +8 -4
  33. package/lib/utils/marketplace-app-helper.js +50 -11
  34. package/lib/utils/taxonomies-helper.js +22 -4
  35. package/oclif.manifest.json +2 -2
  36. package/package.json +6 -6
@@ -9,14 +9,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const tslib_1 = require("tslib");
10
10
  const path = tslib_1.__importStar(require("path"));
11
11
  const lodash_1 = require("lodash");
12
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
12
13
  const utils_1 = require("../../utils");
13
14
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
14
15
  const content_type_helper_1 = require("../../utils/content-type-helper");
15
- const cli_utilities_1 = require("@contentstack/cli-utilities");
16
16
  class ContentTypesImport extends base_class_1.default {
17
17
  constructor({ importConfig, stackAPIClient }) {
18
18
  super({ importConfig, stackAPIClient });
19
19
  this.isExtensionsUpdate = false;
20
+ this.importConfig.context.module = 'content-types';
20
21
  this.cTsConfig = importConfig.modules['content-types'];
21
22
  this.gFsConfig = importConfig.modules['global-fields'];
22
23
  this.reqConcurrency = this.cTsConfig.writeConcurrency || this.importConfig.writeConcurrency;
@@ -44,7 +45,7 @@ class ContentTypesImport extends base_class_1.default {
44
45
  this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'extensions', 'pending_extensions.js');
45
46
  }
46
47
  async start() {
47
- var _a;
48
+ var _a, _b;
48
49
  /**
49
50
  * read content type, check if it is necessary to read the entire dir
50
51
  * Seed content types
@@ -54,51 +55,64 @@ class ContentTypesImport extends base_class_1.default {
54
55
  */
55
56
  this.cTs = utils_1.fsUtil.readFile(path.join(this.cTsFolderPath, 'schema.json'));
56
57
  if (!this.cTs || (0, lodash_1.isEmpty)(this.cTs)) {
57
- (0, utils_1.log)(this.importConfig, 'No content type found to import', 'info');
58
+ cli_utilities_1.log.info('No content type found to import', this.importConfig.context);
58
59
  return;
59
60
  }
61
+ cli_utilities_1.log.debug(`Found ${this.cTs.length} content types to import`, this.importConfig.context);
60
62
  await utils_1.fsUtil.makeDirectory(this.cTsMapperPath);
63
+ cli_utilities_1.log.debug('Created content types mapper directory', this.importConfig.context);
61
64
  this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
65
+ cli_utilities_1.log.debug(`Loaded ${(_a = Object.keys(this.installedExtensions)) === null || _a === void 0 ? void 0 : _a.length} installed extensions`, this.importConfig.context);
62
66
  this.taxonomies = utils_1.fsUtil.readFile(this.taxonomiesPath);
67
+ const taxonomyCount = Object.keys(this.taxonomies || {}).length;
68
+ cli_utilities_1.log.debug(`Loaded ${taxonomyCount} taxonomy definitions`, this.importConfig.context);
69
+ cli_utilities_1.log.info('Starting content types seeding process', this.importConfig.context);
63
70
  await this.seedCTs();
64
- if ((_a = this.createdCTs) === null || _a === void 0 ? void 0 : _a.length)
71
+ if ((_b = this.createdCTs) === null || _b === void 0 ? void 0 : _b.length) {
65
72
  utils_1.fsUtil.writeFile(this.cTsSuccessPath, this.createdCTs);
66
- (0, utils_1.log)(this.importConfig, 'Created content types', 'success');
73
+ cli_utilities_1.log.debug(`Written ${this.createdCTs.length} successful content types to file`, this.importConfig.context);
74
+ }
75
+ cli_utilities_1.log.success('Created content types', this.importConfig.context);
76
+ cli_utilities_1.log.info('Starting content types update process', this.importConfig.context);
67
77
  await this.updateCTs();
68
- (0, utils_1.log)(this.importConfig, 'Updated content types with references', 'success');
78
+ cli_utilities_1.log.success('Updated content types with references', this.importConfig.context);
69
79
  if (this.fieldRules.length > 0) {
70
80
  utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
81
+ cli_utilities_1.log.debug(`Written ${this.fieldRules.length} field rules to file`, this.importConfig.context);
71
82
  }
72
- (0, utils_1.log)(this.importConfig, 'Updating the extensions...', 'success');
83
+ cli_utilities_1.log.info('Updating the extensions...', this.importConfig.context);
73
84
  await this.updatePendingExtensions();
74
85
  if (this.isExtensionsUpdate) {
75
- (0, utils_1.log)(this.importConfig, 'Successfully updated the extensions.', 'success');
86
+ cli_utilities_1.log.success('Successfully updated the extensions.', this.importConfig.context);
76
87
  }
88
+ cli_utilities_1.log.info('Starting pending global fields update', this.importConfig.context);
77
89
  this.pendingGFs = utils_1.fsUtil.readFile(this.gFsPendingPath);
78
90
  if (!this.pendingGFs || (0, lodash_1.isEmpty)(this.pendingGFs)) {
79
- (0, utils_1.log)(this.importConfig, 'No pending global fields found to update', 'info');
91
+ cli_utilities_1.log.info('No pending global fields found to update', this.importConfig.context);
80
92
  return;
81
93
  }
82
94
  await this.updatePendingGFs().catch((error) => {
83
- (0, utils_1.log)(this.importConfig, `Error while updating pending global field ${(0, utils_1.formatError)(error)}`, 'error');
95
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
84
96
  });
85
- (0, utils_1.log)(this.importConfig, 'Updated pending global fields with content type with references', 'success');
86
- (0, utils_1.log)(this.importConfig, 'Content types have been imported successfully!', 'success');
97
+ cli_utilities_1.log.success('Updated pending global fields with content type with references', this.importConfig.context);
98
+ cli_utilities_1.log.success('Content types have been imported successfully!', this.importConfig.context);
87
99
  }
88
100
  async seedCTs() {
89
101
  const onSuccess = ({ response: globalField, apiData: { content_type: { uid = null } = {} } = {} }) => {
90
102
  this.createdCTs.push(uid);
91
- (0, utils_1.log)(this.importConfig, `${uid} content type seeded`, 'info');
103
+ cli_utilities_1.log.info(`${uid} content type seeded`, this.importConfig.context);
104
+ cli_utilities_1.log.debug(`Successfully seeded content type: ${uid}`, this.importConfig.context);
92
105
  };
93
106
  const onReject = ({ error, apiData: { content_type: { uid = null } = {} } = {} }) => {
94
107
  if (error.errorCode === 115 && (error.errors.uid || error.errors.title)) {
95
- (0, utils_1.log)(this.importConfig, `${uid} content type already exist`, 'info');
108
+ cli_utilities_1.log.info(`${uid} content type already exist`, this.importConfig.context);
109
+ cli_utilities_1.log.debug(`Skipping existing content type: ${uid}`, this.importConfig.context);
96
110
  }
97
111
  else {
98
- (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
99
- process.exit(1);
112
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to seed content type ${uid}`);
100
113
  }
101
114
  };
115
+ cli_utilities_1.log.debug(`Starting to seed ${this.cTs.length} content types`, this.importConfig.context);
102
116
  return await this.makeConcurrentCall({
103
117
  processName: 'Import content types',
104
118
  apiContent: this.cTs,
@@ -119,6 +133,7 @@ class ContentTypesImport extends base_class_1.default {
119
133
  */
120
134
  serializeCTs(apiOptions) {
121
135
  const { apiData: contentType } = apiOptions;
136
+ cli_utilities_1.log.debug(`Serializing content type: ${contentType.uid} (${contentType.title})`, this.importConfig.context);
122
137
  const updatedCT = (0, lodash_1.cloneDeep)(utils_1.schemaTemplate);
123
138
  updatedCT.content_type.uid = contentType.uid;
124
139
  updatedCT.content_type.title = contentType.title;
@@ -127,12 +142,14 @@ class ContentTypesImport extends base_class_1.default {
127
142
  }
128
143
  async updateCTs() {
129
144
  const onSuccess = ({ response: contentType, apiData: { uid } }) => {
130
- (0, utils_1.log)(this.importConfig, `'${uid}' updated with references`, 'success');
145
+ cli_utilities_1.log.success(`'${uid}' updated with references`, this.importConfig.context);
146
+ cli_utilities_1.log.debug(`Content type update completed for: ${uid}`, this.importConfig.context);
131
147
  };
132
148
  const onReject = ({ error, apiData: { uid } }) => {
133
- (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
149
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Content type '${uid}' update failed`);
134
150
  throw new Error(`Content type '${uid}' update error`);
135
151
  };
152
+ cli_utilities_1.log.debug(`Starting to update ${this.cTs.length} content types with references`, this.importConfig.context);
136
153
  return await this.makeConcurrentCall({
137
154
  processName: 'Update content types',
138
155
  apiContent: this.cTs,
@@ -153,36 +170,50 @@ class ContentTypesImport extends base_class_1.default {
153
170
  */
154
171
  serializeUpdateCTs(apiOptions) {
155
172
  const { apiData: contentType } = apiOptions;
173
+ cli_utilities_1.log.debug(`Serializing update for content type: ${contentType.uid} (${contentType.title})`, this.importConfig.context);
156
174
  if (contentType.field_rules) {
157
175
  contentType.field_rules = (0, content_type_helper_1.updateFieldRules)(contentType);
158
176
  if (!contentType.field_rules.length) {
159
177
  delete contentType.field_rules;
178
+ cli_utilities_1.log.debug(`Removed empty field rules for content type: ${contentType.uid}`, this.importConfig.context);
179
+ }
180
+ else {
181
+ cli_utilities_1.log.debug(`Updated ${contentType.field_rules.length} field rules for content type: ${contentType.uid}`, this.importConfig.context);
160
182
  }
161
183
  this.fieldRules.push(contentType.uid);
162
184
  }
163
185
  //will remove taxonomy if taxonomy doesn't exists in stack
164
186
  (0, utils_1.lookUpTaxonomy)(this.importConfig, contentType.schema, this.taxonomies);
187
+ cli_utilities_1.log.debug(`Processed taxonomy lookups for content type: ${contentType.uid}`, this.importConfig.context);
165
188
  (0, utils_1.lookupExtension)(this.importConfig, contentType.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
189
+ cli_utilities_1.log.debug(`Processed extension lookups for content type: ${contentType.uid}`, this.importConfig.context);
166
190
  const contentTypePayload = this.stack.contentType(contentType.uid);
167
191
  Object.assign(contentTypePayload, (0, lodash_1.cloneDeep)(contentType));
192
+ cli_utilities_1.log.debug(`Content type update serialization completed for: ${contentType.uid}`, this.importConfig.context);
168
193
  apiOptions.apiData = contentTypePayload;
169
194
  return apiOptions;
170
195
  }
171
196
  async updatePendingGFs() {
197
+ var _a, _b;
172
198
  this.pendingGFs = utils_1.fsUtil.readFile(this.gFsPendingPath);
173
- (0, utils_1.log)(this.importConfig, `Found ${this.pendingGFs.length} pending global fields to update`, 'info');
199
+ cli_utilities_1.log.info(`Found ${this.pendingGFs.length} pending global fields to update`, this.importConfig.context);
174
200
  this.gFs = utils_1.fsUtil.readFile(path.resolve(this.gFsFolderPath, this.gFsConfig.fileName));
175
- const onSuccess = ({ response, apiData: { uid } = undefined }) => {
176
- (0, utils_1.log)(this.importConfig, `Updated the global field ${uid} with content type references`, 'info');
201
+ cli_utilities_1.log.debug(`Found ${((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) || 0} pending global fields to update`, this.importConfig.context);
202
+ cli_utilities_1.log.debug(`Loaded ${((_b = this.gFs) === null || _b === void 0 ? void 0 : _b.length) || 0} global fields from file`, this.importConfig.context);
203
+ const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
204
+ cli_utilities_1.log.info(`Updated the global field ${uid} with content type references`, this.importConfig.context);
205
+ cli_utilities_1.log.debug(`Global field update completed for: ${uid}`, this.importConfig.context);
177
206
  };
178
207
  const onReject = ({ error, apiData: { uid } = undefined }) => {
179
- (0, utils_1.log)(this.importConfig, `Failed to update the global field '${uid}' ${(0, utils_1.formatError)(error)}`, 'error');
208
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to update the global field '${uid}'`);
180
209
  };
210
+ const apiContent = (0, lodash_1.map)(this.pendingGFs, (uid) => {
211
+ return { uid };
212
+ });
213
+ cli_utilities_1.log.debug(`Prepared ${apiContent.length} global field update tasks`, this.importConfig.context);
181
214
  return await this.makeConcurrentCall({
182
215
  processName: 'Update pending global fields',
183
- apiContent: (0, lodash_1.map)(this.pendingGFs, (uid) => {
184
- return { uid };
185
- }),
216
+ apiContent: apiContent,
186
217
  apiParams: {
187
218
  serializeData: this.serializeUpdateGFs.bind(this),
188
219
  reject: onReject.bind(this),
@@ -200,36 +231,50 @@ class ContentTypesImport extends base_class_1.default {
200
231
  */
201
232
  serializeUpdateGFs(apiOptions) {
202
233
  const { apiData: { uid }, } = apiOptions;
234
+ cli_utilities_1.log.debug(`Serializing global field update for: ${uid}`, this.importConfig.context);
203
235
  const globalField = (0, lodash_1.find)(this.gFs, { uid });
236
+ if (!globalField) {
237
+ cli_utilities_1.log.debug(`Global field not found: ${uid}`, this.importConfig.context);
238
+ apiOptions.apiData = null;
239
+ return apiOptions;
240
+ }
241
+ cli_utilities_1.log.debug(`Found global field: ${uid}`, this.importConfig.context);
204
242
  (0, utils_1.lookupExtension)(this.importConfig, globalField.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
243
+ cli_utilities_1.log.debug(`Processed extension lookups for global field: ${uid}`, this.importConfig.context);
205
244
  const globalFieldPayload = this.stack.globalField(uid, { api_version: '3.2' });
206
245
  Object.assign(globalFieldPayload, (0, lodash_1.cloneDeep)(globalField));
246
+ cli_utilities_1.log.debug(`Global field update serialization completed for: ${uid}`, this.importConfig.context);
207
247
  apiOptions.apiData = globalFieldPayload;
208
248
  return apiOptions;
209
249
  }
210
250
  async updatePendingExtensions() {
211
251
  let apiContent = utils_1.fsUtil.readFile(this.extPendingPath);
212
- if ((apiContent === null || apiContent === void 0 ? void 0 : apiContent.length) === 0) {
213
- (0, utils_1.log)(this.importConfig, `No extensions found to be updated.`, 'success');
252
+ cli_utilities_1.log.debug(`Reading pending extensions from: ${this.extPendingPath}`, this.importConfig.context);
253
+ if (!apiContent || (apiContent === null || apiContent === void 0 ? void 0 : apiContent.length) === 0) {
254
+ cli_utilities_1.log.info(`No extensions found to be updated.`, this.importConfig.context);
255
+ cli_utilities_1.log.debug('Skipping extensions update - no pending extensions', this.importConfig.context);
214
256
  return;
215
257
  }
258
+ cli_utilities_1.log.debug(`Found ${apiContent.length} extensions to update`, this.importConfig.context);
216
259
  this.isExtensionsUpdate = true;
217
260
  const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
218
- (0, utils_1.log)(this.importConfig, `Successfully updated the '${response.title}' extension.`, 'success');
261
+ cli_utilities_1.log.success(`Successfully updated the '${response.title}' extension.`, this.importConfig.context);
262
+ cli_utilities_1.log.debug(`Extension update completed for: ${uid}`, this.importConfig.context);
219
263
  };
220
264
  const onReject = ({ error, apiData }) => {
221
265
  var _a;
222
266
  const { uid } = apiData;
223
267
  if ((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.title) {
224
268
  if (!this.importConfig.skipExisting) {
225
- (0, utils_1.log)(this.importConfig, `Extension '${uid}' already exists.`, 'info');
269
+ cli_utilities_1.log.info(`Extension '${uid}' already exists.`, this.importConfig.context);
226
270
  }
271
+ cli_utilities_1.log.debug(`Skipping existing extension: ${uid}`, this.importConfig.context);
227
272
  }
228
273
  else {
229
- (0, utils_1.log)(this.importConfig, `Failed to update '${uid}' extension due to ${(0, utils_1.formatError)(error)}.`, 'error');
230
- (0, utils_1.log)(this.importConfig, error, 'error');
274
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to update '${uid}' extension`);
231
275
  }
232
276
  };
277
+ cli_utilities_1.log.debug('Starting extensions update process', this.importConfig.context);
233
278
  return await this.makeConcurrentCall({
234
279
  apiContent,
235
280
  processName: 'update extensions',
@@ -4,30 +4,49 @@ 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 lodash_1 = require("lodash");
8
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
9
  const utils_1 = require("../../utils");
8
10
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
9
- const lodash_1 = require("lodash");
10
11
  class ImportCustomRoles extends base_class_1.default {
11
12
  constructor({ importConfig, stackAPIClient }) {
12
13
  super({ importConfig, stackAPIClient });
13
14
  this.getTransformUidsFactory = (rule) => {
15
+ var _a, _b, _c;
16
+ cli_utilities_1.log.debug(`Transforming UIDs for rule module: ${rule.module}`, this.importConfig.context);
14
17
  if (rule.module === 'environment') {
15
18
  if (!(0, isEmpty_1.default)(this.environmentsUidMap)) {
19
+ const originalEnvs = ((_a = rule.environments) === null || _a === void 0 ? void 0 : _a.length) || 0;
16
20
  rule.environments = (0, lodash_1.map)(rule.environments, (env) => this.environmentsUidMap[env]);
21
+ cli_utilities_1.log.debug(`Transformed ${originalEnvs} environment UIDs for rule`, this.importConfig.context);
22
+ }
23
+ else {
24
+ cli_utilities_1.log.debug('No environment UID mappings available for transformation', this.importConfig.context);
17
25
  }
18
26
  }
19
27
  else if (rule.module === 'locale') {
20
28
  if (!(0, isEmpty_1.default)(this.localesUidMap)) {
29
+ const originalLocales = ((_b = rule.locales) === null || _b === void 0 ? void 0 : _b.length) || 0;
21
30
  rule.locales = (0, lodash_1.map)(rule.locales, (locale) => this.localesUidMap[locale]);
31
+ cli_utilities_1.log.debug(`Transformed ${originalLocales} locale UIDs for rule`, this.importConfig.context);
32
+ }
33
+ else {
34
+ cli_utilities_1.log.debug('No locale UID mappings available for transformation', this.importConfig.context);
22
35
  }
23
36
  }
24
37
  else if (rule.module === 'entry') {
25
38
  if (!(0, isEmpty_1.default)(this.entriesUidMap)) {
39
+ const originalEntries = ((_c = rule.entries) === null || _c === void 0 ? void 0 : _c.length) || 0;
26
40
  rule.entries = (0, lodash_1.map)(rule.entries, (entry) => this.entriesUidMap[entry]);
41
+ cli_utilities_1.log.debug(`Transformed ${originalEntries} entry UIDs for rule`, this.importConfig.context);
42
+ }
43
+ else {
44
+ cli_utilities_1.log.debug('No entry UID mappings available for transformation', this.importConfig.context);
27
45
  }
28
46
  }
29
47
  return rule;
30
48
  };
49
+ this.importConfig.context.module = 'custom-roles';
31
50
  this.customRolesConfig = importConfig.modules.customRoles;
32
51
  this.customRolesMapperPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'custom-roles');
33
52
  this.customRolesFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.customRolesConfig.dirName);
@@ -50,85 +69,133 @@ class ImportCustomRoles extends base_class_1.default {
50
69
  * @returns {Promise<void>} Promise<void>
51
70
  */
52
71
  async start() {
53
- var _a, _b;
54
- (0, utils_1.log)(this.importConfig, 'Migrating custom-roles', 'info');
72
+ var _a, _b, _c;
73
+ cli_utilities_1.log.debug('Checking for custom roles folder existence', this.importConfig.context);
55
74
  //Step1 check folder exists or not
56
75
  if (utils_1.fileHelper.fileExistsSync(this.customRolesFolderPath)) {
76
+ cli_utilities_1.log.debug(`Found custom roles folder: ${this.customRolesFolderPath}`, this.importConfig.context);
57
77
  this.customRoles = utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesFolderPath, this.customRolesConfig.fileName), true);
58
78
  this.customRolesLocales = utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesFolderPath, this.customRolesConfig.customRolesLocalesFileName), true);
59
79
  }
60
80
  else {
61
- (0, utils_1.log)(this.importConfig, `No custom-rules are found - '${this.customRolesFolderPath}'`, 'info');
81
+ cli_utilities_1.log.info(`No custom-rules are found - '${this.customRolesFolderPath}'`, this.importConfig.context);
62
82
  return;
63
83
  }
64
84
  //create webhooks in mapper directory
85
+ cli_utilities_1.log.debug('Creating custom roles mapper directory', this.importConfig.context);
65
86
  await utils_1.fsUtil.makeDirectory(this.customRolesMapperPath);
87
+ cli_utilities_1.log.debug('Loading existing custom roles UID data', this.importConfig.context);
66
88
  this.customRolesUidMapper = utils_1.fileHelper.fileExistsSync(this.customRolesUidMapperPath)
67
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesUidMapperPath), true)
89
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesUidMapperPath), true) || {}
68
90
  : {};
91
+ cli_utilities_1.log.debug('Loading environments UID data', this.importConfig.context);
69
92
  this.environmentsUidMap = utils_1.fileHelper.fileExistsSync(this.envUidMapperFolderPath)
70
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.envUidMapperFolderPath, 'uid-mapping.json'), true)
93
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.envUidMapperFolderPath, 'uid-mapping.json'), true) || {}
71
94
  : {};
95
+ cli_utilities_1.log.debug('Loading entries UID data', this.importConfig.context);
72
96
  this.entriesUidMap = utils_1.fileHelper.fileExistsSync(this.entriesUidMapperFolderPath)
73
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.entriesUidMapperFolderPath, 'uid-mapping.json'), true)
97
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.entriesUidMapperFolderPath, 'uid-mapping.json'), true) || {}
74
98
  : {};
99
+ if (this.customRolesUidMapper && Object.keys(this.customRolesUidMapper || {}).length > 0) {
100
+ const customRolesUidCount = Object.keys(this.customRolesUidMapper || {}).length;
101
+ cli_utilities_1.log.debug(`Loaded existing custom roles UID data: ${customRolesUidCount} items`, this.importConfig.context);
102
+ }
103
+ else {
104
+ cli_utilities_1.log.debug('No existing custom roles UID data found', this.importConfig.context);
105
+ }
106
+ if (this.environmentsUidMap && ((_a = Object.keys(this.environmentsUidMap || {})) === null || _a === void 0 ? void 0 : _a.length) > 0) {
107
+ const envUidCount = Object.keys(this.environmentsUidMap || {}).length;
108
+ cli_utilities_1.log.debug(`Loaded environments UID data: ${envUidCount} items`, this.importConfig.context);
109
+ }
110
+ else {
111
+ cli_utilities_1.log.debug('No environments UID data found', this.importConfig.context);
112
+ }
113
+ if (this.entriesUidMap && Object.keys(this.entriesUidMap || {}).length > 0) {
114
+ const entriesUidCount = Object.keys(this.entriesUidMap || {}).length;
115
+ cli_utilities_1.log.debug(`Loaded entries UID data: ${entriesUidCount} items`, this.importConfig.context);
116
+ }
117
+ else {
118
+ cli_utilities_1.log.debug('No entries UID data found', this.importConfig.context);
119
+ }
75
120
  //source and target stack locale map
121
+ cli_utilities_1.log.debug('Getting locales UID mapping', this.importConfig.context);
76
122
  await this.getLocalesUidMap();
123
+ cli_utilities_1.log.debug('Starting custom roles import', this.importConfig.context);
77
124
  await this.importCustomRoles();
78
- if ((_a = this.createdCustomRoles) === null || _a === void 0 ? void 0 : _a.length) {
125
+ cli_utilities_1.log.debug('Processing custom roles import results', this.importConfig.context);
126
+ if ((_b = this.createdCustomRoles) === null || _b === void 0 ? void 0 : _b.length) {
79
127
  utils_1.fsUtil.writeFile(this.createdCustomRolesPath, this.createdCustomRoles);
128
+ cli_utilities_1.log.debug(`Written ${this.createdCustomRoles.length} successful custom roles to file`, this.importConfig.context);
80
129
  }
81
- if ((_b = this.failedCustomRoles) === null || _b === void 0 ? void 0 : _b.length) {
130
+ if ((_c = this.failedCustomRoles) === null || _c === void 0 ? void 0 : _c.length) {
82
131
  utils_1.fsUtil.writeFile(this.customRolesFailsPath, this.failedCustomRoles);
132
+ cli_utilities_1.log.debug(`Written ${this.failedCustomRoles.length} failed custom roles to file`, this.importConfig.context);
83
133
  }
84
- (0, utils_1.log)(this.importConfig, 'Custom roles have been imported successfully!', 'success');
134
+ cli_utilities_1.log.success('Custom roles have been imported successfully!', this.importConfig.context);
85
135
  }
86
136
  async getLocalesUidMap() {
137
+ cli_utilities_1.log.debug('Fetching target stack locales', this.importConfig.context);
87
138
  const { items } = await this.stack
88
139
  .locale()
89
140
  .query()
90
141
  .find()
91
- .then((data) => data)
92
- .catch((error) => (0, utils_1.log)(this.importConfig, `Failed to fetch locale.${(0, utils_1.formatError)(error)}`, 'error'));
142
+ .then((data) => {
143
+ var _a;
144
+ cli_utilities_1.log.debug(`Found ${((_a = data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} locales in target stack`, this.importConfig.context);
145
+ return data;
146
+ })
147
+ .catch((error) => {
148
+ cli_utilities_1.log.debug('Error fetching target stack locales', this.importConfig.context);
149
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
150
+ });
93
151
  this.targetLocalesMap = {};
94
152
  this.sourceLocalesMap = {};
153
+ cli_utilities_1.log.debug('Building target locales mapping', this.importConfig.context);
95
154
  (0, lodash_1.forEach)(items, (locale) => {
96
155
  this.targetLocalesMap[locale.code] = locale.uid;
97
156
  });
157
+ cli_utilities_1.log.debug('Building source locales mapping', this.importConfig.context);
98
158
  for (const key in this.customRolesLocales) {
99
159
  const sourceLocales = this.customRolesLocales[key];
100
160
  this.sourceLocalesMap[sourceLocales.code] = key;
101
161
  }
162
+ cli_utilities_1.log.debug('Creating locale UID mapping', this.importConfig.context);
102
163
  for (const key in this.sourceLocalesMap) {
103
164
  const sourceLocaleKey = this.sourceLocalesMap[key];
104
165
  this.localesUidMap[sourceLocaleKey] = this.targetLocalesMap[key];
105
166
  }
167
+ const localesMappingCount = Object.keys(this.localesUidMap || {}).length;
168
+ cli_utilities_1.log.debug(`Created ${localesMappingCount} locale UID mappings`, this.importConfig.context);
106
169
  }
107
170
  async importCustomRoles() {
171
+ cli_utilities_1.log.debug('Starting custom roles import process', this.importConfig.context);
108
172
  if (this.customRoles === undefined || (0, isEmpty_1.default)(this.customRoles)) {
109
- (0, utils_1.log)(this.importConfig, 'No custom-roles found', 'info');
173
+ cli_utilities_1.log.info('No custom-roles found', this.importConfig.context);
110
174
  return;
111
175
  }
112
176
  const apiContent = (0, values_1.default)(this.customRoles);
177
+ cli_utilities_1.log.debug(`Importing ${apiContent.length} custom roles`, this.importConfig.context);
113
178
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
114
179
  this.createdCustomRoles.push(response);
115
180
  this.customRolesUidMapper[uid] = response.uid;
116
- (0, utils_1.log)(this.importConfig, `custom-role '${name}' imported successfully`, 'success');
181
+ cli_utilities_1.log.success(`custom-role '${name}' imported successfully`, this.importConfig.context);
182
+ cli_utilities_1.log.debug(`Custom role import completed: ${name} (${uid})`, this.importConfig.context);
117
183
  utils_1.fsUtil.writeFile(this.customRolesUidMapperPath, this.customRolesUidMapper);
118
184
  };
119
185
  const onReject = ({ error, apiData }) => {
120
186
  var _a;
121
187
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
122
188
  const { name } = apiData;
189
+ cli_utilities_1.log.debug(`Custom role '${name}' import failed`, this.importConfig.context);
123
190
  if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
124
- (0, utils_1.log)(this.importConfig, `custom-role '${name}' already exists`, 'info');
191
+ cli_utilities_1.log.info(`custom-role '${name}' already exists`, this.importConfig.context);
125
192
  }
126
193
  else {
127
194
  this.failedCustomRoles.push(apiData);
128
- (0, utils_1.log)(this.importConfig, `custom-role '${name}' failed to be import.${(0, utils_1.formatError)(error)}`, 'error');
129
- (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
195
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `custom-role '${name}' failed to be import`);
130
196
  }
131
197
  };
198
+ cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
132
199
  await this.makeConcurrentCall({
133
200
  apiContent,
134
201
  processName: 'create custom role',
@@ -141,6 +208,7 @@ class ImportCustomRoles extends base_class_1.default {
141
208
  },
142
209
  concurrencyLimit: this.importConfig.fetchConcurrency || 1,
143
210
  }, undefined, false);
211
+ cli_utilities_1.log.debug('Custom roles import process completed', this.importConfig.context);
144
212
  }
145
213
  /**
146
214
  * @method serializeWebhooks
@@ -148,26 +216,34 @@ class ImportCustomRoles extends base_class_1.default {
148
216
  * @returns {ApiOptions} ApiOptions
149
217
  */
150
218
  serializeWebhooks(apiOptions) {
219
+ var _a;
151
220
  const { apiData: customRole } = apiOptions;
221
+ cli_utilities_1.log.debug(`Serializing custom role: ${customRole.name} (${customRole.uid})`, this.importConfig.context);
152
222
  if (this.customRolesUidMapper.hasOwnProperty(customRole.uid)) {
153
- (0, utils_1.log)(this.importConfig, `custom-role '${customRole.name}' already exists. Skipping it to avoid duplicates!`, 'info');
223
+ cli_utilities_1.log.info(`custom-role '${customRole.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
224
+ cli_utilities_1.log.debug(`Skipping custom role serialization for: ${customRole.uid}`, this.importConfig.context);
154
225
  apiOptions.entity = undefined;
155
226
  }
156
227
  else {
157
228
  let branchRuleExists = false;
229
+ cli_utilities_1.log.debug(`Processing ${((_a = customRole.rules) === null || _a === void 0 ? void 0 : _a.length) || 0} rules for custom role: ${customRole.name}`, this.importConfig.context);
158
230
  (0, lodash_1.forEach)(customRole.rules, (rule) => {
159
231
  rule = this.getTransformUidsFactory(rule);
160
232
  // rules.branch is required to create custom roles.
161
- if (rule.module === 'branch')
233
+ if (rule.module === 'branch') {
162
234
  branchRuleExists = true;
235
+ cli_utilities_1.log.debug(`Found branch rule in custom role: ${customRole.name}`, this.importConfig.context);
236
+ }
163
237
  });
164
238
  if (!branchRuleExists) {
239
+ cli_utilities_1.log.debug(`Adding default branch rule to custom role: ${customRole.name}`, this.importConfig.context);
165
240
  customRole.rules.push({
166
241
  module: 'branch',
167
242
  branches: ['main'],
168
243
  acl: { read: true },
169
244
  });
170
245
  }
246
+ cli_utilities_1.log.debug(`Custom role serialization completed: ${customRole.name}`, this.importConfig.context);
171
247
  apiOptions.apiData = customRole;
172
248
  }
173
249
  return apiOptions;