@contentstack/cli-cm-branches 1.4.1 → 1.4.3

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.
package/README.md CHANGED
@@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches
37
37
  $ csdx COMMAND
38
38
  running command...
39
39
  $ csdx (--version)
40
- @contentstack/cli-cm-branches/1.4.1 linux-x64 node-v22.14.0
40
+ @contentstack/cli-cm-branches/1.4.3 linux-x64 node-v22.16.0
41
41
  $ csdx --help [COMMAND]
42
42
  USAGE
43
43
  $ csdx COMMAND
@@ -84,15 +84,13 @@ class MergeHandler {
84
84
  deleted: [],
85
85
  };
86
86
  const selectedItems = await (0, utils_1.selectCustomPreferences)(module, this.branchCompareData[module]);
87
- if (!selectedItems.length) {
88
- cli_utilities_1.cliux.print(chalk_1.default.red('No items were selected'));
89
- process.exit(1);
87
+ if (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) {
88
+ (0, forEach_1.default)(selectedItems, (item) => {
89
+ this.mergeSettings.mergeContent[module][item.status].push(item.value);
90
+ this.mergeSettings.itemMergeStrategies.push(item.value);
91
+ });
92
+ this.mergeSettings.strategy = 'ignore';
90
93
  }
91
- (0, forEach_1.default)(selectedItems, (item) => {
92
- this.mergeSettings.mergeContent[module][item.status].push(item.value);
93
- this.mergeSettings.itemMergeStrategies.push(item.value);
94
- });
95
- this.mergeSettings.strategy = 'ignore';
96
94
  }
97
95
  }
98
96
  else if (this.strategy === 'merge_prefer_base') {
@@ -120,12 +118,20 @@ class MergeHandler {
120
118
  else if (this.strategy === 'overwrite_with_compare') {
121
119
  this.mergeSettings.strategy = 'overwrite_with_compare';
122
120
  }
123
- if (this.checkEmptySelection()) {
124
- cli_utilities_1.cliux.print(chalk_1.default.red('No items selected'));
121
+ const { allEmpty, moduleStatus } = this.checkEmptySelection();
122
+ const strategyName = this.mergeSettings.strategy;
123
+ if (allEmpty) {
124
+ cli_utilities_1.cliux.print(chalk_1.default.red(`No items selected according to the '${strategyName}' strategy.`));
125
+ process.exit(1);
125
126
  }
126
- else {
127
- await this.displayMergeSummary();
127
+ for (const [type, { exists, empty }] of Object.entries(moduleStatus)) {
128
+ if (exists && empty) {
129
+ const readable = type === 'contentType' ? 'Content Types' : 'Global fields';
130
+ cli_utilities_1.cliux.print('\n');
131
+ cli_utilities_1.cliux.print(chalk_1.default.yellow(`Note: No ${readable} selected according to the '${strategyName}' strategy.`));
132
+ }
128
133
  }
134
+ this.displayMergeSummary();
129
135
  if (!this.executeOption) {
130
136
  const executionResponse = await (0, utils_1.selectMergeExecution)();
131
137
  if (executionResponse === 'previous') {
@@ -145,16 +151,58 @@ class MergeHandler {
145
151
  }
146
152
  }
147
153
  }
154
+ /**
155
+ * Checks whether the selection of modules in the compare branch data is empty.
156
+ *
157
+ * This method evaluates the branch compare data and determines if there are any changes
158
+ * (added, modified, or deleted) in the modules based on the merge strategy defined in the
159
+ * merge settings. It categorizes the status of each module as either existing and empty or
160
+ * not empty.
161
+ *
162
+ * @returns An object containing:
163
+ * - `allEmpty`: A boolean indicating whether all modules are either non-existent or empty.
164
+ * - `moduleStatus`: A record mapping module types (`contentType` and `globalField`) to their
165
+ * respective statuses, which include:
166
+ * - `exists`: A boolean indicating whether the module exists in the branch comparison data.
167
+ * - `empty`: A boolean indicating whether the module has no changes (added, modified, or deleted).
168
+ */
148
169
  checkEmptySelection() {
149
- var _a, _b, _c, _d, _e, _f;
150
- for (let module in this.branchCompareData) {
151
- if (((_b = (_a = this.mergeSettings.mergeContent[module]) === null || _a === void 0 ? void 0 : _a.modified) === null || _b === void 0 ? void 0 : _b.length)
152
- || ((_d = (_c = this.mergeSettings.mergeContent[module]) === null || _c === void 0 ? void 0 : _c.added) === null || _d === void 0 ? void 0 : _d.length)
153
- || ((_f = (_e = this.mergeSettings.mergeContent[module]) === null || _e === void 0 ? void 0 : _e.deleted) === null || _f === void 0 ? void 0 : _f.length)) {
154
- return false;
170
+ const strategy = this.mergeSettings.strategy;
171
+ const useMergeContent = new Set(['custom_preferences', 'ignore']);
172
+ const modifiedOnlyStrategies = new Set(['merge_modified_only_prefer_base', 'merge_modified_only_prefer_compare']);
173
+ const addedOnlyStrategies = new Set(['merge_new_only']);
174
+ const moduleStatus = {
175
+ contentType: { exists: false, empty: true },
176
+ globalField: { exists: false, empty: true },
177
+ };
178
+ for (const module in this.branchCompareData) {
179
+ const content = useMergeContent.has(strategy)
180
+ ? this.mergeSettings.mergeContent[module]
181
+ : this.branchCompareData[module];
182
+ if (!content)
183
+ continue;
184
+ const isGlobalField = module === 'global_fields';
185
+ const type = isGlobalField ? 'globalField' : 'contentType';
186
+ moduleStatus[type].exists = true;
187
+ let hasChanges = false;
188
+ if (modifiedOnlyStrategies.has(strategy)) {
189
+ hasChanges = Array.isArray(content.modified) && content.modified.length > 0;
190
+ }
191
+ else if (addedOnlyStrategies.has(strategy)) {
192
+ hasChanges = Array.isArray(content.added) && content.added.length > 0;
193
+ }
194
+ else {
195
+ hasChanges =
196
+ (Array.isArray(content.modified) && content.modified.length > 0) ||
197
+ (Array.isArray(content.added) && content.added.length > 0) ||
198
+ (Array.isArray(content.deleted) && content.deleted.length > 0);
199
+ }
200
+ if (hasChanges) {
201
+ moduleStatus[type].empty = false;
155
202
  }
156
203
  }
157
- return true;
204
+ const allEmpty = Object.values(moduleStatus).every((status) => !status.exists || status.empty);
205
+ return { allEmpty, moduleStatus };
158
206
  }
159
207
  displayMergeSummary() {
160
208
  if (this.mergeSettings.strategy !== 'ignore') {
@@ -246,10 +294,10 @@ class MergeHandler {
246
294
  });
247
295
  };
248
296
  const mergePreferencesMap = {
249
- 'existing_new': 'merge_existing_new',
250
- 'new': 'merge_new',
251
- 'existing': 'merge_existing',
252
- 'ask_preference': 'custom',
297
+ existing_new: 'merge_existing_new',
298
+ new: 'merge_new',
299
+ existing: 'merge_existing',
300
+ ask_preference: 'custom',
253
301
  };
254
302
  const selectedMergePreference = mergePreferencesMap[mergePreference];
255
303
  if (selectedMergePreference) {
@@ -65,24 +65,23 @@ async function branchCompareSDK(payload, skip, limit) {
65
65
  queryParams['uid'] = payload.uid;
66
66
  const module = payload.module || 'all';
67
67
  switch (module) {
68
- case 'content_types' || 'content_type':
68
+ case 'content_types':
69
+ case 'content_type':
69
70
  return await branchQuery
70
71
  .contentTypes(queryParams)
71
72
  .then((data) => data)
72
73
  .catch((err) => handleErrorMsg(err, payload.spinner));
73
- break;
74
- case 'global_fields' || 'global_field':
74
+ case 'global_fields':
75
+ case 'global_field':
75
76
  return await branchQuery
76
77
  .globalFields(queryParams)
77
78
  .then((data) => data)
78
79
  .catch((err) => handleErrorMsg(err, payload.spinner));
79
- break;
80
80
  case 'all':
81
81
  return await branchQuery
82
82
  .all(queryParams)
83
83
  .then((data) => data)
84
84
  .catch((err) => handleErrorMsg(err, payload.spinner));
85
- break;
86
85
  default:
87
86
  handleErrorMsg({ errorMessage: 'Invalid module!' }, payload.spinner);
88
87
  }
@@ -73,7 +73,7 @@ async function getMergeQueueStatus(stackAPIClient, payload) {
73
73
  .mergeQueue(mergeJobUID)
74
74
  .fetch()
75
75
  .then((data) => data)
76
- .catch((err) => handleErrorMsg(err));
76
+ .catch((err) => handleErrorMsg(err, () => getMergeQueueStatus(stackAPIClient, payload)));
77
77
  }
78
78
  exports.getMergeQueueStatus = getMergeQueueStatus;
79
79
  async function executeMergeRequest(stackAPIClient, payload) {
@@ -90,10 +90,18 @@ async function executeMergeRequest(stackAPIClient, payload) {
90
90
  .branch()
91
91
  .merge(itemMergeStrategies, queryParams)
92
92
  .then((data) => data)
93
- .catch((err) => handleErrorMsg(err));
93
+ .catch((err) => handleErrorMsg(err, () => executeMergeRequest(stackAPIClient, payload)));
94
94
  }
95
95
  exports.executeMergeRequest = executeMergeRequest;
96
- function handleErrorMsg(err) {
96
+ async function handleErrorMsg(err, retryCallback) {
97
+ var _a;
98
+ // Handle rate limit exceeded (status code 429)
99
+ if ((err === null || err === void 0 ? void 0 : err.status) === 429 || ((_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.status) === 429) {
100
+ await new Promise((resolve) => setTimeout(resolve, 1000)); // 1 sec delay
101
+ if (retryCallback) {
102
+ return retryCallback(); // Retry the request
103
+ }
104
+ }
97
105
  if (err === null || err === void 0 ? void 0 : err.errorMessage) {
98
106
  cli_utilities_1.cliux.print(`Error: ${err.errorMessage}`, { color: 'red' });
99
107
  }
@@ -355,5 +355,5 @@
355
355
  ]
356
356
  }
357
357
  },
358
- "version": "1.4.1"
358
+ "version": "1.4.3"
359
359
  }
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-branches",
3
3
  "description": "Contentstack CLI plugin to do branches operations",
4
- "version": "1.4.1",
4
+ "version": "1.4.3",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
8
  "@contentstack/cli-command": "~1.5.0",
9
- "@oclif/core": "^4.2.7",
10
- "@contentstack/cli-utilities": "~1.11.0",
9
+ "@oclif/core": "^4.3.0",
10
+ "@contentstack/cli-utilities": "~1.12.0",
11
11
  "chalk": "^4.1.2",
12
12
  "just-diff": "^6.0.2",
13
13
  "lodash": "^4.17.21"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@contentstack/cli-dev-dependencies": "~1.3.0",
17
- "@oclif/plugin-help": "^6.2.25",
17
+ "@oclif/plugin-help": "^6.2.28",
18
18
  "@types/flat": "^5.0.5",
19
19
  "chai": "^4.5.0",
20
- "dotenv": "^16.4.7",
20
+ "dotenv": "^16.5.0",
21
21
  "dotenv-expand": "^9.0.0",
22
22
  "eslint": "^8.57.1",
23
- "eslint-config-oclif": "^6.0.15",
23
+ "eslint-config-oclif": "^6.0.62",
24
24
  "mocha": "10.8.2",
25
25
  "nyc": "^15.1.0",
26
- "oclif": "^4.17.30",
27
- "sinon": "^19.0.2",
26
+ "oclif": "^4.17.46",
27
+ "sinon": "^19.0.5",
28
28
  "ts-node": "^10.9.2",
29
29
  "typescript": "^4.9.5"
30
30
  },