Skip to content

Commit 8d2d356

Browse files
authored
Merge pull request #304 from contentstack/enhc/DX-9753
feat: force api_version 3.2 (NRP) on all entry/asset/taxonomy publish and unpublish
2 parents 4ceb421 + 411be70 commit 8d2d356

20 files changed

Lines changed: 295 additions & 196 deletions

File tree

.talismanrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,12 @@ fileignoreconfig:
1515
checksum: 35451ca4c03359b06531a8461091f4a3a45c4dea1f8853081fb53e4ce28c1cc3
1616
- filename: packages/contentstack-bulk-operations/test/unit/base-bulk-command.test.ts
1717
checksum: ca699a9d73757d44ded4d9d27beb4f460f911a7c88a14551a9402a3ac0c69873
18+
- filename: packages/contentstack-external-migrate/src/lib/create-stack.ts
19+
checksum: 68a9510db6f2746ac5006c091d276c1ba619a9e15c76a3edae3967e4f9c2dd4e
20+
- filename: packages/contentstack-external-migrate/test/lib/create-stack.test.ts
21+
checksum: 45af4e45e4baadf7e418a11a46a6243b8ffabafdbf32d0269d89c5d3db837a13
22+
- filename: CHANGELOG.md
23+
checksum: 88c7e1dee308fa4ae25e7815ead0842b1aac7ed669b02859cc8b25cba879595d
24+
- filename: packages/contentstack-bulk-operations/test/unit/services/taxonomy-service.test.ts
25+
checksum: abc5ac707341760cf59d5b8b1c4e13cf2c79955e2735c33e2db3ec6bc48eddb6
1826
version: ""

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ Please refer to the Contentstack Command-line Interface release notes [here](htt
55

66

77

8+
## @contentstack/cli-bulk-operations
9+
### Version: 2.0.0-beta.5
10+
#### Date: Jul-21-2025
11+
##### Breaking Change:
12+
- Removed the api version flag from `cm:stacks:bulk-entries`. The NRP header value is now hardcoded at the SDK call site, so the flag is no longer needed. Any scripts or CI pipelines that pass this flag must remove it — it will cause an unrecognized-flag error after this release.
13+
##### Fix:
14+
- Force NRP header to version 3.2 on all entry and asset publish/unpublish requests. The header is injected per-call and does not affect other CMA requests.
15+
816
#### Date: Feb-09-2025
917
## cli
1018
- Refactor Endpoints Integration using Utils SDK in cli-cm-config v1.9.0

packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-entries.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,6 @@ export default class BulkEntries extends BaseBulkCommand {
6565
description: messages.INCLUDE_VARIANTS,
6666
default: false,
6767
}),
68-
69-
'api-version': flags.string({
70-
description: messages.API_VERSION,
71-
default: '3.2',
72-
}),
7368
};
7469

7570
protected resourceType: ResourceType = ResourceType.ENTRY;

packages/contentstack-bulk-operations/src/commands/cm/stacks/bulk-taxonomies.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ export default class BulkTaxonomies extends BaseBulkCommand {
3030
// Multiple locales with a Management token alias
3131
'<%= config.bin %> <%= command.id %> --operation publish --environments staging --locales en-us,fr-fr --taxonomies taxonomy_a -a myAlias',
3232

33-
// Explicit CMA version for taxonomy publish (default is 3.2)
34-
'<%= config.bin %> <%= command.id %> --operation publish --environments development --locales en-us --taxonomies products_tax --api-version 3.2 -k blt123',
35-
3633
// Publish taxonomies on a non-main branch
3734
'<%= config.bin %> <%= command.id %> --operation publish --branch feature --environments development --locales en-us --taxonomies brands_tax -k blt123',
3835
];
@@ -42,10 +39,6 @@ export default class BulkTaxonomies extends BaseBulkCommand {
4239
taxonomies: flags.string({
4340
description: messages.TAXONOMY_ITEMS,
4441
}),
45-
'api-version': flags.string({
46-
default: '3.2',
47-
description: messages.TAXONOMY_API_VERSION,
48-
}),
4942
} as any;
5043

5144
protected resourceType: ResourceType = ResourceType.TAXONOMY;
@@ -173,7 +166,6 @@ export default class BulkTaxonomies extends BaseBulkCommand {
173166
throw new Error($t(messages.UNSUPPORTED_OPERATION, { operation: operation ?? 'unknown' }));
174167
}
175168

176-
const apiVersion = this.parsedFlags['api-version'] || '3.2';
177169
const locales = this.bulkOperationConfig.locales || [];
178170
const environments = this.bulkOperationConfig.environments || [];
179171

@@ -185,8 +177,8 @@ export default class BulkTaxonomies extends BaseBulkCommand {
185177
};
186178
const response =
187179
operation === OperationType.UNPUBLISH
188-
? await taxonomyService.unpublish(payload, apiVersion, this.bulkOperationConfig.branch)
189-
: await taxonomyService.publish(payload, apiVersion, this.bulkOperationConfig.branch);
180+
? await taxonomyService.unpublish(payload, this.bulkOperationConfig.branch)
181+
: await taxonomyService.publish(payload, this.bulkOperationConfig.branch);
190182

191183
const duration = Date.now() - startTime;
192184
const rawJobId = response.job_id;

packages/contentstack-bulk-operations/src/core/operation-executor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export class OperationExecutor {
164164
private async executeEntryOperation(operation: OperationType, data: EntryPublishData): Promise<any> {
165165
const { uid, content_type, locale, version, publish_details } = data;
166166

167-
const entry = this.stack.contentType(content_type).entry(uid);
167+
const entry = this.stack.contentType(content_type).entry(uid).addHeader('api_version', '3.2');
168168

169169
switch (operation) {
170170
case OperationType.PUBLISH:
@@ -197,7 +197,7 @@ export class OperationExecutor {
197197
private async executeAssetOperation(operation: OperationType, data: AssetPublishData): Promise<any> {
198198
const { uid, locale, version, publish_details } = data;
199199

200-
const asset = this.stack.asset(uid);
200+
const asset = this.stack.asset(uid).addHeader('api_version', '3.2');
201201

202202
switch (operation) {
203203
case OperationType.PUBLISH:

packages/contentstack-bulk-operations/src/interfaces/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export interface BulkOperationConfig {
6565

6666
// API configuration
6767
publishMode?: PublishMode;
68-
apiVersion?: string;
6968

7069
// Filtering and selection
7170
branch?: string;
@@ -215,7 +214,6 @@ export interface CommandFlags {
215214
'source-alias'?: string;
216215

217216
// API configuration
218-
'api-version'?: string;
219217
'publish-mode'?: string;
220218

221219
// Retry, reliability, and operations log

packages/contentstack-bulk-operations/src/messages/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,6 @@ const flagDescriptions = {
411411
'(optional) Revert publish operations from a log folder. Specify the folder path containing success logs. Works similar to retry-failed.',
412412
BULK_OPERATION_FOLDER:
413413
'(optional) Folder path to store operation logs. Creates separate files for success and failed operations. Default: bulk-operation',
414-
API_VERSION:
415-
'Specifies the Content Management API version used for publishing. Use version `3.2` when publishing entries with nested references, otherwise, use the default version 3.2',
416-
TAXONOMY_API_VERSION:
417-
'Content Management API version for taxonomy publish (default: `3.2`; required for the `items` + locales/environments body on POST /v3/taxonomies/publish).',
418414
TAXONOMY_ITEMS:
419415
'Comma-separated taxonomy UIDs to include in the job. If omitted, all taxonomies in the stack (current branch) are included. Example: products_tax,brands_tax',
420416
};

packages/contentstack-bulk-operations/src/services/bulk-operation-service.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,17 @@ export class BulkOperationService {
245245
}
246246

247247
private prepareAssetBulkPayload(items: AssetPublishData[], operation: OperationType): any {
248-
const assets = items.map((item) => ({
249-
uid: item.uid,
250-
version: item.version,
251-
}));
248+
const seen = new Set<string>();
249+
const assets = items.reduce<Array<{ uid: string; version: number | undefined }>>((acc, item) => {
250+
if (!seen.has(item.uid)) {
251+
seen.add(item.uid);
252+
acc.push({ uid: item.uid, version: item.version });
253+
}
254+
return acc;
255+
}, []);
252256

253257
const environments = items[0]?.publish_details?.map((pd) => pd.environment) || [];
254-
const locales = items[0]?.publish_details?.map((pd) => pd.locale) || [];
258+
const locales = Array.from(new Set(items.map((item) => item.locale)));
255259

256260
return {
257261
assets,
Lines changed: 11 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,30 @@
11
import type { ManagementStack, TaxonomyPublishJobResponse, TaxonomyPublishPayload } from '../interfaces';
22
import { OperationType } from '../interfaces';
33

4-
const DEFAULT_TAXONOMY_API_VERSION = '3.2';
5-
6-
type TaxonomyPublishWithBranch = (
7-
data: TaxonomyPublishPayload,
8-
apiVersion?: string,
9-
params?: { branch?: string }
10-
) => Promise<TaxonomyPublishJobResponse>;
11-
12-
type TaxonomyOperationApi = {
13-
publish: TaxonomyPublishWithBranch;
14-
unpublish: TaxonomyPublishWithBranch;
15-
};
16-
174
export class TaxonomyService {
185
constructor(private stack: ManagementStack) {}
196

20-
/**
21-
* Publish one or more taxonomies (initiates a publish job).
22-
*/
23-
async publish(
24-
data: TaxonomyPublishPayload,
25-
apiVersion: string = DEFAULT_TAXONOMY_API_VERSION,
26-
branch?: string
27-
): Promise<TaxonomyPublishJobResponse> {
28-
return this.submit(OperationType.PUBLISH, data, apiVersion, branch);
7+
async publish(data: TaxonomyPublishPayload, branch?: string): Promise<TaxonomyPublishJobResponse> {
8+
return this.submit(OperationType.PUBLISH, data, branch);
299
}
3010

31-
/**
32-
* Unpublish one or more taxonomies (initiates an unpublish job).
33-
*/
34-
async unpublish(
35-
data: TaxonomyPublishPayload,
36-
apiVersion: string = DEFAULT_TAXONOMY_API_VERSION,
37-
branch?: string
38-
): Promise<TaxonomyPublishJobResponse> {
39-
return this.submit(OperationType.UNPUBLISH, data, apiVersion, branch);
11+
async unpublish(data: TaxonomyPublishPayload, branch?: string): Promise<TaxonomyPublishJobResponse> {
12+
return this.submit(OperationType.UNPUBLISH, data, branch);
4013
}
4114

4215
private async submit(
4316
operation: OperationType,
4417
data: TaxonomyPublishPayload,
45-
apiVersion: string,
4618
branch?: string
4719
): Promise<TaxonomyPublishJobResponse> {
48-
const taxonomies = this.stack.taxonomy() as unknown as TaxonomyOperationApi;
49-
const params =
50-
branch && branch !== 'main'
51-
? {
52-
branch,
53-
}
54-
: undefined;
55-
if (operation === OperationType.UNPUBLISH) {
56-
if (params) {
57-
return taxonomies.unpublish(data, apiVersion, params);
58-
}
59-
return taxonomies.unpublish(data, apiVersion);
60-
}
20+
const taxonomyInstance = this.stack.taxonomy() as any;
21+
taxonomyInstance.addHeader('api_version', '3.2');
22+
23+
const params = branch && branch !== 'main' ? { branch } : undefined;
6124

62-
if (params) {
63-
return taxonomies.publish(data, apiVersion, params);
25+
if (operation === OperationType.UNPUBLISH) {
26+
return params ? taxonomyInstance.unpublish(data, undefined, params) : taxonomyInstance.unpublish(data);
6427
}
65-
return taxonomies.publish(data, apiVersion);
28+
return params ? taxonomyInstance.publish(data, undefined, params) : taxonomyInstance.publish(data);
6629
}
6730
}

packages/contentstack-bulk-operations/src/utils/config-builder.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,6 @@ function validateConfig(config: BulkOperationConfig): string[] {
9999
}
100100
}
101101

102-
// API version validation
103-
if (config.apiVersion && !['3', '3.2'].includes(config.apiVersion)) {
104-
errors.push(`Invalid API version: ${config.apiVersion}. Supported versions: 3, 3.2`);
105-
}
106-
107102
// Publish mode validation
108103
if (config.publishMode && config.publishMode !== PublishMode.BULK && config.publishMode !== PublishMode.SINGLE) {
109104
errors.push(`Invalid publish mode: ${String(config.publishMode)}. Must be 'bulk' or 'single'`);
@@ -179,11 +174,6 @@ function validateCommandFlags(flags: CommandFlags): string[] {
179174
}
180175
}
181176

182-
// API version validation
183-
if (flags['api-version'] && !['3', '3.2'].includes(flags['api-version'])) {
184-
errors.push(`Invalid API version: ${flags['api-version']}. Supported versions: 3, 3.2`);
185-
}
186-
187177
// Publish mode validation
188178
if (flags['publish-mode'] && !['bulk', 'single'].includes(flags['publish-mode'])) {
189179
errors.push(`Invalid publish mode: ${flags['publish-mode']}. Must be 'bulk' or 'single'`);
@@ -199,11 +189,6 @@ function validateCommandFlags(flags: CommandFlags): string[] {
199189
errors.push('--source-alias can only be used with --source-env for cross-publish operations');
200190
}
201191

202-
// Variants require api-version 3.2
203-
if (flags['include-variants'] && flags['api-version'] !== '3.2') {
204-
errors.push('--include-variants requires --api-version 3.2');
205-
}
206-
207192
return errors;
208193
}
209194

@@ -245,7 +230,6 @@ export function buildConfig(flags: CommandFlags): BulkOperationConfig {
245230
folderUid: flags['folder-uid'],
246231
sourceEnv: flags['source-env'],
247232
publishMode: (flags['publish-mode'] as PublishMode) || PublishMode.BULK,
248-
apiVersion: flags['api-version'] || '3',
249233
branch: flags.branch || 'main',
250234
filter: flags.filter,
251235
maxRetries: flags['max-retries'] || 3,

0 commit comments

Comments
 (0)