@contentstack/cli-cm-clone 1.20.0 → 1.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/commands/cm/stacks/clone.d.ts +21 -0
- package/lib/commands/cm/stacks/clone.js +315 -0
- package/lib/core/helpers/command-helpers.d.ts +31 -0
- package/lib/core/helpers/command-helpers.js +79 -0
- package/lib/core/util/abort-controller.d.ts +30 -0
- package/lib/core/util/abort-controller.js +58 -0
- package/lib/core/util/clone-handler.d.ts +55 -0
- package/lib/core/util/clone-handler.js +763 -0
- package/lib/core/util/dummyConfig.json +1 -0
- package/lib/types/clone-config.d.ts +35 -0
- package/lib/types/clone-config.js +2 -0
- package/lib/types/clone-context.d.ts +10 -0
- package/lib/types/clone-context.js +2 -0
- package/lib/types/command-types.d.ts +39 -0
- package/lib/types/command-types.js +2 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.js +6 -0
- package/lib/utils/constants.d.ts +25 -0
- package/lib/utils/constants.js +40 -0
- package/oclif.manifest.json +169 -0
- package/package.json +1 -1
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CloneHandler = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const ora_1 = tslib_1.__importDefault(require("ora"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
8
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
9
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
10
|
+
const rimraf_1 = require("rimraf");
|
|
11
|
+
const cli_cm_export_1 = tslib_1.__importDefault(require("@contentstack/cli-cm-export"));
|
|
12
|
+
const cli_cm_import_1 = tslib_1.__importDefault(require("@contentstack/cli-cm-import"));
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
14
|
+
const prompt = require('prompt');
|
|
15
|
+
const safe_1 = tslib_1.__importDefault(require("@colors/colors/safe"));
|
|
16
|
+
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
17
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
18
|
+
const command_helpers_1 = require("../helpers/command-helpers");
|
|
19
|
+
const constants_1 = require("../../utils/constants");
|
|
20
|
+
// Override prompt's stop method
|
|
21
|
+
prompt.stop = function () {
|
|
22
|
+
if (prompt.stopped) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
prompt.emit('stop');
|
|
26
|
+
prompt.stopped = true;
|
|
27
|
+
return prompt;
|
|
28
|
+
};
|
|
29
|
+
class CloneHandler {
|
|
30
|
+
constructor(opt) {
|
|
31
|
+
this.orgUidList = {};
|
|
32
|
+
this.stackUidList = {};
|
|
33
|
+
this.masterLocaleList = {};
|
|
34
|
+
this.config = opt;
|
|
35
|
+
this.cloneCommand = new command_helpers_1.Clone();
|
|
36
|
+
this.pathDir = opt.pathDir || '';
|
|
37
|
+
// Create mutable copy of stack name prompt for dynamic default updates
|
|
38
|
+
this.stackNamePrompt = {
|
|
39
|
+
type: constants_1.STACK_NAME_PROMPT.type,
|
|
40
|
+
name: constants_1.STACK_NAME_PROMPT.name,
|
|
41
|
+
default: constants_1.STACK_NAME_PROMPT.default,
|
|
42
|
+
message: constants_1.STACK_NAME_PROMPT.message,
|
|
43
|
+
};
|
|
44
|
+
process.stdin.setMaxListeners(50);
|
|
45
|
+
cli_utilities_1.log.debug('Initializing CloneHandler', Object.assign(Object.assign({}, this.config.cloneContext), { pathDir: opt.pathDir, cloneType: opt.cloneType }));
|
|
46
|
+
}
|
|
47
|
+
setClient(managementSDKClient) {
|
|
48
|
+
this.client = managementSDKClient;
|
|
49
|
+
}
|
|
50
|
+
async getOrganizationChoices(orgMessage) {
|
|
51
|
+
const orgChoice = {
|
|
52
|
+
type: 'list',
|
|
53
|
+
name: 'Organization',
|
|
54
|
+
message: orgMessage !== undefined ? orgMessage : 'Choose an organization',
|
|
55
|
+
choices: [],
|
|
56
|
+
};
|
|
57
|
+
return new Promise(async (resolve, reject) => {
|
|
58
|
+
cli_utilities_1.log.debug('Fetching organization choices', this.config.cloneContext);
|
|
59
|
+
const spinner = (0, ora_1.default)('Fetching Organization').start();
|
|
60
|
+
try {
|
|
61
|
+
let organizations;
|
|
62
|
+
const configOrgUid = cli_utilities_1.configHandler.get('oauthOrgUid');
|
|
63
|
+
cli_utilities_1.log.debug('Getting organizations', Object.assign(Object.assign({}, this.config.cloneContext), { hasConfigOrgUid: !!configOrgUid }));
|
|
64
|
+
if (configOrgUid) {
|
|
65
|
+
organizations = await this.client.organization(configOrgUid).fetch();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
organizations = await this.client.organization().fetchAll({ limit: 100 });
|
|
69
|
+
}
|
|
70
|
+
spinner.succeed('Fetched Organization');
|
|
71
|
+
cli_utilities_1.log.debug('Fetched organizations', this.config.cloneContext);
|
|
72
|
+
for (const element of organizations.items || [organizations]) {
|
|
73
|
+
this.orgUidList[element.name] = element.uid;
|
|
74
|
+
orgChoice.choices.push(element.name);
|
|
75
|
+
}
|
|
76
|
+
return resolve(orgChoice);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
spinner.fail();
|
|
80
|
+
return reject(e);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async handleOrgSelection(options = {}) {
|
|
85
|
+
return new Promise(async (resolve, reject) => {
|
|
86
|
+
var _a;
|
|
87
|
+
const { msg = '', isSource = true } = options || {};
|
|
88
|
+
cli_utilities_1.log.debug('Handling organization selection', this.config.cloneContext);
|
|
89
|
+
const orgList = await this.getOrganizationChoices(msg).catch(reject);
|
|
90
|
+
if (orgList) {
|
|
91
|
+
cli_utilities_1.log.debug(`Found ${((_a = orgList.choices) === null || _a === void 0 ? void 0 : _a.length) || 0} organization(s) to choose from`, this.config.cloneContext);
|
|
92
|
+
const orgSelected = await inquirer_1.default.prompt(orgList);
|
|
93
|
+
cli_utilities_1.log.debug(`Organization selected: ${orgSelected.Organization}`, this.config.cloneContext);
|
|
94
|
+
if (isSource) {
|
|
95
|
+
this.config.sourceOrg = this.orgUidList[orgSelected.Organization];
|
|
96
|
+
cli_utilities_1.log.debug(`Source organization UID: ${this.config.sourceOrg}`, this.config.cloneContext);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.config.targetOrg = this.orgUidList[orgSelected.Organization];
|
|
100
|
+
cli_utilities_1.log.debug(`Target organization UID: ${this.config.targetOrg}`, this.config.cloneContext);
|
|
101
|
+
}
|
|
102
|
+
resolve(orgSelected);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async getStack(answer, stkMessage, isSource = true) {
|
|
107
|
+
const stackChoice = {
|
|
108
|
+
type: 'list',
|
|
109
|
+
name: 'stack',
|
|
110
|
+
message: stkMessage !== undefined ? stkMessage : 'Select the stack',
|
|
111
|
+
choices: [],
|
|
112
|
+
};
|
|
113
|
+
return new Promise(async (resolve, reject) => {
|
|
114
|
+
cli_utilities_1.log.debug('Fetching stacks', this.config.cloneContext);
|
|
115
|
+
const spinner = (0, ora_1.default)('Fetching stacks').start();
|
|
116
|
+
try {
|
|
117
|
+
const organization_uid = this.orgUidList[answer.Organization];
|
|
118
|
+
cli_utilities_1.log.debug('Querying stacks for organization', Object.assign(Object.assign({}, this.config.cloneContext), { organizationUid: organization_uid }));
|
|
119
|
+
const stackList = this.client.stack().query({ organization_uid }).find();
|
|
120
|
+
stackList
|
|
121
|
+
.then((stacklist) => {
|
|
122
|
+
cli_utilities_1.log.debug('Fetched stacks', Object.assign(Object.assign({}, this.config.cloneContext), { count: stacklist.items ? stacklist.items.length : 0 }));
|
|
123
|
+
for (const element of stacklist.items) {
|
|
124
|
+
this.stackUidList[element.name] = element.api_key;
|
|
125
|
+
this.masterLocaleList[element.name] = element.master_locale;
|
|
126
|
+
stackChoice.choices.push(element.name);
|
|
127
|
+
}
|
|
128
|
+
spinner.succeed('Fetched stack');
|
|
129
|
+
return resolve(stackChoice);
|
|
130
|
+
})
|
|
131
|
+
.catch((error) => {
|
|
132
|
+
spinner.fail();
|
|
133
|
+
return reject(error);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
spinner.fail();
|
|
138
|
+
return reject(e);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
displayBackOptionMessage() {
|
|
143
|
+
const ui = new inquirer_1.default.ui.BottomBar();
|
|
144
|
+
ui.updateBottomBar(chalk_1.default.cyan('\nPress shift & left arrow together to undo the operation\n'));
|
|
145
|
+
}
|
|
146
|
+
setBackKeyPressHandler(backKeyPressHandler) {
|
|
147
|
+
this.backKeyPressHandler = backKeyPressHandler;
|
|
148
|
+
}
|
|
149
|
+
removeBackKeyPressHandler() {
|
|
150
|
+
if (this.backKeyPressHandler) {
|
|
151
|
+
process.stdin.removeListener('keypress', this.backKeyPressHandler);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
setExectingCommand(command) {
|
|
155
|
+
// 0 for org, 1 for stack, 1 for branch, 3 stack cancelled, 4 branch cancelled
|
|
156
|
+
this.executingCommand = command;
|
|
157
|
+
}
|
|
158
|
+
async handleStackSelection(options = {}) {
|
|
159
|
+
return new Promise(async (resolve, reject) => {
|
|
160
|
+
var _a;
|
|
161
|
+
try {
|
|
162
|
+
const { org = {}, msg = '', isSource = true } = options || {};
|
|
163
|
+
cli_utilities_1.log.debug('Handling stack selection', Object.assign(Object.assign({}, this.config.cloneContext), { isSource, orgName: org.Organization, msg }));
|
|
164
|
+
const stackList = await this.getStack(org, msg, isSource).catch(reject);
|
|
165
|
+
if (stackList) {
|
|
166
|
+
this.displayBackOptionMessage();
|
|
167
|
+
cli_utilities_1.log.debug(`Found ${((_a = stackList.choices) === null || _a === void 0 ? void 0 : _a.length) || 0} stack(s) to choose from`, this.config.cloneContext);
|
|
168
|
+
const selectedStack = await inquirer_1.default.prompt(stackList);
|
|
169
|
+
cli_utilities_1.log.debug(`Stack selected: ${selectedStack.stack}`, this.config.cloneContext);
|
|
170
|
+
if (this.executingCommand != 1) {
|
|
171
|
+
return reject();
|
|
172
|
+
}
|
|
173
|
+
if (isSource) {
|
|
174
|
+
this.config.sourceStackName = selectedStack.stack;
|
|
175
|
+
this.master_locale = this.masterLocaleList[selectedStack.stack];
|
|
176
|
+
this.config.source_stack = this.stackUidList[selectedStack.stack];
|
|
177
|
+
cli_utilities_1.log.debug(`Source stack configured`, this.config.cloneContext);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
this.config.target_stack = this.stackUidList[selectedStack.stack];
|
|
181
|
+
this.config.destinationStackName = selectedStack.stack;
|
|
182
|
+
cli_utilities_1.log.debug(`Target stack configured`, this.config.cloneContext);
|
|
183
|
+
}
|
|
184
|
+
resolve(selectedStack);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return reject(error);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async validateIfBranchExist(stackAPIClient, isSource) {
|
|
193
|
+
let spinner;
|
|
194
|
+
const completeSpinner = (msg, method = 'succeed') => {
|
|
195
|
+
spinner[method](msg);
|
|
196
|
+
spinner.stop();
|
|
197
|
+
};
|
|
198
|
+
try {
|
|
199
|
+
const branch = isSource ? this.config.sourceStackBranch : this.config.targetStackBranch;
|
|
200
|
+
cli_utilities_1.log.debug('Validating branch existence', this.config.cloneContext);
|
|
201
|
+
spinner = (0, ora_1.default)(`Validation if ${isSource ? 'source' : 'target'} branch exist.!`).start();
|
|
202
|
+
const isBranchExist = await stackAPIClient
|
|
203
|
+
.branch(branch)
|
|
204
|
+
.fetch()
|
|
205
|
+
.then((data) => data);
|
|
206
|
+
if (isBranchExist && typeof isBranchExist === 'object') {
|
|
207
|
+
cli_utilities_1.log.debug('Branch validation successful', this.config.cloneContext);
|
|
208
|
+
completeSpinner(`${isSource ? 'Source' : 'Target'} branch verified.!`);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
cli_utilities_1.log.error('Branch not found', this.config.cloneContext);
|
|
212
|
+
completeSpinner(`${isSource ? 'Source' : 'Target'} branch not found.!`, 'fail');
|
|
213
|
+
process.exit();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
completeSpinner(`${isSource ? 'Source' : 'Target'} branch not found.!`, 'fail');
|
|
218
|
+
throw e;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async resolveBranchAliases(isSource = false) {
|
|
222
|
+
try {
|
|
223
|
+
cli_utilities_1.log.debug('Resolving branch aliases', Object.assign(Object.assign({}, this.config.cloneContext), { isSource, alias: isSource ? this.config.sourceStackBranchAlias : this.config.targetStackBranchAlias }));
|
|
224
|
+
if (isSource) {
|
|
225
|
+
const sourceStack = this.client.stack({ api_key: this.config.source_stack });
|
|
226
|
+
this.config.sourceStackBranch = await (0, cli_utilities_1.getBranchFromAlias)(sourceStack, this.config.sourceStackBranchAlias);
|
|
227
|
+
cli_utilities_1.log.debug('Source branch alias resolved', Object.assign(Object.assign({}, this.config.cloneContext), { alias: this.config.sourceStackBranchAlias, branch: this.config.sourceStackBranch }));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
const targetStack = this.client.stack({ api_key: this.config.target_stack });
|
|
231
|
+
this.config.targetStackBranch = await (0, cli_utilities_1.getBranchFromAlias)(targetStack, this.config.targetStackBranchAlias);
|
|
232
|
+
cli_utilities_1.log.debug('Target branch alias resolved', Object.assign(Object.assign({}, this.config.cloneContext), { alias: this.config.targetStackBranchAlias, branch: this.config.targetStackBranch }));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async handleBranchSelection(options = {}) {
|
|
240
|
+
const { api_key, isSource = true, returnBranch = false } = options;
|
|
241
|
+
return new Promise(async (resolve, reject) => {
|
|
242
|
+
let spinner;
|
|
243
|
+
try {
|
|
244
|
+
cli_utilities_1.log.debug('Handling branch selection', Object.assign(Object.assign({}, this.config.cloneContext), { isSource, returnBranch, stackApiKey: isSource ? this.config.source_stack : this.config.target_stack }));
|
|
245
|
+
const stackAPIClient = this.client.stack({
|
|
246
|
+
api_key: isSource ? this.config.source_stack : this.config.target_stack,
|
|
247
|
+
management_token: this.config.management_token,
|
|
248
|
+
});
|
|
249
|
+
// NOTE validate if source branch is exist
|
|
250
|
+
if (isSource && this.config.sourceStackBranch) {
|
|
251
|
+
cli_utilities_1.log.debug('Validating source branch exists', Object.assign(Object.assign({}, this.config.cloneContext), { branch: this.config.sourceStackBranch }));
|
|
252
|
+
await this.validateIfBranchExist(stackAPIClient, true);
|
|
253
|
+
return resolve(undefined);
|
|
254
|
+
}
|
|
255
|
+
else if (isSource && this.config.sourceStackBranchAlias) {
|
|
256
|
+
cli_utilities_1.log.debug('Resolving source branch alias', Object.assign(Object.assign({}, this.config.cloneContext), { alias: this.config.sourceStackBranchAlias }));
|
|
257
|
+
await this.resolveBranchAliases(true);
|
|
258
|
+
return resolve(undefined);
|
|
259
|
+
}
|
|
260
|
+
// NOTE Validate target branch is exist
|
|
261
|
+
if (!isSource && this.config.targetStackBranch) {
|
|
262
|
+
cli_utilities_1.log.debug('Validating target branch exists', Object.assign(Object.assign({}, this.config.cloneContext), { branch: this.config.targetStackBranch }));
|
|
263
|
+
await this.validateIfBranchExist(stackAPIClient, false);
|
|
264
|
+
return resolve(undefined);
|
|
265
|
+
}
|
|
266
|
+
else if (!isSource && this.config.targetStackBranchAlias) {
|
|
267
|
+
cli_utilities_1.log.debug('Resolving target branch alias', Object.assign(Object.assign({}, this.config.cloneContext), { alias: this.config.targetStackBranchAlias }));
|
|
268
|
+
await this.resolveBranchAliases();
|
|
269
|
+
return resolve(undefined);
|
|
270
|
+
}
|
|
271
|
+
spinner = (0, ora_1.default)('Fetching Branches').start();
|
|
272
|
+
cli_utilities_1.log.debug(`Querying branches for stack: ${isSource ? this.config.source_stack : this.config.target_stack}`, this.config.cloneContext);
|
|
273
|
+
const result = await stackAPIClient
|
|
274
|
+
.branch()
|
|
275
|
+
.query()
|
|
276
|
+
.find()
|
|
277
|
+
.then(({ items }) => items)
|
|
278
|
+
.catch((_err) => { });
|
|
279
|
+
const condition = result && Array.isArray(result) && result.length > 0;
|
|
280
|
+
cli_utilities_1.log.debug(`Found ${(result === null || result === void 0 ? void 0 : result.length) || 0} branch(es)`, this.config.cloneContext);
|
|
281
|
+
// NOTE if want to get only list of branches (Pass param -> returnBranch = true )
|
|
282
|
+
if (returnBranch) {
|
|
283
|
+
resolve(condition ? result : []);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
if (condition) {
|
|
287
|
+
spinner.succeed('Fetched Branches');
|
|
288
|
+
const { branch } = await inquirer_1.default.prompt({
|
|
289
|
+
type: 'list',
|
|
290
|
+
name: 'branch',
|
|
291
|
+
message: 'Choose a branch',
|
|
292
|
+
choices: result.map((row) => row.uid),
|
|
293
|
+
});
|
|
294
|
+
if (this.executingCommand != 2) {
|
|
295
|
+
return reject();
|
|
296
|
+
}
|
|
297
|
+
if (isSource) {
|
|
298
|
+
this.config.sourceStackBranch = branch;
|
|
299
|
+
cli_utilities_1.log.debug(`Source branch selected: ${branch}`, this.config.cloneContext);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
this.config.targetStackBranch = branch;
|
|
303
|
+
cli_utilities_1.log.debug(`Target branch selected: ${branch}`, this.config.cloneContext);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
spinner.succeed('No branches found.!');
|
|
308
|
+
}
|
|
309
|
+
resolve(undefined);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
catch (e) {
|
|
313
|
+
if (spinner)
|
|
314
|
+
spinner.fail();
|
|
315
|
+
return reject(e);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
async executeStackPrompt(params = {}) {
|
|
320
|
+
try {
|
|
321
|
+
this.setExectingCommand(1);
|
|
322
|
+
const sourceStack = await this.cloneCommand.execute((0, command_helpers_1.HandleStackCommand)(params, this));
|
|
323
|
+
if (this.config.source_stack) {
|
|
324
|
+
await this.executeBranchPrompt(params);
|
|
325
|
+
}
|
|
326
|
+
// Update stackName default dynamically
|
|
327
|
+
this.stackNamePrompt.default = this.config.stackName || `Copy of ${sourceStack.stack || this.config.source_alias || 'ABC'}`;
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async executeBranchPrompt(parentParams) {
|
|
334
|
+
try {
|
|
335
|
+
this.setExectingCommand(2);
|
|
336
|
+
await this.cloneCommand.execute((0, command_helpers_1.HandleBranchCommand)({ api_key: this.config.source_stack }, this, this.executeStackPrompt.bind(this, parentParams)));
|
|
337
|
+
await this.executeExport();
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
async executeExport() {
|
|
344
|
+
try {
|
|
345
|
+
cli_utilities_1.log.debug('Executing export operation', this.config.cloneContext);
|
|
346
|
+
const exportRes = await this.cloneCommand.execute((0, command_helpers_1.HandleExportCommand)(null, this));
|
|
347
|
+
await this.cloneCommand.execute((0, command_helpers_1.SetBranchCommand)(null, this));
|
|
348
|
+
if (exportRes) {
|
|
349
|
+
cli_utilities_1.log.debug('Export operation completed, proceeding with destination', this.config.cloneContext);
|
|
350
|
+
this.executeDestination().catch(() => {
|
|
351
|
+
throw '';
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
this.removeBackKeyPressHandler();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
async execute() {
|
|
363
|
+
return new Promise(async (resolve, reject) => {
|
|
364
|
+
let keyPressHandler;
|
|
365
|
+
try {
|
|
366
|
+
cli_utilities_1.log.debug('Starting clone execution', Object.assign(Object.assign({}, this.config.cloneContext), { sourceStack: this.config.source_stack, targetStack: this.config.target_stack }));
|
|
367
|
+
if (!this.config.source_stack) {
|
|
368
|
+
const orgMsg = 'Choose an organization where your source stack exists:';
|
|
369
|
+
cli_utilities_1.log.debug('Source stack not provided, prompting for organization', this.config.cloneContext);
|
|
370
|
+
this.setExectingCommand(0);
|
|
371
|
+
this.removeBackKeyPressHandler();
|
|
372
|
+
const org = await this.cloneCommand.execute((0, command_helpers_1.HandleOrgCommand)({ msg: orgMsg, isSource: true }, this));
|
|
373
|
+
const self = this;
|
|
374
|
+
if (org) {
|
|
375
|
+
keyPressHandler = async function (_ch, key) {
|
|
376
|
+
// executingCommand is a tracking property to determine which method invoked this key press.
|
|
377
|
+
if (key.name === 'left' && key.shift) {
|
|
378
|
+
if (self.executingCommand === 1) {
|
|
379
|
+
self.setExectingCommand(3);
|
|
380
|
+
}
|
|
381
|
+
else if (self.executingCommand === 2) {
|
|
382
|
+
self.setExectingCommand(4);
|
|
383
|
+
}
|
|
384
|
+
self.config.source_stack = undefined;
|
|
385
|
+
self.config.sourceStackBranch = undefined;
|
|
386
|
+
if (self.executingCommand != 0) {
|
|
387
|
+
console.clear();
|
|
388
|
+
await self.cloneCommand.undo();
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
process.stdin.addListener('keypress', keyPressHandler);
|
|
393
|
+
this.setBackKeyPressHandler(keyPressHandler);
|
|
394
|
+
await this.executeStackPrompt({ org, isSource: true, msg: 'Select the source stack' });
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
return reject('Org not found.');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
cli_utilities_1.log.debug('Source stack provided, proceeding with branch selection and export', this.config.cloneContext);
|
|
402
|
+
this.setExectingCommand(2);
|
|
403
|
+
await this.handleBranchSelection({ api_key: this.config.source_stack });
|
|
404
|
+
cli_utilities_1.log.debug('Starting export operation', this.config.cloneContext);
|
|
405
|
+
const exportRes = await this.cloneCommand.execute((0, command_helpers_1.HandleExportCommand)(null, this));
|
|
406
|
+
await this.cloneCommand.execute((0, command_helpers_1.SetBranchCommand)(null, this));
|
|
407
|
+
if (exportRes) {
|
|
408
|
+
cli_utilities_1.log.debug('Export completed, proceeding with destination setup', this.config.cloneContext);
|
|
409
|
+
this.executeDestination().catch((error) => {
|
|
410
|
+
return reject(error);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
cli_utilities_1.log.debug('Clone execution completed successfully', this.config.cloneContext);
|
|
415
|
+
return resolve();
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
return reject(error);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
async executeDestination() {
|
|
423
|
+
return new Promise(async (resolve, reject) => {
|
|
424
|
+
let keyPressHandler;
|
|
425
|
+
try {
|
|
426
|
+
cli_utilities_1.log.debug('Executing destination setup', this.config.cloneContext);
|
|
427
|
+
let canCreateStack = false;
|
|
428
|
+
if (!this.config.target_stack) {
|
|
429
|
+
cli_utilities_1.log.debug('Target stack not provided, prompting for stack creation', this.config.cloneContext);
|
|
430
|
+
canCreateStack = await inquirer_1.default.prompt(constants_1.STACK_CREATION_CONFIRMATION);
|
|
431
|
+
}
|
|
432
|
+
this.setExectingCommand(0);
|
|
433
|
+
this.removeBackKeyPressHandler();
|
|
434
|
+
const orgMsgExistingStack = 'Choose an organization where the destination stack exists: ';
|
|
435
|
+
const orgMsgNewStack = 'Choose an organization where you want to create a stack: ';
|
|
436
|
+
let org;
|
|
437
|
+
if (!this.config.target_stack) {
|
|
438
|
+
org = await this.cloneCommand.execute((0, command_helpers_1.HandleOrgCommand)({
|
|
439
|
+
msg: !canCreateStack.stackCreate ? orgMsgExistingStack : orgMsgNewStack,
|
|
440
|
+
isSource: false,
|
|
441
|
+
}, this));
|
|
442
|
+
}
|
|
443
|
+
const params = { org, canCreateStack };
|
|
444
|
+
if (!this.config.target_stack) {
|
|
445
|
+
const self = this;
|
|
446
|
+
keyPressHandler = async function (_ch, key) {
|
|
447
|
+
if (key.name === 'left' && key.shift) {
|
|
448
|
+
if (self.executingCommand === 1) {
|
|
449
|
+
self.setExectingCommand(3);
|
|
450
|
+
}
|
|
451
|
+
else if (self.executingCommand === 2) {
|
|
452
|
+
self.setExectingCommand(4);
|
|
453
|
+
}
|
|
454
|
+
if (self.createNewStackPrompt) {
|
|
455
|
+
self.createNewStackPrompt.stop();
|
|
456
|
+
}
|
|
457
|
+
self.config.target_stack = undefined;
|
|
458
|
+
self.config.targetStackBranch = undefined;
|
|
459
|
+
if (self.executingCommand != 0) {
|
|
460
|
+
console.clear();
|
|
461
|
+
await self.cloneCommand.undo();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
process.stdin.addListener('keypress', keyPressHandler);
|
|
466
|
+
this.setBackKeyPressHandler(keyPressHandler);
|
|
467
|
+
await this.executeStackDestinationPrompt(params);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
await this.executeBranchDestinationPrompt(params);
|
|
471
|
+
}
|
|
472
|
+
cli_utilities_1.log.debug('Destination setup completed successfully', this.config.cloneContext);
|
|
473
|
+
return resolve();
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
reject(error);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
async executeStackDestinationPrompt(params) {
|
|
481
|
+
try {
|
|
482
|
+
this.setExectingCommand(1);
|
|
483
|
+
const { org, canCreateStack } = params;
|
|
484
|
+
if (!canCreateStack.stackCreate) {
|
|
485
|
+
const stackMsg = 'Choose the destination stack:';
|
|
486
|
+
await this.cloneCommand.execute((0, command_helpers_1.HandleDestinationStackCommand)({ org, msg: stackMsg, isSource: false }, this));
|
|
487
|
+
await this.executeBranchDestinationPrompt(params);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
const orgUid = this.orgUidList[org.Organization];
|
|
491
|
+
await this.cloneCommand.execute((0, command_helpers_1.CreateNewStackCommand)({ orgUid }, this));
|
|
492
|
+
this.removeBackKeyPressHandler();
|
|
493
|
+
await this.cloneCommand.execute((0, command_helpers_1.CloneTypeSelectionCommand)(null, this));
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
catch (error) {
|
|
497
|
+
throw error;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async executeBranchDestinationPrompt(parentParams) {
|
|
501
|
+
try {
|
|
502
|
+
this.setExectingCommand(2);
|
|
503
|
+
await this.cloneCommand.execute((0, command_helpers_1.HandleBranchCommand)({ isSource: false, api_key: this.config.target_stack }, this, this.executeStackDestinationPrompt.bind(this, parentParams)));
|
|
504
|
+
this.removeBackKeyPressHandler();
|
|
505
|
+
await this.cloneCommand.execute((0, command_helpers_1.CloneTypeSelectionCommand)(null, this));
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
throw error;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
async cmdExport() {
|
|
512
|
+
return new Promise((resolve, reject) => {
|
|
513
|
+
var _a;
|
|
514
|
+
cli_utilities_1.log.debug('Preparing export command', Object.assign(Object.assign({}, this.config.cloneContext), { sourceStack: this.config.source_stack, cloneType: this.config.cloneType }));
|
|
515
|
+
// Creating export specific config by merging external configurations
|
|
516
|
+
let exportConfig = Object.assign({}, (0, cloneDeep_1.default)(this.config), Object.assign({}, (_a = this.config) === null || _a === void 0 ? void 0 : _a.export));
|
|
517
|
+
delete exportConfig.import;
|
|
518
|
+
delete exportConfig.export;
|
|
519
|
+
// Resolve path to package root - go up 3 levels from __dirname (core/util -> package root)
|
|
520
|
+
const packageRoot = path.resolve(__dirname, '../../..');
|
|
521
|
+
const exportDir = path.join(packageRoot, 'contents');
|
|
522
|
+
cli_utilities_1.log.debug(`Export directory: ${exportDir}`, this.config.cloneContext);
|
|
523
|
+
const cmd = ['-k', exportConfig.source_stack, '-d', exportDir];
|
|
524
|
+
if (exportConfig.cloneType === 'a') {
|
|
525
|
+
exportConfig.filteredModules = ['stack'].concat(constants_1.STRUCTURE_LIST);
|
|
526
|
+
cli_utilities_1.log.debug(`Filtered modules for structure-only export: ${exportConfig.filteredModules.join(', ')}`, this.config.cloneContext);
|
|
527
|
+
}
|
|
528
|
+
if (exportConfig.source_alias) {
|
|
529
|
+
cmd.push('-a', exportConfig.source_alias);
|
|
530
|
+
cli_utilities_1.log.debug(`Using source alias: ${exportConfig.source_alias}`, this.config.cloneContext);
|
|
531
|
+
}
|
|
532
|
+
if (exportConfig.sourceStackBranch) {
|
|
533
|
+
cmd.push('--branch', exportConfig.sourceStackBranch);
|
|
534
|
+
cli_utilities_1.log.debug(`Using source branch: ${exportConfig.sourceStackBranch}`, this.config.cloneContext);
|
|
535
|
+
}
|
|
536
|
+
if (exportConfig.forceStopMarketplaceAppsPrompt) {
|
|
537
|
+
cmd.push('-y');
|
|
538
|
+
cli_utilities_1.log.debug('Force stop marketplace apps prompt enabled', this.config.cloneContext);
|
|
539
|
+
}
|
|
540
|
+
// dummyConfig.json is in the same directory as this file
|
|
541
|
+
const configFilePath = path.join(__dirname, 'dummyConfig.json');
|
|
542
|
+
cmd.push('-c');
|
|
543
|
+
cmd.push(configFilePath);
|
|
544
|
+
cli_utilities_1.log.debug(`Writing export config to: ${configFilePath}`, this.config.cloneContext);
|
|
545
|
+
fs.writeFileSync(configFilePath, JSON.stringify(exportConfig));
|
|
546
|
+
cli_utilities_1.log.debug('Export command prepared', Object.assign(Object.assign({}, this.config.cloneContext), { cmd: cmd.join(' '), exportDir, sourceStack: exportConfig.source_stack, branch: exportConfig.sourceStackBranch }));
|
|
547
|
+
cli_utilities_1.log.debug('Running export command', Object.assign(Object.assign({}, this.config.cloneContext), { cmd }));
|
|
548
|
+
const exportData = cli_cm_export_1.default.run(cmd);
|
|
549
|
+
exportData.then(() => {
|
|
550
|
+
cli_utilities_1.log.debug('Export command completed successfully', this.config.cloneContext);
|
|
551
|
+
resolve(true);
|
|
552
|
+
}).catch((error) => {
|
|
553
|
+
reject(error);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
async cmdImport() {
|
|
558
|
+
return new Promise(async (resolve, _reject) => {
|
|
559
|
+
var _a;
|
|
560
|
+
cli_utilities_1.log.debug('Preparing import command', Object.assign(Object.assign({}, this.config.cloneContext), { targetStack: this.config.target_stack, targetBranch: this.config.targetStackBranch }));
|
|
561
|
+
// Creating export specific config by merging external configurations
|
|
562
|
+
let importConfig = Object.assign({}, (0, cloneDeep_1.default)(this.config), Object.assign({}, (_a = this.config) === null || _a === void 0 ? void 0 : _a.import));
|
|
563
|
+
delete importConfig.import;
|
|
564
|
+
delete importConfig.export;
|
|
565
|
+
// dummyConfig.json is in the same directory as this file
|
|
566
|
+
const configFilePath = path.join(__dirname, 'dummyConfig.json');
|
|
567
|
+
const cmd = ['-c', configFilePath];
|
|
568
|
+
if (importConfig.destination_alias) {
|
|
569
|
+
cmd.push('-a', importConfig.destination_alias);
|
|
570
|
+
cli_utilities_1.log.debug(`Using destination alias: ${importConfig.destination_alias}`, this.config.cloneContext);
|
|
571
|
+
}
|
|
572
|
+
if (!importConfig.data && importConfig.sourceStackBranch && importConfig.pathDir) {
|
|
573
|
+
const dataPath = path.join(importConfig.pathDir, importConfig.sourceStackBranch);
|
|
574
|
+
cmd.push('-d', dataPath);
|
|
575
|
+
cli_utilities_1.log.debug(`Import data path: ${dataPath}`, this.config.cloneContext);
|
|
576
|
+
}
|
|
577
|
+
if (importConfig.targetStackBranch) {
|
|
578
|
+
cmd.push('--branch', importConfig.targetStackBranch);
|
|
579
|
+
cli_utilities_1.log.debug(`Using target branch: ${importConfig.targetStackBranch}`, this.config.cloneContext);
|
|
580
|
+
}
|
|
581
|
+
if (importConfig.importWebhookStatus) {
|
|
582
|
+
cmd.push('--import-webhook-status', importConfig.importWebhookStatus);
|
|
583
|
+
cli_utilities_1.log.debug(`Import webhook status: ${importConfig.importWebhookStatus}`, this.config.cloneContext);
|
|
584
|
+
}
|
|
585
|
+
if (importConfig.skipAudit) {
|
|
586
|
+
cmd.push('--skip-audit');
|
|
587
|
+
cli_utilities_1.log.debug('Skip audit flag enabled', this.config.cloneContext);
|
|
588
|
+
}
|
|
589
|
+
if (importConfig.forceStopMarketplaceAppsPrompt) {
|
|
590
|
+
cmd.push('-y');
|
|
591
|
+
cli_utilities_1.log.debug('Force stop marketplace apps prompt enabled', this.config.cloneContext);
|
|
592
|
+
}
|
|
593
|
+
cli_utilities_1.log.debug(`Writing import config to: ${configFilePath}`, this.config.cloneContext);
|
|
594
|
+
fs.writeFileSync(configFilePath, JSON.stringify(importConfig));
|
|
595
|
+
cli_utilities_1.log.debug('Import command prepared', Object.assign(Object.assign({}, this.config.cloneContext), { cmd: cmd.join(' '), targetStack: importConfig.target_stack, targetBranch: importConfig.targetStackBranch, dataPath: importConfig.data || (importConfig.pathDir && importConfig.sourceStackBranch ? path.join(importConfig.pathDir, importConfig.sourceStackBranch) : undefined) }));
|
|
596
|
+
cli_utilities_1.log.debug('Running import command', Object.assign(Object.assign({}, this.config.cloneContext), { cmd }));
|
|
597
|
+
const importData = cli_cm_import_1.default.run(cmd);
|
|
598
|
+
importData.then(() => {
|
|
599
|
+
cli_utilities_1.log.debug('Import command completed successfully', this.config.cloneContext);
|
|
600
|
+
cli_utilities_1.log.debug('Clearing import config file', this.config.cloneContext);
|
|
601
|
+
fs.writeFileSync(configFilePath, JSON.stringify({}));
|
|
602
|
+
resolve();
|
|
603
|
+
}).catch((error) => {
|
|
604
|
+
cli_utilities_1.log.error('Import command failed', Object.assign(Object.assign({}, this.config.cloneContext), { error }));
|
|
605
|
+
throw error;
|
|
606
|
+
});
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
setCreateNewStackPrompt(createNewStackPrompt) {
|
|
610
|
+
this.createNewStackPrompt = createNewStackPrompt;
|
|
611
|
+
}
|
|
612
|
+
async setBranch() {
|
|
613
|
+
if (!this.config.sourceStackBranch) {
|
|
614
|
+
try {
|
|
615
|
+
const branches = await this.client
|
|
616
|
+
.stack({ api_key: this.config.source_stack })
|
|
617
|
+
.branch()
|
|
618
|
+
.query()
|
|
619
|
+
.find()
|
|
620
|
+
.catch((_err) => { });
|
|
621
|
+
if (branches && branches.items && branches.items.length) {
|
|
622
|
+
this.config.sourceStackBranch = 'main';
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
catch (_error) {
|
|
626
|
+
// Ignore error
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
getNewStackPromptResult() {
|
|
631
|
+
return new Promise((resolve) => {
|
|
632
|
+
prompt.get({
|
|
633
|
+
properties: {
|
|
634
|
+
name: { description: safe_1.default.white(this.stackNamePrompt.message), default: safe_1.default.grey(this.stackNamePrompt.default) },
|
|
635
|
+
},
|
|
636
|
+
}, function (_, result) {
|
|
637
|
+
if (prompt.stopped) {
|
|
638
|
+
prompt.stopped = false;
|
|
639
|
+
resolve(undefined);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
let _name = result.name.replace(/\[\d+m/g, '');
|
|
643
|
+
_name = _name.replace(//g, '');
|
|
644
|
+
resolve({ stack: _name });
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
async createNewStack(options) {
|
|
650
|
+
return new Promise(async (resolve, reject) => {
|
|
651
|
+
try {
|
|
652
|
+
const { orgUid } = options;
|
|
653
|
+
cli_utilities_1.log.debug('Creating new stack', Object.assign(Object.assign({}, this.config.cloneContext), { orgUid, masterLocale: this.master_locale, stackName: this.config.stackName }));
|
|
654
|
+
this.displayBackOptionMessage();
|
|
655
|
+
let inputvalue;
|
|
656
|
+
if (!this.config.stackName) {
|
|
657
|
+
cli_utilities_1.log.debug('Stack name not provided, prompting user', this.config.cloneContext);
|
|
658
|
+
prompt.start();
|
|
659
|
+
prompt.message = '';
|
|
660
|
+
this.setCreateNewStackPrompt(prompt);
|
|
661
|
+
inputvalue = await this.getNewStackPromptResult();
|
|
662
|
+
this.setCreateNewStackPrompt(null);
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
inputvalue = { stack: this.config.stackName };
|
|
666
|
+
}
|
|
667
|
+
if (this.executingCommand === 0 || !inputvalue) {
|
|
668
|
+
cli_utilities_1.log.debug('Stack creation cancelled or invalid input', this.config.cloneContext);
|
|
669
|
+
return reject();
|
|
670
|
+
}
|
|
671
|
+
let stack = { name: inputvalue.stack, master_locale: this.master_locale };
|
|
672
|
+
cli_utilities_1.log.debug('Creating stack with configuration', this.config.cloneContext);
|
|
673
|
+
const spinner = (0, ora_1.default)('Creating New stack').start();
|
|
674
|
+
cli_utilities_1.log.debug('Sending stack creation API request', this.config.cloneContext);
|
|
675
|
+
const newStack = this.client.stack().create({ stack }, { organization_uid: orgUid });
|
|
676
|
+
newStack
|
|
677
|
+
.then((result) => {
|
|
678
|
+
cli_utilities_1.log.debug('Stack created successfully', Object.assign(Object.assign({}, this.config.cloneContext), { stackName: result.name }));
|
|
679
|
+
spinner.succeed('New Stack created Successfully name as ' + result.name);
|
|
680
|
+
this.config.target_stack = result.api_key;
|
|
681
|
+
this.config.destinationStackName = result.name;
|
|
682
|
+
cli_utilities_1.log.debug('Target stack configuration updated', this.config.cloneContext);
|
|
683
|
+
return resolve(result);
|
|
684
|
+
})
|
|
685
|
+
.catch((error) => {
|
|
686
|
+
spinner.fail();
|
|
687
|
+
return reject(error.errorMessage + ' Contact the Organization owner for Stack Creation access.');
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
catch (error) {
|
|
691
|
+
return reject(error);
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
async cloneTypeSelection() {
|
|
696
|
+
console.clear();
|
|
697
|
+
return new Promise(async (resolve, reject) => {
|
|
698
|
+
try {
|
|
699
|
+
cli_utilities_1.log.debug('Starting clone type selection', this.config.cloneContext);
|
|
700
|
+
const choices = [
|
|
701
|
+
'Structure (all modules except entries & assets)',
|
|
702
|
+
'Structure with content (all modules including entries & assets)',
|
|
703
|
+
];
|
|
704
|
+
const cloneTypeSelection = [
|
|
705
|
+
{
|
|
706
|
+
choices,
|
|
707
|
+
type: 'list',
|
|
708
|
+
name: 'type',
|
|
709
|
+
message: 'Choose the type of data to clone:',
|
|
710
|
+
},
|
|
711
|
+
];
|
|
712
|
+
let successMsg;
|
|
713
|
+
let selectedValue = {};
|
|
714
|
+
// Resolve path to package root - go up 3 levels from __dirname (core/util -> package root)
|
|
715
|
+
const cloneTypePackageRoot = path.resolve(__dirname, '../../..');
|
|
716
|
+
this.config.data = path.join(cloneTypePackageRoot, 'contents', this.config.sourceStackBranch || '');
|
|
717
|
+
cli_utilities_1.log.debug(`Clone data directory: ${this.config.data}`, this.config.cloneContext);
|
|
718
|
+
if (!this.config.cloneType) {
|
|
719
|
+
cli_utilities_1.log.debug('Clone type not specified, prompting user for selection', this.config.cloneContext);
|
|
720
|
+
selectedValue = await inquirer_1.default.prompt(cloneTypeSelection);
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
cli_utilities_1.log.debug(`Using pre-configured clone type: ${this.config.cloneType}`, this.config.cloneContext);
|
|
724
|
+
}
|
|
725
|
+
if (this.config.cloneType === 'a' || selectedValue.type === 'Structure (all modules except entries & assets)') {
|
|
726
|
+
this.config.modules = constants_1.STRUCTURE_LIST;
|
|
727
|
+
successMsg = 'Stack clone Structure completed';
|
|
728
|
+
cli_utilities_1.log.debug(`Clone type: Structure only. Modules to clone: ${constants_1.STRUCTURE_LIST.join(', ')}`, this.config.cloneContext);
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
successMsg = 'Stack clone completed with structure and content';
|
|
732
|
+
cli_utilities_1.log.debug('Clone type: Structure with content (all modules)', this.config.cloneContext);
|
|
733
|
+
}
|
|
734
|
+
this.cmdImport()
|
|
735
|
+
.then(async () => {
|
|
736
|
+
cli_utilities_1.log.debug('Clone type selection and import completed successfully', this.config.cloneContext);
|
|
737
|
+
// Clean up contents directory after import completes
|
|
738
|
+
if (this.config.pathDir) {
|
|
739
|
+
const resolvedPath = path.resolve(this.config.pathDir);
|
|
740
|
+
cli_utilities_1.log.debug('Cleaning up contents directory after import', Object.assign(Object.assign({}, this.config.cloneContext), { pathDir: this.config.pathDir, resolvedPath }));
|
|
741
|
+
try {
|
|
742
|
+
await (0, rimraf_1.rimraf)(resolvedPath);
|
|
743
|
+
cli_utilities_1.log.debug('Contents directory cleaned up successfully', Object.assign(Object.assign({}, this.config.cloneContext), { pathDir: this.config.pathDir, resolvedPath }));
|
|
744
|
+
}
|
|
745
|
+
catch (cleanupError) {
|
|
746
|
+
cli_utilities_1.log.debug('Cleanup error (non-fatal)', Object.assign(Object.assign({}, this.config.cloneContext), { pathDir: this.config.pathDir, resolvedPath, error: cleanupError === null || cleanupError === void 0 ? void 0 : cleanupError.message, code: cleanupError === null || cleanupError === void 0 ? void 0 : cleanupError.code }));
|
|
747
|
+
// Don't fail the clone if cleanup fails
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
cli_utilities_1.log.debug('No pathDir configured, skipping cleanup', this.config.cloneContext);
|
|
752
|
+
}
|
|
753
|
+
resolve(successMsg);
|
|
754
|
+
})
|
|
755
|
+
.catch(reject);
|
|
756
|
+
}
|
|
757
|
+
catch (error) {
|
|
758
|
+
reject(error);
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
exports.CloneHandler = CloneHandler;
|