@contentstack/cli-cm-export 2.0.0-beta.2 → 2.0.0-beta.3

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.2 linux-x64 node-v22.21.1
51
+ @contentstack/cli-cm-export/2.0.0-beta.3 linux-x64 node-v22.21.1
52
52
  $ csdx --help [COMMAND]
53
53
  USAGE
54
54
  $ csdx COMMAND
@@ -83,7 +83,7 @@ FLAGS
83
83
  -m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
84
84
  the modules to the stack. The available modules are assets, content-types, entries,
85
85
  environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
86
- workflows, custom-roles, and taxonomies.
86
+ workflows, custom-roles, taxonomies, and studio.
87
87
  -t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
88
88
  of multiple content types, specify the IDs separated by spaces.
89
89
  -y, --yes [optional] Force override all Marketplace prompts.
@@ -133,7 +133,7 @@ FLAGS
133
133
  -m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
134
134
  the modules to the stack. The available modules are assets, content-types, entries,
135
135
  environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
136
- workflows, custom-roles, and taxonomies.
136
+ workflows, custom-roles, taxonomies, and studio.
137
137
  -t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
138
138
  of multiple content types, specify the IDs separated by spaces.
139
139
  -y, --yes [optional] Force override all Marketplace prompts.
@@ -67,6 +67,9 @@ class ExportCommand extends cli_command_1.Command {
67
67
  if (this.personalizeUrl) {
68
68
  exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl;
69
69
  }
70
+ if (this.composableStudioUrl) {
71
+ exportConfig.modules['composable-studio'].apiBaseUrl = this.composableStudioUrl;
72
+ }
70
73
  }
71
74
  }
72
75
  exports.default = ExportCommand;
@@ -122,7 +125,7 @@ ExportCommand.flags = {
122
125
  }),
123
126
  module: cli_utilities_1.flags.string({
124
127
  char: 'm',
125
- description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and taxonomies.',
128
+ description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.',
126
129
  parse: (0, cli_utilities_1.printFlagDeprecation)(['-m'], ['--module']),
127
130
  }),
128
131
  'content-types': cli_utilities_1.flags.string({
@@ -39,6 +39,7 @@ const config = {
39
39
  'entries',
40
40
  'labels',
41
41
  'marketplace-apps',
42
+ 'composable-studio',
42
43
  ],
43
44
  locales: {
44
45
  dirName: 'locales',
@@ -212,6 +213,12 @@ const config = {
212
213
  dirName: 'marketplace_apps',
213
214
  fileName: 'marketplace_apps.json',
214
215
  },
216
+ 'composable-studio': {
217
+ dirName: 'composable_studio',
218
+ fileName: 'composable_studio.json',
219
+ apiBaseUrl: 'https://composable-studio-api.contentstack.com',
220
+ apiVersion: 'v1',
221
+ },
215
222
  taxonomies: {
216
223
  dirName: 'taxonomies',
217
224
  fileName: 'taxonomies.json',
@@ -77,7 +77,7 @@ class ModuleExporter {
77
77
  return this.exportAllModules();
78
78
  }
79
79
  async exportByModuleByName(moduleName) {
80
- cli_utilities_1.log.info(`Exporting module: ${moduleName}`, this.exportConfig.context);
80
+ cli_utilities_1.log.info(`Exporting module: '${moduleName}'...`, this.exportConfig.context);
81
81
  // export the modules by name
82
82
  // calls the module runner which inturn calls the module itself
83
83
  await (0, modules_1.default)({
@@ -93,7 +93,8 @@ class ModuleExporter {
93
93
  exportModules.push('stack');
94
94
  }
95
95
  if (!this.exportConfig.skipDependencies) {
96
- const { modules: { [moduleName]: { dependencies = [] } = {} }, } = this.exportConfig;
96
+ const moduleConfig = this.exportConfig.modules[moduleName];
97
+ const dependencies = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.dependencies) || [];
97
98
  if (dependencies.length > 0) {
98
99
  exportModules = exportModules.concat(dependencies);
99
100
  }
@@ -0,0 +1,15 @@
1
+ import { HttpClient } from '@contentstack/cli-utilities';
2
+ import { ModuleClassParams, ComposableStudioConfig, ExportConfig, ComposableStudioProject } from '../../types';
3
+ export default class ExportComposableStudio {
4
+ protected composableStudioConfig: ComposableStudioConfig;
5
+ protected composableStudioProject: ComposableStudioProject | null;
6
+ protected apiClient: HttpClient;
7
+ composableStudioPath: string;
8
+ exportConfig: ExportConfig;
9
+ constructor({ exportConfig }: Omit<ModuleClassParams, 'stackAPIClient' | 'moduleName'>);
10
+ start(): Promise<void>;
11
+ /**
12
+ * Export Studio projects connected to the current stack
13
+ */
14
+ exportProjects(): Promise<void>;
15
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_path_1 = require("node:path");
4
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
5
+ const utils_1 = require("../../utils");
6
+ class ExportComposableStudio {
7
+ constructor({ exportConfig }) {
8
+ this.composableStudioProject = null;
9
+ this.exportConfig = exportConfig;
10
+ this.composableStudioConfig = exportConfig.modules['composable-studio'];
11
+ this.exportConfig.context.module = 'composable-studio';
12
+ // Initialize HttpClient with Studio API base URL
13
+ this.apiClient = new cli_utilities_1.HttpClient();
14
+ this.apiClient.baseUrl(`${this.composableStudioConfig.apiBaseUrl}/${this.composableStudioConfig.apiVersion}`);
15
+ }
16
+ async start() {
17
+ cli_utilities_1.log.debug('Starting Studio project export process...', this.exportConfig.context);
18
+ if (!(0, cli_utilities_1.isAuthenticated)()) {
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
+ return Promise.resolve();
21
+ }
22
+ this.composableStudioPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.composableStudioConfig.dirName);
23
+ cli_utilities_1.log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context);
24
+ await utils_1.fsUtil.makeDirectory(this.composableStudioPath);
25
+ cli_utilities_1.log.debug('Created Studio directory', this.exportConfig.context);
26
+ this.exportConfig.org_uid = this.exportConfig.org_uid || (await (0, utils_1.getOrgUid)(this.exportConfig));
27
+ cli_utilities_1.log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context);
28
+ await this.exportProjects();
29
+ cli_utilities_1.log.debug('Studio project export process completed', this.exportConfig.context);
30
+ }
31
+ /**
32
+ * Export Studio projects connected to the current stack
33
+ */
34
+ async exportProjects() {
35
+ var _a, _b;
36
+ cli_utilities_1.log.debug('Starting Studio project export...', this.exportConfig.context);
37
+ try {
38
+ // Get authentication details - following personalization-api-adapter pattern
39
+ cli_utilities_1.log.debug('Initializing Studio API authentication...', this.exportConfig.context);
40
+ await cli_utilities_1.authenticationHandler.getAuthDetails();
41
+ const token = cli_utilities_1.authenticationHandler.accessToken;
42
+ cli_utilities_1.log.debug(`Authentication type: ${cli_utilities_1.authenticationHandler.isOauthEnabled ? 'OAuth' : 'Token'}`, this.exportConfig.context);
43
+ // Set authentication headers based on auth type
44
+ if (cli_utilities_1.authenticationHandler.isOauthEnabled) {
45
+ cli_utilities_1.log.debug('Setting OAuth authorization header', this.exportConfig.context);
46
+ this.apiClient.headers({ authorization: token });
47
+ }
48
+ else {
49
+ cli_utilities_1.log.debug('Setting authtoken header', this.exportConfig.context);
50
+ this.apiClient.headers({ authtoken: token });
51
+ }
52
+ // Set organization_uid header
53
+ this.apiClient.headers({
54
+ organization_uid: this.exportConfig.org_uid,
55
+ Accept: 'application/json',
56
+ });
57
+ const apiUrl = '/projects';
58
+ cli_utilities_1.log.debug(`Fetching projects from: ${this.composableStudioConfig.apiBaseUrl}${apiUrl}`, this.exportConfig.context);
59
+ // Make API call to fetch projects using HttpClient
60
+ const response = await this.apiClient.get(apiUrl);
61
+ if (response.status < 200 || response.status >= 300) {
62
+ throw new Error(`API call failed with status ${response.status}: ${JSON.stringify(response.data)}`);
63
+ }
64
+ const data = response.data;
65
+ cli_utilities_1.log.debug(`Fetched ${((_a = data.projects) === null || _a === void 0 ? void 0 : _a.length) || 0} total projects`, this.exportConfig.context);
66
+ // Filter projects connected to this stack
67
+ const connectedProject = (_b = data.projects) === null || _b === void 0 ? void 0 : _b.filter((project) => project.connectedStackApiKey === this.exportConfig.apiKey);
68
+ if (!connectedProject || connectedProject.length === 0) {
69
+ cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('COMPOSABLE_STUDIO_NOT_FOUND'), this.exportConfig.context);
70
+ return;
71
+ }
72
+ // Use the first connected project (stacks should have only one project)
73
+ this.composableStudioProject = connectedProject[0];
74
+ cli_utilities_1.log.debug(`Found Studio project: ${this.composableStudioProject.name}`, this.exportConfig.context);
75
+ // Write the project to file
76
+ const composableStudioFilePath = (0, node_path_1.resolve)(this.composableStudioPath, this.composableStudioConfig.fileName);
77
+ cli_utilities_1.log.debug(`Writing Studio project to: ${composableStudioFilePath}`, this.exportConfig.context);
78
+ utils_1.fsUtil.writeFile(composableStudioFilePath, this.composableStudioProject);
79
+ cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('COMPOSABLE_STUDIO_EXPORT_COMPLETE', this.composableStudioProject.name), this.exportConfig.context);
80
+ }
81
+ catch (error) {
82
+ cli_utilities_1.log.debug('Error occurred while exporting Studio project', this.exportConfig.context);
83
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
84
+ }
85
+ }
86
+ }
87
+ exports.default = ExportComposableStudio;
@@ -39,12 +39,14 @@ class ContentTypesExport extends base_class_1.default {
39
39
  .find();
40
40
  return [countResponse.count || 0];
41
41
  });
42
+ // Create simple progress manager with total count
43
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
42
44
  if (totalCount === 0) {
43
45
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context);
46
+ await this.writeContentTypes(this.contentTypes);
47
+ this.completeProgress(true);
44
48
  return;
45
49
  }
46
- // Create simple progress manager with total count
47
- const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
48
50
  progress.updateStatus('Fetching content types...');
49
51
  await this.getContentTypes();
50
52
  await this.writeContentTypes(this.contentTypes);
@@ -219,7 +219,7 @@ class EntriesExport extends base_class_1.default {
219
219
  });
220
220
  cli_utilities_1.log.debug('Initialized FsUtility for writing entries', this.exportConfig.context);
221
221
  }
222
- cli_utilities_1.log.debug(`Writing ${entriesSearchResponse.items.length} entries to file`, this.exportConfig.context);
222
+ cli_utilities_1.log.debug(`Writing ${entriesSearchResponse.items.length} entries to file...`, this.exportConfig.context);
223
223
  this.entriesFileHelper.writeIntoFile(entriesSearchResponse.items, { mapKeyVal: true });
224
224
  // Track progress for individual entries
225
225
  entriesSearchResponse.items.forEach((entry) => {
@@ -227,9 +227,9 @@ class EntriesExport extends base_class_1.default {
227
227
  (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `entry: ${entry.uid}`, null, utils_1.PROCESS_NAMES.ENTRIES);
228
228
  });
229
229
  if (this.entriesConfig.exportVersions) {
230
- cli_utilities_1.log.debug('Exporting entry versions is enabled', this.exportConfig.context);
230
+ cli_utilities_1.log.debug('Exporting entry versions is enabled.', this.exportConfig.context);
231
231
  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');
232
- cli_utilities_1.log.debug(`Creating versioned entries directory at: ${versionedEntryPath}`, this.exportConfig.context);
232
+ cli_utilities_1.log.debug(`Creating versioned entries directory at: ${versionedEntryPath}.`, this.exportConfig.context);
233
233
  utils_1.fsUtil.makeDirectory(versionedEntryPath);
234
234
  await this.fetchEntriesVersions(entriesSearchResponse.items, {
235
235
  locale: options.locale,
@@ -269,7 +269,7 @@ class EntriesExport extends base_class_1.default {
269
269
  }
270
270
  }
271
271
  async fetchEntriesVersions(entries, options) {
272
- cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries`, this.exportConfig.context);
272
+ cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context);
273
273
  const onSuccess = ({ response, apiData: entry }) => {
274
274
  var _a;
275
275
  const versionFilePath = path.join((0, cli_utilities_2.sanitizePath)(options.versionedEntryPath), (0, cli_utilities_2.sanitizePath)(`${entry.uid}.json`));
@@ -305,7 +305,7 @@ class EntriesExport extends base_class_1.default {
305
305
  return new Promise(async (resolve, reject) => {
306
306
  return await this.getEntryByVersion(apiParams.queryParam, entry)
307
307
  .then((response) => {
308
- cli_utilities_1.log.debug(`Successfully fetched versions for entry: ${entry.uid}`, this.exportConfig.context);
308
+ cli_utilities_1.log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context);
309
309
  apiParams.resolve({
310
310
  response,
311
311
  apiData: entry,
@@ -313,7 +313,7 @@ class EntriesExport extends base_class_1.default {
313
313
  resolve(true);
314
314
  })
315
315
  .catch((error) => {
316
- cli_utilities_1.log.debug(`Failed to fetch versions for entry: ${entry.uid}`, this.exportConfig.context);
316
+ cli_utilities_1.log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context);
317
317
  apiParams.reject({
318
318
  error,
319
319
  apiData: entry,
@@ -330,7 +330,7 @@ class EntriesExport extends base_class_1.default {
330
330
  },
331
331
  version: entry._version,
332
332
  };
333
- cli_utilities_1.log.debug(`Fetching entry version ${entry._version} for uid: ${entry.uid}`, this.exportConfig.context);
333
+ cli_utilities_1.log.debug(`Fetching entry version ${entry._version} for entry UID: '${entry.uid}'.`, this.exportConfig.context);
334
334
  const entryResponse = await this.stackAPIClient
335
335
  .contentType(options.contentType)
336
336
  .entry(entry.uid)
@@ -35,12 +35,16 @@ class GlobalFieldsExport extends base_class_1.default {
35
35
  .find();
36
36
  return [countResponse.count || 0];
37
37
  });
38
+ // Create simple progress manager for global fields
39
+ const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
38
40
  if (totalCount === 0) {
39
41
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('GLOBAL_FIELDS_NOT_FOUND'), this.exportConfig.context);
42
+ const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName);
43
+ cli_utilities_1.log.debug(`Writing global fields to: ${globalFieldsFilePath}`, this.exportConfig.context);
44
+ utils_1.fsUtil.writeFile(globalFieldsFilePath, this.globalFields);
45
+ this.completeProgress(true);
40
46
  return;
41
47
  }
42
- // Create simple progress manager for global fields
43
- const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
44
48
  progress.updateStatus('Fetching global fields...');
45
49
  await this.getGlobalFields();
46
50
  const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName);
@@ -75,17 +75,17 @@ class ExportMarketplaceApps extends base_class_1.default {
75
75
  }
76
76
  async setupPaths() {
77
77
  this.marketplaceAppPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.marketplaceAppConfig.dirName);
78
- cli_utilities_1.log.debug(`Marketplace apps folder path: ${this.marketplaceAppPath}`, this.exportConfig.context);
78
+ cli_utilities_1.log.debug(`Marketplace apps folder path: '${this.marketplaceAppPath}'`, this.exportConfig.context);
79
79
  await utils_1.fsUtil.makeDirectory(this.marketplaceAppPath);
80
80
  cli_utilities_1.log.debug('Created marketplace apps directory', this.exportConfig.context);
81
81
  this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.exportConfig));
82
- cli_utilities_1.log.debug(`Developer hub base URL: ${this.developerHubBaseUrl}`, this.exportConfig.context);
82
+ cli_utilities_1.log.debug(`Developer hub base URL: '${this.developerHubBaseUrl}'`, this.exportConfig.context);
83
83
  this.exportConfig.org_uid = await (0, utils_1.getOrgUid)(this.exportConfig);
84
84
  this.query = { target_uids: this.exportConfig.source_stack };
85
- cli_utilities_1.log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context);
85
+ cli_utilities_1.log.debug(`Organization UID: '${this.exportConfig.org_uid}'.`, this.exportConfig.context);
86
86
  // NOTE init marketplace app sdk
87
87
  const host = this.developerHubBaseUrl.split('://').pop();
88
- cli_utilities_1.log.debug(`Initializing marketplace SDK with host: ${host}`, this.exportConfig.context);
88
+ cli_utilities_1.log.debug(`Initializing Marketplace SDK with host: '${host}'...`, this.exportConfig.context);
89
89
  this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
90
90
  }
91
91
  async getAppsCount() {
@@ -119,17 +119,28 @@ class ExportMarketplaceApps extends base_class_1.default {
119
119
  * library if it is available.
120
120
  */
121
121
  async exportApps() {
122
+ var _a, _b, _c, _d, _e;
122
123
  cli_utilities_1.log.debug('Starting apps export process...', this.exportConfig.context);
124
+ // Process external query if provided
125
+ const externalQuery = (_a = this.exportConfig.query) === null || _a === void 0 ? void 0 : _a.modules['marketplace-apps'];
126
+ if (externalQuery) {
127
+ if (((_c = (_b = externalQuery.app_uid) === null || _b === void 0 ? void 0 : _b.$in) === null || _c === void 0 ? void 0 : _c.length) > 0) {
128
+ this.query.app_uids = externalQuery.app_uid.$in.join(',');
129
+ }
130
+ if (((_e = (_d = externalQuery.installation_uid) === null || _d === void 0 ? void 0 : _d.$in) === null || _e === void 0 ? void 0 : _e.length) > 0) {
131
+ this.query.installation_uids = externalQuery.installation_uid.$in.join(',');
132
+ }
133
+ }
123
134
  await this.getStackSpecificApps();
124
135
  cli_utilities_1.log.debug(`Retrieved ${this.installedApps.length} stack-specific apps`, this.exportConfig.context);
125
136
  if (!this.nodeCrypto && (0, find_1.default)(this.installedApps, (app) => !(0, isEmpty_1.default)(app.configuration))) {
126
- cli_utilities_1.log.debug('Initializing NodeCrypto for app configuration encryption', this.exportConfig.context);
137
+ cli_utilities_1.log.debug('Initializing NodeCrypto for app configuration encryption...', this.exportConfig.context);
127
138
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
128
139
  }
129
140
  this.installedApps = (0, map_1.default)(this.installedApps, (app) => {
130
141
  var _a;
131
142
  if ((0, has_1.default)(app, 'configuration')) {
132
- cli_utilities_1.log.debug(`Encrypting configuration for app: ${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}`, this.exportConfig.context);
143
+ cli_utilities_1.log.debug(`Encrypting configuration for app: '${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}'...`, this.exportConfig.context);
133
144
  app['configuration'] = this.nodeCrypto.encrypt(app.configuration);
134
145
  }
135
146
  return app;
@@ -149,18 +160,18 @@ class ExportMarketplaceApps extends base_class_1.default {
149
160
  cli_utilities_1.log.debug(`Processing ${this.installedApps.length} installed apps`, this.exportConfig.context);
150
161
  for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
151
162
  if (app.manifest.visibility === 'private') {
152
- cli_utilities_1.log.debug(`Processing private app manifest: ${app.manifest.name}`, this.exportConfig.context);
163
+ cli_utilities_1.log.debug(`Processing private app manifest: '${app.manifest.name}'...`, this.exportConfig.context);
153
164
  await this.getPrivateAppsManifest(+index, app);
154
165
  }
155
166
  }
156
167
  for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
157
- cli_utilities_1.log.debug(`Processing app configurations: ${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}`, this.exportConfig.context);
168
+ cli_utilities_1.log.debug(`Processing app configurations for: '${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}'...`, this.exportConfig.context);
158
169
  await this.getAppConfigurations(+index, app);
159
170
  // Track progress for each app processed
160
171
  (_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `app: ${((_c = app.manifest) === null || _c === void 0 ? void 0 : _c.name) || app.uid}`, null, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
161
172
  }
162
173
  const marketplaceAppsFilePath = (0, node_path_1.resolve)(this.marketplaceAppPath, this.marketplaceAppConfig.fileName);
163
- cli_utilities_1.log.debug(`Writing marketplace apps to: ${marketplaceAppsFilePath}`, this.exportConfig.context);
174
+ cli_utilities_1.log.debug(`Writing Marketplace Apps to: '${marketplaceAppsFilePath}'`, this.exportConfig.context);
164
175
  utils_1.fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps);
165
176
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps || {}).length), this.exportConfig.context);
166
177
  }
@@ -175,17 +186,17 @@ class ExportMarketplaceApps extends base_class_1.default {
175
186
  * app's manifest.
176
187
  */
177
188
  async getPrivateAppsManifest(index, appInstallation) {
178
- cli_utilities_1.log.debug(`Fetching private app manifest for: ${appInstallation.manifest.name} (${appInstallation.manifest.uid})`, this.exportConfig.context);
189
+ cli_utilities_1.log.debug(`Fetching private app manifest for: '${appInstallation.manifest.name}' (${appInstallation.manifest.uid})`, this.exportConfig.context);
179
190
  const manifest = await this.appSdk
180
191
  .marketplace(this.exportConfig.org_uid)
181
192
  .app(appInstallation.manifest.uid)
182
193
  .fetch({ include_oauth: true })
183
194
  .catch((error) => {
184
- cli_utilities_1.log.debug(`Failed to fetch private app manifest for: ${appInstallation.manifest.name}`, this.exportConfig.context);
195
+ cli_utilities_1.log.debug(`Failed to fetch private app manifest for: '${appInstallation.manifest.name}'`, this.exportConfig.context);
185
196
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context), cli_utilities_1.messageHandler.parse('MARKETPLACE_APP_MANIFEST_EXPORT_FAILED', appInstallation.manifest.name));
186
197
  });
187
198
  if (manifest) {
188
- cli_utilities_1.log.debug(`Successfully fetched private app manifest for: ${appInstallation.manifest.name}`, this.exportConfig.context);
199
+ cli_utilities_1.log.debug(`Successfully fetched private app manifest for: '${appInstallation.manifest.name}'`, this.exportConfig.context);
189
200
  this.installedApps[index].manifest = manifest;
190
201
  }
191
202
  }
@@ -204,7 +215,7 @@ class ExportMarketplaceApps extends base_class_1.default {
204
215
  const appName = (_a = appInstallation === null || appInstallation === void 0 ? void 0 : appInstallation.manifest) === null || _a === void 0 ? void 0 : _a.name;
205
216
  const appUid = (_b = appInstallation === null || appInstallation === void 0 ? void 0 : appInstallation.manifest) === null || _b === void 0 ? void 0 : _b.uid;
206
217
  const app = appName || appUid;
207
- cli_utilities_1.log.debug(`Fetching app configuration for: ${app}`, this.exportConfig.context);
218
+ cli_utilities_1.log.debug(`Fetching app configuration for: '${app}'...`, this.exportConfig.context);
208
219
  cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT', app), this.exportConfig.context);
209
220
  await this.appSdk
210
221
  .marketplace(this.exportConfig.org_uid)
@@ -214,17 +225,18 @@ class ExportMarketplaceApps extends base_class_1.default {
214
225
  var _a;
215
226
  const { data, error } = result;
216
227
  if ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration')) {
217
- cli_utilities_1.log.debug(`Found configuration data for app: ${app}`, this.exportConfig.context);
228
+ cli_utilities_1.log.debug(`Found configuration data for app: '${app}'`, this.exportConfig.context);
218
229
  if (!this.nodeCrypto && ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration'))) {
230
+ cli_utilities_1.log.debug(`Initializing NodeCrypto for app: '${app}'...`, this.exportConfig.context);
219
231
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
220
232
  (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
221
233
  }
222
234
  if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.configuration)) {
223
- cli_utilities_1.log.debug(`Encrypting configuration for app: ${app}`, this.exportConfig.context);
235
+ cli_utilities_1.log.debug(`Encrypting configuration for app: '${app}'...`, this.exportConfig.context);
224
236
  this.installedApps[index]['configuration'] = this.nodeCrypto.encrypt(data.configuration);
225
237
  }
226
238
  if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.server_configuration)) {
227
- cli_utilities_1.log.debug(`Encrypting server configuration for app: ${app}`, this.exportConfig.context);
239
+ cli_utilities_1.log.debug(`Encrypting server configuration for app: '${app}'...`, this.exportConfig.context);
228
240
  this.installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration);
229
241
  cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APP_CONFIG_SUCCESS', app), this.exportConfig.context);
230
242
  }
@@ -233,12 +245,12 @@ class ExportMarketplaceApps extends base_class_1.default {
233
245
  }
234
246
  }
235
247
  else if (error) {
236
- cli_utilities_1.log.debug(`Error in app configuration data for: ${app}`, this.exportConfig.context);
248
+ cli_utilities_1.log.debug(`Error in app configuration data for: '${app}'.`, this.exportConfig.context);
237
249
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context), cli_utilities_1.messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT_FAILED', app));
238
250
  }
239
251
  })
240
252
  .catch((error) => {
241
- cli_utilities_1.log.debug(`Failed to fetch app configuration for: ${app}`, this.exportConfig.context);
253
+ cli_utilities_1.log.debug(`Failed to fetch app configuration for: '${app}'.`, this.exportConfig.context);
242
254
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context), cli_utilities_1.messageHandler.parse('MARKETPLACE_APP_CONFIG_EXPORT_FAILED', app));
243
255
  });
244
256
  }
@@ -256,7 +268,7 @@ class ExportMarketplaceApps extends base_class_1.default {
256
268
  .installation()
257
269
  .fetchAll(Object.assign(Object.assign({}, this.query), { skip }))
258
270
  .catch((error) => {
259
- cli_utilities_1.log.debug('Error occurred while fetching stack-specific apps', this.exportConfig.context);
271
+ cli_utilities_1.log.debug('An error occurred while fetching stack-specific apps.', this.exportConfig.context);
260
272
  (0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
261
273
  });
262
274
  if (collection) {
@@ -276,11 +288,11 @@ class ExportMarketplaceApps extends base_class_1.default {
276
288
  });
277
289
  this.installedApps = this.installedApps.concat(installation);
278
290
  if (count - (skip + 50) > 0) {
279
- cli_utilities_1.log.debug(`Continuing to fetch apps with skip: ${skip + 50}`, this.exportConfig.context);
291
+ cli_utilities_1.log.debug(`Continuing to fetch apps with skip: ${skip + 50}.`, this.exportConfig.context);
280
292
  await this.getStackSpecificApps(skip + 50);
281
293
  }
282
294
  else {
283
- cli_utilities_1.log.debug('Completed fetching all stack-specific apps', this.exportConfig.context);
295
+ cli_utilities_1.log.debug('Completed fetching all stack-specific apps.', this.exportConfig.context);
284
296
  }
285
297
  }
286
298
  }
@@ -28,7 +28,7 @@ class ExportStack extends base_class_1.default {
28
28
  // Add processes based on configuration
29
29
  let processCount = 0;
30
30
  if (stackData === null || stackData === void 0 ? void 0 : stackData.org_uid) {
31
- cli_utilities_1.log.debug(`Found organization UID: ${stackData.org_uid}`, this.exportConfig.context);
31
+ cli_utilities_1.log.debug(`Found organization UID: '${stackData.org_uid}'.`, this.exportConfig.context);
32
32
  this.exportConfig.org_uid = stackData.org_uid;
33
33
  this.exportConfig.sourceStackName = stackData.name;
34
34
  cli_utilities_1.log.debug(`Set source stack name: ${stackData.name}`, this.exportConfig.context);
@@ -92,30 +92,30 @@ class ExportStack extends base_class_1.default {
92
92
  }
93
93
  }
94
94
  async getStack() {
95
- cli_utilities_1.log.debug(`Fetching stack data for stack: ${this.exportConfig.source_stack}`, this.exportConfig.context);
95
+ cli_utilities_1.log.debug(`Fetching stack data for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context);
96
96
  const tempAPIClient = await (0, cli_utilities_1.managementSDKClient)({ host: this.exportConfig.host });
97
- cli_utilities_1.log.debug(`Created management SDK client with host: ${this.exportConfig.host}`, this.exportConfig.context);
97
+ cli_utilities_1.log.debug(`Created Management SDK client with host: '${this.exportConfig.host}'.`, this.exportConfig.context);
98
98
  return await tempAPIClient
99
99
  .stack({ api_key: this.exportConfig.source_stack })
100
100
  .fetch()
101
101
  .then((data) => {
102
- cli_utilities_1.log.debug(`Successfully fetched stack data for: ${this.exportConfig.source_stack}`, this.exportConfig.context);
102
+ cli_utilities_1.log.debug(`Successfully fetched stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context);
103
103
  return data;
104
104
  })
105
105
  .catch((error) => {
106
- cli_utilities_1.log.debug(`Failed to fetch stack data for: ${this.exportConfig.source_stack}`, this.exportConfig.context);
106
+ cli_utilities_1.log.debug(`Failed to fetch stack data for: '${this.exportConfig.source_stack}'.`, this.exportConfig.context);
107
107
  return {};
108
108
  });
109
109
  }
110
110
  async getLocales(skip = 0) {
111
111
  if (skip) {
112
112
  this.qs.skip = skip;
113
- cli_utilities_1.log.debug(`Fetching locales with skip: ${skip}`, this.exportConfig.context);
113
+ cli_utilities_1.log.debug(`Fetching locales with skip: ${skip}.`, this.exportConfig.context);
114
114
  }
115
115
  else {
116
- cli_utilities_1.log.debug('Fetching locales with initial query', this.exportConfig.context);
116
+ cli_utilities_1.log.debug('Fetching locales with initial query...', this.exportConfig.context);
117
117
  }
118
- cli_utilities_1.log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context);
118
+ cli_utilities_1.log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context);
119
119
  return await this.stack
120
120
  .locale()
121
121
  .query(this.qs)
@@ -123,7 +123,7 @@ class ExportStack extends base_class_1.default {
123
123
  .then(async (data) => {
124
124
  var _a;
125
125
  const { items, count } = data;
126
- cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} locales out of total ${count}`, this.exportConfig.context);
126
+ cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} locales out of ${count}.`, this.exportConfig.context);
127
127
  if (items === null || items === void 0 ? void 0 : items.length) {
128
128
  cli_utilities_1.log.debug(`Processing ${items.length} locales to find master locale`, this.exportConfig.context);
129
129
  // Track progress for each locale processed
@@ -131,17 +131,17 @@ class ExportStack extends base_class_1.default {
131
131
  skip += this.stackConfig.limit || 100;
132
132
  const masterLocalObj = (0, find_1.default)(items, (locale) => {
133
133
  if (locale.fallback_locale === null) {
134
- cli_utilities_1.log.debug(`Found master locale: ${locale.name} (${locale.code})`, this.exportConfig.context);
134
+ cli_utilities_1.log.debug(`Found master locale: '${locale.name}' (code: ${locale.code}).`, this.exportConfig.context);
135
135
  return locale;
136
136
  }
137
137
  });
138
138
  if (masterLocalObj) {
139
- cli_utilities_1.log.debug(`Returning master locale: ${masterLocalObj.name}`, this.exportConfig.context);
139
+ cli_utilities_1.log.debug(`Returning master locale: '${masterLocalObj.name}'.`, this.exportConfig.context);
140
140
  return masterLocalObj;
141
141
  }
142
142
  else if (skip >= count) {
143
143
  cli_utilities_1.log.error(`Locale locale not found in the stack ${this.exportConfig.source_stack}. Please ensure that the stack has a master locale.`, this.exportConfig.context);
144
- cli_utilities_1.log.debug('Completed searching all locales without finding master locale', this.exportConfig.context);
144
+ cli_utilities_1.log.debug('Completed search. Master locale not found.', this.exportConfig.context);
145
145
  return;
146
146
  }
147
147
  else {
@@ -150,7 +150,7 @@ class ExportStack extends base_class_1.default {
150
150
  }
151
151
  }
152
152
  else {
153
- cli_utilities_1.log.debug('No locales found to process', this.exportConfig.context);
153
+ cli_utilities_1.log.debug('No locales found to process.', this.exportConfig.context);
154
154
  }
155
155
  })
156
156
  .catch((error) => {
@@ -162,20 +162,20 @@ class ExportStack extends base_class_1.default {
162
162
  });
163
163
  }
164
164
  async exportStack() {
165
- cli_utilities_1.log.debug(`Starting stack export for: ${this.exportConfig.source_stack}`, this.exportConfig.context);
165
+ cli_utilities_1.log.debug(`Starting stack export for: '${this.exportConfig.source_stack}'...`, this.exportConfig.context);
166
166
  await utils_1.fsUtil.makeDirectory(this.stackFolderPath);
167
- cli_utilities_1.log.debug(`Created stack directory at: ${this.stackFolderPath}`, this.exportConfig.context);
167
+ cli_utilities_1.log.debug(`Created stack directory at: '${this.stackFolderPath}'`, this.exportConfig.context);
168
168
  return this.stack
169
169
  .fetch()
170
170
  .then((resp) => {
171
171
  var _a;
172
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);
173
+ cli_utilities_1.log.debug(`Writing stack data to: '${stackFilePath}'`, this.exportConfig.context);
174
174
  utils_1.fsUtil.writeFile(stackFilePath, resp);
175
175
  // Track progress for stack export completion
176
176
  (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `stack: ${this.exportConfig.source_stack}`, null, utils_1.PROCESS_NAMES.STACK_DETAILS);
177
177
  cli_utilities_1.log.success(`Stack details exported successfully for stack ${this.exportConfig.source_stack}`, this.exportConfig.context);
178
- cli_utilities_1.log.debug('Stack export completed successfully', this.exportConfig.context);
178
+ cli_utilities_1.log.debug('Stack export completed successfully.', this.exportConfig.context);
179
179
  return resp;
180
180
  })
181
181
  .catch((error) => {
@@ -186,7 +186,7 @@ class ExportStack extends base_class_1.default {
186
186
  });
187
187
  }
188
188
  async exportStackSettings() {
189
- cli_utilities_1.log.info('Exporting stack settings', this.exportConfig.context);
189
+ cli_utilities_1.log.info('Exporting stack settings...', this.exportConfig.context);
190
190
  await utils_1.fsUtil.makeDirectory(this.stackFolderPath);
191
191
  return this.stack
192
192
  .settings()
@@ -42,4 +42,5 @@ export default class ExportTaxonomies extends BaseClass {
42
42
  * Get all locales to export
43
43
  */
44
44
  getLocalesToExport(): string[];
45
+ private isLocalePlanLimitationError;
45
46
  }
@@ -22,12 +22,12 @@ class ExportTaxonomies extends base_class_1.default {
22
22
  }
23
23
  async start() {
24
24
  var _a;
25
- cli_utilities_1.log.debug('Starting taxonomies export process...', this.exportConfig.context);
25
+ cli_utilities_1.log.debug('Starting export process for taxonomies...', this.exportConfig.context);
26
26
  //create taxonomies folder
27
27
  this.taxonomiesFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.taxonomiesConfig.dirName);
28
- cli_utilities_1.log.debug(`Taxonomies folder path: ${this.taxonomiesFolderPath}`, this.exportConfig.context);
28
+ cli_utilities_1.log.debug(`Taxonomies folder path: '${this.taxonomiesFolderPath}'`, this.exportConfig.context);
29
29
  await utils_1.fsUtil.makeDirectory(this.taxonomiesFolderPath);
30
- cli_utilities_1.log.debug('Created taxonomies directory', this.exportConfig.context);
30
+ cli_utilities_1.log.debug('Created taxonomies directory.', this.exportConfig.context);
31
31
  const localesToExport = this.getLocalesToExport();
32
32
  cli_utilities_1.log.debug(`Will attempt to export taxonomies for ${localesToExport.length} locale(s): ${localesToExport.join(', ')}`, this.exportConfig.context);
33
33
  if (localesToExport.length === 0) {
@@ -38,7 +38,10 @@ class ExportTaxonomies extends base_class_1.default {
38
38
  const masterLocale = (_a = this.exportConfig.master_locale) === null || _a === void 0 ? void 0 : _a.code;
39
39
  await this.fetchTaxonomies(masterLocale, true);
40
40
  if (!this.isLocaleBasedExportSupported) {
41
- cli_utilities_1.log.debug('Localization disabled, falling back to legacy export method', this.exportConfig.context);
41
+ this.taxonomies = {};
42
+ this.taxonomiesByLocale = {};
43
+ // Fetch taxonomies without locale parameter
44
+ await this.fetchTaxonomies();
42
45
  await this.exportTaxonomies();
43
46
  await this.writeTaxonomiesMetadata();
44
47
  }
@@ -122,10 +125,18 @@ class ExportTaxonomies extends base_class_1.default {
122
125
  }
123
126
  catch (error) {
124
127
  cli_utilities_1.log.debug(`Error fetching taxonomies ${localeInfo}`, this.exportConfig.context);
125
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.exportConfig.context), (localeCode && { locale: localeCode })));
126
- if (checkLocaleSupport) {
128
+ if (checkLocaleSupport && this.isLocalePlanLimitationError(error)) {
129
+ cli_utilities_1.log.debug('Taxonomy localization is not included in your plan. Falling back to non-localized export.', this.exportConfig.context);
127
130
  this.isLocaleBasedExportSupported = false;
128
131
  }
132
+ else if (checkLocaleSupport) {
133
+ cli_utilities_1.log.debug('Locale-based taxonomy export not supported, will use legacy method', this.exportConfig.context);
134
+ this.isLocaleBasedExportSupported = false;
135
+ }
136
+ else {
137
+ // Log actual errors during normal fetch (not locale check)
138
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.exportConfig.context), (localeCode && { locale: localeCode })));
139
+ }
129
140
  // Break to avoid infinite retry loop on errors
130
141
  break;
131
142
  }
@@ -234,5 +245,11 @@ class ExportTaxonomies extends base_class_1.default {
234
245
  cli_utilities_1.log.debug(`Total unique locales to export: ${localesToExport.length}`, this.exportConfig.context);
235
246
  return localesToExport;
236
247
  }
248
+ isLocalePlanLimitationError(error) {
249
+ var _a, _b;
250
+ return ((error === null || error === void 0 ? void 0 : error.status) === 403 &&
251
+ ((_b = (_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.taxonomies) === null || _b === void 0 ? void 0 : _b.some((msg) => msg.toLowerCase().includes('taxonomy localization') &&
252
+ msg.toLowerCase().includes('not included in your plan'))));
253
+ }
237
254
  }
238
255
  exports.default = ExportTaxonomies;
@@ -140,7 +140,7 @@ class ExportWorkFlows extends base_class_1.default {
140
140
  .catch((err) => {
141
141
  cli_utilities_1.log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context);
142
142
  (0, cli_utilities_1.handleAndLogError)(err, Object.assign({}, this.exportConfig.context));
143
- throw err;
143
+ return undefined; // Return undefined instead of throwing to handle gracefully
144
144
  });
145
145
  }
146
146
  }
@@ -147,6 +147,12 @@ export default interface DefaultConfig {
147
147
  fileName: string;
148
148
  dependencies?: Modules[];
149
149
  };
150
+ 'composable-studio': {
151
+ dirName: string;
152
+ fileName: string;
153
+ apiBaseUrl: string;
154
+ apiVersion: string;
155
+ };
150
156
  masterLocale: {
151
157
  dirName: string;
152
158
  fileName: string;
@@ -26,7 +26,7 @@ export interface Region {
26
26
  cda: string;
27
27
  uiHost: string;
28
28
  }
29
- export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalize';
29
+ export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalize' | 'composable-studio';
30
30
  export type ModuleClassParams = {
31
31
  stackAPIClient: ReturnType<ContentstackClient['stack']>;
32
32
  exportConfig: ExportConfig;
@@ -96,6 +96,32 @@ export interface StackConfig {
96
96
  dependencies?: Modules[];
97
97
  limit?: number;
98
98
  }
99
+ export interface ComposableStudioConfig {
100
+ dirName: string;
101
+ fileName: string;
102
+ apiBaseUrl: string;
103
+ apiVersion: string;
104
+ }
105
+ export interface ComposableStudioProject {
106
+ name: string;
107
+ description: string;
108
+ canvasUrl: string;
109
+ connectedStackApiKey: string;
110
+ contentTypeUid: string;
111
+ organizationUid: string;
112
+ settings: {
113
+ configuration: {
114
+ environment: string;
115
+ locale: string;
116
+ };
117
+ };
118
+ createdBy: string;
119
+ updatedBy: string;
120
+ deletedAt: boolean;
121
+ createdAt: string;
122
+ updatedAt: string;
123
+ uid: string;
124
+ }
99
125
  export interface Context {
100
126
  command: string;
101
127
  module: string;
@@ -26,7 +26,7 @@ const login = async (config) => {
26
26
  return config;
27
27
  }
28
28
  else {
29
- cli_utilities_1.log.error(`Failed to login, Invalid credentials`, config.context);
29
+ cli_utilities_1.log.error(`Failed to log in!`, config.context);
30
30
  process.exit(1);
31
31
  }
32
32
  }
@@ -16,14 +16,14 @@ const setupConfig = async (exportCmdFlags) => {
16
16
  cli_utilities_1.log.debug('Setting up export configuration');
17
17
  // setup the config
18
18
  if (exportCmdFlags['config']) {
19
- cli_utilities_1.log.debug('Loading external configuration file', { configFile: exportCmdFlags['config'] });
19
+ cli_utilities_1.log.debug('Loading external configuration file...', { configFile: exportCmdFlags['config'] });
20
20
  const externalConfig = await (0, file_helper_1.readFile)(exportCmdFlags['config']);
21
21
  config = merge_1.default.recursive(config, externalConfig);
22
22
  }
23
23
  config.exportDir = (0, cli_utilities_1.sanitizePath)(exportCmdFlags['data'] || exportCmdFlags['data-dir'] || config.data || (await (0, interactive_1.askExportDir)()));
24
24
  const pattern = /[*$%#<>{}!&?]/g;
25
25
  if (pattern.test(config.exportDir)) {
26
- cli_utilities_1.cliux.print(`\nPlease add a directory path without any of the special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
26
+ cli_utilities_1.cliux.print(`\nPlease enter a directory path without any special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
27
27
  color: 'yellow',
28
28
  });
29
29
  config.exportDir = (0, cli_utilities_1.sanitizePath)(await (0, interactive_1.askExportDir)());
@@ -40,7 +40,7 @@ const setupConfig = async (exportCmdFlags) => {
40
40
  config.apiKey = apiKey;
41
41
  authenticationMethod = 'Management Token';
42
42
  if (!config.management_token) {
43
- cli_utilities_1.log.debug('Management token not found for alias', { alias: managementTokenAlias });
43
+ cli_utilities_1.log.debug('Management token not found for alias!', { alias: managementTokenAlias });
44
44
  throw new Error(`No management token found on given alias ${managementTokenAlias}`);
45
45
  }
46
46
  cli_utilities_1.log.debug('Management token configuration successful');
@@ -73,7 +73,7 @@ const setupConfig = async (exportCmdFlags) => {
73
73
  config.apiKey =
74
74
  exportCmdFlags['stack-uid'] || exportCmdFlags['stack-api-key'] || config.source_stack || (await (0, interactive_1.askAPIKey)());
75
75
  if (typeof config.apiKey !== 'string') {
76
- cli_utilities_1.log.debug('Invalid API key received', { apiKey: config.apiKey });
76
+ cli_utilities_1.log.debug('Invalid API key received!', { apiKey: config.apiKey });
77
77
  throw new Error('Invalid API key received');
78
78
  }
79
79
  }
@@ -123,7 +123,7 @@ const setupConfig = async (exportCmdFlags) => {
123
123
  cli_utilities_1.configHandler.set('log.progressSupportedModule', 'export');
124
124
  // Add authentication details to config for context tracking
125
125
  config.authenticationMethod = authenticationMethod;
126
- cli_utilities_1.log.debug('Export configuration setup completed', Object.assign({}, config));
126
+ cli_utilities_1.log.debug('Export configuration setup completed.', Object.assign({}, config));
127
127
  return config;
128
128
  };
129
129
  exports.default = setupConfig;
@@ -51,7 +51,7 @@ const readLargeFile = function (filePath, options = {}) {
51
51
  resolve(data);
52
52
  });
53
53
  parseStream.on('error', (error) => {
54
- console.log('error', error);
54
+ console.log('Error', error);
55
55
  reject(error);
56
56
  });
57
57
  readStream.pipe(parseStream);
@@ -22,10 +22,8 @@ async function createNodeCryptoInstance(config) {
22
22
  if (config.forceStopMarketplaceAppsPrompt) {
23
23
  cryptoArgs['encryptionKey'] = config.marketplaceAppEncryptionKey;
24
24
  }
25
- else if (config.marketplaceAppEncryptionKey) {
26
- cryptoArgs['encryptionKey'] = config.marketplaceAppEncryptionKey;
27
- }
28
25
  else {
26
+ // Always prompt when forceStopMarketplaceAppsPrompt is false, using existing key as default
29
27
  cli_utilities_1.cliux.print('');
30
28
  cryptoArgs['encryptionKey'] = await askEncryptionKey(config);
31
29
  cli_utilities_1.cliux.print('');
@@ -1,71 +1,77 @@
1
1
  {
2
- "ASSET_EXPORT_COMPLETE": "Asset export process completed successfully",
3
- "ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully with %s folder(s)",
4
- "ASSET_METADATA_EXPORT_COMPLETE": "Asset metadata exported successfully",
5
- "ASSET_VERSIONED_METADATA_EXPORT_COMPLETE": "Versioned asset metadata exported successfully",
6
- "ASSET_DOWNLOAD_COMPLETE": "Asset download completed successfully",
7
- "ASSET_DOWNLOAD_SUCCESS": "Asset '%s' (UID: %s) downloaded successfully",
8
- "ASSET_DOWNLOAD_FAILED": "Failed to download asset '%s' (UID: %s)",
9
- "ASSET_WRITE_FAILED": "Failed to write asset file '%s' (UID: %s)",
10
- "ASSET_QUERY_FAILED": "Failed to query asset data from the API",
11
- "ASSET_VERSIONED_QUERY_FAILED": "Failed to query versioned asset data from the API",
12
- "ASSET_COUNT_QUERY_FAILED": "Failed to retrieve total asset count",
13
-
14
- "CONTENT_TYPE_EXPORT_COMPLETE": "Content types exported successfully",
15
- "CONTENT_TYPE_NO_TYPES": "No content types found",
16
- "CONTENT_TYPE_EXPORT_FAILED": "Failed to export content types",
17
- "CONTENT_TYPE_NO_TYPES_RETURNED": "API returned no content types for the given query",
18
-
19
- "ENVIRONMENT_EXPORT_COMPLETE": "Successfully exported %s environment(s)",
20
- "ENVIRONMENT_EXPORT_SUCCESS": "Environment '%s' exported successfully",
21
- "ENVIRONMENT_NOT_FOUND": "No environments found in the current stack",
22
-
23
- "EXTENSION_EXPORT_COMPLETE": "Successfully exported %s extension(s)",
24
- "EXTENSION_EXPORT_SUCCESS": "Extension '%s' exported successfully",
25
- "EXTENSION_NOT_FOUND": "No extensions found in the current stack",
26
-
27
- "GLOBAL_FIELDS_EXPORT_COMPLETE": "Successfully exported %s global field(s)",
28
-
29
- "LABELS_EXPORT_COMPLETE": "Successfully exported %s label(s)",
30
- "LABEL_EXPORT_SUCCESS": "Label '%s' exported successfully",
31
- "LABELS_NOT_FOUND": "No labels found in the current stack",
32
-
33
- "LOCALES_EXPORT_COMPLETE": "Successfully exported %s locale(s) including %s master locale(s)",
34
-
35
- "TAXONOMY_EXPORT_COMPLETE": "Successfully exported %s taxonomy entries",
36
- "TAXONOMY_EXPORT_SUCCESS": "Taxonomy '%s' exported successfully",
37
- "TAXONOMY_NOT_FOUND": "No taxonomies found in the current stack",
38
-
39
- "WEBHOOK_EXPORT_COMPLETE": "Successfully exported %s webhook(s)",
40
- "WEBHOOK_EXPORT_SUCCESS": "Webhook '%s' exported successfully",
41
- "WEBHOOK_NOT_FOUND": "No webhooks found in the current stack",
42
-
43
- "WORKFLOW_EXPORT_COMPLETE": "Successfully exported %s workflow(s)",
44
- "WORKFLOW_EXPORT_SUCCESS": "Workflow '%s' exported successfully",
45
- "WORKFLOW_NOT_FOUND": "No workflows found in the current stack",
46
-
47
- "PERSONALIZE_URL_NOT_SET": "Cannot export Personalize project: URL not configured",
48
- "PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN": "Skipping Personalize project export: Management token not supported",
49
- "PERSONALIZE_MODULE_NOT_IMPLEMENTED": "Module '%s' implementation not found",
50
- "PERSONALIZE_NOT_ENABLED": "Personalize feature is not enabled for this organization",
51
-
52
- "MARKETPLACE_APPS_EXPORT_COMPLETE": "Successfully exported %s marketplace app(s)",
53
- "MARKETPLACE_APP_CONFIG_EXPORT": "Exporting configuration for app '%s'",
54
- "MARKETPLACE_APP_CONFIG_SUCCESS": "Successfully exported configuration for app '%s'",
55
- "MARKETPLACE_APP_EXPORT_SUCCESS": "Successfully exported app '%s'",
56
- "MARKETPLACE_APPS_NOT_FOUND": "No marketplace apps found in the current stack",
57
- "MARKETPLACE_APP_CONFIG_EXPORT_FAILED": "Failed to export configuration for app '%s'",
58
- "MARKETPLACE_APP_MANIFEST_EXPORT_FAILED": "Failed to export manifest for app '%s'",
59
-
60
- "ENTRIES_EXPORT_COMPLETE": "Successfully exported entries (Content Type: %s, Locale: %s)",
61
- "ENTRIES_EXPORT_SUCCESS": "All entries exported successfully",
62
- "ENTRIES_VERSIONED_EXPORT_SUCCESS": "Successfully exported versioned entry (Content Type: %s, UID: %s, Locale: %s)",
63
- "ENTRIES_EXPORT_VERSIONS_FAILED": "Failed to export versions for content type '%s' (UID: %s)",
64
-
65
- "BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)",
66
-
67
- "ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack",
68
- "ROLES_EXPORTING_ROLE": "Exporting role '%s'",
2
+ "ASSET_EXPORT_COMPLETE": "Asset export process completed successfully",
3
+ "ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully with %s folder(s)",
4
+ "ASSET_METADATA_EXPORT_COMPLETE": "Asset metadata exported successfully",
5
+ "ASSET_VERSIONED_METADATA_EXPORT_COMPLETE": "Versioned asset metadata exported successfully",
6
+ "ASSET_DOWNLOAD_COMPLETE": "Asset download completed successfully",
7
+ "ASSET_DOWNLOAD_SUCCESS": "Asset '%s' (UID: %s) downloaded successfully",
8
+ "ASSET_DOWNLOAD_FAILED": "Failed to download asset '%s' (UID: %s)",
9
+ "ASSET_WRITE_FAILED": "Failed to write asset file '%s' (UID: %s)",
10
+ "ASSET_QUERY_FAILED": "Failed to query asset data from the API",
11
+ "ASSET_VERSIONED_QUERY_FAILED": "Failed to query versioned asset data from the API",
12
+ "ASSET_COUNT_QUERY_FAILED": "Failed to retrieve total asset count",
13
+
14
+ "CONTENT_TYPE_EXPORT_COMPLETE": "Content types exported successfully",
15
+ "CONTENT_TYPE_NO_TYPES": "No content types found",
16
+ "CONTENT_TYPE_EXPORT_FAILED": "Failed to export content types",
17
+ "CONTENT_TYPE_NO_TYPES_RETURNED": "API returned no content types for the given query",
18
+
19
+ "ENVIRONMENT_EXPORT_COMPLETE": "Successfully exported %s environment(s)",
20
+ "ENVIRONMENT_EXPORT_SUCCESS": "Environment '%s' exported successfully",
21
+ "ENVIRONMENT_NOT_FOUND": "No environments found in the current stack",
22
+
23
+ "EXTENSION_EXPORT_COMPLETE": "Successfully exported %s extension(s)",
24
+ "EXTENSION_EXPORT_SUCCESS": "Extension '%s' exported successfully",
25
+ "EXTENSION_NOT_FOUND": "No extensions found in the current stack",
26
+
27
+ "GLOBAL_FIELDS_EXPORT_COMPLETE": "Successfully exported %s global field(s)",
28
+
29
+ "LABELS_EXPORT_COMPLETE": "Successfully exported %s label(s)",
30
+ "LABEL_EXPORT_SUCCESS": "Label '%s' exported successfully",
31
+ "LABELS_NOT_FOUND": "No labels found in the current stack",
32
+
33
+ "LOCALES_EXPORT_COMPLETE": "Successfully exported %s locale(s) including %s master locale(s)",
34
+
35
+ "TAXONOMY_EXPORT_COMPLETE": "Successfully exported %s taxonomy entries",
36
+ "TAXONOMY_EXPORT_SUCCESS": "Taxonomy '%s' exported successfully",
37
+ "TAXONOMY_NOT_FOUND": "No taxonomies found in the current stack",
38
+
39
+ "WEBHOOK_EXPORT_COMPLETE": "Successfully exported %s webhook(s)",
40
+ "WEBHOOK_EXPORT_SUCCESS": "Webhook '%s' exported successfully",
41
+ "WEBHOOK_NOT_FOUND": "No webhooks found in the current stack",
42
+
43
+ "WORKFLOW_EXPORT_COMPLETE": "Successfully exported %s workflow(s)",
44
+ "WORKFLOW_EXPORT_SUCCESS": "Workflow '%s' exported successfully",
45
+ "WORKFLOW_NOT_FOUND": "No workflows found in the current stack",
46
+
47
+ "PERSONALIZE_URL_NOT_SET": "Cannot export Personalize project: URL not configured",
48
+ "PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN": "Skipping Personalize project export: Management token not supported",
49
+ "PERSONALIZE_MODULE_NOT_IMPLEMENTED": "Module '%s' implementation not found",
50
+ "PERSONALIZE_NOT_ENABLED": "Personalize feature is not enabled for this organization",
51
+
52
+ "MARKETPLACE_APPS_EXPORT_COMPLETE": "Successfully exported %s marketplace app(s)",
53
+ "MARKETPLACE_APP_CONFIG_EXPORT": "Exporting configuration for app '%s'",
54
+ "MARKETPLACE_APP_CONFIG_SUCCESS": "Successfully exported configuration for app '%s'",
55
+ "MARKETPLACE_APP_EXPORT_SUCCESS": "Successfully exported app '%s'",
56
+ "MARKETPLACE_APPS_NOT_FOUND": "No marketplace apps found in the current stack",
57
+ "MARKETPLACE_APP_CONFIG_EXPORT_FAILED": "Failed to export configuration for app '%s'",
58
+ "MARKETPLACE_APP_MANIFEST_EXPORT_FAILED": "Failed to export manifest for app '%s'",
59
+
60
+ "COMPOSABLE_STUDIO_EXPORT_START": "Starting Studio project export...",
61
+ "COMPOSABLE_STUDIO_NOT_FOUND": "No Studio project found for this stack",
62
+ "COMPOSABLE_STUDIO_EXPORT_COMPLETE": "Successfully exported Studio project '%s'",
63
+ "COMPOSABLE_STUDIO_EXPORT_FAILED": "Failed to export Studio project: %s",
64
+ "COMPOSABLE_STUDIO_AUTH_REQUIRED": "To export Studio projects, you must be logged in",
65
+
66
+ "ENTRIES_EXPORT_COMPLETE": "Successfully exported entries (Content Type: %s, Locale: %s)",
67
+ "ENTRIES_EXPORT_SUCCESS": "All entries exported successfully",
68
+ "ENTRIES_VERSIONED_EXPORT_SUCCESS": "Successfully exported versioned entry (Content Type: %s, UID: %s, Locale: %s)",
69
+ "ENTRIES_EXPORT_VERSIONS_FAILED": "Failed to export versions for content type '%s' (UID: %s)",
70
+
71
+ "BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)",
72
+
73
+ "ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack",
74
+ "ROLES_EXPORTING_ROLE": "Exporting role '%s'",
69
75
 
70
76
  "GLOBAL_FIELDS_NOT_FOUND": "No global fields found in the current stack"
71
77
  }
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "module": {
85
85
  "char": "m",
86
- "description": "[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and taxonomies.",
86
+ "description": "[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.",
87
87
  "name": "module",
88
88
  "hasDynamicHelp": false,
89
89
  "multiple": false,
@@ -159,5 +159,5 @@
159
159
  ]
160
160
  }
161
161
  },
162
- "version": "2.0.0-beta.2"
162
+ "version": "2.0.0-beta.3"
163
163
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
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.2",
4
+ "version": "2.0.0-beta.3",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-command": "~1.6.1",
9
- "@contentstack/cli-variants": "~2.0.0-beta",
8
+ "@contentstack/cli-command": "~1.7.0",
10
9
  "@oclif/core": "^4.3.3",
10
+ "@contentstack/cli-variants": "~2.0.0-beta.3",
11
11
  "@contentstack/cli-utilities": "~1.15.0",
12
12
  "async": "^3.2.6",
13
13
  "big-json": "^3.2.0",
@@ -21,8 +21,8 @@
21
21
  "winston": "^3.17.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@contentstack/cli-auth": "~1.6.1",
25
- "@contentstack/cli-config": "~1.15.1",
24
+ "@contentstack/cli-auth": "~1.6.2",
25
+ "@contentstack/cli-config": "~1.15.3",
26
26
  "@contentstack/cli-dev-dependencies": "~1.3.1",
27
27
  "@oclif/plugin-help": "^6.2.28",
28
28
  "@oclif/test": "^4.1.13",