@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
|
@@ -19,6 +19,7 @@ const utils_1 = require("../../utils");
|
|
|
19
19
|
class ImportMarketplaceApps {
|
|
20
20
|
constructor({ importConfig }) {
|
|
21
21
|
this.importConfig = importConfig;
|
|
22
|
+
this.importConfig.context.module = 'marketplace-apps';
|
|
22
23
|
this.marketPlaceAppConfig = importConfig.modules.marketplace_apps;
|
|
23
24
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'marketplace_apps');
|
|
24
25
|
this.marketPlaceFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.marketPlaceAppConfig.dirName);
|
|
@@ -35,59 +36,86 @@ class ImportMarketplaceApps {
|
|
|
35
36
|
* @returns The function `start()` returns a `Promise<void>`.
|
|
36
37
|
*/
|
|
37
38
|
async start() {
|
|
38
|
-
|
|
39
|
+
var _a;
|
|
40
|
+
cli_utilities_1.log.debug('Checking for marketplace apps folder existence', this.importConfig.context);
|
|
39
41
|
if (utils_1.fileHelper.fileExistsSync(this.marketPlaceFolderPath)) {
|
|
42
|
+
cli_utilities_1.log.debug(`Found marketplace apps folder: ${this.marketPlaceFolderPath}`, this.importConfig.context);
|
|
40
43
|
this.marketplaceApps = utils_1.fsUtil.readFile((0, node_path_1.join)(this.marketPlaceFolderPath, this.marketPlaceAppConfig.fileName), true);
|
|
44
|
+
cli_utilities_1.log.debug(`Found ${((_a = this.marketplaceApps) === null || _a === void 0 ? void 0 : _a.length) || 0} marketplace apps to import`, this.importConfig.context);
|
|
41
45
|
}
|
|
42
46
|
else {
|
|
43
|
-
|
|
47
|
+
cli_utilities_1.log.info(`No Marketplace apps are found - '${this.marketPlaceFolderPath}'`, this.importConfig.context);
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
if ((0, isEmpty_1.default)(this.marketplaceApps)) {
|
|
51
|
+
cli_utilities_1.log.debug('No marketplace apps found to import', this.importConfig.context);
|
|
47
52
|
return Promise.resolve();
|
|
48
53
|
}
|
|
49
54
|
else if (!(0, cli_utilities_1.isAuthenticated)()) {
|
|
50
55
|
cli_utilities_1.cliux.print('\nWARNING!!! To import Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in\n', { color: 'yellow' });
|
|
56
|
+
cli_utilities_1.log.info('Skipping marketplace apps import - user not authenticated', this.importConfig.context);
|
|
51
57
|
return Promise.resolve();
|
|
52
58
|
}
|
|
59
|
+
cli_utilities_1.log.debug('Creating marketplace apps mapper directory', this.importConfig.context);
|
|
53
60
|
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
61
|
+
cli_utilities_1.log.debug('Created marketplace apps mapper directory', this.importConfig.context);
|
|
62
|
+
cli_utilities_1.log.debug('Getting developer hub base URL', this.importConfig.context);
|
|
54
63
|
this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.importConfig));
|
|
55
64
|
this.importConfig.developerHubBaseUrl = this.developerHubBaseUrl;
|
|
65
|
+
cli_utilities_1.log.debug(`Using developer hub base URL: ${this.developerHubBaseUrl}`, this.importConfig.context);
|
|
56
66
|
// NOTE init marketplace app sdk
|
|
67
|
+
cli_utilities_1.log.debug('Initializing marketplace SDK client', this.importConfig.context);
|
|
57
68
|
const host = this.developerHubBaseUrl.split('://').pop();
|
|
58
69
|
this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
|
|
70
|
+
cli_utilities_1.log.debug('Initialized marketplace SDK client', this.importConfig.context);
|
|
71
|
+
cli_utilities_1.log.debug('Getting organization UID', this.importConfig.context);
|
|
59
72
|
this.importConfig.org_uid = await (0, utils_1.getOrgUid)(this.importConfig);
|
|
73
|
+
cli_utilities_1.log.debug(`Using organization UID: ${this.importConfig.org_uid}`, this.importConfig.context);
|
|
60
74
|
// NOTE start the marketplace import process
|
|
75
|
+
cli_utilities_1.log.debug('Starting marketplace apps import process', this.importConfig.context);
|
|
61
76
|
await this.importMarketplaceApps();
|
|
62
|
-
|
|
77
|
+
cli_utilities_1.log.success('Marketplace apps have been imported successfully!', this.importConfig.context);
|
|
63
78
|
}
|
|
64
79
|
/**
|
|
65
80
|
* The function `importMarketplaceApps` installs marketplace apps, handles private app creation,
|
|
66
81
|
* validates app installation, and generates a UID mapper.
|
|
67
82
|
*/
|
|
68
83
|
async importMarketplaceApps() {
|
|
84
|
+
var _a, _b, _c;
|
|
85
|
+
cli_utilities_1.log.debug('Setting up security configuration for marketplace apps', this.importConfig.context);
|
|
69
86
|
// NOTE set default encryptionKey
|
|
70
87
|
const cryptoArgs = { encryptionKey: this.importConfig.marketplaceAppEncryptionKey };
|
|
71
88
|
if (this.importConfig.forceStopMarketplaceAppsPrompt) {
|
|
89
|
+
cli_utilities_1.log.debug('Using forced security configuration without validation', this.importConfig.context);
|
|
72
90
|
this.nodeCrypto = new cli_utilities_1.NodeCrypto(cryptoArgs);
|
|
73
91
|
}
|
|
74
92
|
else {
|
|
93
|
+
cli_utilities_1.log.debug('Validating security configuration', this.importConfig.context);
|
|
75
94
|
await this.getAndValidateEncryptionKey(this.importConfig.marketplaceAppEncryptionKey);
|
|
76
95
|
}
|
|
77
96
|
// NOTE install all private apps which is not available for stack.
|
|
97
|
+
cli_utilities_1.log.debug('Handling private apps creation process', this.importConfig.context);
|
|
78
98
|
await this.handleAllPrivateAppsCreationProcess();
|
|
79
99
|
// NOTE getting all apps to validate if it's already installed in the stack to manage conflict
|
|
100
|
+
cli_utilities_1.log.debug('Getting all stack-specific apps for validation', this.importConfig.context);
|
|
80
101
|
this.installedApps = await (0, utils_1.getAllStackSpecificApps)(this.importConfig);
|
|
81
|
-
|
|
102
|
+
cli_utilities_1.log.debug(`Found ${((_a = this.installedApps) === null || _a === void 0 ? void 0 : _a.length) || 0} already installed apps`, this.importConfig.context);
|
|
103
|
+
cli_utilities_1.log.info('Starting marketplace app installation', this.importConfig.context);
|
|
82
104
|
for (let app of this.marketplaceApps) {
|
|
105
|
+
cli_utilities_1.log.debug(`Processing app: ${((_b = app.manifest) === null || _b === void 0 ? void 0 : _b.name) || ((_c = app.manifest) === null || _c === void 0 ? void 0 : _c.uid)}`, this.importConfig.context);
|
|
83
106
|
await this.installApps(app);
|
|
84
107
|
}
|
|
108
|
+
cli_utilities_1.log.debug('Generating UID mapper', this.importConfig.context);
|
|
85
109
|
const uidMapper = await this.generateUidMapper();
|
|
110
|
+
cli_utilities_1.log.debug('Writing UID mappings to file', this.importConfig.context);
|
|
86
111
|
utils_1.fsUtil.writeFile(this.marketPlaceUidMapperPath, {
|
|
87
112
|
app_uid: this.appUidMapping,
|
|
88
113
|
extension_uid: uidMapper || {},
|
|
89
114
|
installation_uid: this.installationUidMapping,
|
|
90
115
|
});
|
|
116
|
+
const appUidCount = Object.keys(this.appUidMapping || {}).length;
|
|
117
|
+
const extensionUidCount = Object.keys(uidMapper || {}).length;
|
|
118
|
+
cli_utilities_1.log.debug(`Written UID data: ${appUidCount} app UIDs, ${extensionUidCount} extension UIDs`, this.importConfig.context);
|
|
91
119
|
}
|
|
92
120
|
/**
|
|
93
121
|
* The function `generateUidMapper` generates a mapping of extension UIDs from old metadata to new
|
|
@@ -96,24 +124,37 @@ class ImportMarketplaceApps {
|
|
|
96
124
|
* unknown>`.
|
|
97
125
|
*/
|
|
98
126
|
async generateUidMapper() {
|
|
99
|
-
var _a, _b;
|
|
127
|
+
var _a, _b, _c, _d, _e;
|
|
128
|
+
cli_utilities_1.log.debug('Generating UID mapper for extensions', this.importConfig.context);
|
|
100
129
|
const listOfNewMeta = [];
|
|
101
130
|
const listOfOldMeta = [];
|
|
102
131
|
const extensionUidMap = {};
|
|
103
132
|
// NOTE After installation getting all apps to create mapper.
|
|
133
|
+
cli_utilities_1.log.debug('Fetching updated list of installed apps', this.importConfig.context);
|
|
104
134
|
this.installedApps = (await (0, utils_1.getAllStackSpecificApps)(this.importConfig)) || [];
|
|
135
|
+
cli_utilities_1.log.debug(`Found ${((_a = this.installedApps) === null || _a === void 0 ? void 0 : _a.length) || 0} installed apps after installation`, this.importConfig.context);
|
|
136
|
+
cli_utilities_1.log.debug('Processing old metadata from marketplace apps', this.importConfig.context);
|
|
105
137
|
for (const app of this.marketplaceApps) {
|
|
106
|
-
|
|
138
|
+
const appMeta = (0, map_1.default)((_b = app === null || app === void 0 ? void 0 : app.ui_location) === null || _b === void 0 ? void 0 : _b.locations, 'meta').flat();
|
|
139
|
+
listOfOldMeta.push(...appMeta);
|
|
140
|
+
cli_utilities_1.log.debug(`Added ${appMeta.length} meta entries from app: ${(_c = app.manifest) === null || _c === void 0 ? void 0 : _c.name}`, this.importConfig.context);
|
|
107
141
|
}
|
|
142
|
+
cli_utilities_1.log.debug('Processing new metadata from installed apps', this.importConfig.context);
|
|
108
143
|
for (const app of this.installedApps) {
|
|
109
|
-
|
|
144
|
+
const appMeta = (0, map_1.default)((_d = app === null || app === void 0 ? void 0 : app.ui_location) === null || _d === void 0 ? void 0 : _d.locations, 'meta').flat();
|
|
145
|
+
listOfNewMeta.push(...appMeta);
|
|
146
|
+
cli_utilities_1.log.debug(`Added ${appMeta.length} meta entries from installed app: ${(_e = app.manifest) === null || _e === void 0 ? void 0 : _e.name}`, this.importConfig.context);
|
|
110
147
|
}
|
|
148
|
+
cli_utilities_1.log.debug(`Creating extension UID mappings from ${listOfOldMeta.length} old meta entries`, this.importConfig.context);
|
|
111
149
|
for (const { extension_uid, uid } of (0, filter_1.default)(listOfOldMeta, 'name')) {
|
|
112
150
|
const meta = (0, find_1.default)(listOfNewMeta, { uid });
|
|
113
151
|
if (meta) {
|
|
114
152
|
extensionUidMap[extension_uid] = meta.extension_uid;
|
|
153
|
+
cli_utilities_1.log.debug(`Extension UID mapping: ${extension_uid} → ${meta.extension_uid}`, this.importConfig.context);
|
|
115
154
|
}
|
|
116
155
|
}
|
|
156
|
+
const extensionMapCount = Object.keys(extensionUidMap || {}).length;
|
|
157
|
+
cli_utilities_1.log.debug(`Generated ${extensionMapCount} extension UID items`, this.importConfig.context);
|
|
117
158
|
return extensionUidMap;
|
|
118
159
|
}
|
|
119
160
|
/**
|
|
@@ -130,24 +171,33 @@ class ImportMarketplaceApps {
|
|
|
130
171
|
* encryption key.
|
|
131
172
|
*/
|
|
132
173
|
async getAndValidateEncryptionKey(defaultValue, retry = 1) {
|
|
174
|
+
cli_utilities_1.log.debug(`Validating security configuration (attempt ${retry})`, this.importConfig.context);
|
|
133
175
|
let appConfig = (0, find_1.default)(this.marketplaceApps, ({ configuration, server_configuration }) => !(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration));
|
|
134
176
|
if (!appConfig) {
|
|
177
|
+
cli_utilities_1.log.debug('No app configuration found requiring encryption', this.importConfig.context);
|
|
135
178
|
return defaultValue;
|
|
136
179
|
}
|
|
180
|
+
cli_utilities_1.log.debug('Found app configuration requiring security setup, asking for input', this.importConfig.context);
|
|
137
181
|
const encryptionKey = await (0, interactive_1.askEncryptionKey)(defaultValue);
|
|
138
182
|
try {
|
|
139
183
|
appConfig = !(0, isEmpty_1.default)(appConfig.configuration) ? appConfig.configuration : appConfig.server_configuration;
|
|
184
|
+
cli_utilities_1.log.debug('Creating NodeCrypto instance with security configuration', this.importConfig.context);
|
|
140
185
|
this.nodeCrypto = new cli_utilities_1.NodeCrypto({ encryptionKey });
|
|
186
|
+
cli_utilities_1.log.debug('Testing security configuration with app data', this.importConfig.context);
|
|
141
187
|
this.nodeCrypto.decrypt(appConfig);
|
|
188
|
+
cli_utilities_1.log.debug('Security configuration validation successful', this.importConfig.context);
|
|
142
189
|
}
|
|
143
190
|
catch (error) {
|
|
191
|
+
cli_utilities_1.log.debug(`Security configuration validation failed: ${error.message}`, this.importConfig.context);
|
|
144
192
|
if (retry < this.importConfig.getEncryptionKeyMaxRetry && error.code === 'ERR_OSSL_EVP_BAD_DECRYPT') {
|
|
145
193
|
cli_utilities_1.cliux.print(`Provided encryption key is not valid or your data might be corrupted.! attempt(${retry}/${this.importConfig.getEncryptionKeyMaxRetry})`, { color: 'red' });
|
|
146
194
|
// NOTE max retry limit is 3
|
|
195
|
+
cli_utilities_1.log.debug(`Retrying security configuration validation (${retry + 1}/${this.importConfig.getEncryptionKeyMaxRetry})`, this.importConfig.context);
|
|
147
196
|
return this.getAndValidateEncryptionKey(encryptionKey, retry + 1);
|
|
148
197
|
}
|
|
149
198
|
else {
|
|
150
199
|
cli_utilities_1.cliux.print(`Maximum retry limit exceeded. Closing the process, please try again.! attempt(${retry}/${this.importConfig.getEncryptionKeyMaxRetry})`, { color: 'red' });
|
|
200
|
+
cli_utilities_1.log.debug('Maximum retry limit exceeded for encryption validation', this.importConfig.context);
|
|
151
201
|
process.exit(1);
|
|
152
202
|
}
|
|
153
203
|
}
|
|
@@ -160,19 +210,26 @@ class ImportMarketplaceApps {
|
|
|
160
210
|
* @returns a Promise that resolves to void.
|
|
161
211
|
*/
|
|
162
212
|
async handleAllPrivateAppsCreationProcess() {
|
|
213
|
+
cli_utilities_1.log.debug('Filtering private apps from marketplace apps', this.importConfig.context);
|
|
163
214
|
const privateApps = (0, filter_1.default)(this.marketplaceApps, { manifest: { visibility: 'private' } });
|
|
215
|
+
cli_utilities_1.log.debug(`Found ${privateApps.length} private apps to process`, this.importConfig.context);
|
|
164
216
|
if ((0, isEmpty_1.default)(privateApps)) {
|
|
217
|
+
cli_utilities_1.log.debug('No private apps found, skipping private app creation process', this.importConfig.context);
|
|
165
218
|
return Promise.resolve();
|
|
166
219
|
}
|
|
220
|
+
cli_utilities_1.log.debug('Getting confirmation to create private apps', this.importConfig.context);
|
|
167
221
|
let canCreatePrivateApp = await (0, utils_1.getConfirmationToCreateApps)(privateApps, this.importConfig);
|
|
168
222
|
this.importConfig.canCreatePrivateApp = canCreatePrivateApp;
|
|
169
223
|
if (canCreatePrivateApp) {
|
|
170
|
-
|
|
224
|
+
cli_utilities_1.log.info('Starting developer hub private apps re-creation', this.importConfig.context);
|
|
225
|
+
cli_utilities_1.log.debug(`Processing ${privateApps.length} private apps for creation`, this.importConfig.context);
|
|
171
226
|
for (let app of privateApps) {
|
|
227
|
+
cli_utilities_1.log.debug(`Checking if private app exists: ${app.manifest.name}`, this.importConfig.context);
|
|
172
228
|
if (await this.isPrivateAppExistInDeveloperHub(app)) {
|
|
173
229
|
// NOTE Found app already exist in the same org
|
|
174
230
|
this.appUidMapping[app.uid] = app.uid;
|
|
175
231
|
cli_utilities_1.cliux.print(`App '${app.manifest.name}' already exist. skipping app recreation.!`, { color: 'yellow' });
|
|
232
|
+
cli_utilities_1.log.debug(`App '${app.manifest.name}' already exists, skipping recreation`, this.importConfig.context);
|
|
176
233
|
continue;
|
|
177
234
|
}
|
|
178
235
|
// NOTE keys can be passed to install new app in the developer hub
|
|
@@ -188,15 +245,19 @@ class ImportMarketplaceApps {
|
|
|
188
245
|
'ui_location',
|
|
189
246
|
'framework_version',
|
|
190
247
|
];
|
|
248
|
+
cli_utilities_1.log.debug(`Extracting valid configuration from app manifest: ${app.manifest.name}`, this.importConfig.context);
|
|
191
249
|
const manifest = (0, pick_1.default)(app.manifest, validKeys);
|
|
192
250
|
this.appOriginalName = manifest.name;
|
|
251
|
+
cli_utilities_1.log.debug(`Creating private app: ${manifest.name}`, this.importConfig.context);
|
|
193
252
|
await this.createPrivateApp(manifest);
|
|
194
253
|
}
|
|
254
|
+
cli_utilities_1.log.success(`Completed processing ${privateApps.length} private apps`, this.importConfig.context);
|
|
195
255
|
}
|
|
196
256
|
else {
|
|
197
|
-
|
|
257
|
+
cli_utilities_1.log.info('Skipping private apps creation on Developer Hub...', this.importConfig.context);
|
|
198
258
|
}
|
|
199
259
|
this.appOriginalName = undefined;
|
|
260
|
+
cli_utilities_1.log.debug('Private apps creation process completed', this.importConfig.context);
|
|
200
261
|
}
|
|
201
262
|
/**
|
|
202
263
|
* The function checks if a private app exists in the developer hub.
|
|
@@ -206,13 +267,20 @@ class ImportMarketplaceApps {
|
|
|
206
267
|
* the installation object is empty.
|
|
207
268
|
*/
|
|
208
269
|
async isPrivateAppExistInDeveloperHub(app) {
|
|
270
|
+
var _a, _b;
|
|
271
|
+
cli_utilities_1.log.debug(`Checking if private app exists in developer hub: ${(_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name} (${app.uid})`, this.importConfig.context);
|
|
209
272
|
const installation = await this.appSdk
|
|
210
273
|
.marketplace(this.importConfig.org_uid)
|
|
211
274
|
.installation(app.uid)
|
|
212
275
|
.fetch()
|
|
213
|
-
.catch(() => {
|
|
214
|
-
|
|
215
|
-
|
|
276
|
+
.catch(() => {
|
|
277
|
+
var _a;
|
|
278
|
+
cli_utilities_1.log.debug(`App ${(_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name} not found in developer hub`, this.importConfig.context);
|
|
279
|
+
return undefined;
|
|
280
|
+
}); // NOTE Keeping this to avoid Unhandled exception
|
|
281
|
+
const exists = !(0, isEmpty_1.default)(installation);
|
|
282
|
+
cli_utilities_1.log.debug(`Private app ${(_b = app.manifest) === null || _b === void 0 ? void 0 : _b.name} exists in developer hub: ${exists}`, this.importConfig.context);
|
|
283
|
+
return exists;
|
|
216
284
|
}
|
|
217
285
|
/**
|
|
218
286
|
* The function creates a private app in a marketplace, with an optional suffix for the app name and
|
|
@@ -228,17 +296,26 @@ class ImportMarketplaceApps {
|
|
|
228
296
|
*/
|
|
229
297
|
async createPrivateApp(app, appSuffix = 1, updateUiLocation = false) {
|
|
230
298
|
var _a, _b;
|
|
299
|
+
cli_utilities_1.log.debug(`Creating private app: ${app.name} (suffix: ${appSuffix}, updateUiLocation: ${updateUiLocation})`, this.importConfig.context);
|
|
231
300
|
if (updateUiLocation && !(0, isEmpty_1.default)((_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations)) {
|
|
301
|
+
cli_utilities_1.log.debug(`Updating UI locations for app: ${app.name}`, this.importConfig.context);
|
|
232
302
|
app.ui_location.locations = this.updateManifestUILocations((_b = app === null || app === void 0 ? void 0 : app.ui_location) === null || _b === void 0 ? void 0 : _b.locations, appSuffix);
|
|
233
303
|
}
|
|
234
304
|
if (app.name.length > 20) {
|
|
305
|
+
const originalName = app.name;
|
|
235
306
|
app.name = app.name.slice(0, 20);
|
|
307
|
+
cli_utilities_1.log.debug(`Truncated app name from '${originalName}' to '${app.name}'`, this.importConfig.context);
|
|
236
308
|
}
|
|
309
|
+
cli_utilities_1.log.debug(`Making API call to create private app: ${app.name}`, this.importConfig.context);
|
|
237
310
|
const response = await this.appSdk
|
|
238
311
|
.marketplace(this.importConfig.org_uid)
|
|
239
312
|
.app()
|
|
240
313
|
.create((0, omit_1.default)(app, ['uid']))
|
|
241
|
-
.catch((error) =>
|
|
314
|
+
.catch((error) => {
|
|
315
|
+
cli_utilities_1.log.debug(`Error creating private app ${app.name}: ${error.message}`, this.importConfig.context);
|
|
316
|
+
return error;
|
|
317
|
+
});
|
|
318
|
+
cli_utilities_1.log.debug(`Processing app creation response for: ${app.name}`, this.importConfig.context);
|
|
242
319
|
return this.appCreationCallback(app, response, appSuffix);
|
|
243
320
|
}
|
|
244
321
|
/**
|
|
@@ -251,11 +328,20 @@ class ImportMarketplaceApps {
|
|
|
251
328
|
* @returns a Promise that resolves to an object.
|
|
252
329
|
*/
|
|
253
330
|
async installApp(config, appManifestUid) {
|
|
331
|
+
cli_utilities_1.log.debug(`Installing app with manifest UID: ${appManifestUid}`, this.importConfig.context);
|
|
332
|
+
cli_utilities_1.log.debug(`Target stack: ${config.target_stack}`, this.importConfig.context);
|
|
254
333
|
return await this.appSdk
|
|
255
334
|
.marketplace(this.importConfig.org_uid)
|
|
256
335
|
.app(appManifestUid)
|
|
257
336
|
.install({ targetUid: config.target_stack, targetType: 'stack' })
|
|
258
|
-
.
|
|
337
|
+
.then((response) => {
|
|
338
|
+
cli_utilities_1.log.debug(`App installation successful: ${appManifestUid}`, this.importConfig.context);
|
|
339
|
+
return response;
|
|
340
|
+
})
|
|
341
|
+
.catch((error) => {
|
|
342
|
+
cli_utilities_1.log.debug(`App installation failed: ${appManifestUid} - ${error.message}`, this.importConfig.context);
|
|
343
|
+
return error;
|
|
344
|
+
});
|
|
259
345
|
}
|
|
260
346
|
/**
|
|
261
347
|
* The function updates the names of locations in a manifest UI based on a given app suffix.
|
|
@@ -267,18 +353,25 @@ class ImportMarketplaceApps {
|
|
|
267
353
|
* @returns The function `updateManifestUILocations` returns an updated array of `locations`.
|
|
268
354
|
*/
|
|
269
355
|
updateManifestUILocations(locations, appSuffix = 1) {
|
|
356
|
+
cli_utilities_1.log.debug(`Updating manifest UI locations with suffix: ${appSuffix}`, this.importConfig.context);
|
|
357
|
+
cli_utilities_1.log.debug(`Processing ${locations.length} locations`, this.importConfig.context);
|
|
270
358
|
return (0, map_1.default)(locations, (location, index) => {
|
|
271
359
|
if (location.meta) {
|
|
360
|
+
cli_utilities_1.log.debug(`Processing location ${index} with ${location.meta.length} meta entries`, this.importConfig.context);
|
|
272
361
|
location.meta = (0, map_1.default)(location.meta, (meta) => {
|
|
273
362
|
if (meta.name && this.appOriginalName == meta.name) {
|
|
274
363
|
const name = (0, interactive_1.getLocationName)((0, first_1.default)((0, split_1.default)(meta.name, '◈')), appSuffix, this.existingNames);
|
|
275
364
|
if (!this.appNameMapping[this.appOriginalName]) {
|
|
276
365
|
this.appNameMapping[this.appOriginalName] = name;
|
|
366
|
+
cli_utilities_1.log.debug(`Created app name mapping: ${this.appOriginalName} → ${name}`, this.importConfig.context);
|
|
277
367
|
}
|
|
278
368
|
meta.name = name;
|
|
369
|
+
cli_utilities_1.log.debug(`Updated meta name to: ${name}`, this.importConfig.context);
|
|
279
370
|
}
|
|
280
371
|
else if (meta.name) {
|
|
281
|
-
|
|
372
|
+
const newName = (0, interactive_1.getLocationName)((0, first_1.default)((0, split_1.default)(meta.name, '◈')), appSuffix + (+index + 1), this.existingNames);
|
|
373
|
+
cli_utilities_1.log.debug(`Updated meta name from '${meta.name}' to '${newName}'`, this.importConfig.context);
|
|
374
|
+
meta.name = newName;
|
|
282
375
|
}
|
|
283
376
|
return meta;
|
|
284
377
|
});
|
|
@@ -301,29 +394,42 @@ class ImportMarketplaceApps {
|
|
|
301
394
|
*/
|
|
302
395
|
async appCreationCallback(app, response, appSuffix) {
|
|
303
396
|
const { statusText, message } = response || {};
|
|
397
|
+
cli_utilities_1.log.debug(`Processing app creation callback for: ${app.name} (suffix: ${appSuffix})`, this.importConfig.context);
|
|
304
398
|
if (message) {
|
|
399
|
+
cli_utilities_1.log.debug(`App creation response has message: ${message}`, this.importConfig.context);
|
|
305
400
|
if ((0, toLower_1.default)(statusText) === 'conflict') {
|
|
401
|
+
cli_utilities_1.log.debug(`Name conflict detected for app: ${app.name}`, this.importConfig.context);
|
|
306
402
|
const updatedApp = await (0, utils_1.handleNameConflict)(app, appSuffix, this.importConfig);
|
|
403
|
+
cli_utilities_1.log.debug(`Retrying app creation with updated name: ${updatedApp.name}`, this.importConfig.context);
|
|
307
404
|
return this.createPrivateApp(updatedApp, appSuffix + 1, true);
|
|
308
405
|
}
|
|
309
406
|
else {
|
|
310
407
|
(0, log_1.trace)(response, 'error', true);
|
|
311
|
-
|
|
312
|
-
if (this.importConfig.forceStopMarketplaceAppsPrompt)
|
|
408
|
+
cli_utilities_1.log.error((0, utils_1.formatError)(message), this.importConfig.context);
|
|
409
|
+
if (this.importConfig.forceStopMarketplaceAppsPrompt) {
|
|
410
|
+
cli_utilities_1.log.debug('Force stop marketplace apps prompt is enabled, resolving', this.importConfig.context);
|
|
313
411
|
return Promise.resolve();
|
|
412
|
+
}
|
|
314
413
|
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)'))) {
|
|
414
|
+
cli_utilities_1.log.debug('User chose to proceed despite error', this.importConfig.context);
|
|
315
415
|
Promise.resolve();
|
|
316
416
|
}
|
|
317
417
|
else {
|
|
418
|
+
cli_utilities_1.log.debug('User chose to exit due to error', this.importConfig.context);
|
|
318
419
|
process.exit();
|
|
319
420
|
}
|
|
320
421
|
}
|
|
321
422
|
}
|
|
322
423
|
else if (response.uid) {
|
|
323
424
|
// NOTE new app installation
|
|
324
|
-
|
|
425
|
+
cli_utilities_1.log.success(`${response.name} app created successfully.!`, this.importConfig.context);
|
|
426
|
+
cli_utilities_1.log.debug(`App UID mapping: ${app.uid} → ${response.uid}`, this.importConfig.context);
|
|
325
427
|
this.appUidMapping[app.uid] = response.uid;
|
|
326
428
|
this.appNameMapping[this.appOriginalName] = response.name;
|
|
429
|
+
cli_utilities_1.log.debug(`App name mapping: ${this.appOriginalName} → ${response.name}`, this.importConfig.context);
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
cli_utilities_1.log.debug(`Unexpected response format for app: ${app.name}`, this.importConfig.context);
|
|
327
433
|
}
|
|
328
434
|
}
|
|
329
435
|
/**
|
|
@@ -334,43 +440,59 @@ class ImportMarketplaceApps {
|
|
|
334
440
|
* @returns {Promise<void>}
|
|
335
441
|
*/
|
|
336
442
|
async installApps(app) {
|
|
337
|
-
var _a;
|
|
443
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
444
|
+
cli_utilities_1.log.debug(`Installing app: ${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || ((_b = app.manifest) === null || _b === void 0 ? void 0 : _b.uid)}`, this.importConfig.context);
|
|
338
445
|
let updateParam;
|
|
339
446
|
const { configuration, server_configuration } = app;
|
|
340
|
-
const currentStackApp = (0, find_1.default)(this.installedApps, { manifest: { uid: (
|
|
447
|
+
const currentStackApp = (0, find_1.default)(this.installedApps, { manifest: { uid: (_c = app === null || app === void 0 ? void 0 : app.manifest) === null || _c === void 0 ? void 0 : _c.uid } });
|
|
341
448
|
if (!currentStackApp) {
|
|
449
|
+
cli_utilities_1.log.debug(`App not found in current stack, installing new app: ${(_d = app.manifest) === null || _d === void 0 ? void 0 : _d.name}`, this.importConfig.context);
|
|
342
450
|
// NOTE install new app
|
|
343
451
|
if (app.manifest.visibility === 'private' && !this.importConfig.canCreatePrivateApp) {
|
|
344
|
-
|
|
452
|
+
cli_utilities_1.log.info(`Skipping the installation of the private app ${app.manifest.name}...`, this.importConfig.context);
|
|
345
453
|
return Promise.resolve();
|
|
346
454
|
}
|
|
455
|
+
cli_utilities_1.log.debug(`Installing app with manifest UID: ${this.appUidMapping[app.manifest.uid] || app.manifest.uid}`, this.importConfig.context);
|
|
347
456
|
const installation = await this.installApp(this.importConfig,
|
|
348
457
|
// NOTE if it's private app it should get uid from mapper else will use manifest uid
|
|
349
458
|
this.appUidMapping[app.manifest.uid] || app.manifest.uid);
|
|
350
459
|
if (installation.installation_uid) {
|
|
351
460
|
const appName = this.appNameMapping[app.manifest.name] || app.manifest.name || app.manifest.uid;
|
|
352
|
-
|
|
461
|
+
cli_utilities_1.log.success(`${appName} app installed successfully.!`, this.importConfig.context);
|
|
462
|
+
cli_utilities_1.log.debug(`Installation UID: ${installation.installation_uid}`, this.importConfig.context);
|
|
463
|
+
cli_utilities_1.log.debug(`Making redirect URL call for app: ${appName}`, this.importConfig.context);
|
|
353
464
|
await (0, utils_1.makeRedirectUrlCall)(installation, appName, this.importConfig);
|
|
354
465
|
this.installationUidMapping[app.uid] = installation.installation_uid;
|
|
466
|
+
cli_utilities_1.log.debug(`Installation UID mapping: ${app.uid} → ${installation.installation_uid}`, this.importConfig.context);
|
|
355
467
|
updateParam = Object.assign(Object.assign({ manifest: app.manifest }, installation), { configuration, server_configuration });
|
|
356
468
|
}
|
|
357
469
|
else if (installation.message) {
|
|
358
|
-
|
|
470
|
+
cli_utilities_1.log.info((0, utils_1.formatError)(installation.message), this.importConfig.context);
|
|
471
|
+
cli_utilities_1.log.debug(`Installation failed for app: ${(_e = app.manifest) === null || _e === void 0 ? void 0 : _e.name}`, this.importConfig.context);
|
|
359
472
|
await (0, utils_1.confirmToCloseProcess)(installation, this.importConfig);
|
|
360
473
|
}
|
|
361
474
|
}
|
|
362
475
|
else if (!(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration)) {
|
|
363
476
|
const appName = app.manifest.name || app.manifest.uid;
|
|
364
|
-
|
|
477
|
+
cli_utilities_1.log.info(`${appName} is already installed`, this.importConfig.context);
|
|
478
|
+
cli_utilities_1.log.debug(`Handling existing app configuration for: ${appName}`, this.importConfig.context);
|
|
365
479
|
updateParam = await (0, utils_1.ifAppAlreadyExist)(app, currentStackApp, this.importConfig);
|
|
366
480
|
}
|
|
481
|
+
else {
|
|
482
|
+
cli_utilities_1.log.debug(`App ${(_f = app.manifest) === null || _f === void 0 ? void 0 : _f.name} is already installed with no configuration to update`, this.importConfig.context);
|
|
483
|
+
}
|
|
367
484
|
if (!this.appUidMapping[app.manifest.uid]) {
|
|
368
485
|
this.appUidMapping[app.manifest.uid] = currentStackApp ? currentStackApp.manifest.uid : app.manifest.uid;
|
|
486
|
+
cli_utilities_1.log.debug(`App UID mapping: ${app.manifest.uid} → ${this.appUidMapping[app.manifest.uid]}`, this.importConfig.context);
|
|
369
487
|
}
|
|
370
488
|
// NOTE update configurations
|
|
371
489
|
if (updateParam && (!(0, isEmpty_1.default)(updateParam.configuration) || !(0, isEmpty_1.default)(updateParam.server_configuration))) {
|
|
490
|
+
cli_utilities_1.log.debug(`Updating app configuration for: ${(_g = app.manifest) === null || _g === void 0 ? void 0 : _g.name}`, this.importConfig.context);
|
|
372
491
|
await this.updateAppsConfig(updateParam);
|
|
373
492
|
}
|
|
493
|
+
else {
|
|
494
|
+
cli_utilities_1.log.debug(`No configuration update needed for: ${(_h = app.manifest) === null || _h === void 0 ? void 0 : _h.name}`, this.importConfig.context);
|
|
495
|
+
}
|
|
374
496
|
}
|
|
375
497
|
/**
|
|
376
498
|
* The `updateAppsConfig` function updates the configuration and server configuration of an app in a
|
|
@@ -380,7 +502,10 @@ class ImportMarketplaceApps {
|
|
|
380
502
|
*/
|
|
381
503
|
async updateAppsConfig(app) {
|
|
382
504
|
const { installation_uid, configuration, server_configuration } = app;
|
|
505
|
+
const appName = app.manifest.name || app.manifest.uid;
|
|
506
|
+
cli_utilities_1.log.debug(`Updating app configuration for: ${appName} (${installation_uid})`, this.importConfig.context);
|
|
383
507
|
if (!(0, isEmpty_1.default)(configuration)) {
|
|
508
|
+
cli_utilities_1.log.debug(`Updating app configuration for: ${appName}`, this.importConfig.context);
|
|
384
509
|
await this.appSdk
|
|
385
510
|
.marketplace(this.importConfig.org_uid)
|
|
386
511
|
.installation(installation_uid)
|
|
@@ -388,19 +513,21 @@ class ImportMarketplaceApps {
|
|
|
388
513
|
.then(({ data }) => {
|
|
389
514
|
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
390
515
|
(0, log_1.trace)(data, 'error', true);
|
|
391
|
-
|
|
516
|
+
cli_utilities_1.log.info((0, utils_1.formatError)(data.message), this.importConfig.context);
|
|
392
517
|
}
|
|
393
518
|
else {
|
|
394
|
-
|
|
395
|
-
|
|
519
|
+
cli_utilities_1.log.success(`${appName} app config updated successfully.!`, this.importConfig.context);
|
|
520
|
+
cli_utilities_1.log.debug(`Configuration update successful for: ${appName}`, this.importConfig.context);
|
|
396
521
|
}
|
|
397
522
|
})
|
|
398
523
|
.catch((error) => {
|
|
399
524
|
(0, log_1.trace)(error, 'error', true);
|
|
400
|
-
|
|
525
|
+
cli_utilities_1.log.error((0, utils_1.formatError)(error), this.importConfig.context);
|
|
526
|
+
cli_utilities_1.log.debug(`Configuration update failed for: ${appName}`, this.importConfig.context);
|
|
401
527
|
});
|
|
402
528
|
}
|
|
403
529
|
if (!(0, isEmpty_1.default)(server_configuration)) {
|
|
530
|
+
cli_utilities_1.log.debug(`Updating server configuration for: ${appName}`, this.importConfig.context);
|
|
404
531
|
await this.appSdk
|
|
405
532
|
.marketplace(this.importConfig.org_uid)
|
|
406
533
|
.installation(installation_uid)
|
|
@@ -408,15 +535,17 @@ class ImportMarketplaceApps {
|
|
|
408
535
|
.then(({ data }) => {
|
|
409
536
|
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
410
537
|
(0, log_1.trace)(data, 'error', true);
|
|
411
|
-
|
|
538
|
+
cli_utilities_1.log.error((0, utils_1.formatError)(data.message), this.importConfig.context);
|
|
412
539
|
}
|
|
413
540
|
else {
|
|
414
|
-
|
|
541
|
+
cli_utilities_1.log.success(`${appName} app server config updated successfully.!`, this.importConfig.context);
|
|
542
|
+
cli_utilities_1.log.debug(`Server configuration update successful for: ${appName}`, this.importConfig.context);
|
|
415
543
|
}
|
|
416
544
|
})
|
|
417
545
|
.catch((error) => {
|
|
418
546
|
(0, log_1.trace)(error, 'error', true);
|
|
419
|
-
|
|
547
|
+
cli_utilities_1.log.error((0, utils_1.formatError)(error), this.importConfig.context);
|
|
548
|
+
cli_utilities_1.log.debug(`Server configuration update failed for: ${appName}`, this.importConfig.context);
|
|
420
549
|
});
|
|
421
550
|
}
|
|
422
551
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const cli_variants_1 = require("@contentstack/cli-variants");
|
|
4
|
-
const
|
|
4
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
5
|
class ImportPersonalize {
|
|
6
6
|
constructor({ importConfig }) {
|
|
7
7
|
this.config = importConfig;
|
|
8
|
+
this.config.context.module = 'personalize';
|
|
8
9
|
this.personalizeConfig = importConfig.modules.personalize;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
@@ -14,16 +15,22 @@ class ImportPersonalize {
|
|
|
14
15
|
async start() {
|
|
15
16
|
try {
|
|
16
17
|
if (!this.personalizeConfig.baseURL[this.config.region.name]) {
|
|
17
|
-
|
|
18
|
+
cli_utilities_1.log.debug(`No baseURL found for region: ${this.config.region.name}`, this.config.context);
|
|
19
|
+
cli_utilities_1.log.info('Skipping Personalize project import, personalize url is not set', this.config.context);
|
|
18
20
|
this.personalizeConfig.importData = false;
|
|
19
21
|
return;
|
|
20
22
|
}
|
|
21
23
|
if (this.config.management_token) {
|
|
22
|
-
|
|
24
|
+
cli_utilities_1.log.debug('Management token detected, skipping personalize import', this.config.context);
|
|
25
|
+
cli_utilities_1.log.info('Skipping Personalize project import when using management token', this.config.context);
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
cli_utilities_1.log.debug('Starting personalize project import', this.config.context);
|
|
29
|
+
cli_utilities_1.log.debug(`Base URL: ${this.personalizeConfig.baseURL[this.config.region.name]}`, this.config.context);
|
|
30
|
+
await new cli_variants_1.Import.Project(this.config).import();
|
|
31
|
+
cli_utilities_1.log.debug('Personalize project import completed', this.config.context);
|
|
26
32
|
if (this.personalizeConfig.importData) {
|
|
33
|
+
cli_utilities_1.log.debug('Personalize data import is enabled', this.config.context);
|
|
27
34
|
const moduleMapper = {
|
|
28
35
|
events: cli_variants_1.Import.Events,
|
|
29
36
|
audiences: cli_variants_1.Import.Audiences,
|
|
@@ -32,17 +39,36 @@ class ImportPersonalize {
|
|
|
32
39
|
};
|
|
33
40
|
const order = this.personalizeConfig
|
|
34
41
|
.importOrder;
|
|
42
|
+
cli_utilities_1.log.debug(`Processing ${order.length} personalize modules in order: ${order.join(', ')}`, this.config.context);
|
|
43
|
+
const moduleTypes = Object.keys(moduleMapper || {}).join(', ');
|
|
44
|
+
cli_utilities_1.log.debug(`Available module types: ${moduleTypes}`, this.config.context);
|
|
35
45
|
for (const module of order) {
|
|
46
|
+
cli_utilities_1.log.debug(`Starting import for personalize module: ${module}`, this.config.context);
|
|
36
47
|
const Module = moduleMapper[module];
|
|
37
|
-
|
|
48
|
+
if (!Module) {
|
|
49
|
+
cli_utilities_1.log.debug(`Module ${module} not found in moduleMapper`, this.config.context);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
cli_utilities_1.log.debug(`Creating instance of ${module} module`, this.config.context);
|
|
53
|
+
const moduleInstance = new Module(this.config);
|
|
54
|
+
cli_utilities_1.log.debug(`Importing ${module} module`, this.config.context);
|
|
55
|
+
await moduleInstance.import();
|
|
56
|
+
cli_utilities_1.log.success(`Successfully imported personalize module: ${module}`, this.config.context);
|
|
57
|
+
cli_utilities_1.log.debug(`Completed import for personalize module: ${module}`, this.config.context);
|
|
38
58
|
}
|
|
59
|
+
cli_utilities_1.log.debug('All personalize modules imported successfully', this.config.context);
|
|
39
60
|
}
|
|
61
|
+
else {
|
|
62
|
+
cli_utilities_1.log.debug('Personalize data import is disabled', this.config.context);
|
|
63
|
+
}
|
|
64
|
+
cli_utilities_1.log.success('Personalize import completed successfully', this.config.context);
|
|
40
65
|
}
|
|
41
66
|
catch (error) {
|
|
42
67
|
this.personalizeConfig.importData = false; // Stop personalize import if project creation fails
|
|
43
|
-
(0,
|
|
68
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.config.context));
|
|
44
69
|
if (!this.personalizeConfig.importData) {
|
|
45
|
-
|
|
70
|
+
cli_utilities_1.log.debug('Personalize import data flag set to false due to error', this.config.context);
|
|
71
|
+
cli_utilities_1.log.info('Skipping personalize migration...', this.config.context);
|
|
46
72
|
}
|
|
47
73
|
}
|
|
48
74
|
}
|
|
@@ -21,6 +21,11 @@ class ImportStack extends base_class_1.default {
|
|
|
21
21
|
else {
|
|
22
22
|
throw new Error('Please run the environments migration first.');
|
|
23
23
|
}
|
|
24
|
+
if (this.importConfig.management_token) {
|
|
25
|
+
(0, utils_1.log)(this.importConfig, 'Skipping stack settings import: Operation is not supported when using a management token.', 'info');
|
|
26
|
+
(0, utils_1.log)(this.importConfig, 'Successfully imported stack', 'success');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
24
29
|
if (utils_1.fileHelper.fileExistsSync(this.stackSettingsPath)) {
|
|
25
30
|
this.stackSettings = utils_1.fsUtil.readFile(this.stackSettingsPath, true);
|
|
26
31
|
}
|