@contentstack/cli-cm-import 2.0.0-beta.12 → 2.0.0-beta.13
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/import/modules/marketplace-apps.js +140 -140
- package/lib/import/modules/workflows.js +55 -55
- package/lib/utils/marketplace-app-helper.js +49 -49
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
4
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
5
|
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
6
6
|
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
7
7
|
const node_path_1 = require("node:path");
|
|
@@ -10,7 +10,7 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
|
10
10
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
11
11
|
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
12
12
|
const findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex"));
|
|
13
|
-
const
|
|
13
|
+
const cli_utilities_2 = require("@contentstack/cli-utilities");
|
|
14
14
|
const constants_1 = require("../../constants");
|
|
15
15
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
16
16
|
const utils_1 = require("../../utils");
|
|
@@ -37,10 +37,10 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
37
37
|
*/
|
|
38
38
|
async start() {
|
|
39
39
|
try {
|
|
40
|
-
|
|
40
|
+
cli_utilities_2.log.debug('Starting workflows import process...', this.importConfig.context);
|
|
41
41
|
const [workflowsCount] = await this.analyzeWorkflows();
|
|
42
42
|
if (workflowsCount === 0) {
|
|
43
|
-
|
|
43
|
+
cli_utilities_2.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
const progress = this.createNestedProgress(this.currentModuleName);
|
|
@@ -51,14 +51,14 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
51
51
|
progress
|
|
52
52
|
.startProcess(utils_1.PROCESS_NAMES.GET_ROLES)
|
|
53
53
|
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.GET_ROLES].FETCHING, utils_1.PROCESS_NAMES.GET_ROLES);
|
|
54
|
-
|
|
54
|
+
cli_utilities_2.log.info('Fetching all roles for workflow processing', this.importConfig.context);
|
|
55
55
|
await this.getRoles();
|
|
56
56
|
progress.completeProcess(utils_1.PROCESS_NAMES.GET_ROLES, true);
|
|
57
57
|
// Step 2: Import workflows
|
|
58
58
|
progress
|
|
59
59
|
.startProcess(utils_1.PROCESS_NAMES.WORKFLOWS_CREATE)
|
|
60
60
|
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.WORKFLOWS_CREATE].IMPORTING, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
61
|
-
|
|
61
|
+
cli_utilities_2.log.info('Starting workflows import process', this.importConfig.context);
|
|
62
62
|
await this.importWorkflows();
|
|
63
63
|
progress.completeProcess(utils_1.PROCESS_NAMES.WORKFLOWS_CREATE, true);
|
|
64
64
|
this.processWorkflowResults();
|
|
@@ -66,91 +66,91 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
68
68
|
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Workflows import failed');
|
|
69
|
-
(0,
|
|
69
|
+
(0, cli_utilities_2.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
async getRoles() {
|
|
73
|
-
|
|
73
|
+
cli_utilities_2.log.debug('Fetching roles from stack', this.importConfig.context);
|
|
74
74
|
const roles = await this.stack
|
|
75
75
|
.role()
|
|
76
76
|
.fetchAll()
|
|
77
77
|
.then((data) => {
|
|
78
78
|
var _a;
|
|
79
|
-
|
|
79
|
+
cli_utilities_2.log.debug(`Successfully fetched ${((_a = data === null || data === void 0 ? void 0 : data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} roles`, this.importConfig.context);
|
|
80
80
|
return data;
|
|
81
81
|
})
|
|
82
82
|
.catch((err) => {
|
|
83
|
-
|
|
84
|
-
(0,
|
|
83
|
+
cli_utilities_2.log.debug('Error fetching roles', this.importConfig.context);
|
|
84
|
+
(0, cli_utilities_2.handleAndLogError)(err, Object.assign({}, this.importConfig.context));
|
|
85
85
|
});
|
|
86
86
|
for (const role of (roles === null || roles === void 0 ? void 0 : roles.items) || []) {
|
|
87
87
|
this.roleNameMap[role.name] = role.uid;
|
|
88
|
-
|
|
88
|
+
cli_utilities_2.log.debug(`Role mapping: ${role.name} → ${role.uid}`, this.importConfig.context);
|
|
89
89
|
}
|
|
90
90
|
const roleCount = Object.keys(this.roleNameMap || {}).length;
|
|
91
|
-
|
|
91
|
+
cli_utilities_2.log.debug(`Created role name data for ${roleCount} roles`, this.importConfig.context);
|
|
92
92
|
}
|
|
93
93
|
async importWorkflows() {
|
|
94
|
-
|
|
94
|
+
cli_utilities_2.log.debug('Validating workflows data', this.importConfig.context);
|
|
95
95
|
const apiContent = (0, values_1.default)(this.workflows);
|
|
96
96
|
const oldWorkflows = (0, cloneDeep_1.default)((0, values_1.default)(this.workflows));
|
|
97
|
-
|
|
97
|
+
cli_utilities_2.log.debug(`Starting to import ${apiContent.length} workflows`, this.importConfig.context);
|
|
98
98
|
//check and create custom roles if not exists
|
|
99
|
-
|
|
99
|
+
cli_utilities_2.log.debug('Checking and creating custom roles if needed', this.importConfig.context);
|
|
100
100
|
for (const workflow of (0, values_1.default)(this.workflows)) {
|
|
101
101
|
if (!this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
|
|
102
|
-
|
|
102
|
+
cli_utilities_2.log.debug(`Processing custom roles for workflow: ${workflow.name}`, this.importConfig.context);
|
|
103
103
|
await this.createCustomRoleIfNotExists(workflow);
|
|
104
104
|
}
|
|
105
105
|
else {
|
|
106
|
-
|
|
106
|
+
cli_utilities_2.log.debug(`Workflow ${workflow.name} already exists, skipping custom role creation`, this.importConfig.context);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
const onSuccess = async ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
110
110
|
var _a, _b;
|
|
111
|
-
|
|
111
|
+
cli_utilities_2.log.debug(`Workflow '${name}' imported successfully, processing next available stages`, this.importConfig.context);
|
|
112
112
|
const oldWorkflowStages = (_a = (0, find_1.default)(oldWorkflows, { uid })) === null || _a === void 0 ? void 0 : _a.workflow_stages;
|
|
113
113
|
if (!(0, isEmpty_1.default)((0, filter_1.default)(oldWorkflowStages, ({ next_available_stages }) => !(0, isEmpty_1.default)(next_available_stages)))) {
|
|
114
|
-
|
|
114
|
+
cli_utilities_2.log.debug(`Updating next available stages for workflow '${name}'`, this.importConfig.context);
|
|
115
115
|
let updateRresponse = await this.updateNextAvailableStagesUid(response, response.workflow_stages, oldWorkflowStages).catch((error) => {
|
|
116
116
|
var _a;
|
|
117
117
|
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `workflow: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to update next available stages', utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
118
|
-
(0,
|
|
118
|
+
(0, cli_utilities_2.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Workflow '${name}' update failed`);
|
|
119
119
|
});
|
|
120
120
|
if (updateRresponse) {
|
|
121
121
|
response = updateRresponse;
|
|
122
|
-
|
|
122
|
+
cli_utilities_2.log.debug(`Successfully updated next available stages for workflow '${name}'`, this.importConfig.context);
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
this.createdWorkflows.push(response);
|
|
126
126
|
this.workflowUidMapper[uid] = response.uid;
|
|
127
127
|
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `workflow: ${name || uid}`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
cli_utilities_2.log.success(`Workflow '${name}' imported successfully`, this.importConfig.context);
|
|
129
|
+
cli_utilities_2.log.debug(`Workflow UID mapping: ${uid} → ${response.uid}`, this.importConfig.context);
|
|
130
130
|
utils_1.fsUtil.writeFile(this.workflowUidMapperPath, this.workflowUidMapper);
|
|
131
131
|
};
|
|
132
132
|
const onReject = ({ error, apiData }) => {
|
|
133
133
|
var _a, _b, _c, _d;
|
|
134
134
|
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
135
135
|
const { name, uid } = apiData;
|
|
136
|
-
|
|
136
|
+
cli_utilities_2.log.debug(`Workflow '${name}' (${uid}) failed to import`, this.importConfig.context);
|
|
137
137
|
const workflowExists = ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) || ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b['workflow.name']);
|
|
138
138
|
if (workflowExists) {
|
|
139
139
|
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `workflow: ${name || uid} (already exists)`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
140
|
-
|
|
140
|
+
cli_utilities_2.log.info(`Workflow '${name}' already exists`, this.importConfig.context);
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
143
143
|
this.failedWebhooks.push(apiData);
|
|
144
144
|
(_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(false, `workflow: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to import workflow', utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
145
145
|
if ((error === null || error === void 0 ? void 0 : error.errors) && error.errors['workflow_stages.0.users']) {
|
|
146
|
-
|
|
146
|
+
cli_utilities_2.log.error("Failed to import Workflows as you've specified certain roles in the Stage transition and access rules section. We currently don't import roles to the stack.", this.importConfig.context);
|
|
147
147
|
}
|
|
148
148
|
else {
|
|
149
|
-
(0,
|
|
149
|
+
(0, cli_utilities_2.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Workflow '${name}' failed to be import`);
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
};
|
|
153
|
-
|
|
153
|
+
cli_utilities_2.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
|
|
154
154
|
await this.makeConcurrentCall({
|
|
155
155
|
apiContent,
|
|
156
156
|
processName: 'create workflows',
|
|
@@ -163,7 +163,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
163
163
|
},
|
|
164
164
|
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
165
165
|
}, undefined, false);
|
|
166
|
-
|
|
166
|
+
cli_utilities_2.log.debug('Workflows import process completed', this.importConfig.context);
|
|
167
167
|
}
|
|
168
168
|
updateNextAvailableStagesUid(workflow, newWorkflowStages, oldWorkflowStages) {
|
|
169
169
|
newWorkflowStages = (0, map_1.default)(newWorkflowStages, (newStage, index) => {
|
|
@@ -196,16 +196,16 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
196
196
|
serializeWorkflows(apiOptions) {
|
|
197
197
|
var _a;
|
|
198
198
|
let { apiData: workflow } = apiOptions;
|
|
199
|
-
|
|
199
|
+
cli_utilities_2.log.debug(`Serializing workflow: ${workflow.name} (${workflow.uid})`, this.importConfig.context);
|
|
200
200
|
if (this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
cli_utilities_2.log.info(`Workflow '${workflow.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
|
|
202
|
+
cli_utilities_2.log.debug(`Skipping workflow serialization for: ${workflow.uid}`, this.importConfig.context);
|
|
203
203
|
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `workflow: ${workflow.name} (skipped - already exists)`, null, utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
204
204
|
apiOptions.entity = undefined;
|
|
205
205
|
}
|
|
206
206
|
else {
|
|
207
207
|
if (workflow.admin_users !== undefined) {
|
|
208
|
-
|
|
208
|
+
cli_utilities_2.log.info((0, cli_utilities_1.getChalk)().yellow('We are skipping import of `Workflow superuser(s)` from workflow'), this.importConfig.context);
|
|
209
209
|
delete workflow.admin_users;
|
|
210
210
|
}
|
|
211
211
|
// One branch is required to create workflow.
|
|
@@ -218,7 +218,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
218
218
|
stage.next_available_stages = ['$all'];
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
|
-
|
|
221
|
+
cli_utilities_2.log.debug(`Workflow serialization completed: ${workflow.name}`, this.importConfig.context);
|
|
222
222
|
apiOptions.apiData = workflow;
|
|
223
223
|
}
|
|
224
224
|
return apiOptions;
|
|
@@ -229,11 +229,11 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
229
229
|
const { name } = apiData;
|
|
230
230
|
this.updateRoleData({ workflowUid, stageIndex, roleData: apiData });
|
|
231
231
|
this.roleNameMap[name] = response === null || response === void 0 ? void 0 : response.uid;
|
|
232
|
-
|
|
232
|
+
cli_utilities_2.log.debug(`Custom role '${name}' created successfully for workflow`, this.importConfig.context);
|
|
233
233
|
};
|
|
234
234
|
const onReject = ({ error, apiData: { name } = { name: '' } }) => {
|
|
235
|
-
|
|
236
|
-
(0,
|
|
235
|
+
cli_utilities_2.log.debug(`Custom role '${name}' creation failed`, this.importConfig.context);
|
|
236
|
+
(0, cli_utilities_2.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Failed to create custom roles '${name}'`);
|
|
237
237
|
};
|
|
238
238
|
const workflowStages = workflow.workflow_stages;
|
|
239
239
|
let stageIndex = 0;
|
|
@@ -243,7 +243,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
243
243
|
}
|
|
244
244
|
if ((_h = (_g = (_f = stage === null || stage === void 0 ? void 0 : stage.SYS_ACL) === null || _f === void 0 ? void 0 : _f.roles) === null || _g === void 0 ? void 0 : _g.uids) === null || _h === void 0 ? void 0 : _h.length) {
|
|
245
245
|
const apiContent = stage.SYS_ACL.roles.uids;
|
|
246
|
-
|
|
246
|
+
cli_utilities_2.log.debug(`Creating ${apiContent.length} custom roles for workflow stage ${stageIndex}`, this.importConfig.context);
|
|
247
247
|
await this.makeConcurrentCall({
|
|
248
248
|
apiContent,
|
|
249
249
|
processName: 'create custom role',
|
|
@@ -268,7 +268,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
268
268
|
*/
|
|
269
269
|
serializeCustomRoles(apiOptions) {
|
|
270
270
|
let { apiData: roleData, additionalInfo: { workflowUid, stageIndex }, } = apiOptions;
|
|
271
|
-
|
|
271
|
+
cli_utilities_2.log.debug(`Serializing custom role: ${roleData.name}`, this.importConfig.context);
|
|
272
272
|
if (!this.roleNameMap[roleData.name]) {
|
|
273
273
|
// rules.branch is required to create custom roles.
|
|
274
274
|
const branchRuleExists = (0, find_1.default)(roleData.rules, (rule) => rule.module === 'branch');
|
|
@@ -278,12 +278,12 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
278
278
|
branches: ['main'],
|
|
279
279
|
acl: { read: true },
|
|
280
280
|
});
|
|
281
|
-
|
|
281
|
+
cli_utilities_2.log.debug(`Added branch rule to custom role: ${roleData.name}`, this.importConfig.context);
|
|
282
282
|
}
|
|
283
283
|
apiOptions = roleData;
|
|
284
284
|
}
|
|
285
285
|
else {
|
|
286
|
-
|
|
286
|
+
cli_utilities_2.log.debug(`Custom role '${roleData.name}' already exists, skipping creation`, this.importConfig.context);
|
|
287
287
|
apiOptions.entity = undefined;
|
|
288
288
|
this.updateRoleData({ workflowUid, stageIndex, roleData });
|
|
289
289
|
}
|
|
@@ -295,51 +295,51 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
295
295
|
const roles = workflowStage[stageIndex].SYS_ACL.roles.uids;
|
|
296
296
|
const index = (0, findIndex_1.default)(roles, ['uid', roleData.uid]);
|
|
297
297
|
roles[index >= 0 ? index : roles.length] = this.roleNameMap[roleData.name];
|
|
298
|
-
|
|
298
|
+
cli_utilities_2.log.debug(`Updated role data for workflow ${workflowUid}, stage ${stageIndex}`, this.importConfig.context);
|
|
299
299
|
}
|
|
300
300
|
async analyzeWorkflows() {
|
|
301
301
|
return this.withLoadingSpinner('WORKFLOWS: Analyzing import data...', async () => {
|
|
302
|
-
|
|
302
|
+
cli_utilities_2.log.debug('Checking for workflows folder existence', this.importConfig.context);
|
|
303
303
|
if (!utils_1.fileHelper.fileExistsSync(this.workflowsFolderPath)) {
|
|
304
|
-
|
|
304
|
+
cli_utilities_2.log.info(`No Workflows Found - '${this.workflowsFolderPath}'`, this.importConfig.context);
|
|
305
305
|
return [0];
|
|
306
306
|
}
|
|
307
|
-
|
|
307
|
+
cli_utilities_2.log.debug(`Found workflows folder: ${this.workflowsFolderPath}`, this.importConfig.context);
|
|
308
308
|
this.workflows = utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName), true);
|
|
309
309
|
if (!this.workflows || (0, isEmpty_1.default)(this.workflows)) {
|
|
310
|
-
|
|
310
|
+
cli_utilities_2.log.info(`No workflows found in file - '${(0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName)}'`, this.importConfig.context);
|
|
311
311
|
return [0];
|
|
312
312
|
}
|
|
313
313
|
const count = Object.keys(this.workflows || {}).length;
|
|
314
|
-
|
|
314
|
+
cli_utilities_2.log.debug(`Loaded ${count} workflow items from file`, this.importConfig.context);
|
|
315
315
|
return [count];
|
|
316
316
|
});
|
|
317
317
|
}
|
|
318
318
|
async prepareWorkflowMapper() {
|
|
319
|
-
|
|
319
|
+
cli_utilities_2.log.debug('Creating workflows mapper directory', this.importConfig.context);
|
|
320
320
|
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
321
|
-
|
|
321
|
+
cli_utilities_2.log.debug('Loading existing workflow UID mappings', this.importConfig.context);
|
|
322
322
|
this.workflowUidMapper = utils_1.fileHelper.fileExistsSync(this.workflowUidMapperPath)
|
|
323
323
|
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowUidMapperPath), true) || {}
|
|
324
324
|
: {};
|
|
325
325
|
const count = Object.keys(this.workflowUidMapper || {}).length;
|
|
326
326
|
if (count > 0) {
|
|
327
|
-
|
|
327
|
+
cli_utilities_2.log.debug(`Loaded existing workflow UID data: ${count} items`, this.importConfig.context);
|
|
328
328
|
}
|
|
329
329
|
else {
|
|
330
|
-
|
|
330
|
+
cli_utilities_2.log.debug('No existing workflow UID mappings found', this.importConfig.context);
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
processWorkflowResults() {
|
|
334
334
|
var _a, _b;
|
|
335
|
-
|
|
335
|
+
cli_utilities_2.log.debug('Processing workflow import results', this.importConfig.context);
|
|
336
336
|
if ((_a = this.createdWorkflows) === null || _a === void 0 ? void 0 : _a.length) {
|
|
337
337
|
utils_1.fsUtil.writeFile(this.createdWorkflowsPath, this.createdWorkflows);
|
|
338
|
-
|
|
338
|
+
cli_utilities_2.log.debug(`Written ${this.createdWorkflows.length} successful workflows to file`, this.importConfig.context);
|
|
339
339
|
}
|
|
340
340
|
if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
|
|
341
341
|
utils_1.fsUtil.writeFile(this.failedWorkflowsPath, this.failedWebhooks);
|
|
342
|
-
|
|
342
|
+
cli_utilities_2.log.debug(`Written ${this.failedWebhooks.length} failed workflows to file`, this.importConfig.context);
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
}
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ifAppAlreadyExist = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.getAllStackSpecificApps = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
6
|
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
7
7
|
const omitBy_1 = tslib_1.__importDefault(require("lodash/omitBy"));
|
|
8
8
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
9
9
|
const includes_1 = tslib_1.__importDefault(require("lodash/includes"));
|
|
10
|
-
const
|
|
10
|
+
const cli_utilities_2 = require("@contentstack/cli-utilities");
|
|
11
11
|
const utils_1 = require("../utils");
|
|
12
12
|
const interactive_1 = require("../utils/interactive");
|
|
13
13
|
const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
14
|
-
|
|
15
|
-
const appSdk = await (0,
|
|
14
|
+
cli_utilities_2.log.debug(`Fetching stack-specific apps with skip: ${skip}, current list size: ${listOfApps.length}`);
|
|
15
|
+
const appSdk = await (0, cli_utilities_2.marketplaceSDKClient)({
|
|
16
16
|
host: config.developerHubBaseUrl.split('://').pop(),
|
|
17
17
|
});
|
|
18
18
|
const collection = await appSdk
|
|
@@ -20,12 +20,12 @@ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
|
20
20
|
.installation()
|
|
21
21
|
.fetchAll({ target_uids: config.apiKey, skip })
|
|
22
22
|
.catch((error) => {
|
|
23
|
-
(0,
|
|
24
|
-
|
|
23
|
+
(0, cli_utilities_2.handleAndLogError)(error);
|
|
24
|
+
cli_utilities_2.log.error(error, config === null || config === void 0 ? void 0 : config.context);
|
|
25
25
|
});
|
|
26
26
|
if (collection) {
|
|
27
27
|
const { items: apps, count } = collection;
|
|
28
|
-
|
|
28
|
+
cli_utilities_2.log.debug(`Retrieved ${apps.length} apps from API, total count: ${count}`);
|
|
29
29
|
// NOTE Remove all the chain functions
|
|
30
30
|
const installation = (0, map_1.default)(apps, (app) => (0, omitBy_1.default)(app, (val, _key) => {
|
|
31
31
|
if (val instanceof Function)
|
|
@@ -33,146 +33,146 @@ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
|
33
33
|
return false;
|
|
34
34
|
}));
|
|
35
35
|
listOfApps = listOfApps.concat(installation);
|
|
36
|
-
|
|
36
|
+
cli_utilities_2.log.debug(`Updated list size: ${listOfApps.length}`);
|
|
37
37
|
if (count - (skip + 50) > 0) {
|
|
38
|
-
|
|
38
|
+
cli_utilities_2.log.debug(`Fetching more apps, remaining: ${count - (skip + 50)}`);
|
|
39
39
|
return await (0, exports.getAllStackSpecificApps)(config, skip + 50, listOfApps);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
cli_utilities_2.log.info(`Successfully retrieved ${listOfApps.length} stack-specific apps`);
|
|
43
43
|
return listOfApps;
|
|
44
44
|
};
|
|
45
45
|
exports.getAllStackSpecificApps = getAllStackSpecificApps;
|
|
46
46
|
const getDeveloperHubUrl = async (config) => {
|
|
47
|
-
|
|
48
|
-
const url = (0,
|
|
49
|
-
|
|
47
|
+
cli_utilities_2.log.debug('Creating developer hub URL');
|
|
48
|
+
const url = (0, cli_utilities_2.createDeveloperHubUrl)(config.host);
|
|
49
|
+
cli_utilities_2.log.debug(`Developer hub URL: ${url}`);
|
|
50
50
|
return url;
|
|
51
51
|
};
|
|
52
52
|
exports.getDeveloperHubUrl = getDeveloperHubUrl;
|
|
53
53
|
const getOrgUid = async (config) => {
|
|
54
|
-
|
|
55
|
-
const tempAPIClient = await (0,
|
|
54
|
+
cli_utilities_2.log.debug('Fetching organization UID');
|
|
55
|
+
const tempAPIClient = await (0, cli_utilities_2.managementSDKClient)({ host: config.host });
|
|
56
56
|
const tempStackData = await tempAPIClient
|
|
57
57
|
.stack({ api_key: config.apiKey })
|
|
58
58
|
.fetch()
|
|
59
59
|
.catch((error) => {
|
|
60
|
-
(0,
|
|
61
|
-
|
|
60
|
+
(0, cli_utilities_2.handleAndLogError)(error);
|
|
61
|
+
cli_utilities_2.log.error(error, config === null || config === void 0 ? void 0 : config.context);
|
|
62
62
|
});
|
|
63
63
|
const orgUid = (tempStackData === null || tempStackData === void 0 ? void 0 : tempStackData.org_uid) || '';
|
|
64
|
-
|
|
64
|
+
cli_utilities_2.log.debug(`Organization UID: ${orgUid}`);
|
|
65
65
|
return orgUid;
|
|
66
66
|
};
|
|
67
67
|
exports.getOrgUid = getOrgUid;
|
|
68
68
|
const getConfirmationToCreateApps = async (privateApps, config) => {
|
|
69
|
-
|
|
69
|
+
cli_utilities_2.log.debug(`Requesting confirmation to create ${privateApps === null || privateApps === void 0 ? void 0 : privateApps.length} private apps`);
|
|
70
70
|
if (!config.forceStopMarketplaceAppsPrompt) {
|
|
71
|
-
if (!(await
|
|
72
|
-
|
|
73
|
-
if (await
|
|
74
|
-
|
|
71
|
+
if (!(await cli_utilities_2.cliux.confirm((0, cli_utilities_1.getChalk)().yellow(`WARNING!!! The listed apps are private apps that are not available in the destination stack: \n\n${(0, map_1.default)(privateApps, ({ manifest: { name } }, index) => `${String(index + 1)}) ${name}`).join('\n')}\n\nWould you like to re-create the private app and then proceed with the installation? (y/n)`)))) {
|
|
72
|
+
cli_utilities_2.log.debug('User declined to create private apps');
|
|
73
|
+
if (await cli_utilities_2.cliux.confirm((0, cli_utilities_1.getChalk)().yellow(`\nWARNING!!! Canceling the app re-creation may break the content type and entry import. Would you like to proceed without re-create the private app? (y/n)`))) {
|
|
74
|
+
cli_utilities_2.log.warn('User confirmed to proceed without creating private apps');
|
|
75
75
|
return Promise.resolve(false);
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
|
-
if (await
|
|
79
|
-
|
|
78
|
+
if (await cli_utilities_2.cliux.confirm((0, cli_utilities_1.getChalk)().yellow('\nWould you like to re-create the private app and then proceed with the installation? (y/n)'))) {
|
|
79
|
+
cli_utilities_2.log.info('User confirmed to create private apps');
|
|
80
80
|
return Promise.resolve(true);
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
83
|
-
|
|
83
|
+
cli_utilities_2.log.debug('User declined to create private apps (second prompt).');
|
|
84
84
|
return Promise.resolve(false);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
else {
|
|
89
|
-
|
|
89
|
+
cli_utilities_2.log.info('User confirmed to create private apps');
|
|
90
90
|
return Promise.resolve(true);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
|
|
94
|
+
cli_utilities_2.log.debug('Force prompt disabled, automatically creating private apps');
|
|
95
95
|
return Promise.resolve(true);
|
|
96
96
|
}
|
|
97
97
|
};
|
|
98
98
|
exports.getConfirmationToCreateApps = getConfirmationToCreateApps;
|
|
99
99
|
const handleNameConflict = async (app, appSuffix, config) => {
|
|
100
|
-
|
|
100
|
+
cli_utilities_2.log.debug(`Handling name conflict for app: ${app === null || app === void 0 ? void 0 : app.name}, suffix: ${appSuffix}`);
|
|
101
101
|
const appName = config.forceStopMarketplaceAppsPrompt
|
|
102
102
|
? (0, interactive_1.getAppName)(app.name, appSuffix)
|
|
103
103
|
: await (0, interactive_1.askAppName)(app, appSuffix);
|
|
104
104
|
app.name = appName;
|
|
105
|
-
|
|
105
|
+
cli_utilities_2.log.debug(`Updated app name to: ${appName}`);
|
|
106
106
|
return app;
|
|
107
107
|
};
|
|
108
108
|
exports.handleNameConflict = handleNameConflict;
|
|
109
109
|
const makeRedirectUrlCall = async (response, appName, config) => {
|
|
110
110
|
if (response.redirect_url) {
|
|
111
|
-
|
|
112
|
-
await new
|
|
111
|
+
cli_utilities_2.log.info(`Starting OAuth API call for app: ${appName}`);
|
|
112
|
+
await new cli_utilities_2.HttpClient({ maxRedirects: 20, maxBodyLength: Infinity })
|
|
113
113
|
.get(response.redirect_url)
|
|
114
114
|
.then(async ({ response }) => {
|
|
115
115
|
if ((0, includes_1.default)([501, 403], response.status)) {
|
|
116
|
-
|
|
116
|
+
cli_utilities_2.log.error(`OAuth API call failed for ${appName}: ${response.statusText}`, config === null || config === void 0 ? void 0 : config.context);
|
|
117
117
|
await (0, exports.confirmToCloseProcess)(response.data, config);
|
|
118
118
|
}
|
|
119
119
|
else {
|
|
120
|
-
|
|
120
|
+
cli_utilities_2.log.success(`OAuth API call completed successfully for app: ${appName}`);
|
|
121
121
|
}
|
|
122
122
|
})
|
|
123
123
|
.catch((error) => {
|
|
124
|
-
|
|
124
|
+
cli_utilities_2.log.error(error, config === null || config === void 0 ? void 0 : config.context);
|
|
125
125
|
if ((0, includes_1.default)([501, 403], error.status)) {
|
|
126
|
-
(0,
|
|
126
|
+
(0, cli_utilities_2.handleAndLogError)(error);
|
|
127
127
|
}
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
else {
|
|
131
|
-
|
|
131
|
+
cli_utilities_2.log.debug(`No redirect URL found for app: ${appName}`);
|
|
132
132
|
}
|
|
133
133
|
};
|
|
134
134
|
exports.makeRedirectUrlCall = makeRedirectUrlCall;
|
|
135
135
|
const confirmToCloseProcess = async (installation, config) => {
|
|
136
|
-
|
|
136
|
+
cli_utilities_2.log.warn(`Installation error occurred: ${(0, utils_1.formatError)(installation === null || installation === void 0 ? void 0 : installation.message)}`);
|
|
137
137
|
if (!config.forceStopMarketplaceAppsPrompt) {
|
|
138
|
-
if (!(await
|
|
139
|
-
|
|
138
|
+
if (!(await cli_utilities_2.cliux.confirm((0, cli_utilities_1.getChalk)().yellow('WARNING!!! The above error may have an impact if the failed app is referenced in entries/content type. Would you like to proceed? (y/n)')))) {
|
|
139
|
+
cli_utilities_2.log.debug('User chose to exit due to installation error');
|
|
140
140
|
process.exit();
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
143
|
-
|
|
143
|
+
cli_utilities_2.log.warn('User chose to proceed despite installation error');
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
else {
|
|
147
|
-
|
|
147
|
+
cli_utilities_2.log.debug('Force prompt disabled, continuing despite installation error');
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
exports.confirmToCloseProcess = confirmToCloseProcess;
|
|
151
151
|
const ifAppAlreadyExist = async (app, currentStackApp, config) => {
|
|
152
152
|
var _a;
|
|
153
|
-
|
|
153
|
+
cli_utilities_2.log.debug(`Checking if app already exists: ${(_a = app === null || app === void 0 ? void 0 : app.manifest) === null || _a === void 0 ? void 0 : _a.name}`);
|
|
154
154
|
let updateParam = {};
|
|
155
155
|
const { manifest: { name }, configuration, server_configuration, } = app;
|
|
156
156
|
if (!(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration)) {
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
cli_utilities_2.log.warn(`App ${name} already exists with existing configuration`);
|
|
158
|
+
cli_utilities_2.cliux.print(`\nWARNING!!! The ${name} app already exists and it may have its own configuration. But the current app you install has its own configuration which is used internally to manage content.\n`, { color: 'yellow' });
|
|
159
159
|
const configOption = config.forceStopMarketplaceAppsPrompt
|
|
160
160
|
? 'Update it with the new configuration.'
|
|
161
161
|
: await (0, interactive_1.selectConfiguration)();
|
|
162
162
|
if (configOption === 'Exit') {
|
|
163
|
-
|
|
163
|
+
cli_utilities_2.log.debug('User chose to exit due to configuration conflict');
|
|
164
164
|
process.exit();
|
|
165
165
|
}
|
|
166
166
|
else if (configOption === 'Update it with the new configuration.') {
|
|
167
|
-
|
|
167
|
+
cli_utilities_2.log.info(`Updating app configuration for: ${name}`);
|
|
168
168
|
updateParam = Object.assign(Object.assign({ manifest: app.manifest }, currentStackApp), { configuration, server_configuration });
|
|
169
169
|
}
|
|
170
170
|
else {
|
|
171
|
-
|
|
171
|
+
cli_utilities_2.log.debug(`User chose to keep existing configuration for: ${name}`);
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
else {
|
|
175
|
-
|
|
175
|
+
cli_utilities_2.log.debug(`App ${name} has no configuration conflicts`);
|
|
176
176
|
}
|
|
177
177
|
return updateParam;
|
|
178
178
|
};
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-import",
|
|
3
3
|
"description": "Contentstack CLI plugin to import content into stack",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.13",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-audit": "~2.0.0-beta.
|
|
9
|
-
"@contentstack/cli-command": "~2.0.0-beta.
|
|
10
|
-
"@contentstack/cli-utilities": "~2.0.0-beta.
|
|
8
|
+
"@contentstack/cli-audit": "~2.0.0-beta.8",
|
|
9
|
+
"@contentstack/cli-command": "~2.0.0-beta.4",
|
|
10
|
+
"@contentstack/cli-utilities": "~2.0.0-beta.4",
|
|
11
11
|
"@contentstack/cli-variants": "~2.0.0-beta.9",
|
|
12
12
|
"@oclif/core": "^4.3.0",
|
|
13
13
|
"big-json": "^3.2.0",
|
|
14
14
|
"bluebird": "^3.7.2",
|
|
15
|
-
"chalk": "^
|
|
15
|
+
"chalk": "^5.6.2",
|
|
16
16
|
"debug": "^4.4.3",
|
|
17
17
|
"fs-extra": "^11.3.3",
|
|
18
18
|
"lodash": "^4.17.23",
|