@contentstack/cli-cm-clone 1.4.8 → 1.4.9
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/oclif.manifest.json +1 -1
- package/package.json +7 -5
- package/src/lib/util/clone-handler.js +112 -80
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-clone
|
|
|
15
15
|
$ csdx COMMAND
|
|
16
16
|
running command...
|
|
17
17
|
$ csdx (--version)
|
|
18
|
-
@contentstack/cli-cm-clone/1.4.
|
|
18
|
+
@contentstack/cli-cm-clone/1.4.9 linux-x64 node-v16.20.0
|
|
19
19
|
$ csdx --help [COMMAND]
|
|
20
20
|
USAGE
|
|
21
21
|
$ csdx COMMAND
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-clone",
|
|
3
3
|
"description": "Contentstack stack clone plugin",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.9",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@
|
|
9
|
-
"@contentstack/cli-cm-
|
|
10
|
-
"@contentstack/cli-
|
|
11
|
-
"@contentstack/cli-
|
|
8
|
+
"@colors/colors": "^1.5.0",
|
|
9
|
+
"@contentstack/cli-cm-export": "^1.5.9",
|
|
10
|
+
"@contentstack/cli-cm-import": "^1.5.9",
|
|
11
|
+
"@contentstack/cli-command": "^1.2.9",
|
|
12
|
+
"@contentstack/cli-utilities": "^1.4.5",
|
|
12
13
|
"async": "^3.2.4",
|
|
13
14
|
"chalk": "^4.1.0",
|
|
14
15
|
"child_process": "^1.0.2",
|
|
15
16
|
"fancy-test": "^1.4.10",
|
|
16
17
|
"inquirer": "8.2.4",
|
|
17
18
|
"ora": "^5.1.0",
|
|
19
|
+
"prompt": "^1.3.0",
|
|
18
20
|
"rimraf": "^3.0.2",
|
|
19
21
|
"winston": "^3.7.2"
|
|
20
22
|
},
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const ora = require('ora');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const inquirer = require('inquirer');
|
|
4
|
-
const rimraf = require('rimraf');
|
|
5
4
|
const chalk = require('chalk');
|
|
5
|
+
const prompt = require('prompt');
|
|
6
|
+
const colors = require('@colors/colors/safe');
|
|
6
7
|
|
|
7
8
|
let exportCmd = require('@contentstack/cli-cm-export');
|
|
8
9
|
let importCmd = require('@contentstack/cli-cm-import');
|
|
9
|
-
const { CustomAbortController } = require('./abort-controller');
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
HandleOrgCommand,
|
|
@@ -57,6 +57,16 @@ let structureList = [
|
|
|
57
57
|
];
|
|
58
58
|
let master_locale;
|
|
59
59
|
|
|
60
|
+
// Overrides prompt's stop method
|
|
61
|
+
prompt.stop = function () {
|
|
62
|
+
if (prompt.stopped) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
prompt.emit('stop');
|
|
66
|
+
prompt.stopped = true;
|
|
67
|
+
return prompt;
|
|
68
|
+
};
|
|
69
|
+
|
|
60
70
|
class CloneHandler {
|
|
61
71
|
constructor(opt) {
|
|
62
72
|
config = opt;
|
|
@@ -124,7 +134,7 @@ class CloneHandler {
|
|
|
124
134
|
let spinner;
|
|
125
135
|
try {
|
|
126
136
|
const stackAPIClient = client.stack({
|
|
127
|
-
api_key: config.source_stack,
|
|
137
|
+
api_key: config.target_stack ? config.target_stack : config.source_stack,
|
|
128
138
|
management_token: config.management_token,
|
|
129
139
|
});
|
|
130
140
|
|
|
@@ -208,12 +218,6 @@ class CloneHandler {
|
|
|
208
218
|
throw e;
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
|
-
setAbortController(abortController) {
|
|
212
|
-
this.abortController = abortController;
|
|
213
|
-
}
|
|
214
|
-
abort() {
|
|
215
|
-
this.abortController && this.abortController.abort();
|
|
216
|
-
}
|
|
217
221
|
displayBackOptionMessage() {
|
|
218
222
|
const ui = new inquirer.ui.BottomBar();
|
|
219
223
|
ui.updateBottomBar(chalk.cyan('\nPress shift & left arrow together to undo the operation\n'));
|
|
@@ -252,7 +256,6 @@ class CloneHandler {
|
|
|
252
256
|
config.source_stack = null;
|
|
253
257
|
config.sourceStackBranch = null;
|
|
254
258
|
if (self.executingCommand != 0) {
|
|
255
|
-
self.abort();
|
|
256
259
|
console.clear();
|
|
257
260
|
await cloneCommand.undo();
|
|
258
261
|
}
|
|
@@ -261,8 +264,7 @@ class CloneHandler {
|
|
|
261
264
|
process.stdin.addListener('keypress', keyPressHandler);
|
|
262
265
|
this.setBackKeyPressHandler(keyPressHandler);
|
|
263
266
|
|
|
264
|
-
|
|
265
|
-
await this.executeStackPrompt(params);
|
|
267
|
+
await this.executeStackPrompt({ org, isSource: true, msg: 'Select the source stack' });
|
|
266
268
|
} else {
|
|
267
269
|
return reject('Org not found.');
|
|
268
270
|
}
|
|
@@ -312,7 +314,7 @@ class CloneHandler {
|
|
|
312
314
|
await cloneCommand.execute(new SetBranchCommand(null, this));
|
|
313
315
|
|
|
314
316
|
if (exportRes) {
|
|
315
|
-
this.executeDestination().catch(() =>
|
|
317
|
+
this.executeDestination().catch(() => { throw ''; });
|
|
316
318
|
}
|
|
317
319
|
} catch (error) {
|
|
318
320
|
throw error;
|
|
@@ -323,61 +325,95 @@ class CloneHandler {
|
|
|
323
325
|
|
|
324
326
|
async executeDestination() {
|
|
325
327
|
return new Promise(async (resolve, reject) => {
|
|
326
|
-
let
|
|
328
|
+
let keyPressHandler;
|
|
327
329
|
try {
|
|
328
|
-
stackAbortController = new CustomAbortController();
|
|
329
|
-
|
|
330
330
|
let canCreateStack = false;
|
|
331
|
-
|
|
332
331
|
if (!config.target_stack) {
|
|
333
332
|
canCreateStack = await inquirer.prompt(stackCreationConfirmation);
|
|
334
333
|
}
|
|
335
334
|
|
|
336
335
|
this.setExectingCommand(0);
|
|
337
|
-
|
|
338
|
-
if (!config.target_stack) {
|
|
339
|
-
const orgMsg = 'Choose an organization where the destination stack exists: ';
|
|
340
|
-
const org = await cloneCommand.execute(new HandleOrgCommand({ msg: orgMsg }, this));
|
|
341
|
-
|
|
342
|
-
if (org) {
|
|
343
|
-
const stackMsg = 'Choose the destination stack:';
|
|
344
|
-
await cloneCommand.execute(
|
|
345
|
-
new HandleDestinationStackCommand({ org, msg: stackMsg, stackAbortController, isSource: false }, this),
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
336
|
+
this.removeBackKeyPressHandler();
|
|
349
337
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
338
|
+
const orgMsgExistingStack = 'Choose an organization where the destination stack exists: ';
|
|
339
|
+
const orgMsgNewStack = 'Choose an organization where you want to create a stack: ';
|
|
340
|
+
|
|
341
|
+
let org;
|
|
342
|
+
if (!config.target_stack) {
|
|
343
|
+
org = await cloneCommand.execute(new HandleOrgCommand({
|
|
344
|
+
msg: !canCreateStack.stackCreate ? orgMsgExistingStack : orgMsgNewStack
|
|
345
|
+
}, this));
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const params = { org, canCreateStack };
|
|
349
|
+
if (!config.target_stack) {
|
|
350
|
+
let self = this;
|
|
351
|
+
keyPressHandler = async function (_ch, key) {
|
|
352
|
+
if (key.name === 'left' && key.shift) {
|
|
353
|
+
if (self.executingCommand === 1) {
|
|
354
|
+
self.setExectingCommand(3);
|
|
355
|
+
} else if (self.executingCommand === 2) {
|
|
356
|
+
self.setExectingCommand(4);
|
|
357
|
+
}
|
|
358
|
+
if (self.createNewStackPrompt) {
|
|
359
|
+
self.createNewStackPrompt.stop();
|
|
360
|
+
}
|
|
361
|
+
config.target_stack = null;
|
|
362
|
+
config.targetStackBranch = null;
|
|
363
|
+
if (self.executingCommand != 0) {
|
|
364
|
+
console.clear();
|
|
365
|
+
await cloneCommand.undo();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
process.stdin.addListener('keypress', keyPressHandler);
|
|
370
|
+
this.setBackKeyPressHandler(keyPressHandler);
|
|
371
|
+
await this.executeStackDestinationPrompt(params);
|
|
356
372
|
} else {
|
|
357
|
-
|
|
358
|
-
const destinationOrg = await cloneCommand.execute(new HandleOrgCommand({ msg: orgMsg }, this));
|
|
359
|
-
const orgUid = orgUidList[destinationOrg.Organization];
|
|
360
|
-
await cloneCommand.execute(new CreateNewStackCommand({ orgUid, stackAbortController }, this));
|
|
373
|
+
await this.executeBranchDestinationPrompt(params);
|
|
361
374
|
}
|
|
362
|
-
|
|
375
|
+
|
|
363
376
|
return resolve();
|
|
364
377
|
} catch (error) {
|
|
365
|
-
console.log(error);
|
|
366
|
-
stackAbortController.signal.aborted = true;
|
|
367
378
|
reject(error);
|
|
368
|
-
} finally {
|
|
369
|
-
// If not aborted and ran successfully
|
|
370
|
-
if (!stackAbortController.signal.aborted) {
|
|
371
|
-
// Call clean dir.
|
|
372
|
-
rimraf(this.pathDir, function () {
|
|
373
|
-
// eslint-disable-next-line no-console
|
|
374
|
-
console.log('Stack cloning process have been completed successfully');
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
379
|
}
|
|
378
380
|
});
|
|
379
381
|
}
|
|
380
382
|
|
|
383
|
+
async executeStackDestinationPrompt(params) {
|
|
384
|
+
try {
|
|
385
|
+
this.setExectingCommand(1);
|
|
386
|
+
const { org, canCreateStack } = params;
|
|
387
|
+
if (!canCreateStack.stackCreate) {
|
|
388
|
+
const stackMsg = 'Choose the destination stack:';
|
|
389
|
+
await cloneCommand.execute(new HandleDestinationStackCommand({ org, msg: stackMsg, isSource: false }, this));
|
|
390
|
+
this.executeBranchDestinationPrompt(params);
|
|
391
|
+
} else {
|
|
392
|
+
const orgUid = orgUidList[org.Organization];
|
|
393
|
+
await cloneCommand.execute(new CreateNewStackCommand({ orgUid }, this));
|
|
394
|
+
this.removeBackKeyPressHandler();
|
|
395
|
+
await cloneCommand.execute(new CloneTypeSelectionCommand(null, this));
|
|
396
|
+
}
|
|
397
|
+
} catch (error) {
|
|
398
|
+
throw error;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
async executeBranchDestinationPrompt(parentParams) {
|
|
403
|
+
try {
|
|
404
|
+
this.setExectingCommand(2);
|
|
405
|
+
await cloneCommand.execute(new HandleBranchCommand({ isSource: false, api_key: config.target_stack }, this, this.executeStackDestinationPrompt.bind(this, parentParams)));
|
|
406
|
+
this.removeBackKeyPressHandler();
|
|
407
|
+
await cloneCommand.execute(new CloneTypeSelectionCommand(null, this));
|
|
408
|
+
} catch (error) {
|
|
409
|
+
throw error;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
setCreateNewStackPrompt(createNewStackPrompt) {
|
|
414
|
+
this.createNewStackPrompt = createNewStackPrompt;
|
|
415
|
+
}
|
|
416
|
+
|
|
381
417
|
async setBranch() {
|
|
382
418
|
if (!config.sourceStackBranch) {
|
|
383
419
|
try {
|
|
@@ -453,38 +489,21 @@ class CloneHandler {
|
|
|
453
489
|
}
|
|
454
490
|
|
|
455
491
|
async createNewStack(options) {
|
|
456
|
-
let keyPressHandler;
|
|
457
492
|
return new Promise(async (resolve, reject) => {
|
|
458
493
|
try {
|
|
459
|
-
const { orgUid
|
|
494
|
+
const { orgUid } = options;
|
|
495
|
+
this.displayBackOptionMessage();
|
|
460
496
|
let inputvalue;
|
|
461
|
-
let uiPromise;
|
|
462
|
-
|
|
463
|
-
keyPressHandler = async function (_ch, key) {
|
|
464
|
-
if (key.name === 'left' && key.shift) {
|
|
465
|
-
stackAbortController.abort();
|
|
466
|
-
// We need to close the inquirer promise correctly, otherwise the unclosed question/answer text is displayed in next line.
|
|
467
|
-
if (uiPromise) {
|
|
468
|
-
uiPromise.ui.close();
|
|
469
|
-
}
|
|
470
|
-
console.clear();
|
|
471
|
-
process.stdin.removeListener('keypress', keyPressHandler);
|
|
472
|
-
await cloneCommand.undo();
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
process.stdin.addListener('keypress', keyPressHandler);
|
|
476
|
-
|
|
477
|
-
const ui = new inquirer.ui.BottomBar();
|
|
478
|
-
ui.updateBottomBar(chalk.cyan('\nPress shift & left arrow together to undo the operation\n'));
|
|
479
|
-
|
|
480
497
|
if (!config.stackName) {
|
|
481
|
-
|
|
482
|
-
|
|
498
|
+
prompt.start();
|
|
499
|
+
prompt.message = '';
|
|
500
|
+
this.setCreateNewStackPrompt(prompt);
|
|
501
|
+
inputvalue = await this.getNewStackPromptResult();
|
|
502
|
+
this.setCreateNewStackPrompt(null);
|
|
483
503
|
} else {
|
|
484
504
|
inputvalue = { stack: config.stackName };
|
|
485
505
|
}
|
|
486
|
-
|
|
487
|
-
if (stackAbortController.signal.aborted) {
|
|
506
|
+
if (this.executingCommand === 0 || !inputvalue) {
|
|
488
507
|
return reject();
|
|
489
508
|
}
|
|
490
509
|
|
|
@@ -504,15 +523,28 @@ class CloneHandler {
|
|
|
504
523
|
});
|
|
505
524
|
} catch (error) {
|
|
506
525
|
return reject(error);
|
|
507
|
-
} finally {
|
|
508
|
-
if (keyPressHandler) {
|
|
509
|
-
process.stdin.removeListener('keypress', keyPressHandler);
|
|
510
|
-
}
|
|
511
526
|
}
|
|
512
527
|
});
|
|
513
528
|
}
|
|
514
529
|
|
|
530
|
+
getNewStackPromptResult() {
|
|
531
|
+
return new Promise((resolve) => {
|
|
532
|
+
prompt.get({ properties: { name: { description: colors.white(stackName.message), default: colors.grey(stackName.default), } } },
|
|
533
|
+
function (_, result) {
|
|
534
|
+
if (prompt.stopped) {
|
|
535
|
+
prompt.stopped = false;
|
|
536
|
+
resolve();
|
|
537
|
+
} else {
|
|
538
|
+
let _name = result.name.replace(/\[\d+m/g, '');
|
|
539
|
+
_name = _name.replace(//g, '');
|
|
540
|
+
resolve({ stack: _name });
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
515
546
|
async cloneTypeSelection() {
|
|
547
|
+
console.clear();
|
|
516
548
|
return new Promise(async (resolve, reject) => {
|
|
517
549
|
const choices = [
|
|
518
550
|
'Structure (all modules except entries & assets)',
|