Skip to content

Commit 0faba53

Browse files
Merge pull request #1914 from contentstack/staging
DX | 12-05-2025 | Release
2 parents 6cfdd3a + 1845ab3 commit 0faba53

File tree

23 files changed

+1244
-731
lines changed

23 files changed

+1244
-731
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ packages/**/package-lock.json
1818
yarn.lock
1919
contents-*
2020
*.http
21-
*.todo
21+
*.todo
22+
talisman_output.log

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,5 @@ fileignoreconfig:
115115
- filename: pnpm-lock.yaml
116116
checksum: fc379207a835de8d851caa256837e2a50e0278c43e0251372f2a5292bee41fac
117117
- filename: package-lock.json
118-
checksum: 7d7b7d6d7de87a58347c4772acc536006be8459df9a4232258f6976fe2704f89
118+
checksum: 0cb373716595912a75e9fd356e7a90a67eb1d2de712c454701231e2d5dd3caf7
119119
version: ""

package-lock.json

Lines changed: 1108 additions & 671 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-audit/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit
1919
$ csdx COMMAND
2020
running command...
2121
$ csdx (--version|-v)
22-
@contentstack/cli-audit/1.12.1 darwin-arm64 node-v22.14.0
22+
@contentstack/cli-audit/1.12.0 darwin-arm64 node-v23.11.0
2323
$ csdx --help [COMMAND]
2424
USAGE
2525
$ csdx COMMAND

packages/contentstack-auth/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-auth
1818
$ csdx COMMAND
1919
running command...
2020
$ csdx (--version)
21-
@contentstack/cli-auth/1.4.0 darwin-arm64 node-v22.14.0
21+
@contentstack/cli-auth/1.4.0 darwin-arm64 node-v23.11.0
2222
$ csdx --help [COMMAND]
2323
USAGE
2424
$ csdx COMMAND

packages/contentstack-bootstrap/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-bootstrap
1515
$ csdx COMMAND
1616
running command...
1717
$ csdx (--version)
18-
@contentstack/cli-cm-bootstrap/1.14.0 darwin-arm64 node-v22.14.0
18+
@contentstack/cli-cm-bootstrap/1.14.0 darwin-arm64 node-v23.11.0
1919
$ csdx --help [COMMAND]
2020
USAGE
2121
$ csdx COMMAND

packages/contentstack-branches/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches
3737
$ csdx COMMAND
3838
running command...
3939
$ csdx (--version)
40-
@contentstack/cli-cm-branches/1.4.1 darwin-arm64 node-v22.14.0
40+
@contentstack/cli-cm-branches/1.4.2 darwin-arm64 node-v22.14.0
4141
$ csdx --help [COMMAND]
4242
USAGE
4343
$ csdx COMMAND

packages/contentstack-branches/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@contentstack/cli-cm-branches",
33
"description": "Contentstack CLI plugin to do branches operations",
4-
"version": "1.4.1",
4+
"version": "1.4.2",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {

packages/contentstack-branches/src/branch/merge-handler.ts

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,13 @@ export default class MergeHandler {
108108
deleted: [],
109109
};
110110
const selectedItems = await selectCustomPreferences(module, this.branchCompareData[module]);
111-
if (!selectedItems.length) {
112-
cliux.print(chalk.red('No items were selected'));
113-
process.exit(1);
111+
if (selectedItems?.length) {
112+
forEach(selectedItems, (item) => {
113+
this.mergeSettings.mergeContent[module][item.status].push(item.value);
114+
this.mergeSettings.itemMergeStrategies.push(item.value);
115+
});
116+
this.mergeSettings.strategy = 'ignore';
114117
}
115-
forEach(selectedItems, (item) => {
116-
this.mergeSettings.mergeContent[module][item.status].push(item.value);
117-
this.mergeSettings.itemMergeStrategies.push(item.value);
118-
});
119-
this.mergeSettings.strategy = 'ignore';
120118
}
121119
} else if (this.strategy === 'merge_prefer_base') {
122120
if (this.strategySubOption === 'new') {
@@ -137,12 +135,25 @@ export default class MergeHandler {
137135
} else if (this.strategy === 'overwrite_with_compare') {
138136
this.mergeSettings.strategy = 'overwrite_with_compare';
139137
}
140-
if (this.checkEmptySelection()) {
141-
cliux.print(chalk.red('No items selected'));
142-
} else {
143-
await this.displayMergeSummary();
144-
}
145138

139+
const { allEmpty, moduleStatus } = this.checkEmptySelection();
140+
const strategyName = this.mergeSettings.strategy;
141+
142+
if (allEmpty) {
143+
cliux.print(chalk.red(`No items selected according to the '${strategyName}' strategy.`));
144+
process.exit(1);
145+
}
146+
147+
for (const [type, { exists, empty }] of Object.entries(moduleStatus)) {
148+
if (exists && empty) {
149+
const readable = type === 'contentType' ? 'Content Types' : 'Global fields';
150+
cliux.print('\n')
151+
cliux.print(chalk.yellow(`Note: No ${readable} selected according to the '${strategyName}' strategy.`));
152+
}
153+
}
154+
155+
this.displayMergeSummary();
156+
146157
if (!this.executeOption) {
147158
const executionResponse = await selectMergeExecution();
148159
if (executionResponse === 'previous') {
@@ -160,17 +171,71 @@ export default class MergeHandler {
160171
}
161172
}
162173

163-
checkEmptySelection() {
164-
for (let module in this.branchCompareData) {
165-
if (this.mergeSettings.mergeContent[module]?.modified?.length
166-
|| this.mergeSettings.mergeContent[module]?.added?.length
167-
|| this.mergeSettings.mergeContent[module]?.deleted?.length) {
168-
return false;
174+
/**
175+
* Checks whether the selection of modules in the compare branch data is empty.
176+
*
177+
* This method evaluates the branch compare data and determines if there are any changes
178+
* (added, modified, or deleted) in the modules based on the merge strategy defined in the
179+
* merge settings. It categorizes the status of each module as either existing and empty or
180+
* not empty.
181+
*
182+
* @returns An object containing:
183+
* - `allEmpty`: A boolean indicating whether all modules are either non-existent or empty.
184+
* - `moduleStatus`: A record mapping module types (`contentType` and `globalField`) to their
185+
* respective statuses, which include:
186+
* - `exists`: A boolean indicating whether the module exists in the branch comparison data.
187+
* - `empty`: A boolean indicating whether the module has no changes (added, modified, or deleted).
188+
*/
189+
checkEmptySelection(): {
190+
allEmpty: boolean;
191+
moduleStatus: Record<string, { exists: boolean; empty: boolean }>;
192+
} {
193+
const strategy = this.mergeSettings.strategy;
194+
195+
const useMergeContent = new Set(['custom_preferences', 'ignore']);
196+
const modifiedOnlyStrategies = new Set(['merge_modified_only_prefer_base', 'merge_modified_only_prefer_compare']);
197+
const addedOnlyStrategies = new Set(['merge_new_only']);
198+
199+
const moduleStatus: Record<string, { exists: boolean; empty: boolean }> = {
200+
contentType: { exists: false, empty: true },
201+
globalField: { exists: false, empty: true },
202+
};
203+
204+
for (const module in this.branchCompareData) {
205+
const content = useMergeContent.has(strategy)
206+
? this.mergeSettings.mergeContent[module]
207+
: this.branchCompareData[module];
208+
209+
if (!content) continue;
210+
211+
const isGlobalField = module === 'global_fields';
212+
const type = isGlobalField ? 'globalField' : 'contentType';
213+
moduleStatus[type].exists = true;
214+
215+
let hasChanges = false;
216+
if (modifiedOnlyStrategies.has(strategy)) {
217+
hasChanges = Array.isArray(content.modified) && content.modified.length > 0;
218+
} else if (addedOnlyStrategies.has(strategy)) {
219+
hasChanges = Array.isArray(content.added) && content.added.length > 0;
220+
} else {
221+
hasChanges =
222+
(Array.isArray(content.modified) && content.modified.length > 0) ||
223+
(Array.isArray(content.added) && content.added.length > 0) ||
224+
(Array.isArray(content.deleted) && content.deleted.length > 0);
225+
}
226+
227+
if (hasChanges) {
228+
moduleStatus[type].empty = false;
169229
}
170230
}
171-
return true;
231+
232+
const allEmpty = Object.values(moduleStatus).every(
233+
(status) => !status.exists || status.empty
234+
);
235+
236+
return { allEmpty, moduleStatus };
172237
}
173-
238+
174239
displayMergeSummary() {
175240
if (this.mergeSettings.strategy !== 'ignore') {
176241
for (let module in this.branchCompareData) {
@@ -269,10 +334,10 @@ export default class MergeHandler {
269334
};
270335

271336
const mergePreferencesMap = {
272-
'existing_new': 'merge_existing_new',
273-
'new': 'merge_new',
274-
'existing': 'merge_existing',
275-
'ask_preference': 'custom',
337+
existing_new: 'merge_existing_new',
338+
new: 'merge_new',
339+
existing: 'merge_existing',
340+
ask_preference: 'custom',
276341
};
277342
const selectedMergePreference = mergePreferencesMap[mergePreference];
278343

@@ -301,7 +366,10 @@ export default class MergeHandler {
301366

302367
if (scriptFolderPath !== undefined) {
303368
cliux.success(`\nSuccess! We have generated entry migration files in the folder ${scriptFolderPath}`);
304-
cliux.print('\nWARNING!!! Migration is not intended to be run more than once. Migrated(entries/assets) will be duplicated if run more than once', { color: 'yellow' });
369+
cliux.print(
370+
'\nWARNING!!! Migration is not intended to be run more than once. Migrated(entries/assets) will be duplicated if run more than once',
371+
{ color: 'yellow' },
372+
);
305373

306374
let migrationCommand: string;
307375
if (os.platform() === 'win32') {

packages/contentstack-branches/src/utils/branch-diff-utility.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,23 @@ async function branchCompareSDK(payload: BranchDiffPayload, skip?: number, limit
7979
const module = payload.module || 'all';
8080

8181
switch (module) {
82-
case 'content_types' || 'content_type':
82+
case 'content_types':
83+
case 'content_type':
8384
return await branchQuery
8485
.contentTypes(queryParams)
8586
.then((data) => data)
8687
.catch((err) => handleErrorMsg(err, payload.spinner));
87-
break;
88-
case 'global_fields' || 'global_field':
88+
case 'global_fields':
89+
case 'global_field':
8990
return await branchQuery
9091
.globalFields(queryParams)
9192
.then((data) => data)
9293
.catch((err) => handleErrorMsg(err, payload.spinner));
93-
break;
9494
case 'all':
9595
return await branchQuery
9696
.all(queryParams)
9797
.then((data) => data)
9898
.catch((err) => handleErrorMsg(err, payload.spinner));
99-
break;
10099
default:
101100
handleErrorMsg({ errorMessage: 'Invalid module!' }, payload.spinner);
102101
}

0 commit comments

Comments
 (0)