@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
@@ -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,46 +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);
87
+ }
88
+ cli_utilities_1.log.info('Starting pending global fields update', this.importConfig.context);
89
+ this.pendingGFs = utils_1.fsUtil.readFile(this.gFsPendingPath);
90
+ if (!this.pendingGFs || (0, lodash_1.isEmpty)(this.pendingGFs)) {
91
+ cli_utilities_1.log.info('No pending global fields found to update', this.importConfig.context);
92
+ return;
76
93
  }
77
94
  await this.updatePendingGFs().catch((error) => {
78
- (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));
79
96
  });
80
- (0, utils_1.log)(this.importConfig, 'Updated pending global fields with content type with references', 'success');
81
- (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);
82
99
  }
83
100
  async seedCTs() {
84
101
  const onSuccess = ({ response: globalField, apiData: { content_type: { uid = null } = {} } = {} }) => {
85
102
  this.createdCTs.push(uid);
86
- (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);
87
105
  };
88
106
  const onReject = ({ error, apiData: { content_type: { uid = null } = {} } = {} }) => {
89
107
  if (error.errorCode === 115 && (error.errors.uid || error.errors.title)) {
90
- (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);
91
110
  }
92
111
  else {
93
- (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
94
- process.exit(1);
112
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to seed content type ${uid}`);
95
113
  }
96
114
  };
115
+ cli_utilities_1.log.debug(`Starting to seed ${this.cTs.length} content types`, this.importConfig.context);
97
116
  return await this.makeConcurrentCall({
98
117
  processName: 'Import content types',
99
118
  apiContent: this.cTs,
@@ -114,6 +133,7 @@ class ContentTypesImport extends base_class_1.default {
114
133
  */
115
134
  serializeCTs(apiOptions) {
116
135
  const { apiData: contentType } = apiOptions;
136
+ cli_utilities_1.log.debug(`Serializing content type: ${contentType.uid} (${contentType.title})`, this.importConfig.context);
117
137
  const updatedCT = (0, lodash_1.cloneDeep)(utils_1.schemaTemplate);
118
138
  updatedCT.content_type.uid = contentType.uid;
119
139
  updatedCT.content_type.title = contentType.title;
@@ -122,12 +142,14 @@ class ContentTypesImport extends base_class_1.default {
122
142
  }
123
143
  async updateCTs() {
124
144
  const onSuccess = ({ response: contentType, apiData: { uid } }) => {
125
- (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);
126
147
  };
127
148
  const onReject = ({ error, apiData: { uid } }) => {
128
- (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`);
129
150
  throw new Error(`Content type '${uid}' update error`);
130
151
  };
152
+ cli_utilities_1.log.debug(`Starting to update ${this.cTs.length} content types with references`, this.importConfig.context);
131
153
  return await this.makeConcurrentCall({
132
154
  processName: 'Update content types',
133
155
  apiContent: this.cTs,
@@ -148,35 +170,50 @@ class ContentTypesImport extends base_class_1.default {
148
170
  */
149
171
  serializeUpdateCTs(apiOptions) {
150
172
  const { apiData: contentType } = apiOptions;
173
+ cli_utilities_1.log.debug(`Serializing update for content type: ${contentType.uid} (${contentType.title})`, this.importConfig.context);
151
174
  if (contentType.field_rules) {
152
175
  contentType.field_rules = (0, content_type_helper_1.updateFieldRules)(contentType);
153
176
  if (!contentType.field_rules.length) {
154
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);
155
182
  }
156
183
  this.fieldRules.push(contentType.uid);
157
184
  }
158
185
  //will remove taxonomy if taxonomy doesn't exists in stack
159
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);
160
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);
161
190
  const contentTypePayload = this.stack.contentType(contentType.uid);
162
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);
163
193
  apiOptions.apiData = contentTypePayload;
164
194
  return apiOptions;
165
195
  }
166
196
  async updatePendingGFs() {
197
+ var _a, _b;
167
198
  this.pendingGFs = utils_1.fsUtil.readFile(this.gFsPendingPath);
199
+ cli_utilities_1.log.info(`Found ${this.pendingGFs.length} pending global fields to update`, this.importConfig.context);
168
200
  this.gFs = utils_1.fsUtil.readFile(path.resolve(this.gFsFolderPath, this.gFsConfig.fileName));
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);
169
203
  const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
170
- (0, utils_1.log)(this.importConfig, `Updated the global field ${uid} with content type references`, 'info');
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);
171
206
  };
172
207
  const onReject = ({ error, apiData: { uid } = undefined }) => {
173
- (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}'`);
174
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);
175
214
  return await this.makeConcurrentCall({
176
215
  processName: 'Update pending global fields',
177
- apiContent: (0, lodash_1.map)(this.pendingGFs, (uid) => {
178
- return { uid };
179
- }),
216
+ apiContent: apiContent,
180
217
  apiParams: {
181
218
  serializeData: this.serializeUpdateGFs.bind(this),
182
219
  reject: onReject.bind(this),
@@ -194,36 +231,50 @@ class ContentTypesImport extends base_class_1.default {
194
231
  */
195
232
  serializeUpdateGFs(apiOptions) {
196
233
  const { apiData: { uid }, } = apiOptions;
234
+ cli_utilities_1.log.debug(`Serializing global field update for: ${uid}`, this.importConfig.context);
197
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);
198
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);
199
244
  const globalFieldPayload = this.stack.globalField(uid, { api_version: '3.2' });
200
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);
201
247
  apiOptions.apiData = globalFieldPayload;
202
248
  return apiOptions;
203
249
  }
204
250
  async updatePendingExtensions() {
205
251
  let apiContent = utils_1.fsUtil.readFile(this.extPendingPath);
206
- if ((apiContent === null || apiContent === void 0 ? void 0 : apiContent.length) === 0) {
207
- (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);
208
256
  return;
209
257
  }
258
+ cli_utilities_1.log.debug(`Found ${apiContent.length} extensions to update`, this.importConfig.context);
210
259
  this.isExtensionsUpdate = true;
211
260
  const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
212
- (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);
213
263
  };
214
264
  const onReject = ({ error, apiData }) => {
215
265
  var _a;
216
266
  const { uid } = apiData;
217
267
  if ((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.title) {
218
268
  if (!this.importConfig.skipExisting) {
219
- (0, utils_1.log)(this.importConfig, `Extension '${uid}' already exists.`, 'info');
269
+ cli_utilities_1.log.info(`Extension '${uid}' already exists.`, this.importConfig.context);
220
270
  }
271
+ cli_utilities_1.log.debug(`Skipping existing extension: ${uid}`, this.importConfig.context);
221
272
  }
222
273
  else {
223
- (0, utils_1.log)(this.importConfig, `Failed to update '${uid}' extension due to ${(0, utils_1.formatError)(error)}.`, 'error');
224
- (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`);
225
275
  }
226
276
  };
277
+ cli_utilities_1.log.debug('Starting extensions update process', this.importConfig.context);
227
278
  return await this.makeConcurrentCall({
228
279
  apiContent,
229
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;