@contentstack/cli-cm-import 1.7.0 → 1.8.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 +1 -1
- package/lib/config/index.js +2 -0
- package/lib/import/module-importer.js +15 -0
- package/lib/import/modules/base-class.d.ts +1 -1
- package/lib/import/modules/base-class.js +31 -1
- package/lib/import/modules/content-types.js +1 -1
- package/lib/import/modules/entries.d.ts +93 -0
- package/lib/import/modules/entries.js +536 -0
- package/lib/import/modules/marketplace-apps.d.ts +5 -2
- package/lib/import/modules/marketplace-apps.js +34 -17
- package/lib/import/modules/workflows.d.ts +41 -0
- package/lib/import/modules/workflows.js +209 -0
- package/lib/import/modules-js/custom-roles.js +1 -1
- package/lib/import/modules-js/entries.js +20 -8
- package/lib/import/modules-js/environments.js +1 -1
- package/lib/import/modules-js/extensions.js +1 -1
- package/lib/import/modules-js/global-fields.js +2 -4
- package/lib/import/modules-js/marketplace-apps.d.ts +6 -4
- package/lib/import/modules-js/marketplace-apps.js +29 -25
- package/lib/import/modules-js/workflows.js +2 -2
- package/lib/types/default-config.d.ts +1 -0
- package/lib/utils/asset-helper.d.ts +1 -1
- package/lib/utils/backup-handler.js +10 -1
- package/lib/utils/entries-helper.d.ts +4 -1
- package/lib/utils/entries-helper.js +322 -2
- package/lib/utils/file-helper.d.ts +1 -0
- package/lib/utils/file-helper.js +5 -1
- package/lib/utils/import-config-handler.js +1 -1
- package/lib/utils/index.d.ts +2 -2
- package/lib/utils/index.js +4 -1
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const
|
|
5
|
-
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
5
|
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
6
|
+
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
7
7
|
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
8
|
+
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
8
9
|
const first_1 = tslib_1.__importDefault(require("lodash/first"));
|
|
9
10
|
const split_1 = tslib_1.__importDefault(require("lodash/split"));
|
|
10
|
-
const toLower_1 = tslib_1.__importDefault(require("lodash/toLower"));
|
|
11
|
-
const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
12
|
-
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
13
11
|
const node_path_1 = require("node:path");
|
|
12
|
+
const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
13
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
14
|
+
const toLower_1 = tslib_1.__importDefault(require("lodash/toLower"));
|
|
14
15
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
15
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
16
16
|
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
17
|
-
const utils_1 = require("../../utils");
|
|
18
17
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
19
18
|
const interactive_1 = require("../../utils/interactive");
|
|
19
|
+
const utils_1 = require("../../utils");
|
|
20
20
|
class ImportMarketplaceApps extends base_class_1.default {
|
|
21
21
|
constructor({ importConfig, stackAPIClient }) {
|
|
22
22
|
super({ importConfig, stackAPIClient });
|
|
@@ -27,7 +27,7 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
27
27
|
this.httpClient = new cli_utilities_1.HttpClient();
|
|
28
28
|
this.appNameMapping = {};
|
|
29
29
|
this.appUidMapping = {};
|
|
30
|
-
this.
|
|
30
|
+
this.appOriginalName = undefined;
|
|
31
31
|
this.installedApps = [];
|
|
32
32
|
this.installationUidMapping = {};
|
|
33
33
|
}
|
|
@@ -105,7 +105,8 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
105
105
|
const listOfNewMeta = [];
|
|
106
106
|
const listOfOldMeta = [];
|
|
107
107
|
const extensionUidMap = {};
|
|
108
|
-
this.installedApps =
|
|
108
|
+
this.installedApps =
|
|
109
|
+
(await (0, utils_1.getAllStackSpecificApps)(this.developerHubBaseUrl, this.httpClient, this.importConfig)) || [];
|
|
109
110
|
for (const app of this.marketplaceApps) {
|
|
110
111
|
listOfOldMeta.push(...(0, map_1.default)((_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations, 'meta').flat());
|
|
111
112
|
}
|
|
@@ -160,7 +161,7 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
160
161
|
for (let app of privateApps) {
|
|
161
162
|
// NOTE keys can be passed to install new app in the developer hub
|
|
162
163
|
app.manifest = (0, pick_1.default)(app.manifest, ['uid', 'name', 'description', 'icon', 'target_type', 'webhook', 'oauth']);
|
|
163
|
-
this.
|
|
164
|
+
this.appOriginalName = app.manifest.name;
|
|
164
165
|
const obj = {
|
|
165
166
|
oauth: app.oauth,
|
|
166
167
|
webhook: app.webhook,
|
|
@@ -168,10 +169,11 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
168
169
|
};
|
|
169
170
|
await this.createPrivateApps(Object.assign(Object.assign({}, obj), app.manifest));
|
|
170
171
|
}
|
|
171
|
-
this.
|
|
172
|
+
this.appOriginalName = undefined;
|
|
172
173
|
}
|
|
173
174
|
async createPrivateApps(app, uidCleaned = false, appSuffix = 1) {
|
|
174
|
-
|
|
175
|
+
var _a;
|
|
176
|
+
let locations = (_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations;
|
|
175
177
|
if (!uidCleaned && !(0, isEmpty_1.default)(locations)) {
|
|
176
178
|
app.ui_location.locations = await this.updateManifestUILocations(locations, 'uid');
|
|
177
179
|
}
|
|
@@ -199,8 +201,8 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
199
201
|
location.meta = (0, map_1.default)(location.meta, (meta) => {
|
|
200
202
|
if (meta.name) {
|
|
201
203
|
const name = `${(0, first_1.default)((0, split_1.default)(meta.name, '◈'))}◈${appSuffix}`;
|
|
202
|
-
if (!this.appNameMapping[this.
|
|
203
|
-
this.appNameMapping[this.
|
|
204
|
+
if (!this.appNameMapping[this.appOriginalName]) {
|
|
205
|
+
this.appNameMapping[this.appOriginalName] = name;
|
|
204
206
|
}
|
|
205
207
|
meta.name = name;
|
|
206
208
|
}
|
|
@@ -234,12 +236,15 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
234
236
|
// NOTE new app installation
|
|
235
237
|
(0, utils_1.log)(this.importConfig, `${response.name} app created successfully.!`, 'success');
|
|
236
238
|
this.appUidMapping[app.uid] = response.uid;
|
|
237
|
-
this.appNameMapping[this.
|
|
239
|
+
this.appNameMapping[this.appOriginalName] = response.name;
|
|
238
240
|
}
|
|
239
241
|
}
|
|
240
242
|
/**
|
|
241
243
|
* @method installApps
|
|
242
|
-
*
|
|
244
|
+
*
|
|
245
|
+
* @param {Record<string, any>} app
|
|
246
|
+
* @param {Record<string, any>[]} installedApps
|
|
247
|
+
* @returns {Promise<void>}
|
|
243
248
|
*/
|
|
244
249
|
async installApps(app) {
|
|
245
250
|
var _a, _b, _c, _d;
|
|
@@ -291,7 +296,19 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
291
296
|
if ((0, isEmpty_1.default)(app) || (0, isEmpty_1.default)(payload) || !uid) {
|
|
292
297
|
return Promise.resolve();
|
|
293
298
|
}
|
|
294
|
-
|
|
299
|
+
// TODO migrate this HTTP API call into SDK
|
|
300
|
+
// NOTE Use updateAppConfig(this.sdkClient, this.importConfig, app, payload) utility when migrating to SDK call;
|
|
301
|
+
return this.httpClient
|
|
302
|
+
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload)
|
|
303
|
+
.then(({ data }) => {
|
|
304
|
+
if (data.message) {
|
|
305
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
(0, utils_1.log)(this.importConfig, `${app.manifest.name} app config updated successfully.!`, 'success');
|
|
309
|
+
}
|
|
310
|
+
})
|
|
311
|
+
.catch((error) => (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error'));
|
|
295
312
|
}
|
|
296
313
|
}
|
|
297
314
|
exports.default = ImportMarketplaceApps;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import BaseClass, { ApiOptions } from './base-class';
|
|
2
|
+
import { ModuleClassParams } from '../../types';
|
|
3
|
+
export default class ImportWorkflows extends BaseClass {
|
|
4
|
+
private mapperDirPath;
|
|
5
|
+
private workflowsFolderPath;
|
|
6
|
+
private workflowUidMapperPath;
|
|
7
|
+
private createdWorkflowsPath;
|
|
8
|
+
private failedWorkflowsPath;
|
|
9
|
+
private workflowsConfig;
|
|
10
|
+
private workflows;
|
|
11
|
+
private workflowUidMapper;
|
|
12
|
+
private createdWorkflows;
|
|
13
|
+
private failedWebhooks;
|
|
14
|
+
private roleNameMap;
|
|
15
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
16
|
+
/**
|
|
17
|
+
* @method start
|
|
18
|
+
* @returns {Promise<void>} Promise<void>
|
|
19
|
+
*/
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
getRoles(): Promise<void>;
|
|
22
|
+
importWorkflows(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* @method serializeWorkflows
|
|
25
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
26
|
+
* @returns {ApiOptions} ApiOptions
|
|
27
|
+
*/
|
|
28
|
+
serializeWorkflows(apiOptions: ApiOptions): ApiOptions;
|
|
29
|
+
createCustomRoleIfNotExists(workflow: Record<string, any>): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* @method serializeCustomRoles
|
|
32
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
33
|
+
* @returns {ApiOptions} ApiOptions
|
|
34
|
+
*/
|
|
35
|
+
serializeCustomRoles(apiOptions: ApiOptions): ApiOptions;
|
|
36
|
+
updateRoleData(params: {
|
|
37
|
+
workflowUid: string;
|
|
38
|
+
stageIndex: number;
|
|
39
|
+
roleData: any;
|
|
40
|
+
}): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
6
|
+
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
7
|
+
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
8
|
+
const findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex"));
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
11
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
12
|
+
const utils_1 = require("../../utils");
|
|
13
|
+
class ImportWorkflows extends base_class_1.default {
|
|
14
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
15
|
+
super({ importConfig, stackAPIClient });
|
|
16
|
+
this.workflowsConfig = config_1.default.modules.workflows;
|
|
17
|
+
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'workflows');
|
|
18
|
+
this.workflowsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.workflowsConfig.dirName);
|
|
19
|
+
this.workflowUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
20
|
+
this.createdWorkflowsPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
|
|
21
|
+
this.failedWorkflowsPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
|
|
22
|
+
this.workflows = {};
|
|
23
|
+
this.failedWebhooks = [];
|
|
24
|
+
this.createdWorkflows = [];
|
|
25
|
+
this.workflowUidMapper = {};
|
|
26
|
+
this.roleNameMap = {};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @method start
|
|
30
|
+
* @returns {Promise<void>} Promise<void>
|
|
31
|
+
*/
|
|
32
|
+
async start() {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
(0, utils_1.log)(this.importConfig, 'Migrating workflows', 'info');
|
|
35
|
+
//Step1 check folder exists or not
|
|
36
|
+
if (utils_1.fileHelper.fileExistsSync(this.workflowsFolderPath)) {
|
|
37
|
+
this.workflows = utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowsFolderPath, this.workflowsConfig.fileName), true);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.workflowsFolderPath}'`, 'error');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
//create workflows in mapper directory
|
|
44
|
+
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
45
|
+
this.workflowUidMapper = utils_1.fileHelper.fileExistsSync(this.workflowUidMapperPath)
|
|
46
|
+
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.workflowUidMapperPath), true)
|
|
47
|
+
: {};
|
|
48
|
+
if (this.workflows === undefined || (0, isEmpty_1.default)(this.workflows)) {
|
|
49
|
+
(0, utils_1.log)(this.importConfig, 'No Workflow Found', 'info');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
//fetch all roles
|
|
53
|
+
await this.getRoles();
|
|
54
|
+
await this.importWorkflows();
|
|
55
|
+
if ((_a = this.createdWorkflows) === null || _a === void 0 ? void 0 : _a.length) {
|
|
56
|
+
utils_1.fsUtil.writeFile(this.createdWorkflowsPath, this.createdWorkflows);
|
|
57
|
+
}
|
|
58
|
+
if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
|
|
59
|
+
utils_1.fsUtil.writeFile(this.failedWorkflowsPath, this.failedWebhooks);
|
|
60
|
+
}
|
|
61
|
+
(0, utils_1.log)(this.importConfig, 'Workflows have been imported successfully!', 'success');
|
|
62
|
+
}
|
|
63
|
+
async getRoles() {
|
|
64
|
+
const roles = await this.stack
|
|
65
|
+
.role()
|
|
66
|
+
.fetchAll()
|
|
67
|
+
.then((data) => data)
|
|
68
|
+
.catch((err) => (0, utils_1.log)(this.importConfig, `Failed to fetch roles. ${(0, utils_1.formatError)(err)}`, 'error'));
|
|
69
|
+
for (const role of roles === null || roles === void 0 ? void 0 : roles.items) {
|
|
70
|
+
this.roleNameMap[role.name] = role.uid;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async importWorkflows() {
|
|
74
|
+
const apiContent = (0, values_1.default)(this.workflows);
|
|
75
|
+
//check and create custom roles if not exists
|
|
76
|
+
for (const workflow of (0, values_1.default)(this.workflows)) {
|
|
77
|
+
if (!this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
|
|
78
|
+
await this.createCustomRoleIfNotExists(workflow);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
82
|
+
this.createdWorkflows.push(response);
|
|
83
|
+
this.workflowUidMapper[uid] = response.uid;
|
|
84
|
+
(0, utils_1.log)(this.importConfig, `Workflow '${name}' imported successfully`, 'success');
|
|
85
|
+
utils_1.fsUtil.writeFile(this.workflowUidMapperPath, this.workflowUidMapper);
|
|
86
|
+
};
|
|
87
|
+
const onReject = ({ error, apiData }) => {
|
|
88
|
+
var _a;
|
|
89
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
90
|
+
const { name } = apiData;
|
|
91
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
|
|
92
|
+
(0, utils_1.log)(this.importConfig, `Workflow '${name}' already exists`, 'info');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.failedWebhooks.push(apiData);
|
|
96
|
+
if (error.errors['workflow_stages.0.users']) {
|
|
97
|
+
(0, utils_1.log)(this.importConfig, "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.", 'error');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
(0, utils_1.log)(this.importConfig, `Workflow '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
await this.makeConcurrentCall({
|
|
105
|
+
apiContent,
|
|
106
|
+
processName: 'create workflows',
|
|
107
|
+
apiParams: {
|
|
108
|
+
serializeData: this.serializeWorkflows.bind(this),
|
|
109
|
+
reject: onReject,
|
|
110
|
+
resolve: onSuccess,
|
|
111
|
+
entity: 'create-workflows',
|
|
112
|
+
includeParamOnCompletion: true,
|
|
113
|
+
},
|
|
114
|
+
concurrencyLimit: config_1.default.fetchConcurrency || 1,
|
|
115
|
+
}, undefined, false);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* @method serializeWorkflows
|
|
119
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
120
|
+
* @returns {ApiOptions} ApiOptions
|
|
121
|
+
*/
|
|
122
|
+
serializeWorkflows(apiOptions) {
|
|
123
|
+
let { apiData: workflow } = apiOptions;
|
|
124
|
+
if (this.workflowUidMapper.hasOwnProperty(workflow.uid)) {
|
|
125
|
+
(0, utils_1.log)(this.importConfig, `Workflow '${workflow.name}' already exists. Skipping it to avoid duplicates!`, 'info');
|
|
126
|
+
apiOptions.entity = undefined;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
if (workflow.admin_users !== undefined) {
|
|
130
|
+
(0, utils_1.log)(this.importConfig, chalk_1.default.yellow('We are skipping import of `Workflow superuser(s)` from workflow'), 'info');
|
|
131
|
+
delete workflow.admin_users;
|
|
132
|
+
}
|
|
133
|
+
// One branch is required to create workflow.
|
|
134
|
+
if (!workflow.branches) {
|
|
135
|
+
workflow.branches = ['main'];
|
|
136
|
+
}
|
|
137
|
+
apiOptions.apiData = workflow;
|
|
138
|
+
}
|
|
139
|
+
return apiOptions;
|
|
140
|
+
}
|
|
141
|
+
async createCustomRoleIfNotExists(workflow) {
|
|
142
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
143
|
+
const onSuccess = ({ response, apiData, additionalInfo: { workflowUid, stageIndex } }) => {
|
|
144
|
+
const { name } = apiData;
|
|
145
|
+
this.updateRoleData({ workflowUid, stageIndex, roleData: apiData });
|
|
146
|
+
this.roleNameMap[name] = response === null || response === void 0 ? void 0 : response.uid;
|
|
147
|
+
};
|
|
148
|
+
const onReject = ({ error, apiData: { name } = { name: '' } }) => {
|
|
149
|
+
(0, utils_1.log)(this.importConfig, `Failed to create custom roles '${name}'.${(0, utils_1.formatError)(error)}`, 'error');
|
|
150
|
+
};
|
|
151
|
+
const workflowStages = workflow.workflow_stages;
|
|
152
|
+
let stageIndex = 0;
|
|
153
|
+
for (const stage of workflowStages) {
|
|
154
|
+
if (((_c = (_b = (_a = stage === null || stage === void 0 ? void 0 : stage.SYS_ACL) === null || _a === void 0 ? void 0 : _a.users) === null || _b === void 0 ? void 0 : _b.uids) === null || _c === void 0 ? void 0 : _c.length) && ((_e = (_d = stage === null || stage === void 0 ? void 0 : stage.SYS_ACL) === null || _d === void 0 ? void 0 : _d.users) === null || _e === void 0 ? void 0 : _e.uids[0]) !== '$all') {
|
|
155
|
+
stage.SYS_ACL.users.uids = ['$all'];
|
|
156
|
+
}
|
|
157
|
+
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) {
|
|
158
|
+
const apiContent = stage.SYS_ACL.roles.uids;
|
|
159
|
+
await this.makeConcurrentCall({
|
|
160
|
+
apiContent,
|
|
161
|
+
processName: 'create custom role',
|
|
162
|
+
apiParams: {
|
|
163
|
+
serializeData: this.serializeCustomRoles.bind(this),
|
|
164
|
+
reject: onReject,
|
|
165
|
+
resolve: onSuccess,
|
|
166
|
+
entity: 'create-custom-role',
|
|
167
|
+
includeParamOnCompletion: true,
|
|
168
|
+
additionalInfo: { workflowUid: workflow.uid, stageIndex },
|
|
169
|
+
},
|
|
170
|
+
concurrencyLimit: config_1.default.fetchConcurrency || 1,
|
|
171
|
+
}, undefined, false);
|
|
172
|
+
}
|
|
173
|
+
stageIndex++;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* @method serializeCustomRoles
|
|
178
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
179
|
+
* @returns {ApiOptions} ApiOptions
|
|
180
|
+
*/
|
|
181
|
+
serializeCustomRoles(apiOptions) {
|
|
182
|
+
let { apiData: roleData, additionalInfo: { workflowUid, stageIndex }, } = apiOptions;
|
|
183
|
+
if (!this.roleNameMap[roleData.name]) {
|
|
184
|
+
// rules.branch is required to create custom roles.
|
|
185
|
+
const branchRuleExists = (0, find_1.default)(roleData.rules, (rule) => rule.module === 'branch');
|
|
186
|
+
if (!branchRuleExists) {
|
|
187
|
+
roleData.rules.push({
|
|
188
|
+
module: 'branch',
|
|
189
|
+
branches: ['main'],
|
|
190
|
+
acl: { read: true },
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
apiOptions = roleData;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
apiOptions.entity = undefined;
|
|
197
|
+
this.updateRoleData({ workflowUid, stageIndex, roleData });
|
|
198
|
+
}
|
|
199
|
+
return apiOptions;
|
|
200
|
+
}
|
|
201
|
+
updateRoleData(params) {
|
|
202
|
+
const { workflowUid, stageIndex, roleData } = params;
|
|
203
|
+
const workflowStage = this.workflows[workflowUid].workflow_stages;
|
|
204
|
+
const roles = workflowStage[stageIndex].SYS_ACL.roles.uids;
|
|
205
|
+
const index = (0, findIndex_1.default)(roles, ['uid', roleData.uid]);
|
|
206
|
+
roles[index >= 0 ? index : roles.length] = this.roleNameMap[roleData.name];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = ImportWorkflows;
|
|
@@ -74,7 +74,7 @@ module.exports = class ImportCustomRoles {
|
|
|
74
74
|
catch (error) {
|
|
75
75
|
self.fails.push(customRole);
|
|
76
76
|
if (((error && error.errors && error.errors.name) || '').includes('is not a unique.')) {
|
|
77
|
-
log(self.config, `custom-role ${customRole.name} already exists`, 'info');
|
|
77
|
+
log(self.config, `custom-role '${customRole.name}' already exists`, 'info');
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
80
|
if (!(error && error.errors && error.errors.name)) {
|
|
@@ -324,12 +324,12 @@ module.exports = class ImportEntries {
|
|
|
324
324
|
}
|
|
325
325
|
})
|
|
326
326
|
.catch((error) => {
|
|
327
|
-
if (error.hasOwnProperty('
|
|
327
|
+
if (error.hasOwnProperty('errorCode') && error.errorCode === 119) {
|
|
328
328
|
if (error.errors.title) {
|
|
329
329
|
log(this.config, 'Entry ' + eUid + ' already exist, skip to avoid creating a duplicate entry', 'error');
|
|
330
330
|
}
|
|
331
331
|
else {
|
|
332
|
-
log(this.config, `Failed to create an entry ${eUid} ${formatError(error)}`, 'error');
|
|
332
|
+
log(this.config, `Failed to create an entry '${eUid}' ${formatError(error)} Title of the failed entry: '${entries[eUid].title}'`, 'error');
|
|
333
333
|
}
|
|
334
334
|
self.createdEntriesWOUid.push({
|
|
335
335
|
content_type: ctUid,
|
|
@@ -342,7 +342,7 @@ module.exports = class ImportEntries {
|
|
|
342
342
|
}
|
|
343
343
|
// TODO: if status code: 422, check the reason
|
|
344
344
|
// 429 for rate limit
|
|
345
|
-
log(this.config, `Failed to create an entry ${eUid} ${formatError(error)}`, 'error');
|
|
345
|
+
log(this.config, `Failed to create an entry '${eUid}' ${formatError(error)}. Title of the failed entry: '${entries[eUid].title}'`, 'error');
|
|
346
346
|
self.fails.push({
|
|
347
347
|
content_type: ctUid,
|
|
348
348
|
locale: lang,
|
|
@@ -394,7 +394,13 @@ module.exports = class ImportEntries {
|
|
|
394
394
|
return resolve();
|
|
395
395
|
})
|
|
396
396
|
.catch((error) => {
|
|
397
|
-
|
|
397
|
+
var _a, _b;
|
|
398
|
+
let title = (_b = JSON.parse(((_a = error === null || error === void 0 ? void 0 : error.request) === null || _a === void 0 ? void 0 : _a.data) || "{}").entry) === null || _b === void 0 ? void 0 : _b.title;
|
|
399
|
+
addlogs(this.config, chalk.red("Failed to create entries in '" +
|
|
400
|
+
lang +
|
|
401
|
+
"' language. " +
|
|
402
|
+
'Title of the failed entry: ' +
|
|
403
|
+
`'${title || ""}'`), 'error');
|
|
398
404
|
return reject(error);
|
|
399
405
|
});
|
|
400
406
|
});
|
|
@@ -473,7 +479,7 @@ module.exports = class ImportEntries {
|
|
|
473
479
|
return _entry;
|
|
474
480
|
}
|
|
475
481
|
catch (error) {
|
|
476
|
-
addlogs(this.config, `Failed to update the entry ${uid} references while reposting ${formatError(error)}`, 'error');
|
|
482
|
+
addlogs(this.config, `Failed to update the entry '${uid}' references while reposting ${formatError(error)}`, 'error');
|
|
477
483
|
}
|
|
478
484
|
});
|
|
479
485
|
log(this.config, 'Starting the reposting process for entries');
|
|
@@ -544,7 +550,7 @@ module.exports = class ImportEntries {
|
|
|
544
550
|
})
|
|
545
551
|
.catch((error) => {
|
|
546
552
|
// error while updating entries with references
|
|
547
|
-
addlogs(this.config, `Failed re-post entries of content type ${ctUid} locale ${lang}`, 'error');
|
|
553
|
+
addlogs(this.config, `Failed re-post entries of content type '${ctUid}' locale '${lang}'`, 'error');
|
|
548
554
|
addlogs(this.config, formatError(error), 'error');
|
|
549
555
|
// throw error;
|
|
550
556
|
});
|
|
@@ -620,7 +626,7 @@ module.exports = class ImportEntries {
|
|
|
620
626
|
})
|
|
621
627
|
.catch((_error) => {
|
|
622
628
|
addlogs(this.config, formatError(_error), 'error');
|
|
623
|
-
reject(`Failed suppress content type ${schema.uid} reference fields`);
|
|
629
|
+
reject(`Failed suppress content type '${schema.uid}' reference fields`);
|
|
624
630
|
});
|
|
625
631
|
// update 5 content types at a time
|
|
626
632
|
}, {
|
|
@@ -786,10 +792,15 @@ module.exports = class ImportEntries {
|
|
|
786
792
|
return new Promise((resolve, reject) => {
|
|
787
793
|
if (schema.field_rules) {
|
|
788
794
|
let fieldRuleLength = schema.field_rules.length;
|
|
795
|
+
const fieldDatatypeMap = {};
|
|
796
|
+
for (let i = 0; i < schema.schema.length; i++) {
|
|
797
|
+
const field = schema.schema[i].uid;
|
|
798
|
+
fieldDatatypeMap[field] = schema.schema[i].data_type;
|
|
799
|
+
}
|
|
789
800
|
for (let k = 0; k < fieldRuleLength; k++) {
|
|
790
801
|
let fieldRuleConditionLength = schema.field_rules[k].conditions.length;
|
|
791
802
|
for (let i = 0; i < fieldRuleConditionLength; i++) {
|
|
792
|
-
if (schema.field_rules[k].conditions[i].operand_field === 'reference') {
|
|
803
|
+
if (fieldDatatypeMap[schema.field_rules[k].conditions[i].operand_field] === 'reference') {
|
|
793
804
|
let fieldRulesValue = schema.field_rules[k].conditions[i].value;
|
|
794
805
|
let fieldRulesArray = fieldRulesValue.split('.');
|
|
795
806
|
let updatedValue = [];
|
|
@@ -824,6 +835,7 @@ module.exports = class ImportEntries {
|
|
|
824
835
|
})
|
|
825
836
|
.catch((error) => {
|
|
826
837
|
log(this.config, `failed to update the field rules ${formatError(error)}`);
|
|
838
|
+
return reject(error);
|
|
827
839
|
});
|
|
828
840
|
});
|
|
829
841
|
}
|
|
@@ -67,7 +67,7 @@ module.exports = class ImportEnvironments {
|
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
69
|
// the environment has already been created
|
|
70
|
-
log(config, `The environment ${env.name} already exists. Skipping it to avoid duplicates!`, 'success');
|
|
70
|
+
log(config, `The environment '${env.name}' already exists. Skipping it to avoid duplicates!`, 'success');
|
|
71
71
|
}
|
|
72
72
|
}, { concurrency: self.fetchConcurrency })
|
|
73
73
|
.then(function () {
|
|
@@ -59,7 +59,7 @@ module.exports = class ImportExtensions {
|
|
|
59
59
|
log(self.config, `Extension '${ext.title}' already exists`, 'error');
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
|
-
log(self.config, "Extension: '" + ext.title + "' failed to
|
|
62
|
+
log(self.config, "Extension: '" + ext.title + "' failed to import" + formatError(error), 'error');
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
}
|
|
@@ -71,13 +71,14 @@ module.exports = class ImportGlobalFields {
|
|
|
71
71
|
log(self.config, chalk.green('Global field ' + global_field_uid + ' created successfully'), 'success');
|
|
72
72
|
})
|
|
73
73
|
.catch(function (err) {
|
|
74
|
+
console.log;
|
|
74
75
|
let error = JSON.parse(err.message);
|
|
75
76
|
if (error.errors.title) {
|
|
76
77
|
// eslint-disable-next-line no-undef
|
|
77
78
|
log(self.config, `Globalfield '${snip.uid} already exists'`, 'error');
|
|
78
79
|
}
|
|
79
80
|
else {
|
|
80
|
-
log(self.config, chalk.red(`Globalfield failed to import ${formatError(error)}`), 'error');
|
|
81
|
+
log(self.config, chalk.red(`Globalfield '${snip.title}' failed to import. ${formatError(error)}`), 'error');
|
|
81
82
|
}
|
|
82
83
|
self.fails.push(snip);
|
|
83
84
|
});
|
|
@@ -96,10 +97,7 @@ module.exports = class ImportGlobalFields {
|
|
|
96
97
|
return resolve();
|
|
97
98
|
})
|
|
98
99
|
.catch(function (err) {
|
|
99
|
-
// error while importing globalfields
|
|
100
100
|
let error = JSON.parse(err);
|
|
101
|
-
// error while importing globalfields
|
|
102
|
-
log(self.config, err, 'error');
|
|
103
101
|
fileHelper.writeFileSync(globalfieldsFailsPath, self.fails);
|
|
104
102
|
log(self.config, `Globalfields import failed. ${formatError(err)}`, 'error');
|
|
105
103
|
return reject(error);
|
|
@@ -3,7 +3,7 @@ declare class ImportMarketplaceApps {
|
|
|
3
3
|
constructor(importConfig: any, stackAPIClient: any);
|
|
4
4
|
client: any;
|
|
5
5
|
httpClient: any;
|
|
6
|
-
|
|
6
|
+
appOriginalName: any;
|
|
7
7
|
appUidMapping: {};
|
|
8
8
|
appNameMapping: {};
|
|
9
9
|
marketplaceApps: any[];
|
|
@@ -42,10 +42,12 @@ declare class ImportMarketplaceApps {
|
|
|
42
42
|
getAppName(name: any, appSuffix?: number): any;
|
|
43
43
|
/**
|
|
44
44
|
* @method installApps
|
|
45
|
-
*
|
|
46
|
-
* @
|
|
45
|
+
*
|
|
46
|
+
* @param {Record<string, any>} app
|
|
47
|
+
* @param {Record<string, any>[]} installedApps
|
|
48
|
+
* @returns {Promise<void>}
|
|
47
49
|
*/
|
|
48
|
-
installApps(app:
|
|
50
|
+
installApps(app: Record<string, any>, installedApps: Record<string, any>[]): Promise<void>;
|
|
49
51
|
makeRedirectUrlCall(response: any, appName: any): Promise<void>;
|
|
50
52
|
ifAppAlreadyExist(app: any, currentStackApp: any): Promise<any>;
|
|
51
53
|
confirmToCloseProcess(installation: any): Promise<void>;
|