@contentstack/cli-cm-clone 0.1.0-beta.6 → 1.1.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/LICENSE +21 -0
- package/README.md +5 -5
- package/package.json +19 -13
- package/src/commands/cm/stacks/clone.js +249 -0
- package/src/lib/helpers/command-helpers.js +67 -0
- package/src/lib/util/abort-controller.js +49 -0
- package/src/lib/util/clone-handler.js +439 -190
- package/src/lib/util/contentstack-management-sdk.js +10 -11
- package/src/lib/util/log.js +32 -27
- package/src/commands/cm/stack-clone.js +0 -102
|
@@ -1,255 +1,504 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
const ora = require('ora');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const inquirer = require('inquirer');
|
|
4
|
+
const rimraf = require('rimraf');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
let exportCmd = require('@contentstack/cli-cm-export');
|
|
8
|
+
let importCmd = require('@contentstack/cli-cm-import');
|
|
9
|
+
const { HttpClient, chooseLocalePrompt } = require('@contentstack/cli-utilities');
|
|
10
|
+
let sdkInstance = require('../../lib/util/contentstack-management-sdk');
|
|
11
|
+
const defaultConfig = require('@contentstack/cli-cm-export/src/config/default');
|
|
12
|
+
const { CustomAbortController } = require('./abort-controller');
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
HandleOrgCommand, HandleStackCommand, HandleDestinationStackCommand, HandleExportCommand,
|
|
16
|
+
SetBranchCommand, CreateNewStackCommand, CloneTypeSelectionCommand, Clone, HandleBranchCommand
|
|
17
|
+
} = require('../helpers/command-helpers');
|
|
18
|
+
|
|
19
|
+
let client = {};
|
|
20
|
+
let config;
|
|
21
|
+
let cloneCommand;
|
|
22
|
+
|
|
23
|
+
let stackCreationConfirmation = [
|
|
24
|
+
{
|
|
25
|
+
type: 'confirm',
|
|
26
|
+
name: 'stackCreate',
|
|
27
|
+
message: 'Want to clone content into a new stack ?',
|
|
28
|
+
initial: true,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
21
31
|
|
|
22
32
|
let stackName = {
|
|
23
33
|
type: 'input',
|
|
24
34
|
name: 'stack',
|
|
35
|
+
default: 'ABC',
|
|
25
36
|
message: 'Enter name for the new stack to store the cloned content ?',
|
|
26
|
-
|
|
27
|
-
}
|
|
37
|
+
};
|
|
28
38
|
|
|
29
|
-
let orgUidList = {}
|
|
30
|
-
let stackUidList = {}
|
|
31
|
-
let masterLocaleList = {}
|
|
39
|
+
let orgUidList = {};
|
|
40
|
+
let stackUidList = {};
|
|
41
|
+
let masterLocaleList = {};
|
|
32
42
|
|
|
33
|
-
let structureList = [
|
|
43
|
+
let structureList = [
|
|
44
|
+
'locales',
|
|
34
45
|
'environments',
|
|
35
46
|
'extensions',
|
|
47
|
+
'marketplace-apps',
|
|
36
48
|
'webhooks',
|
|
37
49
|
'global-fields',
|
|
38
50
|
'content-types',
|
|
39
51
|
'workflows',
|
|
40
|
-
'labels'
|
|
41
|
-
|
|
42
|
-
let master_locale
|
|
52
|
+
'labels',
|
|
53
|
+
];
|
|
54
|
+
let master_locale;
|
|
43
55
|
|
|
44
56
|
class CloneHandler {
|
|
45
57
|
constructor(opt) {
|
|
46
|
-
config = opt
|
|
47
|
-
client = sdkInstance.Client(config)
|
|
58
|
+
config = opt;
|
|
59
|
+
client = sdkInstance.Client(config);
|
|
60
|
+
cloneCommand = new Clone();
|
|
61
|
+
this.pathDir = opt.pathDir;
|
|
62
|
+
process.stdin.setMaxListeners(50);
|
|
48
63
|
}
|
|
49
64
|
|
|
50
|
-
|
|
65
|
+
handleOrgSelection(options = {}) {
|
|
51
66
|
return new Promise(async (resolve, reject) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
67
|
+
const { msg = '', isSource = true } = options || {};
|
|
68
|
+
const orgList = await this.getOrganizationChoices(msg).catch(reject);
|
|
69
|
+
|
|
70
|
+
if (orgList) {
|
|
71
|
+
const orgSelected = await inquirer.prompt(orgList);
|
|
72
|
+
|
|
73
|
+
if (isSource) {
|
|
74
|
+
config.sourceOrg = orgUidList[orgSelected.Organization];
|
|
75
|
+
} else {
|
|
76
|
+
config.targetOrg = orgUidList[orgSelected.Organization];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
resolve(orgSelected);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handleStackSelection(options = {}) {
|
|
85
|
+
let keyPressHandler;
|
|
86
|
+
return new Promise(async (resolve, reject) => {
|
|
87
|
+
try {
|
|
88
|
+
const { org = {}, msg = '', isSource = true, stackAbortController } = options || {}
|
|
89
|
+
|
|
90
|
+
keyPressHandler = async function (_ch, key) {
|
|
91
|
+
if (key.name === 'backspace') {
|
|
92
|
+
stackAbortController.abort();
|
|
93
|
+
console.clear();
|
|
94
|
+
process.stdin.removeListener('keypress', keyPressHandler);
|
|
95
|
+
await cloneCommand.undo();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
process.stdin.addListener('keypress', keyPressHandler);
|
|
99
|
+
|
|
100
|
+
const stackList = await this.getStack(org, msg, isSource).catch(reject)
|
|
101
|
+
|
|
102
|
+
if (stackList) {
|
|
103
|
+
const ui = new inquirer.ui.BottomBar();
|
|
104
|
+
// Use chalk to prettify the text.
|
|
105
|
+
ui.updateBottomBar(chalk.cyan('\nFor undo operation press backspace\n'));
|
|
106
|
+
|
|
107
|
+
const selectedStack = await inquirer.prompt(stackList);
|
|
108
|
+
|
|
109
|
+
if (stackAbortController.signal.aborted) {
|
|
110
|
+
return reject();
|
|
111
|
+
}
|
|
112
|
+
if (isSource) {
|
|
113
|
+
config.sourceStackName = selectedStack.stack;
|
|
114
|
+
master_locale = masterLocaleList[selectedStack.stack];
|
|
115
|
+
config.source_stack = stackUidList[selectedStack.stack];
|
|
116
|
+
} else {
|
|
117
|
+
config.target_stack = stackUidList[selectedStack.stack];
|
|
118
|
+
config.destinationStackName = selectedStack.stack;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
resolve(selectedStack)
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
return reject(error);
|
|
125
|
+
} finally {
|
|
126
|
+
if (keyPressHandler) {
|
|
127
|
+
process.stdin.removeListener('keypress', keyPressHandler);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
handleBranchSelection = async (options) => {
|
|
134
|
+
const { api_key, isSource = true, returnBranch = false } = options
|
|
135
|
+
const baseUrl = defaultConfig.host.startsWith('http')
|
|
136
|
+
? defaultConfig.host
|
|
137
|
+
: `https://${defaultConfig.host}/v3`;
|
|
138
|
+
|
|
139
|
+
return new Promise(async (resolve, reject) => {
|
|
140
|
+
try {
|
|
141
|
+
const headers = { api_key }
|
|
142
|
+
|
|
143
|
+
if (config.auth_token) {
|
|
144
|
+
headers['authtoken'] = config.auth_token
|
|
145
|
+
} else if (config.management_token) {
|
|
146
|
+
headers['authorization'] = config.management_token
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// NOTE validate if source branch is exist
|
|
150
|
+
if (isSource && config.sourceStackBranch) {
|
|
151
|
+
await this.validateIfBranchExist(headers, true)
|
|
152
|
+
return resolve()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// NOTE Validate target branch is exist
|
|
156
|
+
if (!isSource && config.targetStackBranch) {
|
|
157
|
+
await this.validateIfBranchExist(headers, false)
|
|
158
|
+
return resolve()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const spinner = ora('Fetching Branches').start();
|
|
162
|
+
const result = await new HttpClient()
|
|
163
|
+
.headers(headers)
|
|
164
|
+
.get(`${baseUrl}/stacks/branches`)
|
|
165
|
+
.then(({ data: { branches } }) => branches)
|
|
166
|
+
|
|
167
|
+
const condition = (
|
|
168
|
+
result &&
|
|
169
|
+
Array.isArray(result) &&
|
|
170
|
+
result.length > 0
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
// NOTE if want to get only list of branches (Pass param -> returnBranch = true )
|
|
174
|
+
if (returnBranch) {
|
|
175
|
+
resolve(condition ? result : [])
|
|
176
|
+
} else {
|
|
177
|
+
// NOTE list options to use to select branch
|
|
178
|
+
if (condition) {
|
|
179
|
+
spinner.succeed('Fetched Branches');
|
|
180
|
+
const { branch } = await inquirer.prompt({
|
|
181
|
+
type: 'list',
|
|
182
|
+
name: 'branch',
|
|
183
|
+
message: 'Choose a branch',
|
|
184
|
+
choices: result.map(row => row.uid),
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (isSource) {
|
|
188
|
+
config.sourceStackBranch = branch
|
|
189
|
+
} else {
|
|
190
|
+
config.targetStackBranch = branch
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
spinner.succeed('No branches found.!');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
resolve()
|
|
197
|
+
}
|
|
198
|
+
} catch (e) {
|
|
199
|
+
spinner.fail();
|
|
200
|
+
console.log(e && e.message)
|
|
201
|
+
resolve()
|
|
202
|
+
}
|
|
123
203
|
})
|
|
124
204
|
}
|
|
125
205
|
|
|
126
|
-
|
|
206
|
+
async validateIfBranchExist(headers, isSource) {
|
|
207
|
+
const branch = isSource ? config.sourceStackBranch : config.targetStackBranch
|
|
208
|
+
const spinner = ora(`Validation if ${isSource ? 'source' : 'target'} branch exist.!`).start();
|
|
209
|
+
const isBranchExist = await HttpClient.create()
|
|
210
|
+
.headers(headers)
|
|
211
|
+
.get(`https://${config.host}/v3/stacks/branches/${branch}`)
|
|
212
|
+
.then(({ data }) => data);
|
|
213
|
+
|
|
214
|
+
const completeSpinner = (msg, method = 'succeed') => {
|
|
215
|
+
spinner[method](msg)
|
|
216
|
+
spinner.stop()
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (isBranchExist && typeof isBranchExist === 'object' && typeof isBranchExist.branch === 'object') {
|
|
220
|
+
completeSpinner(`${isSource ? 'Source' : 'Target'} branch verified.!`)
|
|
221
|
+
} else {
|
|
222
|
+
completeSpinner(`${isSource ? 'Source' : 'Target'} branch not found.!`, 'fail')
|
|
223
|
+
process.exit()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
execute() {
|
|
228
|
+
return new Promise(async (resolve, reject) => {
|
|
229
|
+
let stackAbortController;
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
if (!config.source_stack) {
|
|
233
|
+
const orgMsg = 'Choose an organization where your source stack exists:';
|
|
234
|
+
const stackMsg = 'Select the source stack';
|
|
235
|
+
|
|
236
|
+
stackAbortController = new CustomAbortController();
|
|
237
|
+
|
|
238
|
+
const org = await cloneCommand.execute(new HandleOrgCommand({ msg: orgMsg, isSource: true }, this));
|
|
239
|
+
if (org) {
|
|
240
|
+
const sourceStack = await cloneCommand.execute(new HandleStackCommand({ org, isSource: true, msg: stackMsg, stackAbortController }, this));
|
|
241
|
+
|
|
242
|
+
if (config.source_stack) {
|
|
243
|
+
if (!(config.master_locale && config.master_locale.code)) {
|
|
244
|
+
|
|
245
|
+
const res = await chooseLocalePrompt(client.stack({ api_key: config.source_stack }), 'Choose Master Locale', master_locale)
|
|
246
|
+
master_locale = res.code
|
|
247
|
+
config.master_locale = res
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
master_locale = config.master_locale.code
|
|
251
|
+
}
|
|
252
|
+
await cloneCommand.execute(
|
|
253
|
+
new HandleBranchCommand({ api_key: config.source_stack }, this)
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (stackAbortController.signal.aborted) {
|
|
258
|
+
return reject();
|
|
259
|
+
}
|
|
260
|
+
stackName.default = config.stackName || `Copy of ${sourceStack.stack || config.source_alias}`;
|
|
261
|
+
} else {
|
|
262
|
+
return reject('Org not found.');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const exportRes = await cloneCommand.execute(new HandleExportCommand(null, this));
|
|
266
|
+
await cloneCommand.execute(new SetBranchCommand(null, this));
|
|
267
|
+
|
|
268
|
+
if (exportRes) {
|
|
269
|
+
this.executeDestination().catch(() => { reject(); });
|
|
270
|
+
}
|
|
271
|
+
return resolve();
|
|
272
|
+
} catch (error) {
|
|
273
|
+
return reject(error);
|
|
274
|
+
} finally {
|
|
275
|
+
if (stackAbortController) {
|
|
276
|
+
stackAbortController.abort();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async executeDestination() {
|
|
283
|
+
return new Promise(async (resolve, reject) => {
|
|
284
|
+
let stackAbortController;
|
|
285
|
+
try {
|
|
286
|
+
stackAbortController = new CustomAbortController();
|
|
287
|
+
|
|
288
|
+
let canCreateStack = false;
|
|
289
|
+
|
|
290
|
+
if (!config.target_stack) {
|
|
291
|
+
canCreateStack = await inquirer.prompt(stackCreationConfirmation);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!canCreateStack.stackCreate) {
|
|
295
|
+
if (!config.target_stack) {
|
|
296
|
+
const orgMsg = 'Choose an organization where the destination stack exists: ';
|
|
297
|
+
const org = await cloneCommand.execute(new HandleOrgCommand({ msg: orgMsg }, this));
|
|
298
|
+
|
|
299
|
+
if (org) {
|
|
300
|
+
const stackMsg = 'Choose the destination stack:';
|
|
301
|
+
await cloneCommand.execute(new HandleDestinationStackCommand({ org, msg: stackMsg, stackAbortController, isSource: false }, this));
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// NOTE GET list of branches if branches enabled
|
|
306
|
+
if (config.target_stack) {
|
|
307
|
+
await cloneCommand.execute(new HandleBranchCommand({ isSource: false, api_key: config.target_stack }, this));
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
const destinationOrg = await this.handleOrgSelection({ isSource: false, msg: 'Choose an organization where you want to create a stack: ' });
|
|
311
|
+
const orgUid = orgUidList[destinationOrg.Organization];
|
|
312
|
+
await cloneCommand.execute(new CreateNewStackCommand(orgUid, this));
|
|
313
|
+
}
|
|
314
|
+
await cloneCommand.execute(new CloneTypeSelectionCommand(null, this));
|
|
315
|
+
return resolve();
|
|
316
|
+
} catch (error) {
|
|
317
|
+
reject(error);
|
|
318
|
+
} finally {
|
|
319
|
+
// If not aborted and ran successfully
|
|
320
|
+
if (!stackAbortController.signal.aborted) {
|
|
321
|
+
// Call clean dir.
|
|
322
|
+
rimraf(this.pathDir, function () {
|
|
323
|
+
// eslint-disable-next-line no-console
|
|
324
|
+
console.log('Stack cloning process have been completed successfully');
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async setBranch() {
|
|
332
|
+
if (!config.sourceStackBranch) {
|
|
333
|
+
try {
|
|
334
|
+
const branches = await client.stack({ api_key: config.source_stack }).branch().query().find();
|
|
335
|
+
|
|
336
|
+
if (branches && branches.items && branches.items.length) {
|
|
337
|
+
config.sourceStackBranch = 'main';
|
|
338
|
+
}
|
|
339
|
+
} catch (_error) { }
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async getOrganizationChoices(orgMessage) {
|
|
127
344
|
let orgChoice = {
|
|
128
345
|
type: 'list',
|
|
129
346
|
name: 'Organization',
|
|
130
|
-
message:
|
|
347
|
+
message: orgMessage !== undefined ? orgMessage : 'Choose an organization',
|
|
131
348
|
choices: [],
|
|
132
|
-
}
|
|
349
|
+
};
|
|
133
350
|
return new Promise(async (resolve, reject) => {
|
|
134
|
-
const spinner = ora(
|
|
351
|
+
const spinner = ora('Fetching Organization').start();
|
|
135
352
|
try {
|
|
136
|
-
let organizations = await client.organization().fetchAll({ limit: 100 })
|
|
137
|
-
spinner.succeed(
|
|
138
|
-
for (
|
|
139
|
-
orgUidList[
|
|
140
|
-
orgChoice.choices.push(
|
|
353
|
+
let organizations = await client.organization().fetchAll({ limit: 100 });
|
|
354
|
+
spinner.succeed('Fetched Organization');
|
|
355
|
+
for (const element of organizations.items) {
|
|
356
|
+
orgUidList[element.name] = element.uid;
|
|
357
|
+
orgChoice.choices.push(element.name);
|
|
141
358
|
}
|
|
142
|
-
return resolve(orgChoice)
|
|
359
|
+
return resolve(orgChoice);
|
|
143
360
|
} catch (e) {
|
|
144
|
-
spinner.fail()
|
|
145
|
-
return reject(e)
|
|
361
|
+
spinner.fail();
|
|
362
|
+
return reject(e);
|
|
146
363
|
}
|
|
147
|
-
})
|
|
148
|
-
}
|
|
364
|
+
});
|
|
365
|
+
};
|
|
149
366
|
|
|
150
|
-
|
|
367
|
+
async getStack(answer, stkMessage) {
|
|
151
368
|
return new Promise(async (resolve, reject) => {
|
|
152
369
|
let stackChoice = {
|
|
153
370
|
type: 'list',
|
|
154
371
|
name: 'stack',
|
|
155
|
-
message: stkMessage,
|
|
156
|
-
message: stkMessage !== undefined ? stkMessage : "Select the stack",
|
|
372
|
+
message: stkMessage !== undefined ? stkMessage : 'Select the stack',
|
|
157
373
|
choices: [],
|
|
158
|
-
}
|
|
159
|
-
const spinner = ora('Fetching stacks').start()
|
|
374
|
+
};
|
|
375
|
+
const spinner = ora('Fetching stacks').start();
|
|
160
376
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
377
|
+
const organization_uid = orgUidList[answer.Organization];
|
|
378
|
+
const stackList = client.stack().query({ organization_uid }).find();
|
|
163
379
|
stackList
|
|
164
|
-
.then(
|
|
165
|
-
for (
|
|
166
|
-
stackUidList[
|
|
167
|
-
masterLocaleList[
|
|
168
|
-
stackChoice.choices.push(
|
|
380
|
+
.then((stacklist) => {
|
|
381
|
+
for (const element of stacklist.items) {
|
|
382
|
+
stackUidList[element.name] = element.api_key;
|
|
383
|
+
masterLocaleList[element.name] = element.master_locale;
|
|
384
|
+
stackChoice.choices.push(element.name);
|
|
169
385
|
}
|
|
170
|
-
spinner.succeed(
|
|
171
|
-
return resolve(stackChoice)
|
|
172
|
-
}).catch(error => {
|
|
173
|
-
spinner.fail()
|
|
174
|
-
return reject(error)
|
|
386
|
+
spinner.succeed('Fetched stack');
|
|
387
|
+
return resolve(stackChoice);
|
|
175
388
|
})
|
|
389
|
+
.catch((error) => {
|
|
390
|
+
spinner.fail();
|
|
391
|
+
return reject(error);
|
|
392
|
+
});
|
|
176
393
|
} catch (e) {
|
|
177
|
-
spinner.fail()
|
|
178
|
-
return reject(e)
|
|
394
|
+
spinner.fail();
|
|
395
|
+
return reject(e);
|
|
179
396
|
}
|
|
180
|
-
})
|
|
181
|
-
}
|
|
397
|
+
});
|
|
398
|
+
};
|
|
182
399
|
|
|
183
400
|
async createNewStack(orgUid) {
|
|
184
401
|
return new Promise(async (resolve, reject) => {
|
|
185
|
-
let inputvalue
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
402
|
+
let inputvalue;
|
|
403
|
+
|
|
404
|
+
if (!config.stackName) {
|
|
405
|
+
inputvalue = await inquirer.prompt(stackName);
|
|
406
|
+
} else {
|
|
407
|
+
inputvalue = { stack: config.stackName };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
let stack = { name: inputvalue.stack, master_locale: master_locale };
|
|
411
|
+
const spinner = ora('Creating New stack').start();
|
|
412
|
+
let newStack = client.stack().create({ stack }, { organization_uid: orgUid });
|
|
189
413
|
newStack
|
|
190
|
-
.then(result => {
|
|
191
|
-
spinner.succeed(
|
|
192
|
-
config.target_stack = result.api_key
|
|
193
|
-
config.destinationStackName = result.name
|
|
194
|
-
return resolve(result)
|
|
195
|
-
}).catch(error => {
|
|
196
|
-
spinner.fail()
|
|
197
|
-
return reject(error)
|
|
414
|
+
.then((result) => {
|
|
415
|
+
spinner.succeed('New Stack created Successfully name as ' + result.name);
|
|
416
|
+
config.target_stack = result.api_key;
|
|
417
|
+
config.destinationStackName = result.name;
|
|
418
|
+
return resolve(result);
|
|
198
419
|
})
|
|
199
|
-
|
|
420
|
+
.catch((error) => {
|
|
421
|
+
spinner.fail();
|
|
422
|
+
return reject(error.errorMessage + ' Contact the Organization owner for Stack Creation access.');
|
|
423
|
+
});
|
|
424
|
+
});
|
|
200
425
|
}
|
|
201
426
|
|
|
202
427
|
async cloneTypeSelection() {
|
|
203
428
|
return new Promise(async (resolve, reject) => {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
429
|
+
const choices = [
|
|
430
|
+
'Structure (all modules except entries & assets)',
|
|
431
|
+
'Structure with content (all modules including entries & assets)',
|
|
432
|
+
];
|
|
433
|
+
const cloneTypeSelection = [
|
|
434
|
+
{
|
|
435
|
+
choices,
|
|
436
|
+
type: 'list',
|
|
437
|
+
name: 'type',
|
|
438
|
+
message: 'Choose the type of data to clone:',
|
|
439
|
+
},
|
|
440
|
+
];
|
|
441
|
+
let successMsg;
|
|
442
|
+
let selectedValue = {};
|
|
443
|
+
config['data'] = path.join(__dirname.split('src')[0], 'contents', config.sourceStackBranch || '');
|
|
444
|
+
|
|
445
|
+
if (!config.cloneType) {
|
|
446
|
+
selectedValue = await inquirer.prompt(cloneTypeSelection);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (config.cloneType === 'a' || selectedValue.type === 'Structure (all modules except entries & assets)') {
|
|
450
|
+
config['modules'] = structureList;
|
|
451
|
+
successMsg = 'Stack clone Structure completed';
|
|
223
452
|
} else {
|
|
224
|
-
|
|
225
|
-
cmdImport.then(() => {
|
|
226
|
-
return resolve("Stack clone completed with structure and content")
|
|
227
|
-
}).catch((error) => {
|
|
228
|
-
return reject(error)
|
|
229
|
-
})
|
|
453
|
+
successMsg = 'Stack clone completed with structure and content';
|
|
230
454
|
}
|
|
231
|
-
|
|
455
|
+
|
|
456
|
+
this.cmdImport()
|
|
457
|
+
.then(() => resolve(successMsg))
|
|
458
|
+
.catch(reject);
|
|
459
|
+
});
|
|
232
460
|
}
|
|
233
461
|
|
|
234
462
|
async cmdExport() {
|
|
235
463
|
return new Promise((resolve, reject) => {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
464
|
+
const cmd = ['-k', config.source_stack, '-d', __dirname.split('src')[0] + 'contents'];
|
|
465
|
+
|
|
466
|
+
if (config.source_alias) {
|
|
467
|
+
cmd.push('-a', config.source_alias);
|
|
468
|
+
}
|
|
469
|
+
if (config.sourceStackBranch) {
|
|
470
|
+
cmd.push('--branch', config.sourceStackBranch);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
let exportData = exportCmd.run(cmd);
|
|
474
|
+
exportData.then(() => resolve(true)).catch(reject);
|
|
475
|
+
});
|
|
243
476
|
}
|
|
244
477
|
|
|
245
478
|
async cmdImport() {
|
|
246
|
-
return new Promise(async (resolve,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
479
|
+
return new Promise(async (resolve, _reject) => {
|
|
480
|
+
const cmd = ['-c', path.join(__dirname, 'dummyConfig.json')];
|
|
481
|
+
|
|
482
|
+
if (config.destination_alias) {
|
|
483
|
+
cmd.push('-a', config.destination_alias);
|
|
484
|
+
}
|
|
485
|
+
if (config.sourceStackBranch) {
|
|
486
|
+
cmd.push('-d', path.join(__dirname, config.sourceStackBranch));
|
|
487
|
+
}
|
|
488
|
+
if (config.targetStackBranch) {
|
|
489
|
+
cmd.push('--branch', config.targetStackBranch);
|
|
490
|
+
}
|
|
491
|
+
if (config.importWebhookStatus) {
|
|
492
|
+
cmd.push('--import-webhook-status', config.importWebhookStatus);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
await importCmd.run(cmd);
|
|
496
|
+
return resolve();
|
|
497
|
+
});
|
|
250
498
|
}
|
|
251
499
|
}
|
|
252
500
|
|
|
253
501
|
module.exports = {
|
|
254
|
-
CloneHandler,
|
|
255
|
-
|
|
502
|
+
CloneHandler,
|
|
503
|
+
client,
|
|
504
|
+
};
|