Skip to content

Commit 6368499

Browse files
author
naman-contentstack
committed
Merge 'v2-dev' in 'feat/AM2.0'
2 parents 340ba38 + 78e091d commit 6368499

File tree

20 files changed

+271
-180
lines changed

20 files changed

+271
-180
lines changed

.talismanrc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
fileignoreconfig:
22
- filename: pnpm-lock.yaml
3-
checksum: 9ad01ca900e007d8ea4f5ffcef9f166665aba852b3b9a0a5f4506c04fd362138
3+
checksum: 9c19eb613068c193fac35e72327198fbc86e759968391f07cc876c56b2b1a63d
4+
- filename: packages/contentstack-export/test/unit/export/modules/base-class.test.ts
5+
checksum: bd2b28305fff90ca26bce56b2c5c61751a62225d310a2553874e9ec009ed78e8
6+
- filename: packages/contentstack-export/test/unit/export/modules/assets.test.ts
7+
checksum: 73ff01e2d19c8d1384dca2ee7087f8c19e0b1fac6b29c75a02ca523a36b7cb92
8+
- filename: packages/contentstack-export/src/types/default-config.ts
9+
checksum: bf399466aae808342ec013c0179fbc24ac2d969c77fdbef47a842b12497d507e
10+
- filename: packages/contentstack-export/src/types/index.ts
11+
checksum: fa36c236abac338b03bf307102a99f25dddac9afe75b6b34fb82e318e7759799
12+
- filename: packages/contentstack-export/src/config/index.ts
13+
checksum: 1eb407ee0bd21597d8a4c673fce99d60fafd151ac843c33dac52ffdcc73e8107
14+
- filename: packages/contentstack-export/test/unit/export/modules/stack.test.ts
15+
checksum: 79876b8f635037a2d8ba38dac055e7625bf85db6a3cf5729434e6a97e44857d6
16+
- filename: packages/contentstack-export/src/export/modules/stack.ts
17+
checksum: 375c0c5f58d43430b355050d122d3283083ca91891abe8105a4b4fd9433ece97
418
version: '1.0'

packages/contentstack-audit/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/cli-audit",
3-
"version": "2.0.0-beta.8",
3+
"version": "2.0.0-beta.9",
44
"description": "Contentstack audit plugin",
55
"author": "Contentstack CLI",
66
"homepage": "https://github.com/contentstack/cli",
@@ -18,8 +18,8 @@
1818
"/oclif.manifest.json"
1919
],
2020
"dependencies": {
21-
"@contentstack/cli-command": "~2.0.0-beta.4",
22-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
21+
"@contentstack/cli-command": "~2.0.0-beta.5",
22+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
2323
"@oclif/core": "^4.3.0",
2424
"@oclif/plugin-help": "^6.2.28",
2525
"chalk": "^5.6.2",

packages/contentstack-bootstrap/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@contentstack/cli-cm-bootstrap",
33
"description": "Bootstrap contentstack apps",
4-
"version": "2.0.0-beta.13",
4+
"version": "2.0.0-beta.14",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"scripts": {
@@ -16,10 +16,10 @@
1616
"test:report": "nyc --reporter=lcov mocha \"test/**/*.test.js\""
1717
},
1818
"dependencies": {
19-
"@contentstack/cli-cm-seed": "~2.0.0-beta.12",
20-
"@contentstack/cli-command": "~2.0.0-beta.4",
21-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
22-
"@contentstack/cli-config": "~2.0.0-beta.5",
19+
"@contentstack/cli-cm-seed": "~2.0.0-beta.13",
20+
"@contentstack/cli-command": "~2.0.0-beta.5",
21+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
22+
"@contentstack/cli-config": "~2.0.0-beta.6",
2323
"@oclif/core": "^4.3.0",
2424
"@oclif/plugin-help": "^6.2.37",
2525
"inquirer": "12.11.1",

packages/contentstack-branches/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"name": "@contentstack/cli-cm-branches",
33
"description": "Contentstack CLI plugin to do branches operations",
4-
"version": "2.0.0-beta.4",
4+
"version": "2.0.0-beta.5",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {
8-
"@contentstack/cli-command": "~2.0.0-beta.4",
8+
"@contentstack/cli-command": "~2.0.0-beta.5",
99
"@oclif/core": "^4.3.0",
1010
"@oclif/plugin-help": "^6.2.28",
11-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
11+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
1212
"chalk": "^5.6.2",
1313
"just-diff": "^6.0.2",
1414
"lodash": "^4.17.23"

packages/contentstack-clone/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "@contentstack/cli-cm-clone",
33
"description": "Contentstack stack clone plugin",
4-
"version": "2.0.0-beta.14",
4+
"version": "2.0.0-beta.15",
55
"author": "Contentstack",
66
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
77
"dependencies": {
88
"@colors/colors": "^1.6.0",
9-
"@contentstack/cli-cm-export": "~2.0.0-beta.13",
10-
"@contentstack/cli-cm-import": "~2.0.0-beta.13",
11-
"@contentstack/cli-command": "~2.0.0-beta.4",
12-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
9+
"@contentstack/cli-cm-export": "~2.0.0-beta.14",
10+
"@contentstack/cli-cm-import": "~2.0.0-beta.14",
11+
"@contentstack/cli-command": "~2.0.0-beta.5",
12+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
1313
"@oclif/core": "^4.3.0",
1414
"@oclif/plugin-help": "^6.2.28",
1515
"chalk": "^5.6.2",

packages/contentstack-export-to-csv/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"name": "@contentstack/cli-cm-export-to-csv",
33
"description": "Export entries, taxonomies, terms, or organization users to CSV",
4-
"version": "2.0.0-beta.4",
4+
"version": "2.0.0-beta.5",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {
8-
"@contentstack/cli-command": "~2.0.0-beta.4",
9-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
8+
"@contentstack/cli-command": "~2.0.0-beta.5",
9+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
1010
"@oclif/core": "^4.8.0",
1111
"@oclif/plugin-help": "^6.2.32",
1212
"fast-csv": "^4.3.6"

packages/contentstack-export/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "@contentstack/cli-cm-export",
33
"description": "Contentstack CLI plugin to export content from stack",
4-
"version": "2.0.0-beta.13",
4+
"version": "2.0.0-beta.14",
55
"author": "Contentstack",
66
"bugs": "https://github.com/contentstack/cli/issues",
77
"dependencies": {
8-
"@contentstack/cli-command": "~2.0.0-beta.4",
9-
"@contentstack/cli-utilities": "~2.0.0-beta.4",
10-
"@contentstack/cli-variants": "~2.0.0-beta.10",
8+
"@contentstack/cli-command": "~2.0.0-beta.5",
9+
"@contentstack/cli-utilities": "~2.0.0-beta.5",
10+
"@contentstack/cli-variants": "~2.0.0-beta.11",
1111
"@oclif/core": "^4.8.0",
1212
"async": "^3.2.6",
1313
"big-json": "^3.2.0",

packages/contentstack-export/src/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ const config: DefaultConfig = {
201201
stack: {
202202
dirName: 'stack',
203203
fileName: 'stack.json',
204+
invalidKeys: ['SYS_ACL', 'user_uids', 'owner_uid', 'description', 'master_key'],
204205
},
205206
dependency: {
206207
entries: ['stack', 'locales', 'content-types'],

packages/contentstack-export/src/export/modules/stack.ts

Lines changed: 86 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import find from 'lodash/find';
2+
import omit from 'lodash/omit';
23
import { resolve as pResolve } from 'node:path';
34
import { handleAndLogError, isAuthenticated, managementSDKClient, log } from '@contentstack/cli-utilities';
45
import { PATH_CONSTANTS } from '../../constants';
@@ -39,50 +40,57 @@ export default class ExportStack extends BaseClass {
3940
try {
4041
log.debug('Starting stack export process...', this.exportConfig.context);
4142

42-
// Initial analysis with loading spinner
43+
// Initial analysis with loading spinner (skip getStack when using management token — no SDK snapshot)
4344
const [stackData] = await this.withLoadingSpinner('STACK: Analyzing stack configuration...', async () => {
44-
const stackData = isAuthenticated() ? await this.getStack() : null;
45+
const stackData = this.exportConfig.management_token || !isAuthenticated() ? null : await this.getStack();
4546
return [stackData];
4647
});
4748

4849
// Create nested progress manager
4950
const progress = this.createNestedProgress(this.currentModuleName);
5051

51-
// Add processes based on configuration
52-
let processCount = 0;
53-
54-
if (stackData?.org_uid) {
55-
log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context);
56-
this.exportConfig.org_uid = stackData.org_uid;
52+
const orgUid = stackData?.org_uid ?? stackData?.organization_uid;
53+
if (orgUid) {
54+
log.debug(`Found organization UID: '${orgUid}'.`, this.exportConfig.context);
55+
this.exportConfig.org_uid = orgUid;
5756
this.exportConfig.sourceStackName = stackData.name;
5857
log.debug(`Set source stack name: ${stackData.name}`, this.exportConfig.context);
5958
}
6059

6160
if (!this.exportConfig.management_token) {
6261
progress.addProcess(PROCESS_NAMES.STACK_SETTINGS, 1);
63-
processCount++;
6462
}
63+
progress.addProcess(PROCESS_NAMES.STACK_DETAILS, 1);
6564

6665
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
6766
progress.addProcess(PROCESS_NAMES.STACK_LOCALE, 1);
68-
processCount++;
69-
} else if (this.exportConfig.preserveStackVersion) {
70-
progress.addProcess(PROCESS_NAMES.STACK_DETAILS, 1);
71-
processCount++;
7267
}
7368

69+
let stackDetailsExportResult: any;
70+
7471
// Execute processes
7572
if (!this.exportConfig.management_token) {
7673
progress
7774
.startProcess(PROCESS_NAMES.STACK_SETTINGS)
7875
.updateStatus(PROCESS_STATUS[PROCESS_NAMES.STACK_SETTINGS].EXPORTING, PROCESS_NAMES.STACK_SETTINGS);
7976
await this.exportStackSettings();
8077
progress.completeProcess(PROCESS_NAMES.STACK_SETTINGS, true);
78+
79+
progress
80+
.startProcess(PROCESS_NAMES.STACK_DETAILS)
81+
.updateStatus(PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING, PROCESS_NAMES.STACK_DETAILS);
82+
stackDetailsExportResult = await this.exportStack(stackData);
83+
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
8184
} else {
8285
log.info(
8386
'Skipping stack settings export: Operation is not supported when using a management token.',
8487
this.exportConfig.context,
8588
);
89+
progress
90+
.startProcess(PROCESS_NAMES.STACK_DETAILS)
91+
.updateStatus(PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING, PROCESS_NAMES.STACK_DETAILS);
92+
stackDetailsExportResult = await this.writeStackJsonFromConfigApiKeyOnly();
93+
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
8694
}
8795

8896
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
@@ -100,14 +108,8 @@ export default class ExportStack extends BaseClass {
100108
this.completeProgress(true);
101109
return masterLocale;
102110
} else if (this.exportConfig.preserveStackVersion) {
103-
progress
104-
.startProcess(PROCESS_NAMES.STACK_DETAILS)
105-
.updateStatus(PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING, PROCESS_NAMES.STACK_DETAILS);
106-
const stackResult = await this.exportStack();
107-
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
108-
109111
this.completeProgress(true);
110-
return stackResult;
112+
return stackDetailsExportResult;
111113
} else {
112114
log.debug('Locale locale already set, skipping locale fetch', this.exportConfig.context);
113115
}
@@ -211,28 +213,36 @@ export default class ExportStack extends BaseClass {
211213
});
212214
}
213215

214-
async exportStack(): Promise<any> {
216+
/**
217+
* Reuse stack snapshot from `getStack()` when present so we do not call `stack.fetch()` twice
218+
* (same GET /stacks payload as writing stack.json). Falls back to `this.stack.fetch()` otherwise.
219+
*/
220+
async exportStack(preloadedStack?: Record<string, any> | null): Promise<any> {
215221
log.debug(`Starting stack export for: '${this.exportConfig.apiKey}'...`, this.exportConfig.context);
216222

217223
await fsUtil.makeDirectory(this.stackFolderPath);
218224
log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context);
219225

226+
if (this.isStackFetchPayload(preloadedStack)) {
227+
log.debug('Reusing stack payload from analysis step (no extra stack.fetch).', this.exportConfig.context);
228+
try {
229+
return this.persistStackJsonPayload(preloadedStack);
230+
} catch (error: any) {
231+
this.progressManager?.tick(
232+
false,
233+
'stack export',
234+
error?.message || PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].FAILED,
235+
PROCESS_NAMES.STACK_DETAILS,
236+
);
237+
handleAndLogError(error, { ...this.exportConfig.context });
238+
return undefined;
239+
}
240+
}
241+
220242
return this.stack
221243
.fetch()
222-
.then(async (resp: any) => {
223-
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
224-
log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
225-
fsUtil.writeFile(stackFilePath, resp);
226-
227-
// Track progress for stack export completion
228-
this.progressManager?.tick(true, `stack: ${this.exportConfig.apiKey}`, null, PROCESS_NAMES.STACK_DETAILS);
229-
230-
log.success(
231-
`Stack details exported successfully for stack ${this.exportConfig.apiKey}`,
232-
this.exportConfig.context,
233-
);
234-
log.debug('Stack export completed successfully.', this.exportConfig.context);
235-
return resp;
244+
.then((resp: any) => {
245+
return this.persistStackJsonPayload(resp);
236246
})
237247
.catch((error: any) => {
238248
log.debug(`Error occurred while exporting stack: ${this.exportConfig.apiKey}`, this.exportConfig.context);
@@ -246,6 +256,47 @@ export default class ExportStack extends BaseClass {
246256
});
247257
}
248258

259+
private isStackFetchPayload(data: unknown): data is Record<string, any> {
260+
return typeof data === 'object' && data !== null && !Array.isArray(data) && ('api_key' in data || 'uid' in data);
261+
}
262+
263+
/**
264+
* Management-token exports cannot use Stack CMA endpoints for full metadata; write api_key from config only.
265+
*/
266+
private async writeStackJsonFromConfigApiKeyOnly(): Promise<{ api_key: string }> {
267+
if (!this.exportConfig.apiKey || typeof this.exportConfig.apiKey !== 'string') {
268+
throw new Error('Stack API key is required to write stack.json when using a management token.');
269+
}
270+
271+
log.debug('Writing config-based stack.json (api_key only, no stack fetch).', this.exportConfig.context);
272+
273+
await fsUtil.makeDirectory(this.stackFolderPath);
274+
const payload = { api_key: this.exportConfig.apiKey };
275+
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
276+
fsUtil.writeFile(stackFilePath, payload);
277+
278+
this.progressManager?.tick(true, `stack: ${this.exportConfig.apiKey}`, null, PROCESS_NAMES.STACK_DETAILS);
279+
280+
log.success(
281+
`Stack identifier written to stack.json from config for stack ${this.exportConfig.apiKey}`,
282+
this.exportConfig.context,
283+
);
284+
return payload;
285+
}
286+
287+
private persistStackJsonPayload(resp: Record<string, any>): any {
288+
const sanitized = omit(resp, this.stackConfig.invalidKeys ?? []);
289+
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
290+
log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
291+
fsUtil.writeFile(stackFilePath, sanitized);
292+
293+
this.progressManager?.tick(true, `stack: ${this.exportConfig.apiKey}`, null, PROCESS_NAMES.STACK_DETAILS);
294+
295+
log.success(`Stack details exported successfully for stack ${this.exportConfig.apiKey}`, this.exportConfig.context);
296+
log.debug('Stack export completed successfully.', this.exportConfig.context);
297+
return sanitized;
298+
}
299+
249300
async exportStackSettings(): Promise<any> {
250301
log.info('Exporting stack settings...', this.exportConfig.context);
251302
await fsUtil.makeDirectory(this.stackFolderPath);

packages/contentstack-export/src/types/default-config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export default interface DefaultConfig {
147147
stack: {
148148
dirName: string;
149149
fileName: string;
150+
invalidKeys: string[];
150151
dependencies?: Modules[];
151152
};
152153
dependency: {

0 commit comments

Comments
 (0)