@contentstack/cli-cm-import 1.26.3 → 1.28.0

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
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
47
47
  $ csdx COMMAND
48
48
  running command...
49
49
  $ csdx (--version)
50
- @contentstack/cli-cm-import/1.26.3 linux-x64 node-v22.18.0
50
+ @contentstack/cli-cm-import/1.28.0 linux-x64 node-v22.19.0
51
51
  $ csdx --help [COMMAND]
52
52
  USAGE
53
53
  $ csdx COMMAND
@@ -91,6 +91,9 @@ FLAGS
91
91
  extensions, marketplace-apps, global-fields, labels, locales, webhooks,
92
92
  workflows, custom-roles, personalize projects, and taxonomies.
93
93
  -y, --yes [optional] Force override all Marketplace prompts.
94
+ --branch-alias=<value> The alias of the branch where you want to import your content. If you don't
95
+ mention the branch alias, then by default the content will be imported to the
96
+ main branch.
94
97
  --exclude-global-modules Excludes the branch-independent module from the import operation.
95
98
  --import-webhook-status=<option> [default: disable] [default: disable] (optional) This webhook state keeps the
96
99
  same state of webhooks as the source stack. <options: disable|current>
@@ -157,6 +160,9 @@ FLAGS
157
160
  extensions, marketplace-apps, global-fields, labels, locales, webhooks,
158
161
  workflows, custom-roles, personalize projects, and taxonomies.
159
162
  -y, --yes [optional] Force override all Marketplace prompts.
163
+ --branch-alias=<value> The alias of the branch where you want to import your content. If you don't
164
+ mention the branch alias, then by default the content will be imported to the
165
+ main branch.
160
166
  --exclude-global-modules Excludes the branch-independent module from the import operation.
161
167
  --import-webhook-status=<option> [default: disable] [default: disable] (optional) This webhook state keeps the
162
168
  same state of webhooks as the source stack. <options: disable|current>
@@ -26,26 +26,6 @@ class ImportCommand extends cli_command_1.Command {
26
26
  if (this.personalizeUrl)
27
27
  importConfig.modules.personalize.baseURL[importConfig.region.name] = this.personalizeUrl;
28
28
  const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(importConfig);
29
- if (!flags.branch) {
30
- try {
31
- // Use stack configuration to check for branch availability
32
- // false positive - no hardcoded secret here
33
- // @ts-ignore-next-line secret-detection
34
- const keyProp = 'api_key';
35
- const branches = await managementAPIClient
36
- .stack({ [keyProp]: importConfig.apiKey })
37
- .branch()
38
- .query()
39
- .find()
40
- .then(({ items }) => items);
41
- if (branches.length) {
42
- flags.branch = 'main';
43
- }
44
- }
45
- catch (error) {
46
- // Branch not enabled, just the let flow continue
47
- }
48
- }
49
29
  const moduleImporter = new import_1.ModuleImporter(managementAPIClient, importConfig);
50
30
  const result = await moduleImporter.start();
51
31
  backupDir = importConfig.backupDir;
@@ -150,6 +130,11 @@ ImportCommand.flags = {
150
130
  char: 'B',
151
131
  description: "The name of the branch where you want to import your content. If you don't mention the branch name, then by default the content will be imported to the main branch.",
152
132
  parse: (0, cli_utilities_1.printFlagDeprecation)(['-B'], ['--branch']),
133
+ exclusive: ['branch-alias'],
134
+ }),
135
+ 'branch-alias': cli_utilities_1.flags.string({
136
+ description: "The alias of the branch where you want to import your content. If you don't mention the branch alias, then by default the content will be imported to the main branch.",
137
+ exclusive: ['branch'],
153
138
  }),
154
139
  'import-webhook-status': cli_utilities_1.flags.string({
155
140
  description: '[default: disable] (optional) This webhook state keeps the same state of webhooks as the source stack. <options: disable|current>',
@@ -9,6 +9,11 @@ declare class ModuleImporter {
9
9
  import(): Promise<any>;
10
10
  importByModuleByName(moduleName: Modules): Promise<any>;
11
11
  importAllModules(): Promise<any>;
12
+ /**
13
+ * Resolves the import path based on directory structure and user configuration
14
+ * @returns Promise<void>
15
+ */
16
+ private resolveImportPath;
12
17
  /**
13
18
  * The `auditImportData` function performs an audit process on imported data, using a specified
14
19
  * configuration, and returns a boolean indicating whether a fix is needed.
@@ -23,8 +23,14 @@ class ModuleImporter {
23
23
  this.importConfig.stackName = stackDetails.name;
24
24
  this.importConfig.org_uid = stackDetails.org_uid;
25
25
  }
26
- if (this.importConfig.branchName) {
27
- await (0, utils_1.validateBranch)(this.stackAPIClient, this.importConfig, this.importConfig.branchName);
26
+ await this.resolveImportPath();
27
+ await (0, utils_1.setupBranchConfig)(this.importConfig, this.stackAPIClient);
28
+ if (this.importConfig.branchAlias && this.importConfig.branchName) {
29
+ this.stackAPIClient = this.managementAPIClient.stack({
30
+ api_key: this.importConfig.apiKey,
31
+ management_token: this.importConfig.management_token,
32
+ branch_uid: this.importConfig.branchName,
33
+ });
28
34
  }
29
35
  if (this.importConfig.management_token) {
30
36
  await (0, cli_utilities_1.addLocale)(this.importConfig.apiKey, this.importConfig.management_token, this.importConfig.host);
@@ -40,15 +46,7 @@ class ModuleImporter {
40
46
  // NOTE audit and fix the import content.
41
47
  if (!this.importConfig.skipAudit &&
42
48
  (!this.importConfig.moduleName ||
43
- [
44
- 'content-types',
45
- 'global-fields',
46
- 'entries',
47
- 'extensions',
48
- 'workflows',
49
- 'custom-roles',
50
- 'assets'
51
- ].includes(this.importConfig.moduleName))) {
49
+ ['content-types', 'global-fields', 'entries', 'extensions', 'workflows', 'custom-roles', 'assets'].includes(this.importConfig.moduleName))) {
52
50
  if (!(await this.auditImportData(logger))) {
53
51
  return { noSuccessMsg: true };
54
52
  }
@@ -62,7 +60,7 @@ class ModuleImporter {
62
60
  return this.import();
63
61
  }
64
62
  async import() {
65
- (0, utils_1.log)(this.importConfig, `Starting to import content version ${this.importConfig.contentVersion}`, 'info');
63
+ cli_utilities_1.log.info(`Starting to import content version ${this.importConfig.contentVersion}`, this.importConfig.context);
66
64
  // checks for single module or all modules
67
65
  if (this.importConfig.singleModuleImport) {
68
66
  return this.importByModuleByName(this.importConfig.moduleName);
@@ -70,7 +68,7 @@ class ModuleImporter {
70
68
  return this.importAllModules();
71
69
  }
72
70
  async importByModuleByName(moduleName) {
73
- (0, utils_1.log)(this.importConfig, `Starting import of ${moduleName} module`, 'info');
71
+ cli_utilities_1.log.info(`Starting import of ${moduleName} module`, this.importConfig.context);
74
72
  // import the modules by name
75
73
  // calls the module runner which inturn calls the module itself
76
74
  // NOTE: Implement a mechanism to determine whether module is new or old
@@ -96,12 +94,26 @@ class ModuleImporter {
96
94
  // use the algorithm to determine the parallel and sequential execution of modules
97
95
  for (let moduleName of this.importConfig.modules.types) {
98
96
  if (this.importConfig.globalModules.includes(moduleName) && this.importConfig['exclude-global-modules']) {
99
- (0, utils_1.log)(this.importConfig, `Skipping the import of the global module '${moduleName}', as it already exists in the stack.`, 'warn');
97
+ cli_utilities_1.log.warn(`Skipping the import of the global module '${moduleName}', as it already exists in the stack.`, this.importConfig.context);
100
98
  continue;
101
99
  }
102
100
  await this.importByModuleByName(moduleName);
103
101
  }
104
102
  }
103
+ /**
104
+ * Resolves the import path based on directory structure and user configuration
105
+ * @returns Promise<void>
106
+ */
107
+ async resolveImportPath() {
108
+ try {
109
+ const resolvedPath = await (0, utils_1.executeImportPathLogic)(this.importConfig, this.stackAPIClient);
110
+ cli_utilities_1.log.debug(`Import path resolved to: ${resolvedPath}`);
111
+ }
112
+ catch (error) {
113
+ cli_utilities_1.log.error(`Failed to resolve import path: ${error}`);
114
+ // Continue with original path if resolution fails
115
+ }
116
+ }
105
117
  /**
106
118
  * The `auditImportData` function performs an audit process on imported data, using a specified
107
119
  * configuration, and returns a boolean indicating whether a fix is needed.
@@ -127,23 +139,15 @@ class ModuleImporter {
127
139
  }
128
140
  else if (this.importConfig.modules.types.length) {
129
141
  this.importConfig.modules.types
130
- .filter((val) => [
131
- 'content-types',
132
- 'global-fields',
133
- 'entries',
134
- 'extensions',
135
- 'workflows',
136
- 'custom-roles',
137
- 'assets'
138
- ].includes(val))
142
+ .filter((val) => ['content-types', 'global-fields', 'entries', 'extensions', 'workflows', 'custom-roles', 'assets'].includes(val))
139
143
  .forEach((val) => {
140
144
  args.push('--modules', val);
141
145
  });
142
146
  }
143
147
  args.push('--modules', 'field-rules');
144
- (0, utils_1.log)(this.importConfig, 'Starting audit process', 'info');
148
+ cli_utilities_1.log.info('Starting audit process', this.importConfig.context);
145
149
  const result = await cli_audit_1.AuditFix.run(args);
146
- (0, utils_1.log)(this.importConfig, 'Audit process completed', 'info');
150
+ cli_utilities_1.log.info('Audit process completed', this.importConfig.context);
147
151
  if (result) {
148
152
  const { hasFix, config } = result;
149
153
  if (hasFix) {
@@ -162,7 +166,7 @@ class ModuleImporter {
162
166
  return true;
163
167
  }
164
168
  catch (error) {
165
- (0, utils_1.log)(this.importConfig, `Audit failed with following error. ${error}`, 'error');
169
+ cli_utilities_1.log.error(`Audit failed with following error. ${error}`, this.importConfig.context);
166
170
  }
167
171
  }
168
172
  }
@@ -8,7 +8,7 @@ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
8
8
  const entries_1 = tslib_1.__importDefault(require("lodash/entries"));
9
9
  const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
10
10
  const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
11
- const utils_1 = require("../../utils");
11
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
12
12
  const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
13
13
  class BaseClass {
14
14
  constructor({ importConfig, stackAPIClient }) {
@@ -84,6 +84,7 @@ class BaseClass {
84
84
  * @returns {Promise} Promise<void>
85
85
  */
86
86
  async logMsgAndWaitIfRequired(processName, start, totelBatches, batchNo, logBatchCompletionMsg = true, indexerCount, currentIndexer) {
87
+ var _a;
87
88
  const end = Date.now();
88
89
  const exeTime = end - start;
89
90
  if (logBatchCompletionMsg) {
@@ -91,7 +92,7 @@ class BaseClass {
91
92
  // info: Batch No. 20 of import assets is complete
92
93
  if (currentIndexer)
93
94
  batchMsg += `Current chunk processing is (${currentIndexer}/${indexerCount})`;
94
- (0, utils_1.log)(this.importConfig, `Batch No. (${batchNo}/${totelBatches}) of ${processName} is complete`, 'success');
95
+ cli_utilities_1.log.debug(`Batch No. (${batchNo}/${totelBatches}) of ${processName} is complete`, (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.context);
95
96
  }
96
97
  if (this.importConfig.modules.assets.displayExecutionTime) {
97
98
  console.log(`Time taken to execute: ${exeTime} milliseconds; wait time: ${exeTime < 1000 ? 1000 - exeTime : 0} milliseconds`);
@@ -158,11 +158,11 @@ class EntriesImport extends base_class_1.default {
158
158
  async disableMandatoryCTReferences() {
159
159
  cli_utilities_1.log.debug(`Starting to disable mandatory CT references for ${this.cTs.length} content types`, this.importConfig.context);
160
160
  const onSuccess = ({ response: contentType, apiData: { uid } }) => {
161
- cli_utilities_1.log.success(`${uid} content type references removed temporarily`, this.importConfig.context);
162
- cli_utilities_1.log.debug(`Successfully processed content type: ${uid}`, this.importConfig.context);
161
+ cli_utilities_1.log.success(`'${uid}' content type references removed temporarily`, this.importConfig.context);
162
+ cli_utilities_1.log.debug(`Successfully processed content type: '${uid}'`, this.importConfig.context);
163
163
  };
164
164
  const onReject = ({ error, apiData: { uid } }) => {
165
- (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `${uid} content type references removal failed`);
165
+ (0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `'${uid}' content type references removal failed`);
166
166
  };
167
167
  return await this.makeConcurrentCall({
168
168
  processName: 'Update content types (removing mandatory references temporarily)',
@@ -27,6 +27,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
27
27
  branches?: branch[];
28
28
  branchEnabled?: boolean;
29
29
  branchDir?: string;
30
+ branchAlias?: string;
30
31
  moduleName?: Modules;
31
32
  master_locale: masterLocale;
32
33
  headers?: {
@@ -11,10 +11,12 @@ async function backupHandler(importConfig) {
11
11
  cli_utilities_1.log.debug(`Using existing backup directory: ${importConfig.useBackedupDir}`);
12
12
  return importConfig.useBackedupDir;
13
13
  }
14
+ const sourceDir = importConfig.branchDir || importConfig.contentDir;
15
+ cli_utilities_1.log.debug(`Using source directory for backup: ${sourceDir} (branchDir: ${importConfig.branchDir}, contentDir: ${importConfig.contentDir})`);
14
16
  let backupDirPath;
15
- const subDir = isSubDirectory(importConfig);
17
+ const subDir = isSubDirectory(importConfig, sourceDir);
16
18
  if (subDir) {
17
- backupDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), '..', '_backup_' + Math.floor(Math.random() * 1000));
19
+ backupDirPath = path.resolve((0, cli_utilities_1.sanitizePath)(sourceDir), '..', '_backup_' + Math.floor(Math.random() * 1000));
18
20
  cli_utilities_1.log.debug(`Detected subdirectory configuration, creating backup at: ${backupDirPath}`);
19
21
  if (importConfig.createBackupDir) {
20
22
  cli_utilities_1.cliux.print(`Warning!!! Provided backup directory path is a sub directory of the content directory, Cannot copy to a sub directory. Hence new backup directory created - ${backupDirPath}`, {
@@ -41,7 +43,7 @@ async function backupHandler(importConfig) {
41
43
  cli_utilities_1.log.debug(`Starting content copy to backup directory: ${backupDirPath}`);
42
44
  cli_utilities_1.cliux.print('Copying content to the backup directory...');
43
45
  return new Promise((resolve, reject) => {
44
- return (0, fs_extra_1.copy)(importConfig.contentDir, backupDirPath, (error) => {
46
+ return (0, fs_extra_1.copy)(sourceDir, backupDirPath, (error) => {
45
47
  if (error) {
46
48
  (0, index_1.trace)(error, 'error', true);
47
49
  return reject(error);
@@ -58,9 +60,9 @@ exports.default = backupHandler;
58
60
  * @param importConfig
59
61
  * @returns
60
62
  */
61
- function isSubDirectory(importConfig) {
63
+ function isSubDirectory(importConfig, sourceDir) {
62
64
  cli_utilities_1.log.debug('Checking if backup directory is a subdirectory');
63
- const parent = importConfig.contentDir;
65
+ const parent = sourceDir;
64
66
  const child = importConfig.createBackupDir ? importConfig.createBackupDir : process.cwd();
65
67
  const relative = path.relative(parent, child);
66
68
  cli_utilities_1.log.debug(`Parent directory: ${parent}, Child directory: ${child}, Relative path: ${relative}`);
@@ -92,6 +92,9 @@ const setupConfig = async (importCmdFlags) => {
92
92
  config.forceStopMarketplaceAppsPrompt = importCmdFlags.yes;
93
93
  config.importWebhookStatus = importCmdFlags['import-webhook-status'];
94
94
  config.skipPrivateAppRecreationIfExist = !importCmdFlags['skip-app-recreation'];
95
+ if (importCmdFlags['branch-alias']) {
96
+ config.branchAlias = importCmdFlags['branch-alias'];
97
+ }
95
98
  if (importCmdFlags['branch']) {
96
99
  config.branchName = importCmdFlags['branch'];
97
100
  config.branchDir = config.contentDir;
@@ -0,0 +1,29 @@
1
+ import { ImportConfig } from '../types';
2
+ /**
3
+ * Selects a branch from directory structure when multiple branches are found
4
+ * @param contentDir - The content directory path
5
+ * @returns Promise<{ branchPath: string } | null>
6
+ */
7
+ export declare const selectBranchFromDirectory: (contentDir: string) => Promise<{
8
+ branchPath: string;
9
+ } | null>;
10
+ /**
11
+ * Resolves the import path based on directory structure and user configuration
12
+ * @param importConfig - The import configuration object
13
+ * @param stackAPIClient - The Contentstack API client
14
+ * @returns Promise<string> - The resolved path
15
+ */
16
+ export declare const resolveImportPath: (importConfig: ImportConfig, stackAPIClient: any) => Promise<string>;
17
+ /**
18
+ * Updates the import configuration with the resolved path
19
+ * @param importConfig - The import configuration object
20
+ * @param resolvedPath - The resolved path
21
+ */
22
+ export declare const updateImportConfigWithResolvedPath: (importConfig: ImportConfig, resolvedPath: string) => void;
23
+ /**
24
+ * Executes the complete import path resolution logic
25
+ * @param importConfig - The import configuration object
26
+ * @param stackAPIClient - The Contentstack API client
27
+ * @returns Promise<string> - The resolved path
28
+ */
29
+ export declare const executeImportPathLogic: (importConfig: ImportConfig, stackAPIClient: any) => Promise<string>;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeImportPathLogic = exports.updateImportConfigWithResolvedPath = exports.resolveImportPath = exports.selectBranchFromDirectory = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const path = tslib_1.__importStar(require("path"));
6
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
+ const file_helper_1 = require("./file-helper");
8
+ const interactive_1 = require("./interactive");
9
+ const config_1 = tslib_1.__importDefault(require("../config"));
10
+ /**
11
+ * Selects a branch from directory structure when multiple branches are found
12
+ * @param contentDir - The content directory path
13
+ * @returns Promise<{ branchPath: string } | null>
14
+ */
15
+ const selectBranchFromDirectory = async (contentDir) => {
16
+ cli_utilities_1.log.debug('Selecting branch directory from directory structure');
17
+ const branchesJsonPath = path.join(contentDir, 'branches.json');
18
+ if (!(0, file_helper_1.fileExistsSync)(branchesJsonPath)) {
19
+ cli_utilities_1.log.debug('No branches.json found - not a branch-enabled export');
20
+ return null;
21
+ }
22
+ try {
23
+ const branchesData = await (0, file_helper_1.readFile)(branchesJsonPath);
24
+ const branches = branchesData || [];
25
+ if (!branches || !Array.isArray(branches) || branches.length === 0) {
26
+ cli_utilities_1.log.debug('No branches found in branches.json - not a branch-enabled export');
27
+ return null;
28
+ }
29
+ if (branches.length === 1) {
30
+ const singleBranch = branches[0];
31
+ const branchPath = path.join(contentDir, singleBranch.uid);
32
+ if (!(0, file_helper_1.fileExistsSync)(branchPath)) {
33
+ cli_utilities_1.log.warn(`Branch path does not exist: ${branchPath}, not a valid branch export`);
34
+ return null;
35
+ }
36
+ cli_utilities_1.log.debug(`Single branch detected: ${singleBranch.uid} - auto-resolving to: ${branchPath}`);
37
+ return { branchPath };
38
+ }
39
+ else {
40
+ cli_utilities_1.log.debug(`Multiple branches detected: ${branches.map((b) => b.uid).join(', ')}`);
41
+ const branchNames = branches.map((b) => b.uid);
42
+ const selectedBranch = await (0, interactive_1.askBranchSelection)(branchNames);
43
+ const selectedBranchPath = path.join(contentDir, selectedBranch);
44
+ if (!(0, file_helper_1.fileExistsSync)(selectedBranchPath)) {
45
+ cli_utilities_1.log.warn(`Selected branch path does not exist: ${selectedBranchPath}, not a valid branch export`);
46
+ return null;
47
+ }
48
+ cli_utilities_1.log.debug(`User selected branch directory: ${selectedBranch} - using path: ${selectedBranchPath}`);
49
+ return { branchPath: selectedBranchPath };
50
+ }
51
+ }
52
+ catch (error) {
53
+ cli_utilities_1.log.error(`Error selecting branch directory from directory structure: ${error}`);
54
+ throw error;
55
+ }
56
+ };
57
+ exports.selectBranchFromDirectory = selectBranchFromDirectory;
58
+ /**
59
+ * Resolves the import path based on directory structure and user configuration
60
+ * @param importConfig - The import configuration object
61
+ * @param stackAPIClient - The Contentstack API client
62
+ * @returns Promise<string> - The resolved path
63
+ */
64
+ const resolveImportPath = async (importConfig, stackAPIClient) => {
65
+ cli_utilities_1.log.debug('Resolving import path based on directory structure');
66
+ const contentDir = importConfig.contentDir || importConfig.data;
67
+ cli_utilities_1.log.debug(`Content directory: ${contentDir}`);
68
+ if (!(0, file_helper_1.fileExistsSync)(contentDir)) {
69
+ throw new Error(`Content directory does not exist: ${contentDir}`);
70
+ }
71
+ if (importConfig.branchName) {
72
+ cli_utilities_1.log.debug(`User specified branch: ${importConfig.branchName}`);
73
+ const currentDirName = path.basename(contentDir);
74
+ if (currentDirName === importConfig.branchName) {
75
+ cli_utilities_1.log.debug(`Already in correct branch directory: ${contentDir}`);
76
+ return contentDir;
77
+ }
78
+ const branchPath = path.join(contentDir, importConfig.branchName);
79
+ if ((0, file_helper_1.fileExistsSync)(branchPath)) {
80
+ cli_utilities_1.log.debug(`Navigating to specified branch directory: ${branchPath}`);
81
+ return branchPath;
82
+ }
83
+ cli_utilities_1.log.debug(`Branch directory not found: ${branchPath}, using contentDir as-is`);
84
+ return contentDir;
85
+ }
86
+ const exportInfoPath = path.join(contentDir, 'export-info.json');
87
+ if ((0, file_helper_1.fileExistsSync)(exportInfoPath)) {
88
+ cli_utilities_1.log.debug('Found export-info.json - using contentDir as-is (v2 export)');
89
+ return contentDir;
90
+ }
91
+ const moduleTypes = config_1.default.modules.types;
92
+ const hasModuleFolders = moduleTypes.some((moduleType) => (0, file_helper_1.fileExistsSync)(path.join(contentDir, moduleType)));
93
+ if (hasModuleFolders) {
94
+ cli_utilities_1.log.debug('Found module folders ');
95
+ return contentDir;
96
+ }
97
+ const branchSelection = await (0, exports.selectBranchFromDirectory)(contentDir);
98
+ if (branchSelection) {
99
+ return branchSelection.branchPath;
100
+ }
101
+ cli_utilities_1.log.debug('No specific structure detected - using contentDir as-is');
102
+ return contentDir;
103
+ };
104
+ exports.resolveImportPath = resolveImportPath;
105
+ /**
106
+ * Updates the import configuration with the resolved path
107
+ * @param importConfig - The import configuration object
108
+ * @param resolvedPath - The resolved path
109
+ */
110
+ const updateImportConfigWithResolvedPath = (importConfig, resolvedPath) => {
111
+ cli_utilities_1.log.debug(`Updating import config with resolved path: ${resolvedPath}`);
112
+ if (!(0, file_helper_1.fileExistsSync)(resolvedPath)) {
113
+ cli_utilities_1.log.warn(`Resolved path does not exist: ${resolvedPath}, skipping config update`);
114
+ return;
115
+ }
116
+ importConfig.branchDir = resolvedPath;
117
+ importConfig.contentDir = resolvedPath;
118
+ importConfig.data = resolvedPath;
119
+ cli_utilities_1.log.debug(`Import config updated - contentDir: ${importConfig.contentDir}, branchDir: ${importConfig.branchDir}, data: ${importConfig.data}`);
120
+ };
121
+ exports.updateImportConfigWithResolvedPath = updateImportConfigWithResolvedPath;
122
+ /**
123
+ * Executes the complete import path resolution logic
124
+ * @param importConfig - The import configuration object
125
+ * @param stackAPIClient - The Contentstack API client
126
+ * @returns Promise<string> - The resolved path
127
+ */
128
+ const executeImportPathLogic = async (importConfig, stackAPIClient) => {
129
+ cli_utilities_1.log.debug('Executing import path resolution logic');
130
+ const resolvedPath = await (0, exports.resolveImportPath)(importConfig, stackAPIClient);
131
+ (0, exports.updateImportConfigWithResolvedPath)(importConfig, resolvedPath);
132
+ return resolvedPath;
133
+ };
134
+ exports.executeImportPathLogic = executeImportPathLogic;
@@ -1,3 +1,5 @@
1
+ export { setupBranchConfig } from './setup-branch';
2
+ export { selectBranchFromDirectory, resolveImportPath, updateImportConfigWithResolvedPath, executeImportPathLogic } from './import-path-resolver';
1
3
  export * as interactive from './interactive';
2
4
  export { default as setupImportConfig } from './import-config-handler';
3
5
  export * as fileHelper from './file-helper';
@@ -1,7 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lookUpTerms = exports.lookUpTaxonomy = exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = void 0;
3
+ exports.lookUpTerms = exports.lookUpTaxonomy = exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = exports.executeImportPathLogic = exports.updateImportConfigWithResolvedPath = exports.resolveImportPath = exports.selectBranchFromDirectory = exports.setupBranchConfig = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ var setup_branch_1 = require("./setup-branch");
6
+ Object.defineProperty(exports, "setupBranchConfig", { enumerable: true, get: function () { return setup_branch_1.setupBranchConfig; } });
7
+ var import_path_resolver_1 = require("./import-path-resolver");
8
+ Object.defineProperty(exports, "selectBranchFromDirectory", { enumerable: true, get: function () { return import_path_resolver_1.selectBranchFromDirectory; } });
9
+ Object.defineProperty(exports, "resolveImportPath", { enumerable: true, get: function () { return import_path_resolver_1.resolveImportPath; } });
10
+ Object.defineProperty(exports, "updateImportConfigWithResolvedPath", { enumerable: true, get: function () { return import_path_resolver_1.updateImportConfigWithResolvedPath; } });
11
+ Object.defineProperty(exports, "executeImportPathLogic", { enumerable: true, get: function () { return import_path_resolver_1.executeImportPathLogic; } });
5
12
  exports.interactive = tslib_1.__importStar(require("./interactive"));
6
13
  var import_config_handler_1 = require("./import-config-handler");
7
14
  Object.defineProperty(exports, "setupImportConfig", { enumerable: true, get: function () { return tslib_1.__importDefault(import_config_handler_1).default; } });
@@ -5,3 +5,4 @@ export declare const askAppName: (app: any, appSuffix: number) => Promise<string
5
5
  export declare const getAppName: (name: string, appSuffix?: number) => string;
6
6
  export declare const getLocationName: (name: string, appSuffix: number, existingNames: Set<string>) => string;
7
7
  export declare const selectConfiguration: () => Promise<string>;
8
+ export declare const askBranchSelection: (branchNames: string[]) => Promise<string>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.selectConfiguration = exports.getLocationName = exports.getAppName = exports.askAppName = exports.askEncryptionKey = exports.askAPIKey = exports.askContentDir = void 0;
3
+ exports.askBranchSelection = exports.selectConfiguration = exports.getLocationName = exports.getAppName = exports.askAppName = exports.askEncryptionKey = exports.askAPIKey = exports.askContentDir = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const cli_utilities_1 = require("@contentstack/cli-utilities");
6
6
  const path = tslib_1.__importStar(require("path"));
@@ -93,3 +93,12 @@ const selectConfiguration = async () => {
93
93
  });
94
94
  };
95
95
  exports.selectConfiguration = selectConfiguration;
96
+ const askBranchSelection = async (branchNames) => {
97
+ return await cli_utilities_1.cliux.inquire({
98
+ type: 'list',
99
+ name: 'branch',
100
+ message: 'Found multiple branches in your export path. Please select one to import:',
101
+ choices: branchNames,
102
+ });
103
+ };
104
+ exports.askBranchSelection = askBranchSelection;
@@ -0,0 +1,3 @@
1
+ import { ContentstackClient } from '@contentstack/cli-utilities';
2
+ import { ImportConfig } from 'src/types';
3
+ export declare const setupBranchConfig: (config: ImportConfig, stackAPIClient: ReturnType<ContentstackClient['stack']>) => Promise<void>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupBranchConfig = void 0;
4
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
5
+ const common_helper_1 = require("./common-helper");
6
+ const setupBranchConfig = async (config, stackAPIClient) => {
7
+ if (config.branchName) {
8
+ await (0, common_helper_1.validateBranch)(stackAPIClient, config, config.branchName);
9
+ return;
10
+ }
11
+ if (config.branchAlias) {
12
+ config.branchName = await (0, cli_utilities_1.getBranchFromAlias)(stackAPIClient, config.branchAlias);
13
+ return;
14
+ }
15
+ try {
16
+ const branches = await stackAPIClient
17
+ .branch()
18
+ .query()
19
+ .find()
20
+ .then(({ items }) => items);
21
+ if (branches.length) {
22
+ cli_utilities_1.log.info(`Stack is branch enabled and branches exist. Default import will be done in main branch.`);
23
+ config.branchName = 'main';
24
+ cli_utilities_1.log.debug(`Setting default target branch to 'main'`);
25
+ }
26
+ }
27
+ catch (error) {
28
+ cli_utilities_1.log.debug('Failed to fetch branches', { error });
29
+ }
30
+ };
31
+ exports.setupBranchConfig = setupBranchConfig;
@@ -102,11 +102,24 @@
102
102
  "branch": {
103
103
  "char": "B",
104
104
  "description": "The name of the branch where you want to import your content. If you don't mention the branch name, then by default the content will be imported to the main branch.",
105
+ "exclusive": [
106
+ "branch-alias"
107
+ ],
105
108
  "name": "branch",
106
109
  "hasDynamicHelp": false,
107
110
  "multiple": false,
108
111
  "type": "option"
109
112
  },
113
+ "branch-alias": {
114
+ "description": "The alias of the branch where you want to import your content. If you don't mention the branch alias, then by default the content will be imported to the main branch.",
115
+ "exclusive": [
116
+ "branch"
117
+ ],
118
+ "name": "branch-alias",
119
+ "hasDynamicHelp": false,
120
+ "multiple": false,
121
+ "type": "option"
122
+ },
110
123
  "import-webhook-status": {
111
124
  "description": "[default: disable] (optional) This webhook state keeps the same state of webhooks as the source stack. <options: disable|current>",
112
125
  "name": "import-webhook-status",
@@ -199,5 +212,5 @@
199
212
  ]
200
213
  }
201
214
  },
202
- "version": "1.26.3"
215
+ "version": "1.28.0"
203
216
  }
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-import",
3
3
  "description": "Contentstack CLI plugin to import content into stack",
4
- "version": "1.26.3",
4
+ "version": "1.28.0",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-audit": "~1.14.0",
9
- "@contentstack/cli-command": "~1.6.0",
10
- "@contentstack/cli-utilities": "~1.13.2",
8
+ "@contentstack/cli-audit": "~1.14.1",
9
+ "@contentstack/cli-command": "~1.6.1",
10
+ "@contentstack/cli-utilities": "~1.14.1",
11
11
  "@contentstack/management": "~1.22.0",
12
- "@contentstack/cli-variants": "~1.3.0",
12
+ "@contentstack/cli-variants": "~1.3.3",
13
13
  "@oclif/core": "^4.3.0",
14
14
  "big-json": "^3.2.0",
15
15
  "bluebird": "^3.7.2",