@contentstack/cli-cm-export 2.0.0-beta.7 → 2.0.0-beta.8

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 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.7 linux-x64 node-v22.22.0
51
+ @contentstack/cli-cm-export/2.0.0-beta.8 linux-x64 node-v22.22.0
52
52
  $ csdx --help [COMMAND]
53
53
  USAGE
54
54
  $ csdx COMMAND
@@ -20,14 +20,15 @@ class ExportCommand extends cli_command_1.Command {
20
20
  const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(exportConfig);
21
21
  const moduleExporter = new export_1.ModuleExporter(managementAPIClient, exportConfig);
22
22
  await moduleExporter.start();
23
+ const sessionLogPath = (0, cli_utilities_1.getSessionLogPath)();
23
24
  cli_utilities_1.log.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`);
24
25
  cli_utilities_1.log.info(`The exported content has been stored at '${exportDir}'`, exportConfig.context);
25
- cli_utilities_1.log.success(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'`, exportConfig.context);
26
+ cli_utilities_1.log.success(`The log has been stored at '${sessionLogPath}'`, exportConfig.context);
26
27
  // Print comprehensive summary at the end
27
28
  if (!exportConfig.branches)
28
29
  cli_utilities_1.CLIProgressManager.printGlobalSummary();
29
30
  if (!((_a = cli_utilities_1.configHandler.get('log')) === null || _a === void 0 ? void 0 : _a.showConsoleLogs)) {
30
- cli_utilities_1.cliux.print(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'`, { color: 'green' });
31
+ cli_utilities_1.cliux.print(`The log has been stored at '${sessionLogPath}'`, { color: 'green' });
31
32
  }
32
33
  // Clear progress module setting now that export is complete
33
34
  (0, cli_utilities_1.clearProgressModuleSetting)();
@@ -36,9 +37,10 @@ class ExportCommand extends cli_command_1.Command {
36
37
  // Clear progress module setting even on error
37
38
  (0, cli_utilities_1.clearProgressModuleSetting)();
38
39
  (0, cli_utilities_1.handleAndLogError)(error);
40
+ const sessionLogPath = (0, cli_utilities_1.getSessionLogPath)();
39
41
  if (!((_b = cli_utilities_1.configHandler.get('log')) === null || _b === void 0 ? void 0 : _b.showConsoleLogs)) {
40
42
  cli_utilities_1.cliux.print(`Error: ${error}`, { color: 'red' });
41
- cli_utilities_1.cliux.print(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'`, { color: 'green' });
43
+ cli_utilities_1.cliux.print(`The log has been stored at '${sessionLogPath}'`, { color: 'green' });
42
44
  }
43
45
  }
44
46
  }
@@ -0,0 +1,57 @@
1
+ export declare const PATH_CONSTANTS: {
2
+ /** Root mapper directory (contains module-specific mapper subdirs) */
3
+ readonly MAPPER: "mapper";
4
+ /** Common mapper file names */
5
+ readonly FILES: {
6
+ readonly SUCCESS: "success.json";
7
+ readonly FAILS: "fails.json";
8
+ readonly UID_MAPPING: "uid-mapping.json";
9
+ readonly URL_MAPPING: "url-mapping.json";
10
+ readonly UID_MAPPER: "uid-mapper.json";
11
+ readonly SCHEMA: "schema.json";
12
+ readonly SETTINGS: "settings.json";
13
+ readonly MODIFIED_SCHEMAS: "modified-schemas.json";
14
+ readonly UNIQUE_MAPPING: "unique-mapping.json";
15
+ readonly TAXONOMIES: "taxonomies.json";
16
+ readonly ENVIRONMENTS: "environments.json";
17
+ readonly PENDING_EXTENSIONS: "pending_extensions.js";
18
+ readonly PENDING_GLOBAL_FIELDS: "pending_global_fields.js";
19
+ readonly INDEX: "index.json";
20
+ readonly FOLDER_MAPPING: "folder-mapping.json";
21
+ readonly VERSIONED_ASSETS: "versioned-assets.json";
22
+ };
23
+ /** Module subdirectory names within mapper */
24
+ readonly MAPPER_MODULES: {
25
+ readonly ASSETS: "assets";
26
+ readonly ENTRIES: "entries";
27
+ readonly CONTENT_TYPES: "content_types";
28
+ readonly TAXONOMIES: "taxonomies";
29
+ readonly TAXONOMY_TERMS: "terms";
30
+ readonly GLOBAL_FIELDS: "global_fields";
31
+ readonly EXTENSIONS: "extensions";
32
+ readonly WORKFLOWS: "workflows";
33
+ readonly WEBHOOKS: "webhooks";
34
+ readonly LABELS: "labels";
35
+ readonly ENVIRONMENTS: "environments";
36
+ readonly MARKETPLACE_APPS: "marketplace_apps";
37
+ readonly CUSTOM_ROLES: "custom-roles";
38
+ readonly LANGUAGES: "languages";
39
+ };
40
+ /** Content directory names (used in both import and export) */
41
+ readonly CONTENT_DIRS: {
42
+ readonly ASSETS: "assets";
43
+ readonly ENTRIES: "entries";
44
+ readonly CONTENT_TYPES: "content_types";
45
+ readonly TAXONOMIES: "taxonomies";
46
+ readonly GLOBAL_FIELDS: "global_fields";
47
+ readonly EXTENSIONS: "extensions";
48
+ readonly WEBHOOKS: "webhooks";
49
+ readonly WORKFLOWS: "workflows";
50
+ readonly LABELS: "labels";
51
+ readonly ENVIRONMENTS: "environments";
52
+ readonly STACK: "stack";
53
+ readonly LOCALES: "locales";
54
+ readonly MARKETPLACE_APPS: "marketplace_apps";
55
+ };
56
+ };
57
+ export type PathConstants = typeof PATH_CONSTANTS;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PATH_CONSTANTS = void 0;
4
+ exports.PATH_CONSTANTS = {
5
+ /** Root mapper directory (contains module-specific mapper subdirs) */
6
+ MAPPER: 'mapper',
7
+ /** Common mapper file names */
8
+ FILES: {
9
+ SUCCESS: 'success.json',
10
+ FAILS: 'fails.json',
11
+ UID_MAPPING: 'uid-mapping.json',
12
+ URL_MAPPING: 'url-mapping.json',
13
+ UID_MAPPER: 'uid-mapper.json',
14
+ SCHEMA: 'schema.json',
15
+ SETTINGS: 'settings.json',
16
+ MODIFIED_SCHEMAS: 'modified-schemas.json',
17
+ UNIQUE_MAPPING: 'unique-mapping.json',
18
+ TAXONOMIES: 'taxonomies.json',
19
+ ENVIRONMENTS: 'environments.json',
20
+ PENDING_EXTENSIONS: 'pending_extensions.js',
21
+ PENDING_GLOBAL_FIELDS: 'pending_global_fields.js',
22
+ INDEX: 'index.json',
23
+ FOLDER_MAPPING: 'folder-mapping.json',
24
+ VERSIONED_ASSETS: 'versioned-assets.json',
25
+ },
26
+ /** Module subdirectory names within mapper */
27
+ MAPPER_MODULES: {
28
+ ASSETS: 'assets',
29
+ ENTRIES: 'entries',
30
+ CONTENT_TYPES: 'content_types',
31
+ TAXONOMIES: 'taxonomies',
32
+ TAXONOMY_TERMS: 'terms',
33
+ GLOBAL_FIELDS: 'global_fields',
34
+ EXTENSIONS: 'extensions',
35
+ WORKFLOWS: 'workflows',
36
+ WEBHOOKS: 'webhooks',
37
+ LABELS: 'labels',
38
+ ENVIRONMENTS: 'environments',
39
+ MARKETPLACE_APPS: 'marketplace_apps',
40
+ CUSTOM_ROLES: 'custom-roles',
41
+ LANGUAGES: 'languages',
42
+ },
43
+ /** Content directory names (used in both import and export) */
44
+ CONTENT_DIRS: {
45
+ ASSETS: 'assets',
46
+ ENTRIES: 'entries',
47
+ CONTENT_TYPES: 'content_types',
48
+ TAXONOMIES: 'taxonomies',
49
+ GLOBAL_FIELDS: 'global_fields',
50
+ EXTENSIONS: 'extensions',
51
+ WEBHOOKS: 'webhooks',
52
+ WORKFLOWS: 'workflows',
53
+ LABELS: 'labels',
54
+ ENVIRONMENTS: 'environments',
55
+ STACK: 'stack',
56
+ LOCALES: 'locales',
57
+ MARKETPLACE_APPS: 'marketplace_apps',
58
+ },
59
+ };
@@ -16,6 +16,7 @@ const progress_stream_1 = tslib_1.__importDefault(require("progress-stream"));
16
16
  const node_fs_1 = require("node:fs");
17
17
  const node_path_1 = require("node:path");
18
18
  const cli_utilities_1 = require("@contentstack/cli-utilities");
19
+ const constants_1 = require("../../constants");
19
20
  const config_1 = tslib_1.__importDefault(require("../../config"));
20
21
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
21
22
  const utils_1 = require("../../utils");
@@ -170,7 +171,7 @@ class ExportAssets extends base_class_1.default {
170
171
  fs = new cli_utilities_1.FsUtility({
171
172
  metaHandler,
172
173
  moduleName: 'assets',
173
- indexFileName: 'assets.json',
174
+ indexFileName: this.assetConfig.fileName,
174
175
  basePath: this.assetsRootPath,
175
176
  chunkFileSize: this.assetConfig.chunkFileSize,
176
177
  metaPickKeys: (0, merge_1.default)(['uid', 'url', 'filename', 'parent_uid'], this.assetConfig.assetsMetaKeys),
@@ -235,7 +236,7 @@ class ExportAssets extends base_class_1.default {
235
236
  if (!fs && !(0, isEmpty_1.default)(response)) {
236
237
  fs = new cli_utilities_1.FsUtility({
237
238
  moduleName: 'assets',
238
- indexFileName: 'versioned-assets.json',
239
+ indexFileName: constants_1.PATH_CONSTANTS.FILES.VERSIONED_ASSETS,
239
240
  chunkFileSize: this.assetConfig.chunkFileSize,
240
241
  basePath: (0, node_path_1.resolve)(this.assetsRootPath, 'versions'),
241
242
  metaPickKeys: (0, merge_1.default)(['uid', 'url', 'filename', '_version', 'parent_uid'], this.assetConfig.assetsMetaKeys),
@@ -57,7 +57,7 @@ export default abstract class BaseClass {
57
57
  * - moduleName: The module name to generate the message (e.g., 'Assets', 'Entries')
58
58
  * If not provided, uses this.currentModuleName
59
59
  * - customSuccessMessage: Optional custom success message. If not provided, generates: "{moduleName} have been exported successfully!"
60
- * - customWarningMessage: Optional custom warning message. If not provided, generates: "{moduleName} have been exported with some errors. Please check the logs for details."
60
+ * - customWarningMessage: Optional custom warning message. If not provided, generates: "{moduleName} have been exported with some errors. Please check the logs at: {sessionLogPath}"
61
61
  * - context: Optional context for logging
62
62
  */
63
63
  protected completeProgressWithMessage(options?: CompleteProgressOptions): void;
@@ -56,7 +56,7 @@ class BaseClass {
56
56
  * - moduleName: The module name to generate the message (e.g., 'Assets', 'Entries')
57
57
  * If not provided, uses this.currentModuleName
58
58
  * - customSuccessMessage: Optional custom success message. If not provided, generates: "{moduleName} have been exported successfully!"
59
- * - customWarningMessage: Optional custom warning message. If not provided, generates: "{moduleName} have been exported with some errors. Please check the logs for details."
59
+ * - customWarningMessage: Optional custom warning message. If not provided, generates: "{moduleName} have been exported with some errors. Please check the logs at: {sessionLogPath}"
60
60
  * - context: Optional context for logging
61
61
  */
62
62
  completeProgressWithMessage(options) {
@@ -67,7 +67,8 @@ class BaseClass {
67
67
  const name = (options === null || options === void 0 ? void 0 : options.moduleName) || this.currentModuleName || 'Module';
68
68
  // Generate default messages if not provided
69
69
  const successMessage = (options === null || options === void 0 ? void 0 : options.customSuccessMessage) || `${name} have been exported successfully!`;
70
- const warningMessage = (options === null || options === void 0 ? void 0 : options.customWarningMessage) || `${name} have been exported with some errors. Please check the logs for details.`;
70
+ const sessionLogPath = (0, cli_utilities_1.getSessionLogPath)();
71
+ const warningMessage = (options === null || options === void 0 ? void 0 : options.customWarningMessage) || `${name} have been exported with some errors. Please check the logs at: ${sessionLogPath}`;
71
72
  this.completeProgress(true);
72
73
  if (hasErrors) {
73
74
  cli_utilities_1.log.warn(warningMessage, logContext);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path = tslib_1.__importStar(require("path"));
5
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
6
+ const constants_1 = require("../../constants");
6
7
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
7
8
  const utils_1 = require("../../utils");
8
9
  class ContentTypesExport extends base_class_1.default {
@@ -105,7 +106,7 @@ class ContentTypesExport extends base_class_1.default {
105
106
  await (0, utils_1.executeTask)(contentTypes, writeWithProgress.bind(this), {
106
107
  concurrency: this.exportConfig.writeConcurrency,
107
108
  });
108
- const schemaFilePath = path.join(this.contentTypesDirPath, 'schema.json');
109
+ const schemaFilePath = path.join(this.contentTypesDirPath, constants_1.PATH_CONSTANTS.FILES.SCHEMA);
109
110
  cli_utilities_1.log.debug(`Writing aggregate schema to: ${schemaFilePath}`, this.exportConfig.context);
110
111
  return utils_1.fsUtil.writeFile(schemaFilePath, contentTypes);
111
112
  }
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path = tslib_1.__importStar(require("path"));
5
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
6
+ const constants_1 = require("../../constants");
6
7
  const cli_variants_1 = require("@contentstack/cli-variants");
7
- const cli_utilities_2 = require("@contentstack/cli-utilities");
8
8
  const utils_1 = require("../../utils");
9
9
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
10
10
  class EntriesExport extends base_class_1.default {
@@ -14,9 +14,9 @@ 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
- this.entriesDirPath = path.resolve((0, cli_utilities_2.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_2.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_2.sanitizePath)(this.entriesConfig.dirName));
18
- this.localesFilePath = path.resolve((0, cli_utilities_2.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_2.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.locales.fileName));
19
- this.schemaFilePath = path.resolve((0, cli_utilities_2.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_2.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_2.sanitizePath)(exportConfig.modules.content_types.dirName), 'schema.json');
17
+ this.entriesDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(this.entriesConfig.dirName));
18
+ this.localesFilePath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.fileName));
19
+ this.schemaFilePath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.content_types.dirName), constants_1.PATH_CONSTANTS.FILES.SCHEMA);
20
20
  this.projectInstance = new cli_variants_1.ExportProjects(this.exportConfig);
21
21
  this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.ENTRIES;
22
22
  this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.ENTRIES];
@@ -205,12 +205,12 @@ class EntriesExport extends base_class_1.default {
205
205
  }
206
206
  if (Array.isArray(entriesSearchResponse === null || entriesSearchResponse === void 0 ? void 0 : entriesSearchResponse.items) && ((_b = entriesSearchResponse === null || entriesSearchResponse === void 0 ? void 0 : entriesSearchResponse.items) === null || _b === void 0 ? void 0 : _b.length) > 0) {
207
207
  if (options.skip === 0) {
208
- const entryBasePath = path.join((0, cli_utilities_2.sanitizePath)(this.entriesDirPath), (0, cli_utilities_2.sanitizePath)(options.contentType), (0, cli_utilities_2.sanitizePath)(options.locale));
208
+ const entryBasePath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesDirPath), (0, cli_utilities_1.sanitizePath)(options.contentType), (0, cli_utilities_1.sanitizePath)(options.locale));
209
209
  cli_utilities_1.log.debug(`Creating directory for entries at: ${entryBasePath}`, this.exportConfig.context);
210
210
  await utils_1.fsUtil.makeDirectory(entryBasePath);
211
211
  this.entriesFileHelper = new cli_utilities_1.FsUtility({
212
212
  moduleName: 'entries',
213
- indexFileName: 'index.json',
213
+ indexFileName: constants_1.PATH_CONSTANTS.FILES.INDEX,
214
214
  basePath: entryBasePath,
215
215
  chunkFileSize: this.entriesConfig.chunkFileSize,
216
216
  keepMetadata: false,
@@ -227,7 +227,7 @@ class EntriesExport extends base_class_1.default {
227
227
  });
228
228
  if (this.entriesConfig.exportVersions) {
229
229
  cli_utilities_1.log.debug('Exporting entry versions is enabled.', this.exportConfig.context);
230
- let versionedEntryPath = path.join((0, cli_utilities_2.sanitizePath)(this.entriesDirPath), (0, cli_utilities_2.sanitizePath)(options.contentType), (0, cli_utilities_2.sanitizePath)(options.locale), 'versions');
230
+ let versionedEntryPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesDirPath), (0, cli_utilities_1.sanitizePath)(options.contentType), (0, cli_utilities_1.sanitizePath)(options.locale), 'versions');
231
231
  cli_utilities_1.log.debug(`Creating versioned entries directory at: ${versionedEntryPath}.`, this.exportConfig.context);
232
232
  utils_1.fsUtil.makeDirectory(versionedEntryPath);
233
233
  await this.fetchEntriesVersions(entriesSearchResponse.items, {
@@ -271,7 +271,7 @@ class EntriesExport extends base_class_1.default {
271
271
  cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context);
272
272
  const onSuccess = ({ response, apiData: entry }) => {
273
273
  var _a;
274
- const versionFilePath = path.join((0, cli_utilities_2.sanitizePath)(options.versionedEntryPath), (0, cli_utilities_2.sanitizePath)(`${entry.uid}.json`));
274
+ const versionFilePath = path.join((0, cli_utilities_1.sanitizePath)(options.versionedEntryPath), (0, cli_utilities_1.sanitizePath)(`${entry.uid}.json`));
275
275
  cli_utilities_1.log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context);
276
276
  utils_1.fsUtil.writeFile(versionFilePath, response);
277
277
  // Track version progress if the process exists
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
4
4
  const find_1 = tslib_1.__importDefault(require("lodash/find"));
5
5
  const node_path_1 = require("node:path");
6
6
  const cli_utilities_1 = require("@contentstack/cli-utilities");
7
+ const constants_1 = require("../../constants");
7
8
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
8
9
  const utils_1 = require("../../utils");
9
10
  class ExportStack extends base_class_1.default {
@@ -191,7 +192,7 @@ class ExportStack extends base_class_1.default {
191
192
  .settings()
192
193
  .then((resp) => {
193
194
  var _a;
194
- utils_1.fsUtil.writeFile((0, node_path_1.resolve)(this.stackFolderPath, 'settings.json'), resp);
195
+ utils_1.fsUtil.writeFile((0, node_path_1.resolve)(this.stackFolderPath, constants_1.PATH_CONSTANTS.FILES.SETTINGS), resp);
195
196
  // Track progress for stack settings completion
196
197
  (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, 'stack settings', null, utils_1.PROCESS_NAMES.STACK_SETTINGS);
197
198
  cli_utilities_1.log.success('Exported stack settings successfully!', this.exportConfig.context);
@@ -10,6 +10,26 @@ export default class ExportTaxonomies extends BaseClass {
10
10
  private localesFilePath;
11
11
  constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
12
12
  start(): Promise<void>;
13
+ /**
14
+ * Initialize export setup (create directories, get initial count)
15
+ */
16
+ private initializeExport;
17
+ /**
18
+ * Setup progress manager with processes
19
+ */
20
+ private setupProgress;
21
+ /**
22
+ * Determine if locale-based export is supported
23
+ */
24
+ private determineExportStrategy;
25
+ /**
26
+ * Fetch all taxonomies based on export strategy
27
+ */
28
+ private fetchAllTaxonomies;
29
+ /**
30
+ * Export all taxonomies with detailed information
31
+ */
32
+ private exportAllTaxonomies;
13
33
  /**
14
34
  * Process and export taxonomies for a specific locale
15
35
  */
@@ -17,44 +17,131 @@ class ExportTaxonomies extends base_class_1.default {
17
17
  this.taxonomiesConfig = exportConfig.modules.taxonomies;
18
18
  this.qs = { include_count: true, limit: this.taxonomiesConfig.limit || 100, skip: 0 };
19
19
  this.applyQueryFilters(this.qs, 'taxonomies');
20
- this.exportConfig.context.module = 'taxonomies';
20
+ this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.TAXONOMIES;
21
+ this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.TAXONOMIES];
21
22
  this.localesFilePath = (0, node_path_1.resolve)((0, cli_utilities_1.sanitizePath)(exportConfig.exportDir), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(exportConfig.modules.locales.fileName));
22
23
  }
23
24
  async start() {
24
25
  var _a;
25
- cli_utilities_1.log.debug('Starting export process for taxonomies...', this.exportConfig.context);
26
- //create taxonomies folder
27
- this.taxonomiesFolderPath = (0, node_path_1.resolve)(this.exportConfig.exportDir, this.exportConfig.branchName || '', this.taxonomiesConfig.dirName);
28
- cli_utilities_1.log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context);
29
- await utils_1.fsUtil.makeDirectory(this.taxonomiesFolderPath);
30
- cli_utilities_1.log.debug('Created taxonomies directory.', this.exportConfig.context);
31
- const localesToExport = this.getLocalesToExport();
32
- cli_utilities_1.log.debug(`Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, this.exportConfig.context);
33
- if (localesToExport.length === 0) {
34
- cli_utilities_1.log.warn('No locales found to export', this.exportConfig.context);
35
- return;
26
+ try {
27
+ cli_utilities_1.log.debug('Starting export process for taxonomies...', this.exportConfig.context);
28
+ const totalCount = await this.initializeExport();
29
+ if (totalCount === 0) {
30
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context);
31
+ return;
32
+ }
33
+ const progress = this.setupProgress(totalCount);
34
+ const localesToExport = this.getLocalesToExport();
35
+ if (localesToExport.length === 0) {
36
+ cli_utilities_1.log.warn('No locales found to export', this.exportConfig.context);
37
+ this.completeProgress(true);
38
+ return;
39
+ }
40
+ // Start fetch process
41
+ progress
42
+ .startProcess(utils_1.PROCESS_NAMES.FETCH_TAXONOMIES)
43
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_TAXONOMIES].FETCHING, utils_1.PROCESS_NAMES.FETCH_TAXONOMIES);
44
+ // Determine export strategy and fetch taxonomies
45
+ await this.determineExportStrategy((_a = this.exportConfig.master_locale) === null || _a === void 0 ? void 0 : _a.code);
46
+ await this.fetchAllTaxonomies(localesToExport);
47
+ progress.completeProcess(utils_1.PROCESS_NAMES.FETCH_TAXONOMIES, true);
48
+ // Export taxonomies with detailed information
49
+ const actualCount = await this.exportAllTaxonomies(progress, localesToExport, totalCount);
50
+ // Write metadata and complete
51
+ await this.writeTaxonomiesMetadata();
52
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', actualCount), this.exportConfig.context);
53
+ this.completeProgress(true);
36
54
  }
37
- // Test locale-based export support with master locale
38
- const masterLocale = (_a = this.exportConfig.master_locale) === null || _a === void 0 ? void 0 : _a.code;
55
+ catch (error) {
56
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
57
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Taxonomies export failed');
58
+ }
59
+ }
60
+ /**
61
+ * Initialize export setup (create directories, get initial count)
62
+ */
63
+ async initializeExport() {
64
+ return this.withLoadingSpinner('TAXONOMIES: Analyzing taxonomy structure...', async () => {
65
+ this.taxonomiesFolderPath = (0, node_path_1.resolve)(this.exportConfig.exportDir, this.exportConfig.branchName || '', this.taxonomiesConfig.dirName);
66
+ cli_utilities_1.log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context);
67
+ await utils_1.fsUtil.makeDirectory(this.taxonomiesFolderPath);
68
+ cli_utilities_1.log.debug('Created taxonomies directory.', this.exportConfig.context);
69
+ // Get count first for progress tracking
70
+ const countResponse = await this.stack
71
+ .taxonomy()
72
+ .query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
73
+ .find();
74
+ return countResponse.count || 0;
75
+ });
76
+ }
77
+ /**
78
+ * Setup progress manager with processes
79
+ */
80
+ setupProgress(totalCount) {
81
+ const progress = this.createNestedProgress(this.currentModuleName);
82
+ // For fetch: count API calls, not individual taxonomies
83
+ const fetchApiCallsCount = Math.ceil(totalCount / (this.qs.limit || 100));
84
+ progress.addProcess(utils_1.PROCESS_NAMES.FETCH_TAXONOMIES, fetchApiCallsCount);
85
+ progress.addProcess(utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, totalCount);
86
+ return progress;
87
+ }
88
+ /**
89
+ * Determine if locale-based export is supported
90
+ */
91
+ async determineExportStrategy(masterLocale) {
39
92
  await this.fetchTaxonomies(masterLocale, true);
40
93
  if (!this.isLocaleBasedExportSupported) {
94
+ cli_utilities_1.log.debug('Falling back to legacy export (non-localized)', this.exportConfig.context);
41
95
  this.taxonomies = {};
42
96
  this.taxonomiesByLocale = {};
43
- // Fetch taxonomies without locale parameter
44
- await this.fetchTaxonomies();
45
- await this.exportTaxonomies();
46
- await this.writeTaxonomiesMetadata();
47
97
  }
48
98
  else {
49
- // Process all locales with locale-based export
50
99
  cli_utilities_1.log.debug('Localization enabled, proceeding with locale-based export', this.exportConfig.context);
100
+ }
101
+ }
102
+ /**
103
+ * Fetch all taxonomies based on export strategy
104
+ */
105
+ async fetchAllTaxonomies(localesToExport) {
106
+ if (!this.isLocaleBasedExportSupported) {
107
+ await this.fetchTaxonomies();
108
+ }
109
+ else {
51
110
  for (const localeCode of localesToExport) {
52
111
  await this.fetchTaxonomies(localeCode);
112
+ }
113
+ }
114
+ }
115
+ /**
116
+ * Export all taxonomies with detailed information
117
+ */
118
+ async exportAllTaxonomies(progress, localesToExport, totalCount) {
119
+ var _a;
120
+ const actualCount = (_a = Object.keys(this.taxonomies || {})) === null || _a === void 0 ? void 0 : _a.length;
121
+ cli_utilities_1.log.debug(`Found ${actualCount} taxonomies to export (API reported ${totalCount})`, this.exportConfig.context);
122
+ if (actualCount === 0) {
123
+ cli_utilities_1.log.info('No taxonomies found to export detailed information', this.exportConfig.context);
124
+ return 0;
125
+ }
126
+ // Update progress total if needed
127
+ if (actualCount !== totalCount) {
128
+ progress.updateProcessTotal(utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, actualCount);
129
+ }
130
+ // Start export process
131
+ progress
132
+ .startProcess(utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS)
133
+ .updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS].EXPORTING, utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS);
134
+ // Export based on strategy
135
+ if (!this.isLocaleBasedExportSupported) {
136
+ await this.exportTaxonomies();
137
+ }
138
+ else {
139
+ for (const localeCode of localesToExport) {
53
140
  await this.processLocaleExport(localeCode);
54
141
  }
55
- await this.writeTaxonomiesMetadata();
56
142
  }
57
- this.completeProgressWithMessage();
143
+ progress.completeProcess(utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, true);
144
+ return actualCount;
58
145
  }
59
146
  /**
60
147
  * Process and export taxonomies for a specific locale
@@ -77,7 +164,7 @@ class ExportTaxonomies extends base_class_1.default {
77
164
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context);
78
165
  return;
79
166
  }
80
- const taxonomiesFilePath = (0, node_path_1.resolve)(this.taxonomiesFolderPath, 'taxonomies.json');
167
+ const taxonomiesFilePath = (0, node_path_1.resolve)(this.taxonomiesFolderPath, this.taxonomiesConfig.fileName);
81
168
  cli_utilities_1.log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context);
82
169
  utils_1.fsUtil.writeFile(taxonomiesFilePath, this.taxonomies);
83
170
  }
@@ -90,7 +177,7 @@ class ExportTaxonomies extends base_class_1.default {
90
177
  * @returns {Promise<void>}
91
178
  */
92
179
  async fetchTaxonomies(localeCode, checkLocaleSupport = false) {
93
- var _a;
180
+ var _a, _b;
94
181
  let skip = 0;
95
182
  const localeInfo = localeCode ? `for locale: ${localeCode}` : '';
96
183
  if (localeCode && !this.taxonomiesByLocale[localeCode]) {
@@ -117,6 +204,10 @@ class ExportTaxonomies extends base_class_1.default {
117
204
  this.isLocaleBasedExportSupported = false;
118
205
  }
119
206
  this.sanitizeTaxonomiesAttribs(items, localeCode);
207
+ // Track progress per API call (only for actual fetch, not locale support check)
208
+ if (!checkLocaleSupport) {
209
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `fetched ${items.length} taxonomies${localeInfo}`, null, utils_1.PROCESS_NAMES.FETCH_TAXONOMIES);
210
+ }
120
211
  skip += this.qs.limit || 100;
121
212
  if (skip >= taxonomiesCount) {
122
213
  cli_utilities_1.log.debug(`Completed fetching all taxonomies ${localeInfo}`, this.exportConfig.context);
@@ -183,13 +274,21 @@ class ExportTaxonomies extends base_class_1.default {
183
274
  cli_utilities_1.log.debug(`Created locale folder: ${exportFolderPath}`, this.exportConfig.context);
184
275
  }
185
276
  const onSuccess = ({ response, uid }) => {
277
+ var _a, _b;
278
+ const taxonomyName = (_a = this.taxonomies[uid]) === null || _a === void 0 ? void 0 : _a.name;
186
279
  const filePath = (0, node_path_1.resolve)(exportFolderPath, `${uid}.json`);
187
280
  cli_utilities_1.log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context);
188
281
  utils_1.fsUtil.writeFile(filePath, response);
189
- cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), this.exportConfig.context);
282
+ // Track progress for each exported taxonomy
283
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `taxonomy: ${taxonomyName || uid}`, null, utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS);
284
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', taxonomyName || uid), this.exportConfig.context);
190
285
  };
191
286
  const onReject = ({ error, uid }) => {
287
+ var _a, _b;
288
+ const taxonomyName = (_a = this.taxonomies[uid]) === null || _a === void 0 ? void 0 : _a.name;
192
289
  cli_utilities_1.log.debug(`Failed to export detailed data for taxonomy: ${uid}${localeInfo}`, this.exportConfig.context);
290
+ // Track failure
291
+ (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(false, `taxonomy: ${taxonomyName || uid}`, (error === null || error === void 0 ? void 0 : error.message) || utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS].FAILED, utils_1.PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS);
193
292
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign(Object.assign({}, this.exportConfig.context), { uid }), (localeCode && { locale: localeCode })));
194
293
  };
195
294
  for (const taxonomyUID of taxonomiesUID) {
@@ -121,5 +121,5 @@
121
121
  ]
122
122
  }
123
123
  },
124
- "version": "2.0.0-beta.7"
124
+ "version": "2.0.0-beta.8"
125
125
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
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.7",
4
+ "version": "2.0.0-beta.8",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  "big-json": "^3.2.0",
14
14
  "bluebird": "^3.7.2",
15
15
  "chalk": "^4.1.2",
16
- "lodash": "^4.17.21",
16
+ "lodash": "^4.17.23",
17
17
  "merge": "^2.1.1",
18
18
  "mkdirp": "^1.0.4",
19
19
  "progress-stream": "^2.0.0",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@contentstack/cli-auth": "~2.0.0-beta.4",
25
- "@contentstack/cli-config": "~1.19.0",
25
+ "@contentstack/cli-config": "~2.0.0-beta",
26
26
  "@contentstack/cli-dev-dependencies": "~1.3.1",
27
27
  "@oclif/plugin-help": "^6.2.28",
28
28
  "@oclif/test": "^4.1.13",