@contentstack/cli-cm-import 1.25.0 → 1.26.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 +3 -3
- package/lib/commands/cm/stacks/import.d.ts +1 -0
- package/lib/commands/cm/stacks/import.js +33 -12
- package/lib/import/module-importer.js +1 -1
- package/lib/import/modules/assets.d.ts +1 -1
- package/lib/import/modules/assets.js +93 -39
- package/lib/import/modules/base-class.js +11 -3
- package/lib/import/modules/content-types.js +79 -28
- package/lib/import/modules/custom-roles.js +95 -19
- package/lib/import/modules/entries.js +128 -57
- package/lib/import/modules/environments.js +48 -14
- package/lib/import/modules/extensions.js +78 -16
- package/lib/import/modules/global-fields.js +86 -19
- package/lib/import/modules/labels.d.ts +4 -4
- package/lib/import/modules/labels.js +60 -18
- package/lib/import/modules/locales.js +63 -20
- package/lib/import/modules/marketplace-apps.js +160 -31
- package/lib/import/modules/personalize.js +33 -7
- package/lib/import/modules/stack.js +5 -0
- package/lib/import/modules/taxonomies.js +52 -13
- package/lib/import/modules/variant-entries.js +21 -3
- package/lib/import/modules/webhooks.js +44 -12
- package/lib/import/modules/workflows.js +65 -21
- package/lib/types/import-config.d.ts +3 -1
- package/lib/types/index.d.ts +22 -0
- package/lib/utils/asset-helper.js +24 -1
- package/lib/utils/backup-handler.js +15 -1
- package/lib/utils/common-helper.js +41 -16
- package/lib/utils/content-type-helper.js +35 -2
- package/lib/utils/entries-helper.js +24 -2
- package/lib/utils/extension-helper.js +35 -1
- package/lib/utils/global-field-helper.js +1 -1
- package/lib/utils/import-config-handler.js +21 -0
- package/lib/utils/login-handler.js +8 -4
- package/lib/utils/marketplace-app-helper.js +50 -11
- package/lib/utils/taxonomies-helper.js +22 -4
- package/oclif.manifest.json +2 -2
- package/package.json +5 -5
|
@@ -11,9 +11,10 @@ const _ = tslib_1.__importStar(require("lodash"));
|
|
|
11
11
|
const config_1 = tslib_1.__importDefault(require("../config"));
|
|
12
12
|
const fileHelper = tslib_1.__importStar(require("./file-helper"));
|
|
13
13
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
14
|
-
const log_1 = require("./log");
|
|
15
14
|
// update references in entry object
|
|
16
15
|
const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
cli_utilities_1.log.debug(`Starting entry lookup for entry: ${(_a = data.entry) === null || _a === void 0 ? void 0 : _a.uid}, content type: ${(_b = data.content_type) === null || _b === void 0 ? void 0 : _b.uid}`);
|
|
17
18
|
let parent = [];
|
|
18
19
|
let uids = [];
|
|
19
20
|
let unmapped = [];
|
|
@@ -35,6 +36,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
35
36
|
case 'reference': {
|
|
36
37
|
if (((_a = Object.keys(element.attrs)) === null || _a === void 0 ? void 0 : _a.length) > 0 && ((_b = element.attrs) === null || _b === void 0 ? void 0 : _b.type) === 'entry') {
|
|
37
38
|
if (uids.indexOf(element.attrs['entry-uid']) === -1) {
|
|
39
|
+
cli_utilities_1.log.debug(`Found entry reference in JSON RTE: ${element.attrs['entry-uid']}`);
|
|
38
40
|
uids.push(element.attrs['entry-uid']);
|
|
39
41
|
}
|
|
40
42
|
}
|
|
@@ -58,12 +60,15 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
58
60
|
if (((_a = _entry[_parent[j]]) === null || _a === void 0 ? void 0 : _a.length) && Object.keys(_entry).includes(_parent[j])) {
|
|
59
61
|
(_b = _entry[_parent[j]]) === null || _b === void 0 ? void 0 : _b.forEach((item, idx) => {
|
|
60
62
|
if (typeof item.uid === 'string' && item._content_type_uid) {
|
|
63
|
+
cli_utilities_1.log.debug(`Found structured reference: ${item.uid}`);
|
|
61
64
|
uids.push(item.uid);
|
|
62
65
|
}
|
|
63
66
|
else if (typeof item === 'string' && preserveStackVersion === true) {
|
|
67
|
+
cli_utilities_1.log.debug(`Found string reference (preserve version): ${item}`);
|
|
64
68
|
uids.push(item);
|
|
65
69
|
}
|
|
66
70
|
else {
|
|
71
|
+
cli_utilities_1.log.debug(`Converting reference to structured format: ${item}`);
|
|
67
72
|
uids.push(item);
|
|
68
73
|
_entry[_parent[j]][idx] = {
|
|
69
74
|
uid: item,
|
|
@@ -76,11 +81,13 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
76
81
|
else if (Array.isArray(_entry[_parent[j]])) {
|
|
77
82
|
for (const element of _entry[_parent[j]]) {
|
|
78
83
|
if ((_c = element.uid) === null || _c === void 0 ? void 0 : _c.length) {
|
|
84
|
+
cli_utilities_1.log.debug(`Found asset reference: ${element.uid}`);
|
|
79
85
|
uids.push(element.uid);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
else if ((_d = _entry[_parent[j]].uid) === null || _d === void 0 ? void 0 : _d.length) {
|
|
90
|
+
cli_utilities_1.log.debug(`Found single asset reference: ${_entry[_parent[j]].uid}`);
|
|
84
91
|
uids.push(_entry[_parent[j]].uid);
|
|
85
92
|
}
|
|
86
93
|
}
|
|
@@ -110,6 +117,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
110
117
|
switch (schema[i].data_type) {
|
|
111
118
|
case 'reference':
|
|
112
119
|
if (Array.isArray(schema[i].reference_to)) {
|
|
120
|
+
cli_utilities_1.log.debug(`Processing multi-reference field: ${schema[i].uid}`);
|
|
113
121
|
isNewRefFields = true;
|
|
114
122
|
(_b = (_a = schema[i]) === null || _a === void 0 ? void 0 : _a.reference_to) === null || _b === void 0 ? void 0 : _b.forEach((reference) => {
|
|
115
123
|
parent.push(schema[i].uid);
|
|
@@ -118,6 +126,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
118
126
|
});
|
|
119
127
|
}
|
|
120
128
|
else {
|
|
129
|
+
cli_utilities_1.log.debug(`Processing single reference field: ${schema[i].uid}`);
|
|
121
130
|
parent.push(schema[i].uid);
|
|
122
131
|
update(parent, schema[i].reference_to, _entry);
|
|
123
132
|
parent.pop();
|
|
@@ -125,11 +134,13 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
125
134
|
break;
|
|
126
135
|
case 'global_field':
|
|
127
136
|
case 'group':
|
|
137
|
+
cli_utilities_1.log.debug(`Processing ${schema[i].data_type} field: ${schema[i].uid}`);
|
|
128
138
|
parent.push(schema[i].uid);
|
|
129
139
|
find(schema[i].schema, _entry);
|
|
130
140
|
parent.pop();
|
|
131
141
|
break;
|
|
132
142
|
case 'blocks':
|
|
143
|
+
cli_utilities_1.log.debug(`Processing blocks field: ${schema[i].uid}`);
|
|
133
144
|
for (let j = 0, _j = (_c = schema[i].blocks) === null || _c === void 0 ? void 0 : _c.length; j < _j; j++) {
|
|
134
145
|
parent.push(schema[i].uid);
|
|
135
146
|
parent.push(schema[i].blocks[j].uid);
|
|
@@ -140,6 +151,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
140
151
|
break;
|
|
141
152
|
case 'json':
|
|
142
153
|
if ((_e = (_d = schema[i]) === null || _d === void 0 ? void 0 : _d.field_metadata) === null || _e === void 0 ? void 0 : _e.rich_text_type) {
|
|
154
|
+
cli_utilities_1.log.debug(`Processing JSON RTE field: ${schema[i].uid}`);
|
|
143
155
|
findEntryIdsFromJsonRte(data.entry, data.content_type.schema);
|
|
144
156
|
}
|
|
145
157
|
break;
|
|
@@ -148,6 +160,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
148
160
|
};
|
|
149
161
|
function findEntryIdsFromJsonRte(entry, ctSchema = []) {
|
|
150
162
|
var _a, _b, _c, _d;
|
|
163
|
+
cli_utilities_1.log.debug('Processing JSON RTE fields for entry references');
|
|
151
164
|
for (const element of ctSchema) {
|
|
152
165
|
switch (element.data_type) {
|
|
153
166
|
case 'blocks': {
|
|
@@ -194,14 +207,17 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
194
207
|
}
|
|
195
208
|
find(data.content_type.schema, data.entry);
|
|
196
209
|
if (isNewRefFields) {
|
|
210
|
+
cli_utilities_1.log.debug('Processing new reference field format');
|
|
197
211
|
findUidsInNewRefFields(data.entry, uids);
|
|
198
212
|
}
|
|
199
213
|
uids = _.flattenDeep(uids);
|
|
200
214
|
// if no references are found, return
|
|
201
215
|
if (uids.length === 0) {
|
|
216
|
+
cli_utilities_1.log.debug('No entry references found');
|
|
202
217
|
return data.entry;
|
|
203
218
|
}
|
|
204
219
|
uids = _.uniq(uids);
|
|
220
|
+
cli_utilities_1.log.debug(`Found ${uids.length} unique entry references`);
|
|
205
221
|
let entry = JSON.stringify(data.entry);
|
|
206
222
|
uids === null || uids === void 0 ? void 0 : uids.forEach(function (uid) {
|
|
207
223
|
if (mappedUids.hasOwnProperty(uid)) {
|
|
@@ -214,7 +230,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
214
230
|
mapped.push(uid);
|
|
215
231
|
}
|
|
216
232
|
else {
|
|
217
|
-
|
|
233
|
+
cli_utilities_1.log.warn(`Skipping entry UID ${uid} due to invalid regex`);
|
|
218
234
|
}
|
|
219
235
|
}
|
|
220
236
|
else {
|
|
@@ -222,6 +238,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
222
238
|
}
|
|
223
239
|
});
|
|
224
240
|
if (unmapped.length > 0) {
|
|
241
|
+
cli_utilities_1.log.warn(`Found ${unmapped.length} unmapped entry references`);
|
|
225
242
|
let unmappedUids = fileHelper.readFileSync(path.join(uidMapperPath, 'unmapped-uids.json'));
|
|
226
243
|
unmappedUids = unmappedUids || {};
|
|
227
244
|
if (unmappedUids.hasOwnProperty(data.content_type.uid)) {
|
|
@@ -236,6 +253,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
236
253
|
fileHelper.writeFile(path.join(uidMapperPath, 'unmapped-uids.json'), unmappedUids);
|
|
237
254
|
}
|
|
238
255
|
if (mapped.length > 0) {
|
|
256
|
+
cli_utilities_1.log.debug(`Successfully mapped ${mapped.length} entry references`);
|
|
239
257
|
let _mappedUids = fileHelper.readFileSync(path.join(uidMapperPath, 'mapped-uids.json'));
|
|
240
258
|
_mappedUids = _mappedUids || {};
|
|
241
259
|
if (_mappedUids.hasOwnProperty(data.content_type.uid)) {
|
|
@@ -249,6 +267,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
249
267
|
// write the mapped contents to ./mapper/language/mapped-uids.json
|
|
250
268
|
fileHelper.writeFile(path.join(uidMapperPath, 'mapped-uids.json'), _mappedUids);
|
|
251
269
|
}
|
|
270
|
+
cli_utilities_1.log.debug(`Entry lookup completed for entry: ${(_c = data.entry) === null || _c === void 0 ? void 0 : _c.uid}`);
|
|
252
271
|
return JSON.parse(entry);
|
|
253
272
|
};
|
|
254
273
|
exports.lookupEntries = lookupEntries;
|
|
@@ -273,6 +292,7 @@ function findUidsInNewRefFields(entry, uids) {
|
|
|
273
292
|
}
|
|
274
293
|
const removeUidsFromJsonRteFields = (entry, ctSchema = []) => {
|
|
275
294
|
var _a;
|
|
295
|
+
cli_utilities_1.log.debug('Removing UIDs from JSON RTE fields');
|
|
276
296
|
for (const element of ctSchema) {
|
|
277
297
|
switch (element.data_type) {
|
|
278
298
|
case 'blocks': {
|
|
@@ -306,6 +326,7 @@ const removeUidsFromJsonRteFields = (entry, ctSchema = []) => {
|
|
|
306
326
|
}
|
|
307
327
|
case 'json': {
|
|
308
328
|
if (entry[element.uid] && ((_a = element === null || element === void 0 ? void 0 : element.field_metadata) === null || _a === void 0 ? void 0 : _a.rich_text_type)) {
|
|
329
|
+
cli_utilities_1.log.debug(`Processing JSON RTE field for UID removal: ${element.uid}`);
|
|
309
330
|
if (element.multiple) {
|
|
310
331
|
entry[element.uid] = entry[element.uid].map((jsonRteData) => {
|
|
311
332
|
delete jsonRteData.uid; // remove uid
|
|
@@ -332,6 +353,7 @@ const removeUidsFromJsonRteFields = (entry, ctSchema = []) => {
|
|
|
332
353
|
}
|
|
333
354
|
}
|
|
334
355
|
}
|
|
356
|
+
cli_utilities_1.log.debug('Completed removing UIDs from JSON RTE fields');
|
|
335
357
|
return entry;
|
|
336
358
|
};
|
|
337
359
|
exports.removeUidsFromJsonRteFields = removeUidsFromJsonRteFields;
|
|
@@ -13,17 +13,22 @@ const node_path_1 = require("node:path");
|
|
|
13
13
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
14
14
|
// eslint-disable-next-line camelcase
|
|
15
15
|
const lookupExtension = function (config, schema, preserveStackVersion, installedExtensions) {
|
|
16
|
+
cli_utilities_1.log.debug('Starting extension lookup process...');
|
|
16
17
|
const fs = new cli_utilities_1.FsUtility({ basePath: config.backupDir });
|
|
17
18
|
const extensionPath = (0, node_path_1.join)(config.backupDir, 'mapper/extensions', 'uid-mapping.json');
|
|
18
19
|
const globalfieldsPath = (0, node_path_1.join)(config.backupDir, 'mapper/globalfields', 'uid-mapping.json');
|
|
19
20
|
const marketPlaceAppsPath = (0, node_path_1.join)(config.backupDir, 'mapper/marketplace_apps', 'uid-mapping.json');
|
|
21
|
+
cli_utilities_1.log.debug(`Extension mapping paths - Extensions: ${extensionPath}, Global fields: ${globalfieldsPath}, Marketplace apps: ${marketPlaceAppsPath}`);
|
|
20
22
|
for (let i in schema) {
|
|
21
23
|
if (schema[i].data_type === 'group') {
|
|
24
|
+
cli_utilities_1.log.debug(`Processing group field: ${schema[i].uid}`);
|
|
22
25
|
(0, exports.lookupExtension)(config, schema[i].schema, preserveStackVersion, installedExtensions);
|
|
23
26
|
}
|
|
24
27
|
else if (schema[i].data_type === 'blocks') {
|
|
28
|
+
cli_utilities_1.log.debug(`Processing blocks field: ${schema[i].uid}`);
|
|
25
29
|
for (let block in schema[i].blocks) {
|
|
26
30
|
if (schema[i].blocks[block].hasOwnProperty('reference_to')) {
|
|
31
|
+
cli_utilities_1.log.debug(`Removing schema from block with reference_to: ${schema[i].blocks[block].uid}`);
|
|
27
32
|
delete schema[i].blocks[block].schema;
|
|
28
33
|
}
|
|
29
34
|
else {
|
|
@@ -34,9 +39,11 @@ const lookupExtension = function (config, schema, preserveStackVersion, installe
|
|
|
34
39
|
else if (schema[i].data_type === 'reference' &&
|
|
35
40
|
!schema[i].field_metadata.hasOwnProperty('ref_multiple_content_types')) {
|
|
36
41
|
if (preserveStackVersion) {
|
|
42
|
+
cli_utilities_1.log.debug(`Preserving stack version for reference field: ${schema[i].uid}`);
|
|
37
43
|
// do nothing
|
|
38
44
|
}
|
|
39
45
|
else {
|
|
46
|
+
cli_utilities_1.log.debug(`Converting reference field to multi-reference format: ${schema[i].uid}`);
|
|
40
47
|
schema[i].reference_to = [schema[i].reference_to];
|
|
41
48
|
schema[i].field_metadata.ref_multiple_content_types = true;
|
|
42
49
|
}
|
|
@@ -45,45 +52,72 @@ const lookupExtension = function (config, schema, preserveStackVersion, installe
|
|
|
45
52
|
schema[i].field_metadata.hasOwnProperty('ref_multiple_content_types') &&
|
|
46
53
|
installedExtensions &&
|
|
47
54
|
installedExtensions[schema[i].extension_uid]) {
|
|
55
|
+
cli_utilities_1.log.debug(`Updating extension UID for reference field: ${schema[i].uid}`);
|
|
48
56
|
schema[i].extension_uid = installedExtensions[schema[i].extension_uid];
|
|
49
57
|
}
|
|
50
58
|
else if (schema[i].data_type === 'text' && installedExtensions && installedExtensions[schema[i].extension_uid]) {
|
|
59
|
+
cli_utilities_1.log.debug(`Updating extension UID for text field: ${schema[i].uid}`);
|
|
51
60
|
schema[i].extension_uid = installedExtensions[schema[i].extension_uid];
|
|
52
61
|
}
|
|
53
62
|
else if (schema[i].data_type === 'global_field') {
|
|
63
|
+
cli_utilities_1.log.debug(`Processing global field: ${schema[i].uid}`);
|
|
54
64
|
const global_fields_key_value = schema[i].reference_to;
|
|
55
65
|
const global_fields_data = fs.readFile(globalfieldsPath);
|
|
56
66
|
if (global_fields_data && global_fields_data.hasOwnProperty(global_fields_key_value)) {
|
|
67
|
+
const mappedValue = global_fields_data[global_fields_key_value];
|
|
68
|
+
cli_utilities_1.log.debug(`Mapping global field reference: ${global_fields_key_value} -> ${mappedValue}`);
|
|
57
69
|
schema[i].reference_to = global_fields_data[global_fields_key_value];
|
|
58
70
|
}
|
|
71
|
+
else {
|
|
72
|
+
cli_utilities_1.log.warn(`No mapping found for global field: ${global_fields_key_value}`);
|
|
73
|
+
}
|
|
59
74
|
}
|
|
60
75
|
else if (schema[i].hasOwnProperty('extension_uid')) {
|
|
76
|
+
cli_utilities_1.log.debug(`Processing field with extension UID: ${schema[i].uid}`);
|
|
61
77
|
const extension_key_value = schema[i].extension_uid;
|
|
62
78
|
const data = fs.readFile(extensionPath);
|
|
63
79
|
if (data && data.hasOwnProperty(extension_key_value)) {
|
|
80
|
+
const mappedExtension = data[extension_key_value];
|
|
81
|
+
cli_utilities_1.log.debug(`Mapping extension UID: ${extension_key_value} -> ${mappedExtension}`);
|
|
64
82
|
// eslint-disable-next-line camelcase
|
|
65
83
|
schema[i].extension_uid = data[extension_key_value];
|
|
66
84
|
}
|
|
67
85
|
else if (schema[i].field_metadata && schema[i].field_metadata.extension) {
|
|
68
86
|
if (installedExtensions && installedExtensions[schema[i].extension_uid]) {
|
|
87
|
+
cli_utilities_1.log.debug(`Using installed extension mapping: ${schema[i].extension_uid}`);
|
|
69
88
|
schema[i].extension_uid = installedExtensions[schema[i].extension_uid];
|
|
70
89
|
}
|
|
90
|
+
else {
|
|
91
|
+
cli_utilities_1.log.warn(`No mapping found for extension: ${extension_key_value}`);
|
|
92
|
+
}
|
|
71
93
|
}
|
|
72
94
|
}
|
|
73
95
|
else if (schema[i].data_type === 'json' && schema[i].hasOwnProperty('plugins') && schema[i].plugins.length > 0) {
|
|
96
|
+
cli_utilities_1.log.debug(`Processing JSON field with plugins: ${schema[i].uid}`);
|
|
74
97
|
const newPluginUidsArray = [];
|
|
75
98
|
const data = fs.readFile(extensionPath);
|
|
76
99
|
const marketPlaceAppsData = fs.readFile(marketPlaceAppsPath);
|
|
77
100
|
schema[i].plugins.forEach((extension_key_value) => {
|
|
78
101
|
if (data && data.hasOwnProperty(extension_key_value)) {
|
|
102
|
+
const mappedPlugin = data[extension_key_value];
|
|
103
|
+
cli_utilities_1.log.debug(`Mapping plugin extension: ${extension_key_value} -> ${mappedPlugin}`);
|
|
79
104
|
newPluginUidsArray.push(data[extension_key_value]);
|
|
80
105
|
}
|
|
81
|
-
else if (marketPlaceAppsData &&
|
|
106
|
+
else if (marketPlaceAppsData &&
|
|
107
|
+
marketPlaceAppsData.extension_uid &&
|
|
108
|
+
marketPlaceAppsData.extension_uid.hasOwnProperty(extension_key_value)) {
|
|
109
|
+
const mappedMarketplaceExt = marketPlaceAppsData.extension_uid[extension_key_value];
|
|
110
|
+
cli_utilities_1.log.debug(`Mapping marketplace app extension: ${extension_key_value} -> ${mappedMarketplaceExt}`);
|
|
82
111
|
newPluginUidsArray.push(marketPlaceAppsData.extension_uid[extension_key_value]);
|
|
83
112
|
}
|
|
113
|
+
else {
|
|
114
|
+
cli_utilities_1.log.warn(`No mapping found for plugin extension: ${extension_key_value}`);
|
|
115
|
+
}
|
|
84
116
|
});
|
|
117
|
+
cli_utilities_1.log.debug(`Updated plugins array with ${newPluginUidsArray.length} mapped extensions`);
|
|
85
118
|
schema[i].plugins = newPluginUidsArray;
|
|
86
119
|
}
|
|
87
120
|
}
|
|
121
|
+
cli_utilities_1.log.debug('Extension lookup process completed');
|
|
88
122
|
};
|
|
89
123
|
exports.lookupExtension = lookupExtension;
|
|
@@ -12,6 +12,8 @@ const login_handler_1 = tslib_1.__importDefault(require("./login-handler"));
|
|
|
12
12
|
const setupConfig = async (importCmdFlags) => {
|
|
13
13
|
var _a;
|
|
14
14
|
let config = (0, merge_1.default)({}, config_1.default);
|
|
15
|
+
// Track authentication method
|
|
16
|
+
let authenticationMethod = 'unknown';
|
|
15
17
|
// setup the config
|
|
16
18
|
if (importCmdFlags['config']) {
|
|
17
19
|
let externalConfig = await (0, file_helper_1.readFile)(importCmdFlags['config']);
|
|
@@ -45,20 +47,36 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
45
47
|
const { token, apiKey } = (_a = cli_utilities_1.configHandler.get(`tokens.${managementTokenAlias}`)) !== null && _a !== void 0 ? _a : {};
|
|
46
48
|
config.management_token = token;
|
|
47
49
|
config.apiKey = apiKey;
|
|
50
|
+
authenticationMethod = 'Management Token';
|
|
48
51
|
if (!config.management_token) {
|
|
49
52
|
throw new Error(`No management token found on given alias ${managementTokenAlias}`);
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
if (!config.management_token) {
|
|
53
56
|
if (!(0, cli_utilities_1.isAuthenticated)()) {
|
|
57
|
+
cli_utilities_1.log.debug('User not authenticated, checking for basic auth credentials');
|
|
54
58
|
if (config.email && config.password) {
|
|
59
|
+
cli_utilities_1.log.debug('Using basic authentication with username/password');
|
|
55
60
|
await (0, login_handler_1.default)(config);
|
|
61
|
+
authenticationMethod = 'Basic Auth';
|
|
62
|
+
cli_utilities_1.log.debug('Basic authentication successful');
|
|
56
63
|
}
|
|
57
64
|
else {
|
|
65
|
+
cli_utilities_1.log.debug('No authentication method available');
|
|
58
66
|
throw new Error('Please login or provide an alias for the management token');
|
|
59
67
|
}
|
|
60
68
|
}
|
|
61
69
|
else {
|
|
70
|
+
// Check if user is authenticated via OAuth
|
|
71
|
+
const isOAuthUser = cli_utilities_1.configHandler.get('authorisationType') === 'OAUTH' || false;
|
|
72
|
+
if (isOAuthUser) {
|
|
73
|
+
authenticationMethod = 'OAuth';
|
|
74
|
+
cli_utilities_1.log.debug('User authenticated via OAuth');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
authenticationMethod = 'Basic Auth';
|
|
78
|
+
cli_utilities_1.log.debug('User authenticated via auth token');
|
|
79
|
+
}
|
|
62
80
|
config.apiKey =
|
|
63
81
|
importCmdFlags['stack-uid'] || importCmdFlags['stack-api-key'] || config.target_stack || (await (0, interactive_1.askAPIKey)());
|
|
64
82
|
if (typeof config.apiKey !== 'string') {
|
|
@@ -99,6 +117,9 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
99
117
|
if (importCmdFlags['exclude-global-modules']) {
|
|
100
118
|
config['exclude-global-modules'] = importCmdFlags['exclude-global-modules'];
|
|
101
119
|
}
|
|
120
|
+
// Add authentication details to config for context tracking
|
|
121
|
+
config.authenticationMethod = authenticationMethod;
|
|
122
|
+
cli_utilities_1.log.debug('Import configuration setup completed', Object.assign({}, config));
|
|
102
123
|
return config;
|
|
103
124
|
};
|
|
104
125
|
exports.default = setupConfig;
|
|
@@ -8,20 +8,21 @@
|
|
|
8
8
|
* MIT Licensed
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const logger_1 = require("./logger");
|
|
12
11
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
13
12
|
const login = async (config) => {
|
|
13
|
+
cli_utilities_1.log.debug('Starting login process');
|
|
14
14
|
const client = await (0, cli_utilities_1.managementSDKClient)(config);
|
|
15
15
|
if (config.email && config.password) {
|
|
16
|
+
cli_utilities_1.log.debug('Attempting login with email and password');
|
|
16
17
|
const { user: { authtoken = null } = {} } = await client.login({ email: config.email, password: config.password });
|
|
17
18
|
if (authtoken) {
|
|
19
|
+
cli_utilities_1.log.debug('Login successful, setting up headers');
|
|
18
20
|
config.headers = {
|
|
19
21
|
api_key: config.source_stack,
|
|
20
22
|
access_token: config.access_token,
|
|
21
23
|
authtoken: config.authtoken,
|
|
22
24
|
'X-User-Agent': 'contentstack-export/v',
|
|
23
25
|
};
|
|
24
|
-
(0, logger_1.log)(config, 'Contentstack account authenticated successfully!', 'success');
|
|
25
26
|
return config;
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
@@ -29,9 +30,11 @@ const login = async (config) => {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
else if (config.management_token) {
|
|
33
|
+
cli_utilities_1.log.debug('Using management token for authentication');
|
|
32
34
|
return config;
|
|
33
35
|
}
|
|
34
36
|
else if ((0, cli_utilities_1.isAuthenticated)()) {
|
|
37
|
+
cli_utilities_1.log.debug('Using existing authentication, validating stack access');
|
|
35
38
|
const stackAPIClient = client.stack({
|
|
36
39
|
api_key: config.target_stack,
|
|
37
40
|
management_token: config.management_token,
|
|
@@ -40,10 +43,11 @@ const login = async (config) => {
|
|
|
40
43
|
var _a;
|
|
41
44
|
let errorstack_key = (_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.api_key;
|
|
42
45
|
if (errorstack_key) {
|
|
43
|
-
|
|
46
|
+
const keyError = errorstack_key[0];
|
|
47
|
+
cli_utilities_1.log.error(`Invalid stack API token: ${keyError} Please enter valid stack API token.`);
|
|
44
48
|
throw error;
|
|
45
49
|
}
|
|
46
|
-
|
|
50
|
+
cli_utilities_1.log.error(`Stack fetch error: ${error === null || error === void 0 ? void 0 : error.errorMessage}`);
|
|
47
51
|
throw error;
|
|
48
52
|
});
|
|
49
53
|
config.destinationStackName = stack.name;
|
|
@@ -8,11 +8,11 @@ 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
10
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
11
|
-
const logger_1 = require("./logger");
|
|
12
11
|
const log_1 = require("../utils/log");
|
|
13
12
|
const utils_1 = require("../utils");
|
|
14
13
|
const interactive_1 = require("../utils/interactive");
|
|
15
14
|
const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
15
|
+
cli_utilities_1.log.debug(`Fetching stack-specific apps with skip: ${skip}, current list size: ${listOfApps.length}`);
|
|
16
16
|
const appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({
|
|
17
17
|
host: config.developerHubBaseUrl.split('://').pop(),
|
|
18
18
|
});
|
|
@@ -21,11 +21,12 @@ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
|
21
21
|
.installation()
|
|
22
22
|
.fetchAll({ target_uids: config.target_stack, skip })
|
|
23
23
|
.catch((error) => {
|
|
24
|
+
(0, cli_utilities_1.handleAndLogError)(error);
|
|
24
25
|
(0, log_1.trace)(error, 'error', true);
|
|
25
|
-
(0, logger_1.log)(config, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error');
|
|
26
26
|
});
|
|
27
27
|
if (collection) {
|
|
28
28
|
const { items: apps, count } = collection;
|
|
29
|
+
cli_utilities_1.log.debug(`Retrieved ${apps.length} apps from API, total count: ${count}`);
|
|
29
30
|
// NOTE Remove all the chain functions
|
|
30
31
|
const installation = (0, map_1.default)(apps, (app) => (0, omitBy_1.default)(app, (val, _key) => {
|
|
31
32
|
if (val instanceof Function)
|
|
@@ -33,109 +34,147 @@ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
|
33
34
|
return false;
|
|
34
35
|
}));
|
|
35
36
|
listOfApps = listOfApps.concat(installation);
|
|
37
|
+
cli_utilities_1.log.debug(`Updated list size: ${listOfApps.length}`);
|
|
36
38
|
if (count - (skip + 50) > 0) {
|
|
39
|
+
cli_utilities_1.log.debug(`Fetching more apps, remaining: ${count - (skip + 50)}`);
|
|
37
40
|
return await (0, exports.getAllStackSpecificApps)(config, skip + 50, listOfApps);
|
|
38
41
|
}
|
|
39
42
|
}
|
|
43
|
+
cli_utilities_1.log.info(`Successfully retrieved ${listOfApps.length} stack-specific apps`);
|
|
40
44
|
return listOfApps;
|
|
41
45
|
};
|
|
42
46
|
exports.getAllStackSpecificApps = getAllStackSpecificApps;
|
|
43
47
|
const getDeveloperHubUrl = async (config) => {
|
|
44
|
-
|
|
48
|
+
cli_utilities_1.log.debug('Creating developer hub URL');
|
|
49
|
+
const url = (0, cli_utilities_1.createDeveloperHubUrl)(config.host);
|
|
50
|
+
cli_utilities_1.log.debug(`Developer hub URL: ${url}`);
|
|
51
|
+
return url;
|
|
45
52
|
};
|
|
46
53
|
exports.getDeveloperHubUrl = getDeveloperHubUrl;
|
|
47
54
|
const getOrgUid = async (config) => {
|
|
55
|
+
cli_utilities_1.log.debug('Fetching organization UID');
|
|
48
56
|
const tempAPIClient = await (0, cli_utilities_1.managementSDKClient)({ host: config.host });
|
|
49
57
|
const tempStackData = await tempAPIClient
|
|
50
58
|
.stack({ api_key: config.target_stack })
|
|
51
59
|
.fetch()
|
|
52
60
|
.catch((error) => {
|
|
61
|
+
(0, cli_utilities_1.handleAndLogError)(error);
|
|
53
62
|
(0, log_1.trace)(error, 'error', true);
|
|
54
|
-
(0, logger_1.log)(config, (0, utils_1.formatError)(error), 'error');
|
|
55
63
|
});
|
|
56
|
-
|
|
64
|
+
const orgUid = (tempStackData === null || tempStackData === void 0 ? void 0 : tempStackData.org_uid) || '';
|
|
65
|
+
cli_utilities_1.log.debug(`Organization UID: ${orgUid}`);
|
|
66
|
+
return orgUid;
|
|
57
67
|
};
|
|
58
68
|
exports.getOrgUid = getOrgUid;
|
|
59
69
|
const getConfirmationToCreateApps = async (privateApps, config) => {
|
|
70
|
+
cli_utilities_1.log.debug(`Requesting confirmation to create ${privateApps === null || privateApps === void 0 ? void 0 : privateApps.length} private apps`);
|
|
60
71
|
if (!config.forceStopMarketplaceAppsPrompt) {
|
|
61
72
|
if (!(await cli_utilities_1.cliux.confirm(chalk_1.default.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)`)))) {
|
|
73
|
+
cli_utilities_1.log.debug('User declined to create private apps');
|
|
62
74
|
if (await cli_utilities_1.cliux.confirm(chalk_1.default.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)`))) {
|
|
75
|
+
cli_utilities_1.log.warn('User confirmed to proceed without creating private apps');
|
|
63
76
|
return Promise.resolve(false);
|
|
64
77
|
}
|
|
65
78
|
else {
|
|
66
79
|
if (await cli_utilities_1.cliux.confirm(chalk_1.default.yellow('\nWould you like to re-create the private app and then proceed with the installation? (y/n)'))) {
|
|
80
|
+
cli_utilities_1.log.info('User confirmed to create private apps');
|
|
67
81
|
return Promise.resolve(true);
|
|
68
82
|
}
|
|
69
83
|
else {
|
|
84
|
+
cli_utilities_1.log.debug('User declined to create private apps (second prompt)');
|
|
70
85
|
return Promise.resolve(false);
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
}
|
|
74
89
|
else {
|
|
90
|
+
cli_utilities_1.log.info('User confirmed to create private apps');
|
|
75
91
|
return Promise.resolve(true);
|
|
76
92
|
}
|
|
77
93
|
}
|
|
78
94
|
else {
|
|
95
|
+
cli_utilities_1.log.debug('Force prompt disabled, automatically creating private apps');
|
|
79
96
|
return Promise.resolve(true);
|
|
80
97
|
}
|
|
81
98
|
};
|
|
82
99
|
exports.getConfirmationToCreateApps = getConfirmationToCreateApps;
|
|
83
100
|
const handleNameConflict = async (app, appSuffix, config) => {
|
|
101
|
+
cli_utilities_1.log.debug(`Handling name conflict for app: ${app === null || app === void 0 ? void 0 : app.name}, suffix: ${appSuffix}`);
|
|
84
102
|
const appName = config.forceStopMarketplaceAppsPrompt
|
|
85
103
|
? (0, interactive_1.getAppName)(app.name, appSuffix)
|
|
86
104
|
: await (0, interactive_1.askAppName)(app, appSuffix);
|
|
87
105
|
app.name = appName;
|
|
106
|
+
cli_utilities_1.log.debug(`Updated app name to: ${appName}`);
|
|
88
107
|
return app;
|
|
89
108
|
};
|
|
90
109
|
exports.handleNameConflict = handleNameConflict;
|
|
91
110
|
const makeRedirectUrlCall = async (response, appName, config) => {
|
|
92
111
|
if (response.redirect_url) {
|
|
93
|
-
|
|
112
|
+
cli_utilities_1.log.info(`Starting OAuth API call for app: ${appName}`);
|
|
94
113
|
await new cli_utilities_1.HttpClient({ maxRedirects: 20, maxBodyLength: Infinity })
|
|
95
114
|
.get(response.redirect_url)
|
|
96
115
|
.then(async ({ response }) => {
|
|
97
116
|
if ((0, includes_1.default)([501, 403], response.status)) {
|
|
117
|
+
cli_utilities_1.log.error(`OAuth API call failed for ${appName}: ${response.statusText}`);
|
|
98
118
|
(0, log_1.trace)(response, 'error', true);
|
|
99
|
-
(0, logger_1.log)(config, `${appName} - ${response.statusText}, OAuth api call failed.!`, 'error');
|
|
100
|
-
(0, logger_1.log)(config, (0, utils_1.formatError)(response), 'error');
|
|
101
119
|
await (0, exports.confirmToCloseProcess)(response.data, config);
|
|
102
120
|
}
|
|
103
121
|
else {
|
|
104
|
-
|
|
122
|
+
cli_utilities_1.log.success(`OAuth API call completed successfully for app: ${appName}`);
|
|
105
123
|
}
|
|
106
124
|
})
|
|
107
125
|
.catch((error) => {
|
|
108
126
|
(0, log_1.trace)(error, 'error', true);
|
|
109
127
|
if ((0, includes_1.default)([501, 403], error.status)) {
|
|
110
|
-
(0,
|
|
128
|
+
(0, cli_utilities_1.handleAndLogError)(error);
|
|
111
129
|
}
|
|
112
130
|
});
|
|
113
131
|
}
|
|
132
|
+
else {
|
|
133
|
+
cli_utilities_1.log.debug(`No redirect URL found for app: ${appName}`);
|
|
134
|
+
}
|
|
114
135
|
};
|
|
115
136
|
exports.makeRedirectUrlCall = makeRedirectUrlCall;
|
|
116
137
|
const confirmToCloseProcess = async (installation, config) => {
|
|
117
|
-
cli_utilities_1.
|
|
138
|
+
cli_utilities_1.log.warn(`Installation error occurred: ${(0, utils_1.formatError)(installation === null || installation === void 0 ? void 0 : installation.message)}`);
|
|
118
139
|
if (!config.forceStopMarketplaceAppsPrompt) {
|
|
119
140
|
if (!(await cli_utilities_1.cliux.confirm(chalk_1.default.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)')))) {
|
|
141
|
+
cli_utilities_1.log.debug('User chose to exit due to installation error');
|
|
120
142
|
process.exit();
|
|
121
143
|
}
|
|
144
|
+
else {
|
|
145
|
+
cli_utilities_1.log.warn('User chose to proceed despite installation error');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
cli_utilities_1.log.debug('Force prompt disabled, continuing despite installation error');
|
|
122
150
|
}
|
|
123
151
|
};
|
|
124
152
|
exports.confirmToCloseProcess = confirmToCloseProcess;
|
|
125
153
|
const ifAppAlreadyExist = async (app, currentStackApp, config) => {
|
|
154
|
+
var _a;
|
|
155
|
+
cli_utilities_1.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}`);
|
|
126
156
|
let updateParam = {};
|
|
127
157
|
const { manifest: { name }, configuration, server_configuration, } = app;
|
|
128
158
|
if (!(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration)) {
|
|
159
|
+
cli_utilities_1.log.warn(`App ${name} already exists with existing configuration`);
|
|
129
160
|
cli_utilities_1.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' });
|
|
130
161
|
const configOption = config.forceStopMarketplaceAppsPrompt
|
|
131
162
|
? 'Update it with the new configuration.'
|
|
132
163
|
: await (0, interactive_1.selectConfiguration)();
|
|
133
164
|
if (configOption === 'Exit') {
|
|
165
|
+
cli_utilities_1.log.debug('User chose to exit due to configuration conflict');
|
|
134
166
|
process.exit();
|
|
135
167
|
}
|
|
136
168
|
else if (configOption === 'Update it with the new configuration.') {
|
|
169
|
+
cli_utilities_1.log.info(`Updating app configuration for: ${name}`);
|
|
137
170
|
updateParam = Object.assign(Object.assign({ manifest: app.manifest }, currentStackApp), { configuration, server_configuration });
|
|
138
171
|
}
|
|
172
|
+
else {
|
|
173
|
+
cli_utilities_1.log.debug(`User chose to keep existing configuration for: ${name}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
cli_utilities_1.log.debug(`App ${name} has no configuration conflicts`);
|
|
139
178
|
}
|
|
140
179
|
return updateParam;
|
|
141
180
|
};
|