Skip to content

Commit bbde5e7

Browse files
committed
merged latest changes
2 parents f27b79a + 78e091d commit bbde5e7

20 files changed

Lines changed: 291 additions & 192 deletions

File tree

.talismanrc

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
fileignoreconfig:
22
- filename: pnpm-lock.yaml
3-
checksum: ac795ffbdc0f82463baf34715a30b76cf6a67b2d8893ec835a5861aa915b20bf
4-
- filename: .cursor/rules/contentstack-cli.mdc
5-
checksum: ba287a9e9dcf6565d2d2e79c9bbf6350a89e13afbd1f8755973d837563115c83
6-
- filename: .cursor/rules/dev-workflow.md
7-
checksum: ae8f8b2894c5cf0da6a85eb53c97775bd38835c191f9132ecaa24dcb9f439811
8-
- filename: .cursor/rules/oclif-commands.mdc
9-
checksum: 3f9891d3d5872a2823c83215bc1727911dd32935d17d91ad5f2e7d5f75f3ab61
10-
- filename: packages/contentstack-audit/test/unit/logger-config.js
11-
checksum: 493e2e65939325f48d354469f409f1dbf84462adca995ed3a78461e80148d309
12-
- filename: packages/contentstack-audit/test/unit/base-command.test.ts
13-
checksum: 4208fae6e7cf1aeeb2b936d119c85cdc40e5e3560c7207e04bb94ba3e0305557
14-
- filename: packages/contentstack-audit/test/unit/modules/entries.test.ts
15-
checksum: aaf2e125c5e93ab15364e41559390502a18b83a4b3de5879c02572969381c0a6
3+
checksum: 78b7fca30ae03e2570a384c5432c10f0e6b023f492b68929795adcb4613e8673
4+
- filename: packages/contentstack-export/test/unit/export/modules/assets.test.ts
5+
checksum: 73ff01e2d19c8d1384dca2ee7087f8c19e0b1fac6b29c75a02ca523a36b7cb92
6+
- filename: packages/contentstack-export/src/config/index.ts
7+
checksum: 1eb407ee0bd21597d8a4c673fce99d60fafd151ac843c33dac52ffdcc73e8107
8+
- filename: packages/contentstack-export/src/types/default-config.ts
9+
checksum: bf399466aae808342ec013c0179fbc24ac2d969c77fdbef47a842b12497d507e
10+
- filename: packages/contentstack-export/test/unit/export/modules/base-class.test.ts
11+
checksum: bd2b28305fff90ca26bce56b2c5c61751a62225d310a2553874e9ec009ed78e8
12+
- filename: packages/contentstack-export/src/types/index.ts
13+
checksum: 0b637d20d7b6f434aff7cf0a92ea8d27f8750dca0d1e46ca3f35511e5740ad80
14+
- filename: packages/contentstack-export/test/unit/export/modules/stack.test.ts
15+
checksum: 436c099888888297bcdae4d55e71af388b512871f2e3814f6ec5689b5f20bff9
16+
- filename: packages/contentstack-export/src/export/modules/stack.ts
17+
checksum: f222d6864ac24faaa6585a003536b9ec1eae0d53e8fddf2bdc783790376d85bc
1618
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: 109 additions & 41 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 {
45
handleAndLogError,
@@ -43,38 +44,35 @@ export default class ExportStack extends BaseClass {
4344
try {
4445
log.debug('Starting stack export process...', this.exportConfig.context);
4546

46-
// Initial analysis with loading spinner
47+
// Initial analysis with loading spinner (skip getStack when using management token — no SDK snapshot)
4748
const [stackData] = await this.withLoadingSpinner('STACK: Analyzing stack configuration...', async () => {
48-
const stackData = isAuthenticated() ? await this.getStack() : null;
49+
const stackData =
50+
this.exportConfig.management_token || !isAuthenticated() ? null : await this.getStack();
4951
return [stackData];
5052
});
5153

5254
// Create nested progress manager
5355
const progress = this.createNestedProgress(this.currentModuleName);
5456

55-
// Add processes based on configuration
56-
let processCount = 0;
57-
58-
if (stackData?.org_uid) {
59-
log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context);
60-
this.exportConfig.org_uid = stackData.org_uid;
57+
const orgUid = stackData?.org_uid ?? stackData?.organization_uid;
58+
if (orgUid) {
59+
log.debug(`Found organization UID: '${orgUid}'.`, this.exportConfig.context);
60+
this.exportConfig.org_uid = orgUid;
6161
this.exportConfig.sourceStackName = stackData.name;
6262
log.debug(`Set source stack name: ${stackData.name}`, this.exportConfig.context);
6363
}
6464

6565
if (!this.exportConfig.management_token) {
6666
progress.addProcess(PROCESS_NAMES.STACK_SETTINGS, 1);
67-
processCount++;
6867
}
68+
progress.addProcess(PROCESS_NAMES.STACK_DETAILS, 1);
6969

7070
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
7171
progress.addProcess(PROCESS_NAMES.STACK_LOCALE, 1);
72-
processCount++;
73-
} else if (this.exportConfig.preserveStackVersion) {
74-
progress.addProcess(PROCESS_NAMES.STACK_DETAILS, 1);
75-
processCount++;
7672
}
7773

74+
let stackDetailsExportResult: any;
75+
7876
// Execute processes
7977
if (!this.exportConfig.management_token) {
8078
progress
@@ -85,11 +83,28 @@ export default class ExportStack extends BaseClass {
8583
);
8684
await this.exportStackSettings();
8785
progress.completeProcess(PROCESS_NAMES.STACK_SETTINGS, true);
86+
87+
progress
88+
.startProcess(PROCESS_NAMES.STACK_DETAILS)
89+
.updateStatus(
90+
PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING,
91+
PROCESS_NAMES.STACK_DETAILS,
92+
);
93+
stackDetailsExportResult = await this.exportStack(stackData);
94+
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
8895
} else {
8996
log.info(
9097
'Skipping stack settings export: Operation is not supported when using a management token.',
9198
this.exportConfig.context,
9299
);
100+
progress
101+
.startProcess(PROCESS_NAMES.STACK_DETAILS)
102+
.updateStatus(
103+
PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING,
104+
PROCESS_NAMES.STACK_DETAILS,
105+
);
106+
stackDetailsExportResult = await this.writeStackJsonFromConfigApiKeyOnly();
107+
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
93108
}
94109

95110
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
@@ -110,17 +125,8 @@ export default class ExportStack extends BaseClass {
110125
this.completeProgress(true);
111126
return masterLocale;
112127
} else if (this.exportConfig.preserveStackVersion) {
113-
progress
114-
.startProcess(PROCESS_NAMES.STACK_DETAILS)
115-
.updateStatus(
116-
PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING,
117-
PROCESS_NAMES.STACK_DETAILS,
118-
);
119-
const stackResult = await this.exportStack();
120-
progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true);
121-
122128
this.completeProgress(true);
123-
return stackResult;
129+
return stackDetailsExportResult;
124130
} else {
125131
log.debug('Locale locale already set, skipping locale fetch', this.exportConfig.context);
126132
}
@@ -225,33 +231,36 @@ export default class ExportStack extends BaseClass {
225231
});
226232
}
227233

228-
async exportStack(): Promise<any> {
234+
/**
235+
* Reuse stack snapshot from `getStack()` when present so we do not call `stack.fetch()` twice
236+
* (same GET /stacks payload as writing stack.json). Falls back to `this.stack.fetch()` otherwise.
237+
*/
238+
async exportStack(preloadedStack?: Record<string, any> | null): Promise<any> {
229239
log.debug(`Starting stack export for: '${this.exportConfig.apiKey}'...`, this.exportConfig.context);
230240

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

234-
return this.stack
235-
.fetch()
236-
.then((resp: any) => {
237-
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
238-
log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
239-
fsUtil.writeFile(stackFilePath, resp);
240-
241-
// Track progress for stack export completion
244+
if (this.isStackFetchPayload(preloadedStack)) {
245+
log.debug('Reusing stack payload from analysis step (no extra stack.fetch).', this.exportConfig.context);
246+
try {
247+
return this.persistStackJsonPayload(preloadedStack);
248+
} catch (error: any) {
242249
this.progressManager?.tick(
243-
true,
244-
`stack: ${this.exportConfig.apiKey}`,
245-
null,
250+
false,
251+
'stack export',
252+
error?.message || PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].FAILED,
246253
PROCESS_NAMES.STACK_DETAILS,
247254
);
255+
handleAndLogError(error, { ...this.exportConfig.context });
256+
return undefined;
257+
}
258+
}
248259

249-
log.success(
250-
`Stack details exported successfully for stack ${this.exportConfig.apiKey}`,
251-
this.exportConfig.context,
252-
);
253-
log.debug('Stack export completed successfully.', this.exportConfig.context);
254-
return resp;
260+
return this.stack
261+
.fetch()
262+
.then((resp: any) => {
263+
return this.persistStackJsonPayload(resp);
255264
})
256265
.catch((error: any) => {
257266
log.debug(`Error occurred while exporting stack: ${this.exportConfig.apiKey}`, this.exportConfig.context);
@@ -265,6 +274,65 @@ export default class ExportStack extends BaseClass {
265274
});
266275
}
267276

277+
private isStackFetchPayload(data: unknown): data is Record<string, any> {
278+
return (
279+
typeof data === 'object' &&
280+
data !== null &&
281+
!Array.isArray(data) &&
282+
('api_key' in data || 'uid' in data)
283+
);
284+
}
285+
286+
/**
287+
* Management-token exports cannot use Stack CMA endpoints for full metadata; write api_key from config only.
288+
*/
289+
private async writeStackJsonFromConfigApiKeyOnly(): Promise<{ api_key: string }> {
290+
if (!this.exportConfig.apiKey || typeof this.exportConfig.apiKey !== 'string') {
291+
throw new Error('Stack API key is required to write stack.json when using a management token.');
292+
}
293+
294+
log.debug('Writing config-based stack.json (api_key only, no stack fetch).', this.exportConfig.context);
295+
296+
await fsUtil.makeDirectory(this.stackFolderPath);
297+
const payload = { api_key: this.exportConfig.apiKey };
298+
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
299+
fsUtil.writeFile(stackFilePath, payload);
300+
301+
this.progressManager?.tick(
302+
true,
303+
`stack: ${this.exportConfig.apiKey}`,
304+
null,
305+
PROCESS_NAMES.STACK_DETAILS,
306+
);
307+
308+
log.success(
309+
`Stack identifier written to stack.json from config for stack ${this.exportConfig.apiKey}`,
310+
this.exportConfig.context,
311+
);
312+
return payload;
313+
}
314+
315+
private persistStackJsonPayload(resp: Record<string, any>): any {
316+
const sanitized = omit(resp, this.stackConfig.invalidKeys ?? []);
317+
const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName);
318+
log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
319+
fsUtil.writeFile(stackFilePath, sanitized);
320+
321+
this.progressManager?.tick(
322+
true,
323+
`stack: ${this.exportConfig.apiKey}`,
324+
null,
325+
PROCESS_NAMES.STACK_DETAILS,
326+
);
327+
328+
log.success(
329+
`Stack details exported successfully for stack ${this.exportConfig.apiKey}`,
330+
this.exportConfig.context,
331+
);
332+
log.debug('Stack export completed successfully.', this.exportConfig.context);
333+
return sanitized;
334+
}
335+
268336
async exportStackSettings(): Promise<any> {
269337
log.info('Exporting stack settings...', this.exportConfig.context);
270338
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)