@contentstack/cli-cm-import 1.28.1 → 2.0.1-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +5 -7
  2. package/lib/commands/cm/stacks/import.d.ts +2 -0
  3. package/lib/commands/cm/stacks/import.js +46 -11
  4. package/lib/config/index.js +0 -1
  5. package/lib/import/module-importer.js +6 -20
  6. package/lib/import/modules/assets.d.ts +6 -0
  7. package/lib/import/modules/assets.js +102 -25
  8. package/lib/import/modules/base-class.d.ts +17 -0
  9. package/lib/import/modules/base-class.js +45 -0
  10. package/lib/import/modules/content-types.d.ts +7 -10
  11. package/lib/import/modules/content-types.js +132 -68
  12. package/lib/import/modules/custom-roles.d.ts +6 -2
  13. package/lib/import/modules/custom-roles.js +80 -69
  14. package/lib/import/modules/entries.d.ts +7 -0
  15. package/lib/import/modules/entries.js +278 -163
  16. package/lib/import/modules/environments.d.ts +3 -0
  17. package/lib/import/modules/environments.js +69 -38
  18. package/lib/import/modules/extensions.d.ts +3 -0
  19. package/lib/import/modules/extensions.js +99 -64
  20. package/lib/import/modules/global-fields.d.ts +8 -1
  21. package/lib/import/modules/global-fields.js +123 -63
  22. package/lib/import/modules/index.d.ts +1 -0
  23. package/lib/import/modules/index.js +1 -0
  24. package/lib/import/modules/labels.d.ts +3 -0
  25. package/lib/import/modules/labels.js +104 -54
  26. package/lib/import/modules/locales.d.ts +15 -4
  27. package/lib/import/modules/locales.js +194 -94
  28. package/lib/import/modules/marketplace-apps.d.ts +6 -3
  29. package/lib/import/modules/marketplace-apps.js +177 -102
  30. package/lib/import/modules/personalize.d.ts +11 -4
  31. package/lib/import/modules/personalize.js +138 -47
  32. package/lib/import/modules/stack.d.ts +6 -0
  33. package/lib/import/modules/stack.js +71 -27
  34. package/lib/import/modules/taxonomies.d.ts +4 -2
  35. package/lib/import/modules/taxonomies.js +60 -46
  36. package/lib/import/modules/variant-entries.d.ts +7 -4
  37. package/lib/import/modules/variant-entries.js +76 -35
  38. package/lib/import/modules/webhooks.d.ts +3 -0
  39. package/lib/import/modules/webhooks.js +71 -40
  40. package/lib/import/modules/workflows.d.ts +3 -0
  41. package/lib/import/modules/workflows.js +98 -48
  42. package/lib/types/default-config.d.ts +0 -1
  43. package/lib/types/import-config.d.ts +0 -1
  44. package/lib/types/index.d.ts +1 -12
  45. package/lib/utils/backup-handler.js +0 -1
  46. package/lib/utils/constants.d.ts +243 -0
  47. package/lib/utils/constants.js +264 -0
  48. package/lib/utils/import-config-handler.js +2 -0
  49. package/lib/utils/import-path-resolver.js +3 -13
  50. package/lib/utils/index.d.ts +1 -1
  51. package/lib/utils/index.js +6 -2
  52. package/lib/utils/marketplace-app-helper.js +3 -8
  53. package/lib/utils/progress-strategy-registry.d.ts +7 -0
  54. package/lib/utils/progress-strategy-registry.js +78 -0
  55. package/lib/utils/setup-branch.js +1 -1
  56. package/oclif.manifest.json +2 -2
  57. package/package.json +3 -3
  58. package/lib/import/modules-js/assets.d.ts +0 -33
  59. package/lib/import/modules-js/assets.js +0 -428
  60. package/lib/import/modules-js/content-types.d.ts +0 -34
  61. package/lib/import/modules-js/content-types.js +0 -204
  62. package/lib/import/modules-js/custom-roles.d.ts +0 -15
  63. package/lib/import/modules-js/custom-roles.js +0 -143
  64. package/lib/import/modules-js/entries.d.ts +0 -54
  65. package/lib/import/modules-js/entries.js +0 -1280
  66. package/lib/import/modules-js/environments.d.ts +0 -13
  67. package/lib/import/modules-js/environments.js +0 -85
  68. package/lib/import/modules-js/extensions.d.ts +0 -18
  69. package/lib/import/modules-js/extensions.js +0 -86
  70. package/lib/import/modules-js/global-fields.d.ts +0 -13
  71. package/lib/import/modules-js/global-fields.js +0 -106
  72. package/lib/import/modules-js/index.d.ts +0 -1
  73. package/lib/import/modules-js/index.js +0 -33
  74. package/lib/import/modules-js/labels.d.ts +0 -20
  75. package/lib/import/modules-js/labels.js +0 -148
  76. package/lib/import/modules-js/locales.d.ts +0 -24
  77. package/lib/import/modules-js/locales.js +0 -196
  78. package/lib/import/modules-js/marketplace-apps.d.ts +0 -63
  79. package/lib/import/modules-js/marketplace-apps.js +0 -429
  80. package/lib/import/modules-js/webhooks.d.ts +0 -17
  81. package/lib/import/modules-js/webhooks.js +0 -85
  82. package/lib/import/modules-js/workflows.d.ts +0 -19
  83. package/lib/import/modules-js/workflows.js +0 -170
  84. package/lib/utils/log.d.ts +0 -12
  85. package/lib/utils/log.js +0 -31
@@ -16,7 +16,8 @@ const global_field_helper_1 = require("../../utils/global-field-helper");
16
16
  class ImportGlobalFields extends base_class_1.default {
17
17
  constructor({ importConfig, stackAPIClient }) {
18
18
  super({ importConfig, stackAPIClient });
19
- this.importConfig.context.module = 'global-fields';
19
+ this.importConfig.context.module = utils_1.MODULE_CONTEXTS.GLOBAL_FIELDS;
20
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.GLOBAL_FIELDS];
20
21
  this.config = importConfig;
21
22
  this.gFsConfig = importConfig.modules['global-fields'];
22
23
  this.gFs = [];
@@ -34,85 +35,86 @@ class ImportGlobalFields extends base_class_1.default {
34
35
  this.gFsPendingPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'global_fields', 'pending_global_fields.js');
35
36
  this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'marketplace_apps', 'uid-mapping.json');
36
37
  }
38
+ /**
39
+ * @method start
40
+ * @returns {Promise<void>} Promise<void>
41
+ */
37
42
  async start() {
38
- var _a, _b, _c, _d;
39
- cli_utilities_1.log.debug('Reading global fields from file', this.importConfig.context);
40
- this.gFs = utils_1.fsUtil.readFile(path.join(this.gFsFolderPath, this.gFsConfig.fileName));
41
- if (!this.gFs || (0, lodash_1.isEmpty)(this.gFs)) {
42
- cli_utilities_1.log.info('No global fields found to import', this.importConfig.context);
43
- return;
44
- }
45
- const gfsCount = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
46
- cli_utilities_1.log.debug(`Loaded ${gfsCount} global field items from file`, this.importConfig.context);
47
- cli_utilities_1.log.debug('Creating global fields mapper directory', this.importConfig.context);
48
- await utils_1.fsUtil.makeDirectory(this.gFsMapperPath);
49
- cli_utilities_1.log.debug('Loading existing global fields UID data', this.importConfig.context);
50
- if (utils_1.fileHelper.fileExistsSync(this.gFsUidMapperPath)) {
51
- this.gFsUidMapper = (utils_1.fsUtil.readFile(this.gFsUidMapperPath) || {});
52
- const gfsUidCount = Object.keys(this.gFsUidMapper || {}).length;
53
- cli_utilities_1.log.debug(`Loaded existing global fields UID data: ${gfsUidCount} items`, this.importConfig.context);
54
- }
55
- else {
56
- cli_utilities_1.log.debug('No existing global fields UID data found', this.importConfig.context);
57
- }
58
- cli_utilities_1.log.debug('Loading installed extensions data', this.importConfig.context);
59
- this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
60
- const installedExtCount = Object.keys(this.installedExtensions || {}).length;
61
- cli_utilities_1.log.debug(`Loaded ${installedExtCount} installed extension references`, this.importConfig.context);
62
- cli_utilities_1.log.debug('Starting global fields seeding process', this.importConfig.context);
63
- await this.seedGFs();
64
- if ((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) {
65
- utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
66
- cli_utilities_1.log.debug(`Written ${this.pendingGFs.length} pending global fields to file`, this.importConfig.context);
67
- }
68
- cli_utilities_1.log.success('Created Global Fields', this.importConfig.context);
69
- cli_utilities_1.log.debug('Starting global fields update process', this.importConfig.context);
70
- await this.updateGFs();
71
- if ((_b = this.pendingGFs) === null || _b === void 0 ? void 0 : _b.length)
72
- utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
73
- cli_utilities_1.log.success('Updated Global Fields', this.importConfig.context);
74
- if (this.importConfig.replaceExisting && this.existingGFs.length > 0) {
75
- cli_utilities_1.log.debug(`Replacing ${this.existingGFs.length} existing global fields`, this.importConfig.context);
76
- await this.replaceGFs().catch((error) => {
77
- cli_utilities_1.log.debug('Error replacing global fields', this.importConfig.context);
78
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
79
- });
80
- }
81
- cli_utilities_1.log.debug('Processing global fields import results', this.importConfig.context);
82
- if ((_c = this.createdGFs) === null || _c === void 0 ? void 0 : _c.length) {
83
- utils_1.fsUtil.writeFile(this.gFsSuccessPath, this.createdGFs);
84
- cli_utilities_1.log.debug(`Written ${this.createdGFs.length} successful global fields to file`, this.importConfig.context);
43
+ try {
44
+ cli_utilities_1.log.debug('Starting global fields import process...', this.importConfig.context);
45
+ const [globalFieldsCount] = await this.analyzeGlobalFields();
46
+ if (globalFieldsCount === 0) {
47
+ cli_utilities_1.log.info('No global fields found to import', this.importConfig.context);
48
+ return;
49
+ }
50
+ const progress = this.createNestedProgress(this.currentModuleName);
51
+ progress.addProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE, globalFieldsCount);
52
+ progress.addProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE, globalFieldsCount);
53
+ await this.prepareGlobalFieldMapper();
54
+ // Step 1: Create global fields
55
+ progress
56
+ .startProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE)
57
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE].CREATING, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE);
58
+ cli_utilities_1.log.info('Starting Create process', this.importConfig.context);
59
+ await this.seedGFs();
60
+ progress.completeProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE, true);
61
+ // Step 2: Update global fields with references
62
+ progress
63
+ .startProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE)
64
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE].UPDATING, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE);
65
+ cli_utilities_1.log.info('Starting Update process', this.importConfig.context);
66
+ await this.updateGFs();
67
+ progress.completeProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE, true);
68
+ // Step 3: Replace existing global fields if needed
69
+ if (this.importConfig.replaceExisting && this.existingGFs.length > 0) {
70
+ progress.addProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING, this.existingGFs.length);
71
+ progress
72
+ .startProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING)
73
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING].REPLACING, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING);
74
+ cli_utilities_1.log.info('Starting Replace Existing process', this.importConfig.context);
75
+ await this.replaceGFs();
76
+ progress.completeProcess(utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING, true);
77
+ }
78
+ await this.processGlobalFieldResults();
79
+ this.completeProgress(true);
80
+ cli_utilities_1.log.success('Global fields import has been completed!', this.importConfig.context);
85
81
  }
86
- if ((_d = this.failedGFs) === null || _d === void 0 ? void 0 : _d.length) {
87
- utils_1.fsUtil.writeFile(this.gFsFailsPath, this.failedGFs);
88
- cli_utilities_1.log.debug(`Written ${this.failedGFs.length} failed global fields to file`, this.importConfig.context);
82
+ catch (error) {
83
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Global fields import failed');
84
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
89
85
  }
90
- cli_utilities_1.log.success('Global fields import has been completed!', this.importConfig.context);
91
86
  }
92
87
  async seedGFs() {
93
88
  cli_utilities_1.log.debug('Starting global fields seeding process', this.importConfig.context);
94
- const gfsToSeed = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
89
+ const gfsToSeed = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs || {}).length;
95
90
  cli_utilities_1.log.debug(`Seeding ${gfsToSeed} global fields`, this.importConfig.context);
96
91
  const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
92
+ var _a;
97
93
  this.createdGFs.push(globalField);
98
94
  this.gFsUidMapper[uid] = globalField;
95
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `global field: ${globalField.uid}`, null, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE);
99
96
  cli_utilities_1.log.success(`Global field ${globalField.uid} created successfully`, this.importConfig.context);
100
- cli_utilities_1.log.debug(`Global field creation completed: ${globalField.uid}`, this.importConfig.context);
97
+ cli_utilities_1.log.debug(`Global field Create completed: ${globalField.uid}`, this.importConfig.context);
101
98
  };
102
99
  const onReject = ({ error, apiData: globalField = undefined }) => {
103
- var _a, _b;
100
+ var _a, _b, _c, _d, _e;
104
101
  const uid = (_a = globalField === null || globalField === void 0 ? void 0 : globalField.global_field) === null || _a === void 0 ? void 0 : _a.uid;
105
- cli_utilities_1.log.debug(`Global field '${uid}' creation failed`, this.importConfig.context);
102
+ cli_utilities_1.log.debug(`Global field '${uid}' Create failed`, this.importConfig.context);
106
103
  if ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.title) {
107
104
  if (this.importConfig.replaceExisting) {
108
105
  this.existingGFs.push(globalField);
106
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `global field: ${uid} (marked for replacement)`, null, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE);
109
107
  cli_utilities_1.log.debug(`Global field '${uid}' marked for replacement`, this.importConfig.context);
110
108
  }
109
+ else {
110
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(true, `global field: ${uid} (already exists)`, null, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE);
111
+ }
111
112
  if (!this.importConfig.skipExisting) {
112
113
  cli_utilities_1.log.info(`Global fields '${uid}' already exist`, this.importConfig.context);
113
114
  }
114
115
  }
115
116
  else {
117
+ (_e = this.progressManager) === null || _e === void 0 ? void 0 : _e.tick(false, `global field: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to create global field', utils_1.PROCESS_NAMES.GLOBAL_FIELDS_CREATE);
116
118
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Global fields '${uid}' failed to import`);
117
119
  this.failedGFs.push({ uid });
118
120
  }
@@ -149,14 +151,18 @@ class ImportGlobalFields extends base_class_1.default {
149
151
  return apiOptions;
150
152
  }
151
153
  async updateGFs() {
152
- cli_utilities_1.log.debug('Starting global fields update process', this.importConfig.context);
153
- const gfsToUpdate = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
154
+ cli_utilities_1.log.debug('Starting Update process', this.importConfig.context);
155
+ const gfsToUpdate = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs || {}).length;
154
156
  cli_utilities_1.log.debug(`Updating ${gfsToUpdate} global fields`, this.importConfig.context);
155
157
  const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
156
- cli_utilities_1.log.info(`Updated the global field ${uid}`, this.importConfig.context);
158
+ var _a;
159
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `global field: ${uid}`, null, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE);
160
+ cli_utilities_1.log.success(`Updated the global field ${uid}`, this.importConfig.context);
157
161
  cli_utilities_1.log.debug(`Global field update completed: ${uid}`, this.importConfig.context);
158
162
  };
159
163
  const onReject = ({ error, apiData: { uid } = undefined }) => {
164
+ var _a;
165
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `global field: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Failed to update the global field '${uid}'`, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_UPDATE);
160
166
  cli_utilities_1.log.debug(`Global field '${uid}' update failed`, this.importConfig.context);
161
167
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to update the global field '${uid}'`);
162
168
  };
@@ -172,7 +178,7 @@ class ImportGlobalFields extends base_class_1.default {
172
178
  },
173
179
  concurrencyLimit: this.reqConcurrency,
174
180
  }, this.updateSerializedGFs.bind(this));
175
- cli_utilities_1.log.debug('Global fields update process completed', this.importConfig.context);
181
+ cli_utilities_1.log.debug('Update process completed', this.importConfig.context);
176
182
  return result;
177
183
  }
178
184
  async updateSerializedGFs({ apiParams, element: globalField, isLastRequest, }) {
@@ -219,17 +225,19 @@ class ImportGlobalFields extends base_class_1.default {
219
225
  async replaceGFs() {
220
226
  cli_utilities_1.log.debug(`Replacing ${this.existingGFs.length} existing global fields`, this.importConfig.context);
221
227
  const onSuccess = ({ response: globalField, apiData }) => {
222
- var _a, _b, _c;
228
+ var _a, _b, _c, _d;
223
229
  const uid = (_c = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.uid) !== null && _a !== void 0 ? _a : (_b = apiData === null || apiData === void 0 ? void 0 : apiData.global_field) === null || _b === void 0 ? void 0 : _b.uid) !== null && _c !== void 0 ? _c : 'unknown';
224
230
  this.createdGFs.push(globalField);
225
231
  this.gFsUidMapper[uid] = globalField;
232
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(true, `global field: ${uid} (replaced)`, null, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING);
226
233
  utils_1.fsUtil.writeFile(this.gFsUidMapperPath, this.gFsUidMapper);
227
234
  cli_utilities_1.log.success(`Global field '${uid}' replaced successfully`, this.importConfig.context);
228
235
  cli_utilities_1.log.debug(`Global field replacement completed: ${uid}`, this.importConfig.context);
229
236
  };
230
237
  const onReject = ({ error, apiData }) => {
231
- var _a, _b, _c;
238
+ var _a, _b, _c, _d;
232
239
  const uid = (_c = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.uid) !== null && _a !== void 0 ? _a : (_b = apiData === null || apiData === void 0 ? void 0 : apiData.global_field) === null || _b === void 0 ? void 0 : _b.uid) !== null && _c !== void 0 ? _c : 'unknown';
240
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(false, `global field: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Global fields '${uid}' failed to replace`, utils_1.PROCESS_NAMES.GLOBAL_FIELDS_REPLACE_EXISTING);
233
241
  cli_utilities_1.log.debug(`Global field '${uid}' replacement failed`, this.importConfig.context);
234
242
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Global fields '${uid}' failed to replace`);
235
243
  this.failedGFs.push({ uid });
@@ -247,7 +255,7 @@ class ImportGlobalFields extends base_class_1.default {
247
255
  },
248
256
  concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
249
257
  }, undefined, false);
250
- cli_utilities_1.log.debug('Global fields replacement process completed', this.importConfig.context);
258
+ cli_utilities_1.log.debug('Replace Existing process completed', this.importConfig.context);
251
259
  }
252
260
  /**
253
261
  * @method serializeReplaceGFs
@@ -267,5 +275,57 @@ class ImportGlobalFields extends base_class_1.default {
267
275
  apiOptions.apiData = globalFieldPayload;
268
276
  return apiOptions;
269
277
  }
278
+ async analyzeGlobalFields() {
279
+ return this.withLoadingSpinner('GLOBAL FIELDS: Analyzing import data...', async () => {
280
+ var _a, _b;
281
+ cli_utilities_1.log.debug('Checking for global fields folder existence', this.importConfig.context);
282
+ if (!utils_1.fileHelper.fileExistsSync(this.gFsFolderPath)) {
283
+ cli_utilities_1.log.info(`No global fields found - '${this.gFsFolderPath}'`, this.importConfig.context);
284
+ return [0];
285
+ }
286
+ cli_utilities_1.log.debug(`Found global fields folder: ${this.gFsFolderPath}`, this.importConfig.context);
287
+ this.gFs = utils_1.fsUtil.readFile(path.join(this.gFsFolderPath, this.gFsConfig.fileName));
288
+ if (!this.gFs || (0, lodash_1.isEmpty)(this.gFs)) {
289
+ cli_utilities_1.log.info(`No global fields found in file - '${path.join(this.gFsFolderPath, this.gFsConfig.fileName)}'`, this.importConfig.context);
290
+ return [0];
291
+ }
292
+ const count = Array.isArray(this.gFs) ? (_a = this.gFs) === null || _a === void 0 ? void 0 : _a.length : (_b = Object.keys(this.gFs || {})) === null || _b === void 0 ? void 0 : _b.length;
293
+ cli_utilities_1.log.debug(`Loaded ${count} global field items from file`, this.importConfig.context);
294
+ return [count];
295
+ });
296
+ }
297
+ async prepareGlobalFieldMapper() {
298
+ cli_utilities_1.log.debug('Creating global fields mapper directory', this.importConfig.context);
299
+ await utils_1.fsUtil.makeDirectory(this.gFsMapperPath);
300
+ cli_utilities_1.log.debug('Loading existing global fields UID data', this.importConfig.context);
301
+ if (utils_1.fileHelper.fileExistsSync(this.gFsUidMapperPath)) {
302
+ this.gFsUidMapper = (utils_1.fsUtil.readFile(this.gFsUidMapperPath) || {});
303
+ const gfsUidCount = Object.keys(this.gFsUidMapper || {}).length;
304
+ cli_utilities_1.log.debug(`Loaded existing global fields UID data: ${gfsUidCount} items`, this.importConfig.context);
305
+ }
306
+ else {
307
+ cli_utilities_1.log.debug('No existing global fields UID data found', this.importConfig.context);
308
+ }
309
+ cli_utilities_1.log.debug('Loading installed extensions data', this.importConfig.context);
310
+ this.installedExtensions = (utils_1.fsUtil.readFile(this.marketplaceAppMapperPath) || { extension_uid: {} }).extension_uid;
311
+ const installedExtCount = Object.keys(this.installedExtensions || {}).length;
312
+ cli_utilities_1.log.debug(`Loaded ${installedExtCount} installed extension references`, this.importConfig.context);
313
+ }
314
+ async processGlobalFieldResults() {
315
+ var _a, _b, _c;
316
+ cli_utilities_1.log.debug('Processing global fields import results', this.importConfig.context);
317
+ if ((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) {
318
+ utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
319
+ cli_utilities_1.log.debug(`Written ${this.pendingGFs.length} pending global fields to file`, this.importConfig.context);
320
+ }
321
+ if ((_b = this.createdGFs) === null || _b === void 0 ? void 0 : _b.length) {
322
+ utils_1.fsUtil.writeFile(this.gFsSuccessPath, this.createdGFs);
323
+ cli_utilities_1.log.debug(`Written ${this.createdGFs.length} successful global fields to file`, this.importConfig.context);
324
+ }
325
+ if ((_c = this.failedGFs) === null || _c === void 0 ? void 0 : _c.length) {
326
+ utils_1.fsUtil.writeFile(this.gFsFailsPath, this.failedGFs);
327
+ cli_utilities_1.log.debug(`Written ${this.failedGFs.length} failed global fields to file`, this.importConfig.context);
328
+ }
329
+ }
270
330
  }
271
331
  exports.default = ImportGlobalFields;
@@ -1,2 +1,3 @@
1
1
  import { ModuleClassParams } from '../../types';
2
+ import '../../utils/progress-strategy-registry';
2
3
  export default function startModuleImport(modulePayload: ModuleClassParams): Promise<any>;
@@ -24,6 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  var _a;
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
+ require("../../utils/progress-strategy-registry");
27
28
  async function startModuleImport(modulePayload) {
28
29
  const { default: ModuleRunner } = await (_a = `./${modulePayload.moduleName}`, Promise.resolve().then(() => __importStar(require(_a))));
29
30
  const moduleRunner = new ModuleRunner(modulePayload);
@@ -31,4 +31,7 @@ export default class ImportLabels extends BaseClass {
31
31
  * @returns {ApiOptions} ApiOptions
32
32
  */
33
33
  serializeUpdateLabels(apiOptions: ApiOptions): ApiOptions;
34
+ private analyzeLabels;
35
+ private prepareLabelMapper;
36
+ private processLabelResults;
34
37
  }
@@ -1,17 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
- const values_1 = tslib_1.__importDefault(require("lodash/values"));
6
4
  const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
7
5
  const node_path_1 = require("node:path");
8
- const utils_1 = require("../../utils");
6
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
7
+ const values_1 = tslib_1.__importDefault(require("lodash/values"));
9
8
  const cli_utilities_1 = require("@contentstack/cli-utilities");
9
+ const utils_1 = require("../../utils");
10
10
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
11
11
  class ImportLabels extends base_class_1.default {
12
12
  constructor({ importConfig, stackAPIClient }) {
13
13
  super({ importConfig, stackAPIClient });
14
- this.importConfig.context.module = 'labels';
14
+ this.importConfig.context.module = utils_1.MODULE_CONTEXTS.LABELS;
15
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.LABELS];
15
16
  this.labelsConfig = importConfig.modules.labels;
16
17
  this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'labels');
17
18
  this.labelsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.labelsConfig.dirName);
@@ -28,77 +29,72 @@ class ImportLabels extends base_class_1.default {
28
29
  * @returns {Promise<void>} Promise<void>
29
30
  */
30
31
  async start() {
31
- var _a, _b;
32
- cli_utilities_1.log.debug('Checking for labels folder existence', this.importConfig.context);
33
- //Step1 check folder exists or not
34
- if (utils_1.fileHelper.fileExistsSync(this.labelsFolderPath)) {
35
- cli_utilities_1.log.debug(`Found labels folder: ${this.labelsFolderPath}`, this.importConfig.context);
36
- this.labels = utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelsFolderPath, 'labels.json'), true);
37
- // Check if labels file was read successfully
38
- if (!this.labels) {
39
- cli_utilities_1.log.info(`No labels found in file - '${(0, node_path_1.join)(this.labelsFolderPath, 'labels.json')}'`, this.importConfig.context);
32
+ try {
33
+ cli_utilities_1.log.debug('Starting labels import process...', this.importConfig.context);
34
+ const [labelsCount] = await this.analyzeLabels();
35
+ if (labelsCount === 0) {
36
+ cli_utilities_1.log.info('No labels found to import', this.importConfig.context);
40
37
  return;
41
38
  }
42
- const labelCount = Object.keys(this.labels || {}).length;
43
- cli_utilities_1.log.debug(`Loaded ${labelCount} label items from file`, this.importConfig.context);
44
- }
45
- else {
46
- cli_utilities_1.log.info(`No labels found - '${this.labelsFolderPath}'`, this.importConfig.context);
47
- return;
39
+ const progress = this.createNestedProgress(this.currentModuleName);
40
+ progress.addProcess(utils_1.PROCESS_NAMES.LABELS_CREATE, labelsCount);
41
+ progress.addProcess(utils_1.PROCESS_NAMES.LABELS_UPDATE, labelsCount);
42
+ await this.prepareLabelMapper();
43
+ // Step 1: Import labels (without parent references)
44
+ progress
45
+ .startProcess(utils_1.PROCESS_NAMES.LABELS_CREATE)
46
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.LABELS_CREATE].CREATING, utils_1.PROCESS_NAMES.LABELS_CREATE);
47
+ cli_utilities_1.log.info('Starting labels creation process', this.importConfig.context);
48
+ await this.importLabels();
49
+ progress.completeProcess(utils_1.PROCESS_NAMES.LABELS_CREATE, true);
50
+ // Step 2: Update labels with parent references
51
+ progress
52
+ .startProcess(utils_1.PROCESS_NAMES.LABELS_UPDATE)
53
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.LABELS_UPDATE].UPDATING, utils_1.PROCESS_NAMES.LABELS_UPDATE);
54
+ cli_utilities_1.log.info('Starting labels update process', this.importConfig.context);
55
+ await this.updateLabels();
56
+ progress.completeProcess(utils_1.PROCESS_NAMES.LABELS_UPDATE, true);
57
+ this.processLabelResults();
58
+ this.completeProgress(true);
59
+ cli_utilities_1.log.success('Labels have been imported successfully!', this.importConfig.context);
48
60
  }
49
- //create labels in mapper directory
50
- cli_utilities_1.log.debug('Creating labels mapper directory', this.importConfig.context);
51
- await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
52
- cli_utilities_1.log.debug('Loading existing label UID mappings', this.importConfig.context);
53
- this.labelUidMapper = utils_1.fileHelper.fileExistsSync(this.labelUidMapperPath)
54
- ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelUidMapperPath), true) || {}
55
- : {};
56
- if (Object.keys(this.labelUidMapper || {}).length > 0) {
57
- const labelUidCount = Object.keys(this.labelUidMapper || {}).length;
58
- cli_utilities_1.log.debug(`Loaded existing label UID data: ${labelUidCount} items`, this.importConfig.context);
59
- }
60
- else {
61
- cli_utilities_1.log.debug('No existing label UID mappings found', this.importConfig.context);
62
- }
63
- cli_utilities_1.log.debug('Starting labels import', this.importConfig.context);
64
- await this.importLabels();
65
- //update parent in created label
66
- cli_utilities_1.log.debug('Starting labels update process', this.importConfig.context);
67
- await this.updateLabels();
68
- cli_utilities_1.log.debug('Processing labels import results', this.importConfig.context);
69
- if ((_a = this.createdLabel) === null || _a === void 0 ? void 0 : _a.length) {
70
- utils_1.fsUtil.writeFile(this.createdLabelPath, this.createdLabel);
71
- cli_utilities_1.log.debug(`Written ${this.createdLabel.length} successful labels to file`, this.importConfig.context);
72
- }
73
- if ((_b = this.failedLabel) === null || _b === void 0 ? void 0 : _b.length) {
74
- utils_1.fsUtil.writeFile(this.labelFailsPath, this.failedLabel);
75
- cli_utilities_1.log.debug(`Written ${this.failedLabel.length} failed labels to file`, this.importConfig.context);
61
+ catch (error) {
62
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Labels import failed');
63
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
76
64
  }
77
- cli_utilities_1.log.success('Labels have been imported successfully!', this.importConfig.context);
78
65
  }
79
66
  async importLabels() {
67
+ cli_utilities_1.log.debug('Validating labels data', this.importConfig.context);
80
68
  if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
81
69
  cli_utilities_1.log.info('No Labels Found', this.importConfig.context);
82
70
  return;
83
71
  }
84
72
  const apiContent = (0, values_1.default)(this.labels);
73
+ cli_utilities_1.log.debug(`Starting to import ${apiContent.length} labels`, this.importConfig.context);
85
74
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
75
+ var _a;
86
76
  this.labelUidMapper[uid] = response;
77
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `label: ${name || uid}`, null, utils_1.PROCESS_NAMES.LABELS_CREATE);
87
78
  cli_utilities_1.log.success(`Label '${name}' imported successfully`, this.importConfig.context);
79
+ cli_utilities_1.log.debug(`Label UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
88
80
  utils_1.fsUtil.writeFile(this.labelUidMapperPath, this.labelUidMapper);
89
81
  };
90
82
  const onReject = ({ error, apiData }) => {
91
- var _a;
83
+ var _a, _b, _c;
92
84
  const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
93
- const { name } = apiData;
85
+ const { name, uid } = apiData;
86
+ cli_utilities_1.log.debug(`Label '${name}' (${uid}) failed to import`, this.importConfig.context);
94
87
  if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
88
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `label: ${name || uid} (already exists)`, null, utils_1.PROCESS_NAMES.LABELS_CREATE);
95
89
  cli_utilities_1.log.info(`Label '${name}' already exists`, this.importConfig.context);
96
90
  }
97
91
  else {
98
92
  this.failedLabel.push(apiData);
93
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `label: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to import label', utils_1.PROCESS_NAMES.LABELS_CREATE);
99
94
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Label '${name}' failed to be import`);
100
95
  }
101
96
  };
97
+ cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
102
98
  await this.makeConcurrentCall({
103
99
  apiContent,
104
100
  processName: 'create labels',
@@ -111,6 +107,7 @@ class ImportLabels extends base_class_1.default {
111
107
  },
112
108
  concurrencyLimit: this.importConfig.fetchConcurrency || 1,
113
109
  }, undefined, false);
110
+ cli_utilities_1.log.debug('Labels creation process completed', this.importConfig.context);
114
111
  }
115
112
  /**
116
113
  * @method serializeLabels
@@ -118,17 +115,18 @@ class ImportLabels extends base_class_1.default {
118
115
  * @returns {ApiOptions} ApiOptions
119
116
  */
120
117
  serializeLabels(apiOptions) {
121
- var _a;
118
+ var _a, _b;
122
119
  const { apiData: label } = apiOptions;
123
120
  cli_utilities_1.log.debug(`Serializing label: ${label.name} (${label.uid})`, this.importConfig.context);
124
121
  if (this.labelUidMapper.hasOwnProperty(label.uid)) {
125
122
  cli_utilities_1.log.info(`Label '${label.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
126
123
  cli_utilities_1.log.debug(`Skipping label serialization for: ${label.uid}`, this.importConfig.context);
124
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `label: ${label.name} (skipped - already exists)`, null, utils_1.PROCESS_NAMES.LABELS_CREATE);
127
125
  apiOptions.entity = undefined;
128
126
  }
129
127
  else {
130
128
  let labelReq = label;
131
- if (((_a = label === null || label === void 0 ? void 0 : label.parent) === null || _a === void 0 ? void 0 : _a.length) != 0) {
129
+ if (((_b = label === null || label === void 0 ? void 0 : label.parent) === null || _b === void 0 ? void 0 : _b.length) != 0) {
132
130
  cli_utilities_1.log.debug(`Label '${label.name}' has parent labels, removing parent for initial creation`, this.importConfig.context);
133
131
  labelReq = (0, omit_1.default)(label, ['parent']);
134
132
  }
@@ -142,13 +140,18 @@ class ImportLabels extends base_class_1.default {
142
140
  const apiContent = (0, values_1.default)(this.labels);
143
141
  cli_utilities_1.log.debug(`Updating ${apiContent.length} labels`, this.importConfig.context);
144
142
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
143
+ var _a;
145
144
  this.createdLabel.push(response);
145
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `label: ${name || uid}`, null, utils_1.PROCESS_NAMES.LABELS_UPDATE);
146
146
  cli_utilities_1.log.success(`Label '${name}' updated successfully`, this.importConfig.context);
147
147
  cli_utilities_1.log.debug(`Label update completed: ${name} (${uid})`, this.importConfig.context);
148
148
  };
149
149
  const onReject = ({ error, apiData }) => {
150
- cli_utilities_1.log.debug(`Label '${apiData === null || apiData === void 0 ? void 0 : apiData.name}' update failed`, this.importConfig.context);
151
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name: apiData === null || apiData === void 0 ? void 0 : apiData.name }), `Failed to update label '${apiData === null || apiData === void 0 ? void 0 : apiData.name}'`);
150
+ var _a;
151
+ const { name, uid } = apiData;
152
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `label: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to update label', utils_1.PROCESS_NAMES.LABELS_UPDATE);
153
+ cli_utilities_1.log.debug(`Label '${name}' update failed`, this.importConfig.context);
154
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name: name }), `Failed to update label '${name}'`);
152
155
  };
153
156
  cli_utilities_1.log.debug(`Using concurrency limit for updates: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
154
157
  await this.makeConcurrentCall({
@@ -175,7 +178,7 @@ class ImportLabels extends base_class_1.default {
175
178
  * @returns {ApiOptions} ApiOptions
176
179
  */
177
180
  serializeUpdateLabels(apiOptions) {
178
- var _a, _b;
181
+ var _a, _b, _c, _d;
179
182
  const { apiData: label } = apiOptions;
180
183
  const labelUid = label.uid;
181
184
  cli_utilities_1.log.debug(`Serializing label update: ${label.name} (${labelUid})`, this.importConfig.context);
@@ -198,15 +201,62 @@ class ImportLabels extends base_class_1.default {
198
201
  }
199
202
  else {
200
203
  cli_utilities_1.log.debug(`Label '${label.name}' has no parent labels, adding to created list`, this.importConfig.context);
204
+ (_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `label: ${label.name} (no parent update needed)`, null, utils_1.PROCESS_NAMES.LABELS_UPDATE);
201
205
  apiOptions.entity = undefined;
202
206
  this.createdLabel.push(newLabel);
203
207
  }
204
208
  }
205
209
  else {
206
210
  cli_utilities_1.log.debug(`Label '${label.name}' not found in UID mapper, skipping update`, this.importConfig.context);
211
+ (_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(true, `label: ${label.name} (skipped - not found)`, null, utils_1.PROCESS_NAMES.LABELS_UPDATE);
207
212
  apiOptions.entity = undefined;
208
213
  }
209
214
  return apiOptions;
210
215
  }
216
+ async analyzeLabels() {
217
+ return this.withLoadingSpinner('LABELS: Analyzing import data...', async () => {
218
+ cli_utilities_1.log.debug('Checking for labels folder existence', this.importConfig.context);
219
+ if (!utils_1.fileHelper.fileExistsSync(this.labelsFolderPath)) {
220
+ cli_utilities_1.log.info(`No labels found - '${this.labelsFolderPath}'`, this.importConfig.context);
221
+ return [0];
222
+ }
223
+ cli_utilities_1.log.debug(`Found labels folder: ${this.labelsFolderPath}`, this.importConfig.context);
224
+ this.labels = utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelsFolderPath, 'labels.json'), true);
225
+ if (!this.labels) {
226
+ cli_utilities_1.log.info(`No labels found in file - '${(0, node_path_1.join)(this.labelsFolderPath, 'labels.json')}'`, this.importConfig.context);
227
+ return [0];
228
+ }
229
+ const count = Object.keys(this.labels || {}).length;
230
+ cli_utilities_1.log.debug(`Loaded ${count} label items from file`, this.importConfig.context);
231
+ return [count];
232
+ });
233
+ }
234
+ async prepareLabelMapper() {
235
+ cli_utilities_1.log.debug('Creating labels mapper directory', this.importConfig.context);
236
+ await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
237
+ cli_utilities_1.log.debug('Loading existing label UID mappings', this.importConfig.context);
238
+ this.labelUidMapper = utils_1.fileHelper.fileExistsSync(this.labelUidMapperPath)
239
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelUidMapperPath), true) || {}
240
+ : {};
241
+ const count = Object.keys(this.labelUidMapper || {}).length;
242
+ if (count > 0) {
243
+ cli_utilities_1.log.debug(`Loaded existing label UID data: ${count} items`, this.importConfig.context);
244
+ }
245
+ else {
246
+ cli_utilities_1.log.debug('No existing label UID mappings found', this.importConfig.context);
247
+ }
248
+ }
249
+ processLabelResults() {
250
+ var _a, _b;
251
+ cli_utilities_1.log.debug('Processing labels import results', this.importConfig.context);
252
+ if ((_a = this.createdLabel) === null || _a === void 0 ? void 0 : _a.length) {
253
+ utils_1.fsUtil.writeFile(this.createdLabelPath, this.createdLabel);
254
+ cli_utilities_1.log.debug(`Written ${this.createdLabel.length} successful labels to file`, this.importConfig.context);
255
+ }
256
+ if ((_b = this.failedLabel) === null || _b === void 0 ? void 0 : _b.length) {
257
+ utils_1.fsUtil.writeFile(this.labelFailsPath, this.failedLabel);
258
+ cli_utilities_1.log.debug(`Written ${this.failedLabel.length} failed labels to file`, this.importConfig.context);
259
+ }
260
+ }
211
261
  }
212
262
  exports.default = ImportLabels;
@@ -3,8 +3,8 @@
3
3
  * Copyright (c) 2024 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
- import { ModuleClassParams } from '../../types';
7
6
  import BaseClass from './base-class';
7
+ import { ModuleClassParams } from '../../types';
8
8
  export default class ImportLocales extends BaseClass {
9
9
  private langMapperPath;
10
10
  private langFolderPath;
@@ -24,8 +24,19 @@ export default class ImportLocales extends BaseClass {
24
24
  private masterLanguageConfig;
25
25
  private sourceMasterLanguage;
26
26
  constructor({ importConfig, stackAPIClient }: ModuleClassParams);
27
- start(): Promise<any>;
28
- checkAndUpdateMasterLocale(): Promise<any>;
27
+ start(): Promise<void>;
28
+ checkAndUpdateMasterLocale(): Promise<void>;
29
29
  createLocales(): Promise<any>;
30
- updateLocales(): Promise<unknown>;
30
+ updateLocales(): Promise<any>;
31
+ private analyzeLocales;
32
+ private setupLocalesProgress;
33
+ private prepareLocalesMapper;
34
+ private processMasterLocale;
35
+ private processLocaleCreation;
36
+ private processLocaleUpdate;
37
+ private getSourceMasterLangDetails;
38
+ private fetchTargetMasterLocale;
39
+ private logCodeMismatch;
40
+ private handleNameMismatch;
41
+ private tickProgress;
31
42
  }