@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 +1 -1
- package/lib/branch/merge-handler.js +71 -23
- package/lib/utils/branch-diff-utility.js +4 -5
- package/lib/utils/index.js +11 -3
- package/oclif.manifest.json +1 -1
- package/package.json +8 -8
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.
|
|
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 (
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
124
|
-
|
|
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
|
-
|
|
127
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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'
|
|
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
|
-
|
|
74
|
-
case '
|
|
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
|
}
|
package/lib/utils/index.js
CHANGED
|
@@ -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
|
}
|
package/oclif.manifest.json
CHANGED
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.
|
|
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.
|
|
10
|
-
"@contentstack/cli-utilities": "~1.
|
|
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.
|
|
17
|
+
"@oclif/plugin-help": "^6.2.28",
|
|
18
18
|
"@types/flat": "^5.0.5",
|
|
19
19
|
"chai": "^4.5.0",
|
|
20
|
-
"dotenv": "^16.
|
|
20
|
+
"dotenv": "^16.5.0",
|
|
21
21
|
"dotenv-expand": "^9.0.0",
|
|
22
22
|
"eslint": "^8.57.1",
|
|
23
|
-
"eslint-config-oclif": "^6.0.
|
|
23
|
+
"eslint-config-oclif": "^6.0.62",
|
|
24
24
|
"mocha": "10.8.2",
|
|
25
25
|
"nyc": "^15.1.0",
|
|
26
|
-
"oclif": "^4.17.
|
|
27
|
-
"sinon": "^19.0.
|
|
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
|
},
|