@contentstack/cli-cm-import 1.28.0 → 2.0.0-beta
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 -7
- package/lib/commands/cm/stacks/import.d.ts +2 -0
- package/lib/commands/cm/stacks/import.js +46 -11
- package/lib/config/index.js +0 -1
- package/lib/import/module-importer.d.ts +2 -2
- package/lib/import/module-importer.js +9 -25
- package/lib/import/modules/assets.d.ts +6 -0
- package/lib/import/modules/assets.js +102 -25
- package/lib/import/modules/base-class.d.ts +17 -0
- package/lib/import/modules/base-class.js +45 -0
- package/lib/import/modules/content-types.d.ts +7 -10
- package/lib/import/modules/content-types.js +132 -68
- package/lib/import/modules/custom-roles.d.ts +6 -2
- package/lib/import/modules/custom-roles.js +80 -69
- package/lib/import/modules/entries.d.ts +7 -0
- package/lib/import/modules/entries.js +278 -163
- package/lib/import/modules/environments.d.ts +3 -0
- package/lib/import/modules/environments.js +69 -38
- package/lib/import/modules/extensions.d.ts +3 -0
- package/lib/import/modules/extensions.js +99 -64
- package/lib/import/modules/global-fields.d.ts +8 -1
- package/lib/import/modules/global-fields.js +123 -63
- package/lib/import/modules/index.d.ts +1 -0
- package/lib/import/modules/index.js +1 -0
- package/lib/import/modules/labels.d.ts +3 -0
- package/lib/import/modules/labels.js +104 -54
- package/lib/import/modules/locales.d.ts +15 -4
- package/lib/import/modules/locales.js +194 -94
- package/lib/import/modules/marketplace-apps.d.ts +6 -3
- package/lib/import/modules/marketplace-apps.js +177 -102
- package/lib/import/modules/personalize.d.ts +11 -4
- package/lib/import/modules/personalize.js +138 -47
- package/lib/import/modules/stack.d.ts +6 -0
- package/lib/import/modules/stack.js +71 -27
- package/lib/import/modules/taxonomies.d.ts +4 -2
- package/lib/import/modules/taxonomies.js +60 -46
- package/lib/import/modules/variant-entries.d.ts +7 -4
- package/lib/import/modules/variant-entries.js +76 -35
- package/lib/import/modules/webhooks.d.ts +3 -0
- package/lib/import/modules/webhooks.js +71 -40
- package/lib/import/modules/workflows.d.ts +3 -0
- package/lib/import/modules/workflows.js +98 -48
- package/lib/types/default-config.d.ts +0 -1
- package/lib/types/import-config.d.ts +0 -1
- package/lib/types/index.d.ts +1 -12
- package/lib/utils/backup-handler.js +1 -2
- package/lib/utils/constants.d.ts +243 -0
- package/lib/utils/constants.js +264 -0
- package/lib/utils/import-config-handler.js +2 -7
- package/lib/utils/import-path-resolver.d.ts +1 -1
- package/lib/utils/import-path-resolver.js +5 -5
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +6 -2
- package/lib/utils/marketplace-app-helper.js +3 -8
- package/lib/utils/progress-strategy-registry.d.ts +7 -0
- package/lib/utils/progress-strategy-registry.js +72 -0
- package/lib/utils/setup-branch.js +1 -1
- package/oclif.manifest.json +2 -2
- package/package.json +2 -2
- package/lib/import/modules-js/assets.d.ts +0 -33
- package/lib/import/modules-js/assets.js +0 -428
- package/lib/import/modules-js/content-types.d.ts +0 -34
- package/lib/import/modules-js/content-types.js +0 -204
- package/lib/import/modules-js/custom-roles.d.ts +0 -15
- package/lib/import/modules-js/custom-roles.js +0 -143
- package/lib/import/modules-js/entries.d.ts +0 -54
- package/lib/import/modules-js/entries.js +0 -1280
- package/lib/import/modules-js/environments.d.ts +0 -13
- package/lib/import/modules-js/environments.js +0 -85
- package/lib/import/modules-js/extensions.d.ts +0 -18
- package/lib/import/modules-js/extensions.js +0 -86
- package/lib/import/modules-js/global-fields.d.ts +0 -13
- package/lib/import/modules-js/global-fields.js +0 -106
- package/lib/import/modules-js/index.d.ts +0 -1
- package/lib/import/modules-js/index.js +0 -33
- package/lib/import/modules-js/labels.d.ts +0 -20
- package/lib/import/modules-js/labels.js +0 -148
- package/lib/import/modules-js/locales.d.ts +0 -24
- package/lib/import/modules-js/locales.js +0 -196
- package/lib/import/modules-js/marketplace-apps.d.ts +0 -63
- package/lib/import/modules-js/marketplace-apps.js +0 -429
- package/lib/import/modules-js/webhooks.d.ts +0 -17
- package/lib/import/modules-js/webhooks.js +0 -85
- package/lib/import/modules-js/workflows.d.ts +0 -19
- package/lib/import/modules-js/workflows.js +0 -170
- package/lib/utils/log.d.ts +0 -12
- package/lib/utils/log.js +0 -31
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable no-prototype-builtins */
|
|
3
|
-
/*!
|
|
4
|
-
* Contentstack Import
|
|
5
|
-
* Copyright (c) 2024 Contentstack LLC
|
|
6
|
-
* MIT Licensed
|
|
7
|
-
*/
|
|
8
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
3
|
const tslib_1 = require("tslib");
|
|
10
4
|
const path = tslib_1.__importStar(require("path"));
|
|
11
5
|
const lodash_1 = require("lodash");
|
|
12
6
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
13
|
-
const utils_1 = require("../../utils");
|
|
14
7
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
15
8
|
const content_type_helper_1 = require("../../utils/content-type-helper");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
16
10
|
class ContentTypesImport extends base_class_1.default {
|
|
17
11
|
constructor({ importConfig, stackAPIClient }) {
|
|
18
12
|
super({ importConfig, stackAPIClient });
|
|
19
13
|
this.isExtensionsUpdate = false;
|
|
20
|
-
this.importConfig.context.module =
|
|
14
|
+
this.importConfig.context.module = utils_1.MODULE_CONTEXTS.CONTENT_TYPES;
|
|
15
|
+
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.CONTENT_TYPES];
|
|
21
16
|
this.cTsConfig = importConfig.modules['content-types'];
|
|
22
17
|
this.gFsConfig = importConfig.modules['global-fields'];
|
|
23
18
|
this.reqConcurrency = this.cTsConfig.writeConcurrency || this.importConfig.writeConcurrency;
|
|
24
19
|
this.cTsFolderPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), (0, cli_utilities_1.sanitizePath)(this.cTsConfig.dirName));
|
|
25
20
|
this.cTsMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'content_types');
|
|
26
|
-
this.cTsSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.
|
|
21
|
+
this.cTsSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', 'content_types', 'success.json');
|
|
27
22
|
this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.importConfig.data), (0, cli_utilities_1.sanitizePath)(this.gFsConfig.dirName));
|
|
28
23
|
this.gFsMapperFolderPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'global_fields', 'success.json');
|
|
29
24
|
this.gFsPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'global_fields', 'pending_global_fields.js');
|
|
@@ -41,69 +36,55 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
41
36
|
this.gFs = [];
|
|
42
37
|
this.createdGFs = [];
|
|
43
38
|
this.pendingGFs = [];
|
|
44
|
-
this.
|
|
39
|
+
this.pendingExts = [];
|
|
40
|
+
this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'taxonomies', 'success.json');
|
|
45
41
|
this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.data), 'mapper', 'extensions', 'pending_extensions.js');
|
|
46
42
|
}
|
|
47
43
|
async start() {
|
|
48
|
-
var _a
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
cli_utilities_1.log.success('Created content types', this.importConfig.context);
|
|
76
|
-
cli_utilities_1.log.info('Starting content types update process', this.importConfig.context);
|
|
77
|
-
await this.updateCTs();
|
|
78
|
-
cli_utilities_1.log.success('Updated content types with references', this.importConfig.context);
|
|
79
|
-
if (this.fieldRules.length > 0) {
|
|
80
|
-
utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
|
|
81
|
-
cli_utilities_1.log.debug(`Written ${this.fieldRules.length} field rules to file`, this.importConfig.context);
|
|
82
|
-
}
|
|
83
|
-
cli_utilities_1.log.info('Updating the extensions...', this.importConfig.context);
|
|
84
|
-
await this.updatePendingExtensions();
|
|
85
|
-
if (this.isExtensionsUpdate) {
|
|
86
|
-
cli_utilities_1.log.success('Successfully updated the extensions.', this.importConfig.context);
|
|
87
|
-
}
|
|
88
|
-
cli_utilities_1.log.info('Starting pending global fields update', this.importConfig.context);
|
|
89
|
-
this.pendingGFs = utils_1.fsUtil.readFile(this.gFsPendingPath);
|
|
90
|
-
if (!this.pendingGFs || (0, lodash_1.isEmpty)(this.pendingGFs)) {
|
|
91
|
-
cli_utilities_1.log.info('No pending global fields found to update', this.importConfig.context);
|
|
92
|
-
return;
|
|
44
|
+
var _a;
|
|
45
|
+
try {
|
|
46
|
+
cli_utilities_1.log.debug('Starting content types import process...', this.importConfig.context);
|
|
47
|
+
await this.analyzeImportData();
|
|
48
|
+
if (!((_a = this.cTs) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
49
|
+
cli_utilities_1.log.info('No content type found to import', this.importConfig.context);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
await utils_1.fsUtil.makeDirectory(this.cTsMapperPath);
|
|
53
|
+
cli_utilities_1.log.debug('Created content types mapper directory', this.importConfig.context);
|
|
54
|
+
const progress = this.initializeProgress();
|
|
55
|
+
if (this.cTs.length > 0) {
|
|
56
|
+
await this.handleContentTypesCreation(progress);
|
|
57
|
+
await this.handleContentTypesUpdate(progress);
|
|
58
|
+
}
|
|
59
|
+
if (this.fieldRules.length > 0) {
|
|
60
|
+
utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
|
|
61
|
+
cli_utilities_1.log.debug(`Written ${this.fieldRules.length} field rules to file`, this.importConfig.context);
|
|
62
|
+
}
|
|
63
|
+
if (this.pendingExts.length > 0) {
|
|
64
|
+
await this.handlePendingExtensions(progress);
|
|
65
|
+
}
|
|
66
|
+
if (this.pendingGFs.length > 0) {
|
|
67
|
+
await this.handlePendingGlobalFields(progress);
|
|
68
|
+
}
|
|
69
|
+
this.completeProgress(true);
|
|
70
|
+
cli_utilities_1.log.success('Content types have been imported successfully!', this.importConfig.context);
|
|
93
71
|
}
|
|
94
|
-
|
|
72
|
+
catch (error) {
|
|
73
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Content types import failed');
|
|
95
74
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
|
|
96
|
-
}
|
|
97
|
-
cli_utilities_1.log.success('Updated pending global fields with content type with references', this.importConfig.context);
|
|
98
|
-
cli_utilities_1.log.success('Content types have been imported successfully!', this.importConfig.context);
|
|
75
|
+
}
|
|
99
76
|
}
|
|
100
77
|
async seedCTs() {
|
|
101
78
|
const onSuccess = ({ response: globalField, apiData: { content_type: { uid = null } = {} } = {} }) => {
|
|
79
|
+
var _a;
|
|
102
80
|
this.createdCTs.push(uid);
|
|
103
|
-
|
|
81
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `content type: ${uid}`, null, utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE);
|
|
82
|
+
cli_utilities_1.log.success(`Content type '${uid}' created successfully`, this.importConfig.context);
|
|
104
83
|
cli_utilities_1.log.debug(`Successfully seeded content type: ${uid}`, this.importConfig.context);
|
|
105
84
|
};
|
|
106
85
|
const onReject = ({ error, apiData: { content_type: { uid = null } = {} } = {} }) => {
|
|
86
|
+
var _a;
|
|
87
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `content type: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Failed to create content type '${uid}'`, utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE);
|
|
107
88
|
if (error.errorCode === 115 && (error.errors.uid || error.errors.title)) {
|
|
108
89
|
cli_utilities_1.log.info(`${uid} content type already exist`, this.importConfig.context);
|
|
109
90
|
cli_utilities_1.log.debug(`Skipping existing content type: ${uid}`, this.importConfig.context);
|
|
@@ -142,12 +123,15 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
142
123
|
}
|
|
143
124
|
async updateCTs() {
|
|
144
125
|
const onSuccess = ({ response: contentType, apiData: { uid } }) => {
|
|
126
|
+
var _a;
|
|
127
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `content type: ${uid}`, null, utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE);
|
|
145
128
|
cli_utilities_1.log.success(`'${uid}' updated with references`, this.importConfig.context);
|
|
146
129
|
cli_utilities_1.log.debug(`Content type update completed for: ${uid}`, this.importConfig.context);
|
|
147
130
|
};
|
|
148
131
|
const onReject = ({ error, apiData: { uid } }) => {
|
|
132
|
+
var _a;
|
|
133
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `content type: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Content type '${uid}' update failed`, utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE);
|
|
149
134
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Content type '${uid}' update failed`);
|
|
150
|
-
throw new Error(`Content type '${uid}' update error`);
|
|
151
135
|
};
|
|
152
136
|
cli_utilities_1.log.debug(`Starting to update ${this.cTs.length} content types with references`, this.importConfig.context);
|
|
153
137
|
return await this.makeConcurrentCall({
|
|
@@ -195,16 +179,21 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
195
179
|
}
|
|
196
180
|
async updatePendingGFs() {
|
|
197
181
|
var _a, _b;
|
|
198
|
-
this.pendingGFs
|
|
199
|
-
|
|
200
|
-
|
|
182
|
+
if (!this.pendingGFs || this.pendingGFs.length === 0) {
|
|
183
|
+
cli_utilities_1.log.info('No pending global fields found to update', this.importConfig.context);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
201
186
|
cli_utilities_1.log.debug(`Found ${((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) || 0} pending global fields to update`, this.importConfig.context);
|
|
202
187
|
cli_utilities_1.log.debug(`Loaded ${((_b = this.gFs) === null || _b === void 0 ? void 0 : _b.length) || 0} global fields from file`, this.importConfig.context);
|
|
203
188
|
const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
|
|
204
|
-
|
|
189
|
+
var _a;
|
|
190
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `global field: ${uid}`, null, utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE);
|
|
191
|
+
cli_utilities_1.log.success(`Updated the global field ${uid} with content type references`, this.importConfig.context);
|
|
205
192
|
cli_utilities_1.log.debug(`Global field update completed for: ${uid}`, this.importConfig.context);
|
|
206
193
|
};
|
|
207
194
|
const onReject = ({ error, apiData: { uid } = undefined }) => {
|
|
195
|
+
var _a;
|
|
196
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `global field: ${uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Failed to update the global field '${uid}'`, utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE);
|
|
208
197
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to update the global field '${uid}'`);
|
|
209
198
|
};
|
|
210
199
|
const apiContent = (0, lodash_1.map)(this.pendingGFs, (uid) => {
|
|
@@ -258,13 +247,16 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
258
247
|
cli_utilities_1.log.debug(`Found ${apiContent.length} extensions to update`, this.importConfig.context);
|
|
259
248
|
this.isExtensionsUpdate = true;
|
|
260
249
|
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
|
|
250
|
+
var _a;
|
|
251
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `extension: ${response.title || title || uid}`, null, utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE);
|
|
261
252
|
cli_utilities_1.log.success(`Successfully updated the '${response.title}' extension.`, this.importConfig.context);
|
|
262
253
|
cli_utilities_1.log.debug(`Extension update completed for: ${uid}`, this.importConfig.context);
|
|
263
254
|
};
|
|
264
255
|
const onReject = ({ error, apiData }) => {
|
|
265
|
-
var _a;
|
|
266
|
-
const { uid } = apiData;
|
|
267
|
-
|
|
256
|
+
var _a, _b;
|
|
257
|
+
const { uid, title } = apiData;
|
|
258
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `extension: ${title || uid}`, (error === null || error === void 0 ? void 0 : error.message) || `Failed to update '${uid}' extension`, utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE);
|
|
259
|
+
if ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.title) {
|
|
268
260
|
if (!this.importConfig.skipExisting) {
|
|
269
261
|
cli_utilities_1.log.info(`Extension '${uid}' already exists.`, this.importConfig.context);
|
|
270
262
|
}
|
|
@@ -287,5 +279,77 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
287
279
|
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
288
280
|
}, undefined, false);
|
|
289
281
|
}
|
|
282
|
+
async analyzeImportData() {
|
|
283
|
+
var _a, _b, _c, _d, _e;
|
|
284
|
+
const [cts, gfs, pendingGfs, pendingExt] = await this.withLoadingSpinner('CONTENT TYPES: Analyzing import data...', async () => {
|
|
285
|
+
const cts = utils_1.fsUtil.readFile(path.join(this.cTsFolderPath, 'schema.json'));
|
|
286
|
+
const gfs = utils_1.fsUtil.readFile(path.resolve(this.gFsFolderPath, this.gFsConfig.fileName));
|
|
287
|
+
const pendingGfs = utils_1.fsUtil.readFile(this.gFsPendingPath);
|
|
288
|
+
const pendingExt = utils_1.fsUtil.readFile(this.extPendingPath);
|
|
289
|
+
return [cts, gfs, pendingGfs, pendingExt];
|
|
290
|
+
});
|
|
291
|
+
this.cTs = (Array.isArray(cts) ? cts : []);
|
|
292
|
+
this.gFs = (Array.isArray(gfs) ? gfs : []);
|
|
293
|
+
this.pendingGFs = (Array.isArray(pendingGfs) ? pendingGfs : []);
|
|
294
|
+
this.pendingExts = (Array.isArray(pendingExt) ? pendingExt : []);
|
|
295
|
+
const marketplaceAppData = utils_1.fsUtil.readFile(this.marketplaceAppMapperPath);
|
|
296
|
+
this.installedExtensions = (marketplaceAppData === null || marketplaceAppData === void 0 ? void 0 : marketplaceAppData.extension_uid) || { extension_uid: {} };
|
|
297
|
+
this.taxonomies = utils_1.fsUtil.readFile(this.taxonomiesPath);
|
|
298
|
+
cli_utilities_1.log.debug(`Analysis complete: ${(_a = this.cTs) === null || _a === void 0 ? void 0 : _a.length} content types, ${(_b = this.gFs) === null || _b === void 0 ? void 0 : _b.length} global fields, ${(_c = this.pendingGFs) === null || _c === void 0 ? void 0 : _c.length} pending GFs, ${(_d = Object.keys(this.installedExtensions || {})) === null || _d === void 0 ? void 0 : _d.length} extensions, ${(_e = Object.keys(this.taxonomies || {})) === null || _e === void 0 ? void 0 : _e.length} taxonomies`, this.importConfig.context);
|
|
299
|
+
}
|
|
300
|
+
initializeProgress() {
|
|
301
|
+
const progress = this.createNestedProgress(this.currentModuleName);
|
|
302
|
+
if (this.cTs.length) {
|
|
303
|
+
progress.addProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE, this.cTs.length);
|
|
304
|
+
progress.addProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE, this.cTs.length);
|
|
305
|
+
}
|
|
306
|
+
if (this.pendingGFs.length) {
|
|
307
|
+
progress.addProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE, this.pendingGFs.length);
|
|
308
|
+
}
|
|
309
|
+
if (this.pendingExts.length) {
|
|
310
|
+
progress.addProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE, this.pendingExts.length);
|
|
311
|
+
}
|
|
312
|
+
return progress;
|
|
313
|
+
}
|
|
314
|
+
async handlePendingGlobalFields(progress) {
|
|
315
|
+
progress
|
|
316
|
+
.startProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE)
|
|
317
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE].UPDATING, utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE);
|
|
318
|
+
cli_utilities_1.log.info('Starting pending global fields update process', this.importConfig.context);
|
|
319
|
+
await this.updatePendingGFs();
|
|
320
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_GF_UPDATE, true);
|
|
321
|
+
}
|
|
322
|
+
async handleContentTypesCreation(progress) {
|
|
323
|
+
var _a;
|
|
324
|
+
progress
|
|
325
|
+
.startProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE)
|
|
326
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE].CREATING, utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE);
|
|
327
|
+
cli_utilities_1.log.info('Starting content types seeding process', this.importConfig.context);
|
|
328
|
+
await this.seedCTs();
|
|
329
|
+
if ((_a = this.createdCTs) === null || _a === void 0 ? void 0 : _a.length) {
|
|
330
|
+
utils_1.fsUtil.writeFile(this.cTsSuccessPath, this.createdCTs);
|
|
331
|
+
cli_utilities_1.log.debug(`Written ${this.createdCTs.length} successful content types to file`, this.importConfig.context);
|
|
332
|
+
}
|
|
333
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_CREATE, true);
|
|
334
|
+
}
|
|
335
|
+
async handleContentTypesUpdate(progress) {
|
|
336
|
+
progress
|
|
337
|
+
.startProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE)
|
|
338
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE].UPDATING, utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE);
|
|
339
|
+
cli_utilities_1.log.info('Starting Update process', this.importConfig.context);
|
|
340
|
+
await this.updateCTs();
|
|
341
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_UPDATE, true);
|
|
342
|
+
}
|
|
343
|
+
async handlePendingExtensions(progress) {
|
|
344
|
+
progress
|
|
345
|
+
.startProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE)
|
|
346
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE].UPDATING, utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE);
|
|
347
|
+
cli_utilities_1.log.info('Starting pending extensions update process', this.importConfig.context);
|
|
348
|
+
await this.updatePendingExtensions();
|
|
349
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.CONTENT_TYPES_EXT_UPDATE, true);
|
|
350
|
+
if (this.isExtensionsUpdate) {
|
|
351
|
+
cli_utilities_1.log.success('Successfully updated the extensions.', this.importConfig.context);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
290
354
|
}
|
|
291
355
|
exports.default = ContentTypesImport;
|
|
@@ -28,10 +28,14 @@ export default class ImportCustomRoles extends BaseClass {
|
|
|
28
28
|
getLocalesUidMap(): Promise<void>;
|
|
29
29
|
importCustomRoles(): Promise<void>;
|
|
30
30
|
/**
|
|
31
|
-
* @method
|
|
31
|
+
* @method serializeCustomRoles
|
|
32
32
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
33
33
|
* @returns {ApiOptions} ApiOptions
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
serializeCustomRoles(apiOptions: ApiOptions): ApiOptions;
|
|
36
36
|
getTransformUidsFactory: (rule: Record<string, any>) => Record<string, any>;
|
|
37
|
+
private analyzeCustomRoles;
|
|
38
|
+
private prepareForImport;
|
|
39
|
+
private loadJsonFileIfExists;
|
|
40
|
+
private handleImportResults;
|
|
37
41
|
}
|
|
@@ -46,7 +46,8 @@ class ImportCustomRoles extends base_class_1.default {
|
|
|
46
46
|
}
|
|
47
47
|
return rule;
|
|
48
48
|
};
|
|
49
|
-
this.importConfig.context.module =
|
|
49
|
+
this.importConfig.context.module = utils_1.MODULE_CONTEXTS.CUSTOM_ROLES;
|
|
50
|
+
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.CUSTOM_ROLES];
|
|
50
51
|
this.customRolesConfig = importConfig.modules.customRoles;
|
|
51
52
|
this.customRolesMapperPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'custom-roles');
|
|
52
53
|
this.customRolesFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.customRolesConfig.dirName);
|
|
@@ -69,69 +70,27 @@ class ImportCustomRoles extends base_class_1.default {
|
|
|
69
70
|
* @returns {Promise<void>} Promise<void>
|
|
70
71
|
*/
|
|
71
72
|
async start() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.customRolesUidMapper = utils_1.fileHelper.fileExistsSync(this.customRolesUidMapperPath)
|
|
89
|
-
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesUidMapperPath), true) || {}
|
|
90
|
-
: {};
|
|
91
|
-
cli_utilities_1.log.debug('Loading environments UID data', this.importConfig.context);
|
|
92
|
-
this.environmentsUidMap = utils_1.fileHelper.fileExistsSync(this.envUidMapperFolderPath)
|
|
93
|
-
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.envUidMapperFolderPath, 'uid-mapping.json'), true) || {}
|
|
94
|
-
: {};
|
|
95
|
-
cli_utilities_1.log.debug('Loading entries UID data', this.importConfig.context);
|
|
96
|
-
this.entriesUidMap = utils_1.fileHelper.fileExistsSync(this.entriesUidMapperFolderPath)
|
|
97
|
-
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.entriesUidMapperFolderPath, 'uid-mapping.json'), true) || {}
|
|
98
|
-
: {};
|
|
99
|
-
if (this.customRolesUidMapper && Object.keys(this.customRolesUidMapper || {}).length > 0) {
|
|
100
|
-
const customRolesUidCount = Object.keys(this.customRolesUidMapper || {}).length;
|
|
101
|
-
cli_utilities_1.log.debug(`Loaded existing custom roles UID data: ${customRolesUidCount} items`, this.importConfig.context);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
cli_utilities_1.log.debug('No existing custom roles UID data found', this.importConfig.context);
|
|
105
|
-
}
|
|
106
|
-
if (this.environmentsUidMap && ((_a = Object.keys(this.environmentsUidMap || {})) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
107
|
-
const envUidCount = Object.keys(this.environmentsUidMap || {}).length;
|
|
108
|
-
cli_utilities_1.log.debug(`Loaded environments UID data: ${envUidCount} items`, this.importConfig.context);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
cli_utilities_1.log.debug('No environments UID data found', this.importConfig.context);
|
|
112
|
-
}
|
|
113
|
-
if (this.entriesUidMap && Object.keys(this.entriesUidMap || {}).length > 0) {
|
|
114
|
-
const entriesUidCount = Object.keys(this.entriesUidMap || {}).length;
|
|
115
|
-
cli_utilities_1.log.debug(`Loaded entries UID data: ${entriesUidCount} items`, this.importConfig.context);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
cli_utilities_1.log.debug('No entries UID data found', this.importConfig.context);
|
|
119
|
-
}
|
|
120
|
-
//source and target stack locale map
|
|
121
|
-
cli_utilities_1.log.debug('Getting locales UID mapping', this.importConfig.context);
|
|
122
|
-
await this.getLocalesUidMap();
|
|
123
|
-
cli_utilities_1.log.debug('Starting custom roles import', this.importConfig.context);
|
|
124
|
-
await this.importCustomRoles();
|
|
125
|
-
cli_utilities_1.log.debug('Processing custom roles import results', this.importConfig.context);
|
|
126
|
-
if ((_b = this.createdCustomRoles) === null || _b === void 0 ? void 0 : _b.length) {
|
|
127
|
-
utils_1.fsUtil.writeFile(this.createdCustomRolesPath, this.createdCustomRoles);
|
|
128
|
-
cli_utilities_1.log.debug(`Written ${this.createdCustomRoles.length} successful custom roles to file`, this.importConfig.context);
|
|
73
|
+
try {
|
|
74
|
+
cli_utilities_1.log.debug('Starting custom roles import process...', this.importConfig.context);
|
|
75
|
+
const [customRolesCount] = await this.analyzeCustomRoles();
|
|
76
|
+
if (customRolesCount === 0) {
|
|
77
|
+
cli_utilities_1.log.info(`No custom-rules are found - '${this.customRolesFolderPath}'`, this.importConfig.context);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const progress = this.createSimpleProgress(this.currentModuleName, customRolesCount);
|
|
81
|
+
await this.prepareForImport();
|
|
82
|
+
progress.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CUSTOM_ROLES_BUILD_MAPPINGS].BUILDING);
|
|
83
|
+
await this.getLocalesUidMap();
|
|
84
|
+
progress.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.CUSTOM_ROLES_IMPORT].IMPORTING);
|
|
85
|
+
await this.importCustomRoles();
|
|
86
|
+
this.handleImportResults();
|
|
87
|
+
this.completeProgress(true);
|
|
88
|
+
cli_utilities_1.log.success('Custom roles have been imported successfully!', this.importConfig.context);
|
|
129
89
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
cli_utilities_1.
|
|
90
|
+
catch (error) {
|
|
91
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Custom roles import failed');
|
|
92
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
|
|
133
93
|
}
|
|
134
|
-
cli_utilities_1.log.success('Custom roles have been imported successfully!', this.importConfig.context);
|
|
135
94
|
}
|
|
136
95
|
async getLocalesUidMap() {
|
|
137
96
|
cli_utilities_1.log.debug('Fetching target stack locales', this.importConfig.context);
|
|
@@ -176,31 +135,35 @@ class ImportCustomRoles extends base_class_1.default {
|
|
|
176
135
|
const apiContent = (0, values_1.default)(this.customRoles);
|
|
177
136
|
cli_utilities_1.log.debug(`Importing ${apiContent.length} custom roles`, this.importConfig.context);
|
|
178
137
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
138
|
+
var _a;
|
|
179
139
|
this.createdCustomRoles.push(response);
|
|
180
140
|
this.customRolesUidMapper[uid] = response.uid;
|
|
141
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `custom role: ${name}`, `custom role: ${name || uid}`, utils_1.PROCESS_NAMES.CUSTOM_ROLES_IMPORT);
|
|
181
142
|
cli_utilities_1.log.success(`custom-role '${name}' imported successfully`, this.importConfig.context);
|
|
182
143
|
cli_utilities_1.log.debug(`Custom role import completed: ${name} (${uid})`, this.importConfig.context);
|
|
183
144
|
utils_1.fsUtil.writeFile(this.customRolesUidMapperPath, this.customRolesUidMapper);
|
|
184
145
|
};
|
|
185
146
|
const onReject = ({ error, apiData }) => {
|
|
186
|
-
var _a;
|
|
147
|
+
var _a, _b, _c;
|
|
187
148
|
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
188
149
|
const { name } = apiData;
|
|
189
150
|
cli_utilities_1.log.debug(`Custom role '${name}' import failed`, this.importConfig.context);
|
|
190
151
|
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
|
|
152
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `custom role: ${name}`, `custom role: ${name} (already exists)`, utils_1.PROCESS_NAMES.CUSTOM_ROLES_IMPORT);
|
|
191
153
|
cli_utilities_1.log.info(`custom-role '${name}' already exists`, this.importConfig.context);
|
|
192
154
|
}
|
|
193
155
|
else {
|
|
194
156
|
this.failedCustomRoles.push(apiData);
|
|
157
|
+
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `custom role: ${name}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to import custom role', utils_1.PROCESS_NAMES.CUSTOM_ROLES_IMPORT);
|
|
195
158
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `custom-role '${name}' failed to be import`);
|
|
196
159
|
}
|
|
197
160
|
};
|
|
198
|
-
cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency ||
|
|
161
|
+
cli_utilities_1.log.debug(`Using concurrency limit: ${this.importConfig.fetchConcurrency || 2}`, this.importConfig.context);
|
|
199
162
|
await this.makeConcurrentCall({
|
|
200
163
|
apiContent,
|
|
201
164
|
processName: 'create custom role',
|
|
202
165
|
apiParams: {
|
|
203
|
-
serializeData: this.
|
|
166
|
+
serializeData: this.serializeCustomRoles.bind(this),
|
|
204
167
|
reject: onReject.bind(this),
|
|
205
168
|
resolve: onSuccess.bind(this),
|
|
206
169
|
entity: 'create-custom-role',
|
|
@@ -211,22 +174,25 @@ class ImportCustomRoles extends base_class_1.default {
|
|
|
211
174
|
cli_utilities_1.log.debug('Custom roles import process completed', this.importConfig.context);
|
|
212
175
|
}
|
|
213
176
|
/**
|
|
214
|
-
* @method
|
|
177
|
+
* @method serializeCustomRoles
|
|
215
178
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
216
179
|
* @returns {ApiOptions} ApiOptions
|
|
217
180
|
*/
|
|
218
|
-
|
|
219
|
-
var _a;
|
|
181
|
+
serializeCustomRoles(apiOptions) {
|
|
182
|
+
var _a, _b;
|
|
220
183
|
const { apiData: customRole } = apiOptions;
|
|
221
184
|
cli_utilities_1.log.debug(`Serializing custom role: ${customRole.name} (${customRole.uid})`, this.importConfig.context);
|
|
222
185
|
if (this.customRolesUidMapper.hasOwnProperty(customRole.uid)) {
|
|
223
186
|
cli_utilities_1.log.info(`custom-role '${customRole.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
|
|
224
187
|
cli_utilities_1.log.debug(`Skipping custom role serialization for: ${customRole.uid}`, this.importConfig.context);
|
|
188
|
+
// Still tick progress for skipped custom roles
|
|
189
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `custom role: ${customRole.name} (skipped - already exists)`, utils_1.PROCESS_NAMES.CUSTOM_ROLES_IMPORT);
|
|
225
190
|
apiOptions.entity = undefined;
|
|
226
191
|
}
|
|
227
192
|
else {
|
|
193
|
+
cli_utilities_1.log.debug(`Processing custom role: ${customRole.name}`, this.importConfig.context);
|
|
228
194
|
let branchRuleExists = false;
|
|
229
|
-
cli_utilities_1.log.debug(`Processing ${((
|
|
195
|
+
cli_utilities_1.log.debug(`Processing ${((_b = customRole.rules) === null || _b === void 0 ? void 0 : _b.length) || 0} rules for custom role: ${customRole.name}`, this.importConfig.context);
|
|
230
196
|
(0, lodash_1.forEach)(customRole.rules, (rule) => {
|
|
231
197
|
rule = this.getTransformUidsFactory(rule);
|
|
232
198
|
// rules.branch is required to create custom roles.
|
|
@@ -248,5 +214,50 @@ class ImportCustomRoles extends base_class_1.default {
|
|
|
248
214
|
}
|
|
249
215
|
return apiOptions;
|
|
250
216
|
}
|
|
217
|
+
async analyzeCustomRoles() {
|
|
218
|
+
return this.withLoadingSpinner('CUSTOM ROLES: Analyzing import data...', async () => {
|
|
219
|
+
cli_utilities_1.log.debug('Checking for custom roles folder existence', this.importConfig.context);
|
|
220
|
+
if (!utils_1.fileHelper.fileExistsSync(this.customRolesFolderPath)) {
|
|
221
|
+
cli_utilities_1.log.info(`No custom-rules are found - '${this.customRolesFolderPath}'`, this.importConfig.context);
|
|
222
|
+
return [0];
|
|
223
|
+
}
|
|
224
|
+
cli_utilities_1.log.debug(`Found custom roles folder: ${this.customRolesFolderPath}`, this.importConfig.context);
|
|
225
|
+
this.customRoles = utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesFolderPath, this.customRolesConfig.fileName), true);
|
|
226
|
+
this.customRolesLocales = utils_1.fsUtil.readFile((0, node_path_1.join)(this.customRolesFolderPath, this.customRolesConfig.customRolesLocalesFileName), true);
|
|
227
|
+
const count = Object.keys(this.customRoles || {}).length;
|
|
228
|
+
cli_utilities_1.log.debug(`Loaded ${count} custom roles from file`, this.importConfig.context);
|
|
229
|
+
return [count];
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async prepareForImport() {
|
|
233
|
+
cli_utilities_1.log.debug('Creating custom roles mapper directory', this.importConfig.context);
|
|
234
|
+
await utils_1.fsUtil.makeDirectory(this.customRolesMapperPath);
|
|
235
|
+
this.customRolesUidMapper = this.loadJsonFileIfExists(this.customRolesUidMapperPath, 'custom roles');
|
|
236
|
+
this.environmentsUidMap = this.loadJsonFileIfExists((0, node_path_1.join)(this.envUidMapperFolderPath, 'uid-mapping.json'), 'environments');
|
|
237
|
+
this.entriesUidMap = this.loadJsonFileIfExists((0, node_path_1.join)(this.entriesUidMapperFolderPath, 'uid-mapping.json'), 'entries');
|
|
238
|
+
}
|
|
239
|
+
loadJsonFileIfExists(path, label) {
|
|
240
|
+
if (utils_1.fileHelper.fileExistsSync(path)) {
|
|
241
|
+
const data = utils_1.fsUtil.readFile(path, true);
|
|
242
|
+
const count = Object.keys(data || {}).length;
|
|
243
|
+
cli_utilities_1.log.debug(`Loaded ${label}: ${count} items`, this.importConfig.context);
|
|
244
|
+
return data || {};
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
cli_utilities_1.log.debug(`No ${label} UID data found`, this.importConfig.context);
|
|
248
|
+
return {};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
handleImportResults() {
|
|
252
|
+
var _a, _b;
|
|
253
|
+
if ((_a = this.createdCustomRoles) === null || _a === void 0 ? void 0 : _a.length) {
|
|
254
|
+
utils_1.fsUtil.writeFile(this.createdCustomRolesPath, this.createdCustomRoles);
|
|
255
|
+
cli_utilities_1.log.debug(`Written ${this.createdCustomRoles.length} successful custom roles to file`, this.importConfig.context);
|
|
256
|
+
}
|
|
257
|
+
if ((_b = this.failedCustomRoles) === null || _b === void 0 ? void 0 : _b.length) {
|
|
258
|
+
utils_1.fsUtil.writeFile(this.customRolesFailsPath, this.failedCustomRoles);
|
|
259
|
+
cli_utilities_1.log.debug(`Written ${this.failedCustomRoles.length} failed custom roles to file`, this.importConfig.context);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
251
262
|
}
|
|
252
263
|
exports.default = ImportCustomRoles;
|
|
@@ -40,6 +40,13 @@ export default class EntriesImport extends BaseClass {
|
|
|
40
40
|
}>;
|
|
41
41
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
42
42
|
start(): Promise<any>;
|
|
43
|
+
private analyzeEntryData;
|
|
44
|
+
private initializeProgress;
|
|
45
|
+
private processEntryCreation;
|
|
46
|
+
private processEntryReplacement;
|
|
47
|
+
private processEntryReferenceUpdates;
|
|
48
|
+
private processEntryPublishing;
|
|
49
|
+
private processCleanup;
|
|
43
50
|
/**
|
|
44
51
|
* The function `createEntryDataForVariantEntry` writes the `entriesForVariant` data to a JSON file
|
|
45
52
|
* named `data-for-variant-entry.json`.
|