@contentstack/cli-cm-clone 1.15.0 → 1.16.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 +5 -1
- package/package.json +5 -5
- package/src/commands/cm/stacks/clone.js +28 -3
- package/src/lib/util/clone-handler.js +29 -7
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone
|
|
|
16
16
|
$ csdx COMMAND
|
|
17
17
|
running command...
|
|
18
18
|
$ csdx (--version)
|
|
19
|
-
@contentstack/cli-cm-clone/1.15.0 darwin-arm64 node-
|
|
19
|
+
@contentstack/cli-cm-clone/1.15.0 darwin-arm64 node-v22.13.1
|
|
20
20
|
$ csdx --help [COMMAND]
|
|
21
21
|
USAGE
|
|
22
22
|
$ csdx COMMAND
|
|
@@ -62,9 +62,11 @@ FLAGS
|
|
|
62
62
|
--skip-audit (optional) Skips the audit fix that occurs during an import
|
|
63
63
|
operation.
|
|
64
64
|
--source-branch=<value> Branch of the source stack.
|
|
65
|
+
--source-branch-alias=<value> Alias of Branch of the source stack.
|
|
65
66
|
--source-management-token-alias=<value> Source management token alias.
|
|
66
67
|
--source-stack-api-key=<value> Source stack API key
|
|
67
68
|
--target-branch=<value> Branch of the target stack.
|
|
69
|
+
--target-branch-alias=<value> Alias of Branch of the target stack.
|
|
68
70
|
--type=<option> Type of data to clone. You can select option a or b.
|
|
69
71
|
a) Structure (all modules except entries & assets).
|
|
70
72
|
b) Structure with content (all modules including entries & assets).
|
|
@@ -115,9 +117,11 @@ FLAGS
|
|
|
115
117
|
--skip-audit (optional) Skips the audit fix that occurs during an import
|
|
116
118
|
operation.
|
|
117
119
|
--source-branch=<value> Branch of the source stack.
|
|
120
|
+
--source-branch-alias=<value> Alias of Branch of the source stack.
|
|
118
121
|
--source-management-token-alias=<value> Source management token alias.
|
|
119
122
|
--source-stack-api-key=<value> Source stack API key
|
|
120
123
|
--target-branch=<value> Branch of the target stack.
|
|
124
|
+
--target-branch-alias=<value> Alias of Branch of the target stack.
|
|
121
125
|
--type=<option> Type of data to clone. You can select option a or b.
|
|
122
126
|
a) Structure (all modules except entries & assets).
|
|
123
127
|
b) Structure with content (all modules including entries & assets).
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-clone",
|
|
3
3
|
"description": "Contentstack stack clone plugin",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.16.0",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@colors/colors": "^1.6.0",
|
|
9
|
-
"@contentstack/cli-cm-export": "~1.
|
|
10
|
-
"@contentstack/cli-cm-import": "~1.
|
|
11
|
-
"@contentstack/cli-command": "~1.6.
|
|
12
|
-
"@contentstack/cli-utilities": "~1.
|
|
9
|
+
"@contentstack/cli-cm-export": "~1.20.0",
|
|
10
|
+
"@contentstack/cli-cm-import": "~1.27.0",
|
|
11
|
+
"@contentstack/cli-command": "~1.6.1",
|
|
12
|
+
"@contentstack/cli-utilities": "~1.14.0",
|
|
13
13
|
"@oclif/core": "^4.3.0",
|
|
14
14
|
"@oclif/plugin-help": "^6.2.28",
|
|
15
15
|
"chalk": "^4.1.2",
|
|
@@ -18,7 +18,9 @@ class StackCloneCommand extends Command {
|
|
|
18
18
|
type: cloneType,
|
|
19
19
|
'stack-name': stackName,
|
|
20
20
|
'source-branch': sourceStackBranch,
|
|
21
|
+
'source-branch-alias': sourceStackBranchAlias,
|
|
21
22
|
'target-branch': targetStackBranch,
|
|
23
|
+
'target-branch-alias': targetStackBranchAlias,
|
|
22
24
|
'source-stack-api-key': sourceStackApiKey,
|
|
23
25
|
'destination-stack-api-key': destinationStackApiKey,
|
|
24
26
|
'source-management-token-alias': sourceManagementTokenAlias,
|
|
@@ -47,8 +49,14 @@ class StackCloneCommand extends Command {
|
|
|
47
49
|
if (sourceStackBranch) {
|
|
48
50
|
config.sourceStackBranch = sourceStackBranch;
|
|
49
51
|
}
|
|
52
|
+
if (sourceStackBranchAlias) {
|
|
53
|
+
config.sourceStackBranchAlias = sourceStackBranchAlias;
|
|
54
|
+
}
|
|
50
55
|
if (targetStackBranch) {
|
|
51
56
|
config.targetStackBranch = targetStackBranch;
|
|
57
|
+
}
|
|
58
|
+
if (targetStackBranchAlias) {
|
|
59
|
+
config.targetStackBranchAlias = targetStackBranchAlias;
|
|
52
60
|
}
|
|
53
61
|
if (sourceStackApiKey) {
|
|
54
62
|
config.source_stack = sourceStackApiKey;
|
|
@@ -74,6 +82,8 @@ class StackCloneCommand extends Command {
|
|
|
74
82
|
config.importWebhookStatus = importWebhookStatus;
|
|
75
83
|
}
|
|
76
84
|
|
|
85
|
+
const managementAPIClient = await managementSDKClient(config);
|
|
86
|
+
|
|
77
87
|
await this.removeContentDirIfNotEmptyBeforeClone(pathdir); // NOTE remove if folder not empty before clone
|
|
78
88
|
this.registerCleanupOnInterrupt(pathdir);
|
|
79
89
|
|
|
@@ -82,7 +92,6 @@ class StackCloneCommand extends Command {
|
|
|
82
92
|
config.cdn = this.cdaHost;
|
|
83
93
|
config.pathDir = pathdir;
|
|
84
94
|
const cloneHandler = new CloneHandler(config);
|
|
85
|
-
const managementAPIClient = await managementSDKClient(config);
|
|
86
95
|
cloneHandler.setClient(managementAPIClient);
|
|
87
96
|
cloneHandler.execute().catch((error) => {
|
|
88
97
|
console.log(error);
|
|
@@ -115,6 +124,8 @@ class StackCloneCommand extends Command {
|
|
|
115
124
|
}
|
|
116
125
|
}
|
|
117
126
|
|
|
127
|
+
|
|
128
|
+
|
|
118
129
|
async removeContentDirIfNotEmptyBeforeClone(dir) {
|
|
119
130
|
try {
|
|
120
131
|
const dirNotEmpty = readdirSync(dir).length;
|
|
@@ -202,11 +213,25 @@ StackCloneCommand.flags = {
|
|
|
202
213
|
required: false,
|
|
203
214
|
multiple: false,
|
|
204
215
|
description: 'Branch of the source stack.',
|
|
216
|
+
exclusive: ['source-branch-alias']
|
|
217
|
+
}),
|
|
218
|
+
'source-branch-alias': flags.string({
|
|
219
|
+
required: false,
|
|
220
|
+
multiple: false,
|
|
221
|
+
description: 'Alias of Branch of the source stack.',
|
|
222
|
+
exclusive: ['source-branch']
|
|
205
223
|
}),
|
|
206
224
|
'target-branch': flags.string({
|
|
207
225
|
required: false,
|
|
208
226
|
multiple: false,
|
|
209
227
|
description: 'Branch of the target stack.',
|
|
228
|
+
exclusive: ['target-branch-alias']
|
|
229
|
+
}),
|
|
230
|
+
'target-branch-alias': flags.string({
|
|
231
|
+
required: false,
|
|
232
|
+
multiple: false,
|
|
233
|
+
description: 'Alias of Branch of the target stack.',
|
|
234
|
+
exclusive: ['target-branch']
|
|
210
235
|
}),
|
|
211
236
|
'source-management-token-alias': flags.string({
|
|
212
237
|
required: false,
|
|
@@ -229,8 +254,8 @@ StackCloneCommand.flags = {
|
|
|
229
254
|
multiple: false,
|
|
230
255
|
options: ['a', 'b'],
|
|
231
256
|
description: ` Type of data to clone. You can select option a or b.
|
|
232
|
-
a) Structure (all modules except entries & assets).
|
|
233
|
-
b) Structure with content (all modules including entries & assets).
|
|
257
|
+
a) Structure (all modules except entries & assets).
|
|
258
|
+
b) Structure with content (all modules including entries & assets).
|
|
234
259
|
`,
|
|
235
260
|
}),
|
|
236
261
|
'source-stack-api-key': flags.string({
|
|
@@ -8,7 +8,7 @@ let { default: importCmd } = require('@contentstack/cli-cm-import');
|
|
|
8
8
|
const { CustomAbortController } = require('./abort-controller');
|
|
9
9
|
const prompt = require('prompt');
|
|
10
10
|
const colors = require('@colors/colors/safe');
|
|
11
|
-
const cloneDeep = require(
|
|
11
|
+
const cloneDeep = require('lodash/cloneDeep');
|
|
12
12
|
|
|
13
13
|
const {
|
|
14
14
|
HandleOrgCommand,
|
|
@@ -21,7 +21,7 @@ const {
|
|
|
21
21
|
Clone,
|
|
22
22
|
HandleBranchCommand,
|
|
23
23
|
} = require('../helpers/command-helpers');
|
|
24
|
-
const { configHandler } = require('@contentstack/cli-utilities')
|
|
24
|
+
const { configHandler, getBranchFromAlias } = require('@contentstack/cli-utilities');
|
|
25
25
|
|
|
26
26
|
let client = {};
|
|
27
27
|
let config;
|
|
@@ -137,7 +137,7 @@ class CloneHandler {
|
|
|
137
137
|
let spinner;
|
|
138
138
|
try {
|
|
139
139
|
const stackAPIClient = client.stack({
|
|
140
|
-
api_key:
|
|
140
|
+
api_key: isSource ? config.source_stack : config.target_stack,
|
|
141
141
|
management_token: config.management_token,
|
|
142
142
|
});
|
|
143
143
|
|
|
@@ -145,12 +145,18 @@ class CloneHandler {
|
|
|
145
145
|
if (isSource && config.sourceStackBranch) {
|
|
146
146
|
await this.validateIfBranchExist(stackAPIClient, true);
|
|
147
147
|
return resolve();
|
|
148
|
+
} else if(isSource && config.sourceStackBranchAlias) {
|
|
149
|
+
await this.resolveBranchAliases(true);
|
|
150
|
+
return resolve();
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
// NOTE Validate target branch is exist
|
|
151
154
|
if (!isSource && config.targetStackBranch) {
|
|
152
155
|
await this.validateIfBranchExist(stackAPIClient, false);
|
|
153
156
|
return resolve();
|
|
157
|
+
} else if (!isSource && config.targetStackBranchAlias) {
|
|
158
|
+
await this.resolveBranchAliases();
|
|
159
|
+
return resolve();
|
|
154
160
|
}
|
|
155
161
|
spinner = ora('Fetching Branches').start();
|
|
156
162
|
const result = await stackAPIClient
|
|
@@ -272,6 +278,8 @@ class CloneHandler {
|
|
|
272
278
|
return reject('Org not found.');
|
|
273
279
|
}
|
|
274
280
|
} else {
|
|
281
|
+
this.setExectingCommand(2);
|
|
282
|
+
await this.handleBranchSelection({ api_key: config.sourceStack });
|
|
275
283
|
const exportRes = await cloneCommand.execute(new HandleExportCommand(null, this));
|
|
276
284
|
await cloneCommand.execute(new SetBranchCommand(null, this));
|
|
277
285
|
|
|
@@ -471,7 +479,7 @@ class CloneHandler {
|
|
|
471
479
|
} else {
|
|
472
480
|
organizations = await client.organization().fetchAll({ limit: 100 });
|
|
473
481
|
}
|
|
474
|
-
|
|
482
|
+
|
|
475
483
|
spinner.succeed('Fetched Organization');
|
|
476
484
|
for (const element of organizations.items || [organizations]) {
|
|
477
485
|
orgUidList[element.name] = element.uid;
|
|
@@ -579,6 +587,20 @@ class CloneHandler {
|
|
|
579
587
|
});
|
|
580
588
|
}
|
|
581
589
|
|
|
590
|
+
async resolveBranchAliases(isSource = false) {
|
|
591
|
+
try {
|
|
592
|
+
if (isSource) {
|
|
593
|
+
const sourceStack = client.stack({ api_key: config.source_stack });
|
|
594
|
+
config.sourceStackBranch = await getBranchFromAlias(sourceStack, config.sourceStackBranchAlias);
|
|
595
|
+
} else {
|
|
596
|
+
const targetStack = client.stack({ api_key: config.target_stack });
|
|
597
|
+
config.targetStackBranch = await getBranchFromAlias(targetStack, config.targetStackBranchAlias);
|
|
598
|
+
}
|
|
599
|
+
} catch (error) {
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
582
604
|
async cloneTypeSelection() {
|
|
583
605
|
console.clear();
|
|
584
606
|
return new Promise(async (resolve, reject) => {
|
|
@@ -618,7 +640,7 @@ class CloneHandler {
|
|
|
618
640
|
async cmdExport() {
|
|
619
641
|
return new Promise((resolve, reject) => {
|
|
620
642
|
// Creating export specific config by merging external configurations
|
|
621
|
-
let exportConfig = Object.assign({}, cloneDeep(config), {...config?.export});
|
|
643
|
+
let exportConfig = Object.assign({}, cloneDeep(config), { ...config?.export });
|
|
622
644
|
delete exportConfig.import;
|
|
623
645
|
delete exportConfig.export;
|
|
624
646
|
|
|
@@ -648,7 +670,7 @@ class CloneHandler {
|
|
|
648
670
|
async cmdImport() {
|
|
649
671
|
return new Promise(async (resolve, _reject) => {
|
|
650
672
|
// Creating export specific config by merging external configurations
|
|
651
|
-
let importConfig = Object.assign({}, cloneDeep(config), {...config?.import});
|
|
673
|
+
let importConfig = Object.assign({}, cloneDeep(config), { ...config?.import });
|
|
652
674
|
delete importConfig.import;
|
|
653
675
|
delete importConfig.export;
|
|
654
676
|
|
|
@@ -673,7 +695,7 @@ class CloneHandler {
|
|
|
673
695
|
|
|
674
696
|
fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify(importConfig));
|
|
675
697
|
await importCmd.run(cmd);
|
|
676
|
-
fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify({}))
|
|
698
|
+
fs.writeFileSync(path.join(__dirname, 'dummyConfig.json'), JSON.stringify({}));
|
|
677
699
|
return resolve();
|
|
678
700
|
});
|
|
679
701
|
}
|