@contentstack/cli-cm-export 2.0.0-beta.13 → 2.0.0-beta.15
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/config/index.js +1 -0
- package/lib/export/module-exporter.js +0 -2
- package/lib/export/modules/assets.js +1 -1
- package/lib/export/modules/composable-studio.js +1 -1
- package/lib/export/modules/content-types.js +1 -1
- package/lib/export/modules/custom-roles.js +1 -1
- package/lib/export/modules/entries.js +4 -3
- package/lib/export/modules/environments.js +1 -1
- package/lib/export/modules/extensions.js +1 -1
- package/lib/export/modules/global-fields.js +1 -1
- package/lib/export/modules/labels.js +1 -1
- package/lib/export/modules/locales.js +1 -1
- package/lib/export/modules/marketplace-apps.js +1 -1
- package/lib/export/modules/stack.d.ts +11 -1
- package/lib/export/modules/stack.js +74 -30
- package/lib/export/modules/taxonomies.js +2 -2
- package/lib/export/modules/webhooks.js +1 -1
- package/lib/export/modules/workflows.js +1 -1
- package/lib/types/default-config.d.ts +1 -0
- package/lib/types/export-config.d.ts +0 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/utils/export-config-handler.js +3 -0
- package/lib/utils/file-helper.d.ts +4 -0
- package/lib/utils/file-helper.js +26 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +3 -1
- package/lib/utils/path-helper.d.ts +6 -0
- package/lib/utils/path-helper.js +11 -0
- package/lib/utils/setup-branches.js +0 -6
- package/lib/utils/setup-export-dir.d.ts +1 -1
- package/lib/utils/setup-export-dir.js +1 -6
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
|
|
|
48
48
|
$ csdx COMMAND
|
|
49
49
|
running command...
|
|
50
50
|
$ csdx (--version)
|
|
51
|
-
@contentstack/cli-cm-export/2.0.0-beta.
|
|
51
|
+
@contentstack/cli-cm-export/2.0.0-beta.15 linux-x64 node-v22.22.2
|
|
52
52
|
$ csdx --help [COMMAND]
|
|
53
53
|
USAGE
|
|
54
54
|
$ csdx COMMAND
|
package/lib/config/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const path = tslib_1.__importStar(require("path"));
|
|
5
4
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
5
|
const modules_1 = tslib_1.__importDefault(require("./modules"));
|
|
7
6
|
const utils_1 = require("../utils");
|
|
@@ -54,7 +53,6 @@ class ModuleExporter {
|
|
|
54
53
|
try {
|
|
55
54
|
this.exportConfig.branchName = targetBranch.uid;
|
|
56
55
|
this.stackAPIClient.stackHeaders.branch = targetBranch.uid;
|
|
57
|
-
this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, targetBranch.uid);
|
|
58
56
|
// Initialize progress manager for the target branch
|
|
59
57
|
cli_utilities_1.CLIProgressManager.clearGlobalSummary();
|
|
60
58
|
cli_utilities_1.CLIProgressManager.initializeGlobalSummary(`EXPORT-${targetBranch.uid}`, targetBranch.uid, `Exporting "${targetBranch.uid}" branch content...`);
|
|
@@ -37,7 +37,7 @@ class ExportAssets extends base_class_1.default {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
async start() {
|
|
40
|
-
this.assetsRootPath = (0, node_path_1.resolve)(
|
|
40
|
+
this.assetsRootPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.assetConfig.dirName);
|
|
41
41
|
cli_utilities_2.log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context);
|
|
42
42
|
cli_utilities_2.log.debug('Fetching assets and folders count...', this.exportConfig.context);
|
|
43
43
|
// NOTE step 1: Get assets and it's folder count in parallel
|
|
@@ -19,7 +19,7 @@ class ExportComposableStudio {
|
|
|
19
19
|
cli_utilities_1.cliux.print('WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' });
|
|
20
20
|
return Promise.resolve();
|
|
21
21
|
}
|
|
22
|
-
this.composableStudioPath = (0, node_path_1.resolve)(
|
|
22
|
+
this.composableStudioPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.composableStudioConfig.dirName);
|
|
23
23
|
cli_utilities_1.log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context);
|
|
24
24
|
await utils_1.fsUtil.makeDirectory(this.composableStudioPath);
|
|
25
25
|
cli_utilities_1.log.debug('Created Studio directory', this.exportConfig.context);
|
|
@@ -22,7 +22,7 @@ class ContentTypesExport extends base_class_1.default {
|
|
|
22
22
|
}
|
|
23
23
|
// Add after existing qs setup and before contentTypesDirPath
|
|
24
24
|
this.applyQueryFilters(this.qs, 'content-types');
|
|
25
|
-
this.contentTypesDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(
|
|
25
|
+
this.contentTypesDirPath = path.resolve((0, cli_utilities_1.sanitizePath)((0, utils_1.getExportBasePath)(exportConfig)), (0, cli_utilities_1.sanitizePath)(this.contentTypesConfig.dirName));
|
|
26
26
|
this.contentTypes = [];
|
|
27
27
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.CONTENT_TYPES;
|
|
28
28
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.CONTENT_TYPES];
|
|
@@ -25,7 +25,7 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
25
25
|
cli_utilities_1.log.debug('Starting custom roles export process...', this.exportConfig.context);
|
|
26
26
|
const [totalRoles, totalLocales] = await this.withLoadingSpinner('CUSTOM-ROLES: Analyzing roles and locales...', async () => {
|
|
27
27
|
var _a;
|
|
28
|
-
this.rolesFolderPath = (0, node_path_1.resolve)(
|
|
28
|
+
this.rolesFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.customRolesConfig.dirName);
|
|
29
29
|
await utils_1.fsUtil.makeDirectory(this.rolesFolderPath);
|
|
30
30
|
this.customRolesLocalesFilepath = (0, node_path_1.resolve)(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName);
|
|
31
31
|
// Get counts for progress tracking
|
|
@@ -14,9 +14,10 @@ class EntriesExport extends base_class_1.default {
|
|
|
14
14
|
this.stackAPIClient = stackAPIClient;
|
|
15
15
|
this.exportConfig = exportConfig;
|
|
16
16
|
this.entriesConfig = exportConfig.modules.entries;
|
|
17
|
-
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
17
|
+
const basePath = (0, utils_1.getExportBasePath)(exportConfig);
|
|
18
|
+
this.entriesDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(this.entriesConfig.dirName));
|
|
19
|
+
this.localesFilePath = path.resolve((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.fileName));
|
|
20
|
+
this.contentTypesDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(basePath), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.content_types.dirName));
|
|
20
21
|
this.projectInstance = new cli_variants_1.ExportProjects(this.exportConfig);
|
|
21
22
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.ENTRIES;
|
|
22
23
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.ENTRIES];
|
|
@@ -21,7 +21,7 @@ class ExportEnvironments extends base_class_1.default {
|
|
|
21
21
|
cli_utilities_1.log.debug('Starting environment export process...', this.exportConfig.context);
|
|
22
22
|
// Setup with loading spinner
|
|
23
23
|
const [totalCount] = await this.withLoadingSpinner('ENVIRONMENTS: Analyzing environments...', async () => {
|
|
24
|
-
this.environmentsFolderPath = (0, node_path_1.resolve)(
|
|
24
|
+
this.environmentsFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.environmentConfig.dirName);
|
|
25
25
|
await utils_1.fsUtil.makeDirectory(this.environmentsFolderPath);
|
|
26
26
|
cli_utilities_1.log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context);
|
|
27
27
|
// Get count for progress tracking
|
|
@@ -22,7 +22,7 @@ class ExportExtensions extends base_class_1.default {
|
|
|
22
22
|
cli_utilities_1.log.debug('Starting extensions export process...', this.exportConfig.context);
|
|
23
23
|
// Setup with loading spinner
|
|
24
24
|
const [totalCount] = await this.withLoadingSpinner('EXTENSIONS: Analyzing extensions...', async () => {
|
|
25
|
-
this.extensionsFolderPath = (0, node_path_1.resolve)(
|
|
25
|
+
this.extensionsFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.extensionConfig.dirName);
|
|
26
26
|
await utils_1.fsUtil.makeDirectory(this.extensionsFolderPath);
|
|
27
27
|
cli_utilities_1.log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context);
|
|
28
28
|
// Get count for progress tracking
|
|
@@ -17,7 +17,7 @@ class GlobalFieldsExport extends base_class_1.default {
|
|
|
17
17
|
limit: this.globalFieldsConfig.limit,
|
|
18
18
|
include_global_field_schema: true,
|
|
19
19
|
};
|
|
20
|
-
this.globalFieldsDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(
|
|
20
|
+
this.globalFieldsDirPath = path.resolve((0, cli_utilities_1.sanitizePath)((0, utils_1.getExportBasePath)(exportConfig)), (0, cli_utilities_1.sanitizePath)(this.globalFieldsConfig.dirName));
|
|
21
21
|
this.globalFields = [];
|
|
22
22
|
this.applyQueryFilters(this.qs, 'global-fields');
|
|
23
23
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.GLOBAL_FIELDS;
|
|
@@ -21,7 +21,7 @@ class ExportLabels extends base_class_1.default {
|
|
|
21
21
|
cli_utilities_1.log.debug('Starting labels export process...', this.exportConfig.context);
|
|
22
22
|
// Setup with loading spinner
|
|
23
23
|
const [totalCount] = await this.withLoadingSpinner('LABELS: Analyzing labels...', async () => {
|
|
24
|
-
this.labelsFolderPath = (0, node_path_1.resolve)(
|
|
24
|
+
this.labelsFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.labelConfig.dirName);
|
|
25
25
|
await utils_1.fsUtil.makeDirectory(this.labelsFolderPath);
|
|
26
26
|
cli_utilities_1.log.debug(`Labels folder path: ${this.labelsFolderPath}`, this.exportConfig.context);
|
|
27
27
|
// Get count for progress tracking
|
|
@@ -18,7 +18,7 @@ class LocaleExport extends base_class_1.default {
|
|
|
18
18
|
BASE: this.localeConfig.requiredKeys,
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
|
-
this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(
|
|
21
|
+
this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)((0, utils_1.getExportBasePath)(exportConfig)), (0, cli_utilities_1.sanitizePath)(this.localeConfig.dirName));
|
|
22
22
|
this.locales = {};
|
|
23
23
|
this.masterLocale = {};
|
|
24
24
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.LOCALES;
|
|
@@ -72,7 +72,7 @@ class ExportMarketplaceApps extends base_class_1.default {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
async setupPaths() {
|
|
75
|
-
this.marketplaceAppPath = (0, node_path_1.resolve)(
|
|
75
|
+
this.marketplaceAppPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.marketplaceAppConfig.dirName);
|
|
76
76
|
cli_utilities_1.log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context);
|
|
77
77
|
await utils_1.fsUtil.makeDirectory(this.marketplaceAppPath);
|
|
78
78
|
cli_utilities_1.log.debug('Created marketplace apps directory', this.exportConfig.context);
|
|
@@ -8,6 +8,16 @@ export default class ExportStack extends BaseClass {
|
|
|
8
8
|
start(): Promise<void>;
|
|
9
9
|
getStack(): Promise<any>;
|
|
10
10
|
getLocales(skip?: number): Promise<any>;
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Reuse stack snapshot from `getStack()` when present so we do not call `stack.fetch()` twice
|
|
13
|
+
* (same GET /stacks payload as writing stack.json). Falls back to `this.stack.fetch()` otherwise.
|
|
14
|
+
*/
|
|
15
|
+
exportStack(preloadedStack?: Record<string, any> | null): Promise<any>;
|
|
16
|
+
private isStackFetchPayload;
|
|
17
|
+
/**
|
|
18
|
+
* Management-token exports cannot use Stack CMA endpoints for full metadata; write api_key from config only.
|
|
19
|
+
*/
|
|
20
|
+
private writeStackJsonFromConfigApiKeyOnly;
|
|
21
|
+
private persistStackJsonPayload;
|
|
12
22
|
exportStackSettings(): Promise<any>;
|
|
13
23
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
5
|
+
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
5
6
|
const node_path_1 = require("node:path");
|
|
6
7
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
7
8
|
const constants_1 = require("../../constants");
|
|
@@ -12,40 +13,36 @@ class ExportStack extends base_class_1.default {
|
|
|
12
13
|
super({ exportConfig, stackAPIClient });
|
|
13
14
|
this.stackConfig = exportConfig.modules.stack;
|
|
14
15
|
this.qs = { include_count: true };
|
|
15
|
-
this.stackFolderPath = (0, node_path_1.resolve)(
|
|
16
|
+
this.stackFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.stackConfig.dirName);
|
|
16
17
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.STACK;
|
|
17
18
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.STACK];
|
|
18
19
|
}
|
|
19
20
|
async start() {
|
|
21
|
+
var _a;
|
|
20
22
|
try {
|
|
21
23
|
cli_utilities_1.log.debug('Starting stack export process...', this.exportConfig.context);
|
|
22
|
-
// Initial analysis with loading spinner
|
|
24
|
+
// Initial analysis with loading spinner (skip getStack when using management token — no SDK snapshot)
|
|
23
25
|
const [stackData] = await this.withLoadingSpinner('STACK: Analyzing stack configuration...', async () => {
|
|
24
|
-
const stackData = (0, cli_utilities_1.isAuthenticated)() ? await this.getStack()
|
|
26
|
+
const stackData = this.exportConfig.management_token || !(0, cli_utilities_1.isAuthenticated)() ? null : await this.getStack();
|
|
25
27
|
return [stackData];
|
|
26
28
|
});
|
|
27
29
|
// Create nested progress manager
|
|
28
30
|
const progress = this.createNestedProgress(this.currentModuleName);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.exportConfig.org_uid = stackData.org_uid;
|
|
31
|
+
const orgUid = (_a = stackData === null || stackData === void 0 ? void 0 : stackData.org_uid) !== null && _a !== void 0 ? _a : stackData === null || stackData === void 0 ? void 0 : stackData.organization_uid;
|
|
32
|
+
if (orgUid) {
|
|
33
|
+
cli_utilities_1.log.debug(`Found organization UID: '${orgUid}'.`, this.exportConfig.context);
|
|
34
|
+
this.exportConfig.org_uid = orgUid;
|
|
34
35
|
this.exportConfig.sourceStackName = stackData.name;
|
|
35
36
|
cli_utilities_1.log.debug(`Set source stack name: ${stackData.name}`, this.exportConfig.context);
|
|
36
37
|
}
|
|
37
38
|
if (!this.exportConfig.management_token) {
|
|
38
39
|
progress.addProcess(utils_1.PROCESS_NAMES.STACK_SETTINGS, 1);
|
|
39
|
-
processCount++;
|
|
40
40
|
}
|
|
41
|
+
progress.addProcess(utils_1.PROCESS_NAMES.STACK_DETAILS, 1);
|
|
41
42
|
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
|
|
42
43
|
progress.addProcess(utils_1.PROCESS_NAMES.STACK_LOCALE, 1);
|
|
43
|
-
processCount++;
|
|
44
|
-
}
|
|
45
|
-
else if (this.exportConfig.preserveStackVersion) {
|
|
46
|
-
progress.addProcess(utils_1.PROCESS_NAMES.STACK_DETAILS, 1);
|
|
47
|
-
processCount++;
|
|
48
44
|
}
|
|
45
|
+
let stackDetailsExportResult;
|
|
49
46
|
// Execute processes
|
|
50
47
|
if (!this.exportConfig.management_token) {
|
|
51
48
|
progress
|
|
@@ -53,9 +50,19 @@ class ExportStack extends base_class_1.default {
|
|
|
53
50
|
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.STACK_SETTINGS].EXPORTING, utils_1.PROCESS_NAMES.STACK_SETTINGS);
|
|
54
51
|
await this.exportStackSettings();
|
|
55
52
|
progress.completeProcess(utils_1.PROCESS_NAMES.STACK_SETTINGS, true);
|
|
53
|
+
progress
|
|
54
|
+
.startProcess(utils_1.PROCESS_NAMES.STACK_DETAILS)
|
|
55
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.STACK_DETAILS].EXPORTING, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
56
|
+
stackDetailsExportResult = await this.exportStack(stackData);
|
|
57
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.STACK_DETAILS, true);
|
|
56
58
|
}
|
|
57
59
|
else {
|
|
58
60
|
cli_utilities_1.log.info('Skipping stack settings export: Operation is not supported when using a management token.', this.exportConfig.context);
|
|
61
|
+
progress
|
|
62
|
+
.startProcess(utils_1.PROCESS_NAMES.STACK_DETAILS)
|
|
63
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.STACK_DETAILS].EXPORTING, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
64
|
+
stackDetailsExportResult = await this.writeStackJsonFromConfigApiKeyOnly();
|
|
65
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.STACK_DETAILS, true);
|
|
59
66
|
}
|
|
60
67
|
if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) {
|
|
61
68
|
progress
|
|
@@ -71,13 +78,8 @@ class ExportStack extends base_class_1.default {
|
|
|
71
78
|
return masterLocale;
|
|
72
79
|
}
|
|
73
80
|
else if (this.exportConfig.preserveStackVersion) {
|
|
74
|
-
progress
|
|
75
|
-
.startProcess(utils_1.PROCESS_NAMES.STACK_DETAILS)
|
|
76
|
-
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.STACK_DETAILS].EXPORTING, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
77
|
-
const stackResult = await this.exportStack();
|
|
78
|
-
progress.completeProcess(utils_1.PROCESS_NAMES.STACK_DETAILS, true);
|
|
79
81
|
this.completeProgress(true);
|
|
80
|
-
return
|
|
82
|
+
return stackDetailsExportResult;
|
|
81
83
|
}
|
|
82
84
|
else {
|
|
83
85
|
cli_utilities_1.log.debug('Locale locale already set, skipping locale fetch', this.exportConfig.context);
|
|
@@ -161,22 +163,30 @@ class ExportStack extends base_class_1.default {
|
|
|
161
163
|
throw error;
|
|
162
164
|
});
|
|
163
165
|
}
|
|
164
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Reuse stack snapshot from `getStack()` when present so we do not call `stack.fetch()` twice
|
|
168
|
+
* (same GET /stacks payload as writing stack.json). Falls back to `this.stack.fetch()` otherwise.
|
|
169
|
+
*/
|
|
170
|
+
async exportStack(preloadedStack) {
|
|
171
|
+
var _a;
|
|
165
172
|
cli_utilities_1.log.debug(`Starting stack export for: '${this.exportConfig.apiKey}'...`, this.exportConfig.context);
|
|
166
173
|
await utils_1.fsUtil.makeDirectory(this.stackFolderPath);
|
|
167
174
|
cli_utilities_1.log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context);
|
|
175
|
+
if (this.isStackFetchPayload(preloadedStack)) {
|
|
176
|
+
cli_utilities_1.log.debug('Reusing stack payload from analysis step (no extra stack.fetch).', this.exportConfig.context);
|
|
177
|
+
try {
|
|
178
|
+
return this.persistStackJsonPayload(preloadedStack);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, 'stack export', (error === null || error === void 0 ? void 0 : error.message) || utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.STACK_DETAILS].FAILED, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
182
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
168
186
|
return this.stack
|
|
169
187
|
.fetch()
|
|
170
188
|
.then((resp) => {
|
|
171
|
-
|
|
172
|
-
const stackFilePath = (0, node_path_1.resolve)(this.stackFolderPath, this.stackConfig.fileName);
|
|
173
|
-
cli_utilities_1.log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
|
|
174
|
-
utils_1.fsUtil.writeFile(stackFilePath, resp);
|
|
175
|
-
// Track progress for stack export completion
|
|
176
|
-
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `stack: ${this.exportConfig.apiKey}`, null, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
177
|
-
cli_utilities_1.log.success(`Stack details exported successfully for stack ${this.exportConfig.apiKey}`, this.exportConfig.context);
|
|
178
|
-
cli_utilities_1.log.debug('Stack export completed successfully.', this.exportConfig.context);
|
|
179
|
-
return resp;
|
|
189
|
+
return this.persistStackJsonPayload(resp);
|
|
180
190
|
})
|
|
181
191
|
.catch((error) => {
|
|
182
192
|
var _a;
|
|
@@ -185,6 +195,40 @@ class ExportStack extends base_class_1.default {
|
|
|
185
195
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
186
196
|
});
|
|
187
197
|
}
|
|
198
|
+
isStackFetchPayload(data) {
|
|
199
|
+
return (typeof data === 'object' &&
|
|
200
|
+
data !== null &&
|
|
201
|
+
!Array.isArray(data) &&
|
|
202
|
+
('api_key' in data || 'uid' in data));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Management-token exports cannot use Stack CMA endpoints for full metadata; write api_key from config only.
|
|
206
|
+
*/
|
|
207
|
+
async writeStackJsonFromConfigApiKeyOnly() {
|
|
208
|
+
var _a;
|
|
209
|
+
if (!this.exportConfig.apiKey || typeof this.exportConfig.apiKey !== 'string') {
|
|
210
|
+
throw new Error('Stack API key is required to write stack.json when using a management token.');
|
|
211
|
+
}
|
|
212
|
+
cli_utilities_1.log.debug('Writing config-based stack.json (api_key only, no stack fetch).', this.exportConfig.context);
|
|
213
|
+
await utils_1.fsUtil.makeDirectory(this.stackFolderPath);
|
|
214
|
+
const payload = { api_key: this.exportConfig.apiKey };
|
|
215
|
+
const stackFilePath = (0, node_path_1.resolve)(this.stackFolderPath, this.stackConfig.fileName);
|
|
216
|
+
utils_1.fsUtil.writeFile(stackFilePath, payload);
|
|
217
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `stack: ${this.exportConfig.apiKey}`, null, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
218
|
+
cli_utilities_1.log.success(`Stack identifier written to stack.json from config for stack ${this.exportConfig.apiKey}`, this.exportConfig.context);
|
|
219
|
+
return payload;
|
|
220
|
+
}
|
|
221
|
+
persistStackJsonPayload(resp) {
|
|
222
|
+
var _a, _b;
|
|
223
|
+
const sanitized = (0, omit_1.default)(resp, (_a = this.stackConfig.invalidKeys) !== null && _a !== void 0 ? _a : []);
|
|
224
|
+
const stackFilePath = (0, node_path_1.resolve)(this.stackFolderPath, this.stackConfig.fileName);
|
|
225
|
+
cli_utilities_1.log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
|
|
226
|
+
utils_1.fsUtil.writeFile(stackFilePath, sanitized);
|
|
227
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `stack: ${this.exportConfig.apiKey}`, null, utils_1.PROCESS_NAMES.STACK_DETAILS);
|
|
228
|
+
cli_utilities_1.log.success(`Stack details exported successfully for stack ${this.exportConfig.apiKey}`, this.exportConfig.context);
|
|
229
|
+
cli_utilities_1.log.debug('Stack export completed successfully.', this.exportConfig.context);
|
|
230
|
+
return sanitized;
|
|
231
|
+
}
|
|
188
232
|
async exportStackSettings() {
|
|
189
233
|
cli_utilities_1.log.info('Exporting stack settings...', this.exportConfig.context);
|
|
190
234
|
await utils_1.fsUtil.makeDirectory(this.stackFolderPath);
|
|
@@ -19,7 +19,7 @@ class ExportTaxonomies extends base_class_1.default {
|
|
|
19
19
|
this.applyQueryFilters(this.qs, 'taxonomies');
|
|
20
20
|
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.TAXONOMIES;
|
|
21
21
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.TAXONOMIES];
|
|
22
|
-
this.localesFilePath = (0, node_path_1.resolve)((0, cli_utilities_1.sanitizePath)(
|
|
22
|
+
this.localesFilePath = (0, node_path_1.resolve)((0, cli_utilities_1.sanitizePath)((0, utils_1.getExportBasePath)(exportConfig)), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.fileName));
|
|
23
23
|
}
|
|
24
24
|
async start() {
|
|
25
25
|
var _a;
|
|
@@ -62,7 +62,7 @@ class ExportTaxonomies extends base_class_1.default {
|
|
|
62
62
|
*/
|
|
63
63
|
async initializeExport() {
|
|
64
64
|
return this.withLoadingSpinner('TAXONOMIES: Analyzing taxonomy structure...', async () => {
|
|
65
|
-
this.taxonomiesFolderPath = (0, node_path_1.resolve)(
|
|
65
|
+
this.taxonomiesFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.taxonomiesConfig.dirName);
|
|
66
66
|
cli_utilities_1.log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context);
|
|
67
67
|
await utils_1.fsUtil.makeDirectory(this.taxonomiesFolderPath);
|
|
68
68
|
cli_utilities_1.log.debug('Created taxonomies directory.', this.exportConfig.context);
|
|
@@ -21,7 +21,7 @@ class ExportWebhooks extends base_class_1.default {
|
|
|
21
21
|
cli_utilities_1.log.debug('Starting webhooks export process...', this.exportConfig.context);
|
|
22
22
|
// Setup with loading spinner
|
|
23
23
|
const [totalCount] = await this.withLoadingSpinner('WEBHOOKS: Analyzing webhooks...', async () => {
|
|
24
|
-
this.webhooksFolderPath = (0, node_path_1.resolve)(
|
|
24
|
+
this.webhooksFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.webhookConfig.dirName);
|
|
25
25
|
await utils_1.fsUtil.makeDirectory(this.webhooksFolderPath);
|
|
26
26
|
// Get count for progress tracking
|
|
27
27
|
const countResponse = await this.stack.webhook().fetchAll(Object.assign(Object.assign({}, this.qs), { limit: 1 }));
|
|
@@ -22,7 +22,7 @@ class ExportWorkFlows extends base_class_1.default {
|
|
|
22
22
|
// Setup with loading spinner
|
|
23
23
|
const [totalCount] = await this.withLoadingSpinner('WORKFLOWS: Analyzing workflows...', async () => {
|
|
24
24
|
var _a;
|
|
25
|
-
this.webhooksFolderPath = (0, node_path_1.resolve)(
|
|
25
|
+
this.webhooksFolderPath = (0, node_path_1.resolve)((0, utils_1.getExportBasePath)(this.exportConfig), this.workflowConfig.dirName);
|
|
26
26
|
await utils_1.fsUtil.makeDirectory(this.webhooksFolderPath);
|
|
27
27
|
// Get count for progress tracking
|
|
28
28
|
const countResponse = await this.stack.workflow().fetchAll(Object.assign(Object.assign({}, this.qs), { limit: 1 }));
|
package/lib/types/index.d.ts
CHANGED
|
@@ -33,6 +33,9 @@ const setupConfig = async (exportCmdFlags) => {
|
|
|
33
33
|
}
|
|
34
34
|
config.exportDir = config.exportDir.replace(/['"]/g, '');
|
|
35
35
|
config.exportDir = path.resolve(config.exportDir);
|
|
36
|
+
if ((0, file_helper_1.isDirectoryNonEmpty)(config.exportDir)) {
|
|
37
|
+
cli_utilities_1.cliux.print('\nThe export directory is not empty. Existing files in this folder may be overwritten.', { color: 'yellow' });
|
|
38
|
+
}
|
|
36
39
|
const managementTokenAlias = exportCmdFlags['management-token-alias'] || exportCmdFlags['alias'];
|
|
37
40
|
if (managementTokenAlias) {
|
|
38
41
|
cli_utilities_1.log.debug('Using management token alias', { alias: managementTokenAlias });
|
|
@@ -11,4 +11,8 @@ export declare const writeFile: (filePath: string, data: any) => Promise<any>;
|
|
|
11
11
|
export declare const writeLargeFile: (filePath: string, data: any) => Promise<any>;
|
|
12
12
|
export declare const makeDirectory: (dir: string) => void;
|
|
13
13
|
export declare const readdir: (dirPath: string) => any;
|
|
14
|
+
/**
|
|
15
|
+
* Returns true if the path exists, is a directory, and contains at least one entry.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isDirectoryNonEmpty(absolutePath: string): boolean;
|
|
14
18
|
export declare const fsUtil: FsUtility;
|
package/lib/utils/file-helper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fsUtil = exports.readdir = exports.makeDirectory = exports.writeLargeFile = exports.writeFile = exports.writeFileSync = exports.readLargeFile = exports.readFile = exports.readFileSync = void 0;
|
|
3
|
+
exports.fsUtil = exports.isDirectoryNonEmpty = exports.readdir = exports.makeDirectory = exports.writeLargeFile = exports.writeFile = exports.writeFileSync = exports.readLargeFile = exports.readFile = exports.readFileSync = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs = tslib_1.__importStar(require("fs"));
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
@@ -114,6 +114,31 @@ const readdir = function (dirPath) {
|
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
116
|
exports.readdir = readdir;
|
|
117
|
+
/**
|
|
118
|
+
* Returns true if the path exists, is a directory, and contains at least one entry.
|
|
119
|
+
*/
|
|
120
|
+
function isDirectoryNonEmpty(absolutePath) {
|
|
121
|
+
if (!absolutePath || !fs.existsSync(absolutePath)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
let stat;
|
|
125
|
+
try {
|
|
126
|
+
stat = fs.statSync(absolutePath);
|
|
127
|
+
}
|
|
128
|
+
catch (_a) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (!stat.isDirectory()) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
return fs.readdirSync(absolutePath).length > 0;
|
|
136
|
+
}
|
|
137
|
+
catch (_b) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.isDirectoryNonEmpty = isDirectoryNonEmpty;
|
|
117
142
|
exports.fileExistsSync = function (path) {
|
|
118
143
|
return fs.existsSync(path);
|
|
119
144
|
};
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * as fileHelper from './file-helper';
|
|
|
4
4
|
export { fsUtil } from './file-helper';
|
|
5
5
|
export { default as setupBranches } from './setup-branches';
|
|
6
6
|
export { default as setupExportDir } from './setup-export-dir';
|
|
7
|
+
export { getExportBasePath } from './path-helper';
|
|
7
8
|
export { log, unlinkFileLogger } from './logger';
|
|
8
9
|
export { default as login } from './basic-login';
|
|
9
10
|
export * from './common-helper';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PROCESS_STATUS = exports.PROCESS_NAMES = exports.MODULE_NAMES = exports.MODULE_CONTEXTS = exports.login = exports.unlinkFileLogger = exports.log = exports.setupExportDir = exports.setupBranches = exports.fsUtil = exports.fileHelper = exports.setupExportConfig = exports.interactive = void 0;
|
|
3
|
+
exports.PROCESS_STATUS = exports.PROCESS_NAMES = exports.MODULE_NAMES = exports.MODULE_CONTEXTS = exports.login = exports.unlinkFileLogger = exports.log = exports.getExportBasePath = exports.setupExportDir = exports.setupBranches = exports.fsUtil = exports.fileHelper = exports.setupExportConfig = exports.interactive = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
exports.interactive = tslib_1.__importStar(require("./interactive"));
|
|
6
6
|
var export_config_handler_1 = require("./export-config-handler");
|
|
@@ -12,6 +12,8 @@ var setup_branches_1 = require("./setup-branches");
|
|
|
12
12
|
Object.defineProperty(exports, "setupBranches", { enumerable: true, get: function () { return tslib_1.__importDefault(setup_branches_1).default; } });
|
|
13
13
|
var setup_export_dir_1 = require("./setup-export-dir");
|
|
14
14
|
Object.defineProperty(exports, "setupExportDir", { enumerable: true, get: function () { return tslib_1.__importDefault(setup_export_dir_1).default; } });
|
|
15
|
+
var path_helper_1 = require("./path-helper");
|
|
16
|
+
Object.defineProperty(exports, "getExportBasePath", { enumerable: true, get: function () { return path_helper_1.getExportBasePath; } });
|
|
15
17
|
var logger_1 = require("./logger");
|
|
16
18
|
Object.defineProperty(exports, "log", { enumerable: true, get: function () { return logger_1.log; } });
|
|
17
19
|
Object.defineProperty(exports, "unlinkFileLogger", { enumerable: true, get: function () { return logger_1.unlinkFileLogger; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ExportConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the base path under which module content should be exported.
|
|
4
|
+
* Content is always written directly under this path (no branch subfolder).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getExportBasePath(exportConfig: ExportConfig): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getExportBasePath = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the base path under which module content should be exported.
|
|
6
|
+
* Content is always written directly under this path (no branch subfolder).
|
|
7
|
+
*/
|
|
8
|
+
function getExportBasePath(exportConfig) {
|
|
9
|
+
return exportConfig.exportDir;
|
|
10
|
+
}
|
|
11
|
+
exports.getExportBasePath = getExportBasePath;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const path = tslib_1.__importStar(require("path"));
|
|
5
|
-
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
3
|
const file_helper_1 = require("./file-helper");
|
|
7
4
|
const setupBranches = async (config, stackAPIClient) => {
|
|
8
5
|
if (typeof config !== 'object') {
|
|
@@ -42,9 +39,6 @@ const setupBranches = async (config, stackAPIClient) => {
|
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
41
|
(0, file_helper_1.makeDirectory)(config.exportDir);
|
|
45
|
-
// create branch info file
|
|
46
|
-
(0, file_helper_1.writeFileSync)(path.join((0, cli_utilities_1.sanitizePath)(config.exportDir), 'branches.json'), branches);
|
|
47
|
-
// add branches list in the
|
|
48
42
|
config.branches = branches;
|
|
49
43
|
};
|
|
50
44
|
exports.default = setupBranches;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ExportConfig } from '../types';
|
|
2
|
-
export default function setupExportDir(exportConfig: ExportConfig): Promise<void
|
|
2
|
+
export default function setupExportDir(exportConfig: ExportConfig): Promise<void>;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
5
|
-
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
3
|
const file_helper_1 = require("./file-helper");
|
|
7
4
|
async function setupExportDir(exportConfig) {
|
|
8
5
|
(0, file_helper_1.makeDirectory)(exportConfig.exportDir);
|
|
9
|
-
|
|
10
|
-
return Promise.all(exportConfig.branches.map((branch) => (0, file_helper_1.makeDirectory)(path_1.default.join((0, cli_utilities_1.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_1.sanitizePath)(branch.uid)))));
|
|
11
|
-
}
|
|
6
|
+
// Single-branch export: content goes directly under exportDir; no per-branch subdirs.
|
|
12
7
|
}
|
|
13
8
|
exports.default = setupExportDir;
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-export",
|
|
3
3
|
"description": "Contentstack CLI plugin to export content from stack",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.15",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-command": "~2.0.0-beta.
|
|
9
|
-
"@contentstack/cli-utilities": "~2.0.0-beta.
|
|
10
|
-
"@contentstack/cli-variants": "~2.0.0-beta.
|
|
8
|
+
"@contentstack/cli-command": "~2.0.0-beta.6",
|
|
9
|
+
"@contentstack/cli-utilities": "~2.0.0-beta.7",
|
|
10
|
+
"@contentstack/cli-variants": "~2.0.0-beta.12",
|
|
11
11
|
"@oclif/core": "^4.8.0",
|
|
12
12
|
"async": "^3.2.6",
|
|
13
13
|
"big-json": "^3.2.0",
|
|
14
14
|
"bluebird": "^3.7.2",
|
|
15
15
|
"chalk": "^5.6.2",
|
|
16
|
-
"lodash": "^4.
|
|
16
|
+
"lodash": "^4.18.1",
|
|
17
17
|
"merge": "^2.1.1",
|
|
18
18
|
"mkdirp": "^1.0.4",
|
|
19
19
|
"progress-stream": "^2.0.0",
|