@contentstack/cli-cm-import 1.12.0 → 1.12.2
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 -1
- package/lib/commands/cm/stacks/import.js +3 -2
- package/lib/import/modules/entries.d.ts +1 -1
- package/lib/import/modules/entries.js +10 -6
- package/lib/import/modules/index.js +24 -11
- package/lib/import/modules/marketplace-apps.d.ts +93 -21
- package/lib/import/modules/marketplace-apps.js +204 -120
- package/lib/import/modules/workflows.js +1 -0
- package/lib/import/modules-js/marketplace-apps.js +3 -2
- package/lib/import/modules-js/workflows.js +1 -0
- package/lib/types/entries.d.ts +11 -0
- package/lib/types/entries.js +2 -0
- package/lib/types/import-config.d.ts +1 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.js +3 -0
- package/lib/types/marketplace-app.d.ts +54 -0
- package/lib/types/marketplace-app.js +2 -0
- package/lib/utils/asset-helper.js +4 -2
- package/lib/utils/entries-helper.d.ts +1 -1
- package/lib/utils/entries-helper.js +126 -74
- package/lib/utils/import-config-handler.js +1 -0
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +1 -4
- package/lib/utils/marketplace-app-helper.d.ts +2 -9
- package/lib/utils/marketplace-app-helper.js +25 -48
- package/oclif.manifest.json +7 -1
- package/package.json +4 -4
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
5
|
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
6
|
-
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
7
6
|
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
7
|
+
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
8
8
|
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
9
9
|
const first_1 = tslib_1.__importDefault(require("lodash/first"));
|
|
10
10
|
const split_1 = tslib_1.__importDefault(require("lodash/split"));
|
|
@@ -13,18 +13,16 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
|
13
13
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
14
14
|
const toLower_1 = tslib_1.__importDefault(require("lodash/toLower"));
|
|
15
15
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
16
|
-
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
17
16
|
const log_1 = require("../../utils/log");
|
|
18
17
|
const interactive_1 = require("../../utils/interactive");
|
|
19
18
|
const utils_1 = require("../../utils");
|
|
20
|
-
class ImportMarketplaceApps
|
|
21
|
-
constructor({ importConfig
|
|
22
|
-
|
|
19
|
+
class ImportMarketplaceApps {
|
|
20
|
+
constructor({ importConfig }) {
|
|
21
|
+
this.importConfig = importConfig;
|
|
23
22
|
this.marketPlaceAppConfig = importConfig.modules.marketplace_apps;
|
|
24
23
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'marketplace_apps');
|
|
25
24
|
this.marketPlaceFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.marketPlaceAppConfig.dirName);
|
|
26
25
|
this.marketPlaceUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
27
|
-
this.httpClient = new cli_utilities_1.HttpClient();
|
|
28
26
|
this.appNameMapping = {};
|
|
29
27
|
this.appUidMapping = {};
|
|
30
28
|
this.appOriginalName = undefined;
|
|
@@ -32,8 +30,8 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
32
30
|
this.installationUidMapping = {};
|
|
33
31
|
}
|
|
34
32
|
/**
|
|
35
|
-
*
|
|
36
|
-
* @returns
|
|
33
|
+
* This function starts the process of importing marketplace apps.
|
|
34
|
+
* @returns The function `start()` returns a `Promise<void>`.
|
|
37
35
|
*/
|
|
38
36
|
async start() {
|
|
39
37
|
(0, utils_1.log)(this.importConfig, 'Migrating marketplace apps', 'info');
|
|
@@ -53,37 +51,23 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
53
51
|
}
|
|
54
52
|
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
55
53
|
this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.importConfig));
|
|
56
|
-
this.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
54
|
+
this.importConfig.developerHubBaseUrl = this.developerHubBaseUrl;
|
|
55
|
+
// NOTE init marketplace app sdk
|
|
56
|
+
const host = this.developerHubBaseUrl.split('://').pop();
|
|
57
|
+
this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
|
|
60
58
|
this.importConfig.org_uid = await (0, utils_1.getOrgUid)(this.importConfig);
|
|
61
|
-
|
|
62
|
-
await this.
|
|
59
|
+
// NOTE start the marketplace import process
|
|
60
|
+
await this.importMarketplaceApps();
|
|
63
61
|
(0, utils_1.log)(this.importConfig, 'Marketplace apps have been imported successfully!', 'success');
|
|
64
62
|
}
|
|
65
|
-
async setHttpClient() {
|
|
66
|
-
if (!this.importConfig.auth_token) {
|
|
67
|
-
this.httpClient = new cli_utilities_1.OauthDecorator(this.httpClient);
|
|
68
|
-
const headers = await this.httpClient.preHeadersCheck(this.importConfig);
|
|
69
|
-
this.httpClient = this.httpClient.headers(headers);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
this.httpClient = new cli_utilities_1.HttpClientDecorator(this.httpClient);
|
|
73
|
-
this.httpClient.headers(this.importConfig);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
63
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
64
|
+
* The function `importMarketplaceApps` installs marketplace apps, handles private app creation,
|
|
65
|
+
* validates app installation, and generates a UID mapper.
|
|
79
66
|
*/
|
|
80
|
-
async
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
cryptoArgs['encryptionKey'] = this.importConfig.marketplaceAppEncryptionKey;
|
|
84
|
-
}
|
|
67
|
+
async importMarketplaceApps() {
|
|
68
|
+
// NOTE set default encryptionKey
|
|
69
|
+
const cryptoArgs = { encryptionKey: this.importConfig.marketplaceAppEncryptionKey };
|
|
85
70
|
if (this.importConfig.forceStopMarketplaceAppsPrompt) {
|
|
86
|
-
cryptoArgs['encryptionKey'] = this.importConfig.marketplaceAppEncryptionKey;
|
|
87
71
|
this.nodeCrypto = new cli_utilities_1.NodeCrypto(cryptoArgs);
|
|
88
72
|
}
|
|
89
73
|
else {
|
|
@@ -91,7 +75,8 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
91
75
|
}
|
|
92
76
|
// NOTE install all private apps which is not available for stack.
|
|
93
77
|
await this.handleAllPrivateAppsCreationProcess();
|
|
94
|
-
|
|
78
|
+
// NOTE getting all apps to validate if it's already installed in the stack to manage conflict
|
|
79
|
+
this.installedApps = await (0, utils_1.getAllStackSpecificApps)(this.importConfig);
|
|
95
80
|
(0, utils_1.log)(this.importConfig, 'Starting marketplace app installation', 'success');
|
|
96
81
|
for (let app of this.marketplaceApps) {
|
|
97
82
|
await this.installApps(app);
|
|
@@ -103,29 +88,46 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
103
88
|
installation_uid: this.installationUidMapping,
|
|
104
89
|
});
|
|
105
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* The function `generateUidMapper` generates a mapping of extension UIDs from old metadata to new
|
|
93
|
+
* metadata based on the installed and marketplace apps.
|
|
94
|
+
* @returns The function `generateUidMapper` returns a Promise that resolves to a `Record<string,
|
|
95
|
+
* unknown>`.
|
|
96
|
+
*/
|
|
106
97
|
async generateUidMapper() {
|
|
107
98
|
var _a, _b;
|
|
108
99
|
const listOfNewMeta = [];
|
|
109
100
|
const listOfOldMeta = [];
|
|
110
101
|
const extensionUidMap = {};
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
// NOTE After installation getting all apps to create mapper.
|
|
103
|
+
this.installedApps = (await (0, utils_1.getAllStackSpecificApps)(this.importConfig)) || [];
|
|
113
104
|
for (const app of this.marketplaceApps) {
|
|
114
105
|
listOfOldMeta.push(...(0, map_1.default)((_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations, 'meta').flat());
|
|
115
106
|
}
|
|
116
107
|
for (const app of this.installedApps) {
|
|
117
108
|
listOfNewMeta.push(...(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());
|
|
118
109
|
}
|
|
119
|
-
for (const { extension_uid,
|
|
120
|
-
const meta = (0, find_1.default)(listOfNewMeta, {
|
|
121
|
-
(0, find_1.default)(listOfNewMeta, { name: this.appNameMapping[name], path }) ||
|
|
122
|
-
(0, find_1.default)(listOfNewMeta, { name, uid, data_type });
|
|
110
|
+
for (const { extension_uid, uid } of (0, filter_1.default)(listOfOldMeta, 'name')) {
|
|
111
|
+
const meta = (0, find_1.default)(listOfNewMeta, { uid });
|
|
123
112
|
if (meta) {
|
|
124
113
|
extensionUidMap[extension_uid] = meta.extension_uid;
|
|
125
114
|
}
|
|
126
115
|
}
|
|
127
116
|
return extensionUidMap;
|
|
128
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* The function `getAndValidateEncryptionKey` retrieves and validates an encryption key, with the
|
|
120
|
+
* option to retry a specified number of times.
|
|
121
|
+
* @param {string} defaultValue - The defaultValue parameter is a string that represents the default
|
|
122
|
+
* encryption key value to use if no valid encryption key is found in the marketplaceApps
|
|
123
|
+
* configuration.
|
|
124
|
+
* @param [retry=1] - The `retry` parameter is an optional parameter that specifies the number of
|
|
125
|
+
* times the function should retry getting and validating the encryption key if it fails. The default
|
|
126
|
+
* value is 1, meaning that if the function fails to get and validate the encryption key on the first
|
|
127
|
+
* attempt, it will not retry.
|
|
128
|
+
* @returns The function `getAndValidateEncryptionKey` returns a Promise that resolves to the
|
|
129
|
+
* encryption key.
|
|
130
|
+
*/
|
|
129
131
|
async getAndValidateEncryptionKey(defaultValue, retry = 1) {
|
|
130
132
|
let appConfig = (0, find_1.default)(this.marketplaceApps, ({ configuration, server_configuration }) => !(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration));
|
|
131
133
|
if (!appConfig) {
|
|
@@ -151,8 +153,10 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
151
153
|
return encryptionKey;
|
|
152
154
|
}
|
|
153
155
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
+
* The function `handleAllPrivateAppsCreationProcess` handles the creation process for all private
|
|
157
|
+
* apps in a developer hub, including checking for existing apps, getting confirmation from the user,
|
|
158
|
+
* and creating the apps if necessary.
|
|
159
|
+
* @returns a Promise that resolves to void.
|
|
156
160
|
*/
|
|
157
161
|
async handleAllPrivateAppsCreationProcess() {
|
|
158
162
|
const privateApps = (0, filter_1.default)(this.marketplaceApps, { manifest: { visibility: 'private' } });
|
|
@@ -162,66 +166,137 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
162
166
|
await (0, utils_1.getConfirmationToCreateApps)(privateApps, this.importConfig);
|
|
163
167
|
(0, utils_1.log)(this.importConfig, 'Starting developer hub private apps re-creation', 'success');
|
|
164
168
|
for (let app of privateApps) {
|
|
169
|
+
if (this.importConfig.skipPrivateAppRecreationIfExist && (await this.isPrivateAppExistInDeveloperHub(app))) {
|
|
170
|
+
// NOTE Found app already exist in the same org
|
|
171
|
+
this.appUidMapping[app.uid] = app.uid;
|
|
172
|
+
cli_utilities_1.cliux.print(`App '${app.manifest.name}' already exist. skipping app recreation.!`, { color: 'yellow' });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
165
175
|
// NOTE keys can be passed to install new app in the developer hub
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
const validKeys = [
|
|
177
|
+
'uid',
|
|
178
|
+
'name',
|
|
179
|
+
'icon',
|
|
180
|
+
'oauth',
|
|
181
|
+
'webhook',
|
|
182
|
+
'visibility',
|
|
183
|
+
'target_type',
|
|
184
|
+
'description',
|
|
185
|
+
'ui_location',
|
|
186
|
+
'framework_version',
|
|
187
|
+
];
|
|
188
|
+
const manifest = (0, pick_1.default)(app.manifest, validKeys);
|
|
189
|
+
this.appOriginalName = manifest.name;
|
|
190
|
+
await this.createPrivateApp(manifest);
|
|
174
191
|
}
|
|
175
192
|
this.appOriginalName = undefined;
|
|
176
193
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
194
|
+
/**
|
|
195
|
+
* The function checks if a private app exists in the developer hub.
|
|
196
|
+
* @param {App} app - The `app` parameter is an object representing an application. It likely has
|
|
197
|
+
* properties such as `uid` which is a unique identifier for the app.
|
|
198
|
+
* @returns a boolean value. It returns true if the installation object is not empty, and false if
|
|
199
|
+
* the installation object is empty.
|
|
200
|
+
*/
|
|
201
|
+
async isPrivateAppExistInDeveloperHub(app) {
|
|
202
|
+
const installation = await this.appSdk
|
|
203
|
+
.marketplace(this.importConfig.org_uid)
|
|
204
|
+
.installation(app.uid)
|
|
205
|
+
.fetch()
|
|
206
|
+
.catch(() => { }); // NOTE Keeping this to avoid Unhandled exception
|
|
207
|
+
return !(0, isEmpty_1.default)(installation);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The function creates a private app in a marketplace, with an optional suffix for the app name and
|
|
211
|
+
* an option to update the UI location.
|
|
212
|
+
* @param {Manifest} app - The `app` parameter is an object that represents the manifest of the app
|
|
213
|
+
* being created. It contains various properties such as `name`, `ui_location`, and `uid`.
|
|
214
|
+
* @param [appSuffix=1] - The appSuffix parameter is an optional parameter that specifies a suffix to
|
|
215
|
+
* be added to the app's UI location. It is used when updating the UI location of the app.
|
|
216
|
+
* @param [updateUiLocation=false] - A boolean value indicating whether to update the UI location of
|
|
217
|
+
* the app.
|
|
218
|
+
* @returns the result of the `appCreationCallback` function, which takes in the `app`, `response`,
|
|
219
|
+
* and `appSuffix` as arguments.
|
|
220
|
+
*/
|
|
221
|
+
async createPrivateApp(app, appSuffix = 1, updateUiLocation = false) {
|
|
222
|
+
var _a, _b;
|
|
223
|
+
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)) {
|
|
224
|
+
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);
|
|
185
225
|
}
|
|
186
|
-
if (app.name > 20) {
|
|
226
|
+
if (app.name.length > 20) {
|
|
187
227
|
app.name = app.name.slice(0, 20);
|
|
188
228
|
}
|
|
189
|
-
const response = await
|
|
229
|
+
const response = await this.appSdk
|
|
230
|
+
.marketplace(this.importConfig.org_uid)
|
|
231
|
+
.app()
|
|
232
|
+
.create((0, omit_1.default)(app, ['uid']))
|
|
233
|
+
.catch((error) => error);
|
|
190
234
|
return this.appCreationCallback(app, response, appSuffix);
|
|
191
235
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
236
|
+
/**
|
|
237
|
+
* The function installs an app from a marketplace onto a target stack.
|
|
238
|
+
* @param {ImportConfig} config - The `config` parameter is an object that contains the configuration
|
|
239
|
+
* for the installation. It likely includes information such as the target stack UID and other
|
|
240
|
+
* relevant details.
|
|
241
|
+
* @param {string} [appManifestUid] - The `appManifestUid` parameter is the unique identifier of the
|
|
242
|
+
* app manifest. It is used to specify which app to install from the marketplace.
|
|
243
|
+
* @returns a Promise that resolves to an object.
|
|
244
|
+
*/
|
|
245
|
+
async installApp(config, appManifestUid) {
|
|
246
|
+
return await this.appSdk
|
|
247
|
+
.marketplace(this.importConfig.org_uid)
|
|
248
|
+
.app(appManifestUid)
|
|
249
|
+
.install({ targetUid: config.target_stack, targetType: 'stack' })
|
|
250
|
+
.catch((error) => error);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The function updates the names of locations in a manifest UI based on a given app suffix.
|
|
254
|
+
* @param {any} locations - An array of objects representing different locations in a manifest file.
|
|
255
|
+
* Each object has a "meta" property which is an array of objects representing metadata for that
|
|
256
|
+
* location.
|
|
257
|
+
* @param [appSuffix=1] - The `appSuffix` parameter is an optional parameter that specifies a suffix
|
|
258
|
+
* to be added to the app name. It is set to 1 by default.
|
|
259
|
+
* @returns The function `updateManifestUILocations` returns an updated array of `locations`.
|
|
260
|
+
*/
|
|
261
|
+
updateManifestUILocations(locations, appSuffix = 1) {
|
|
262
|
+
return (0, map_1.default)(locations, (location, index) => {
|
|
263
|
+
if (location.meta) {
|
|
264
|
+
location.meta = (0, map_1.default)(location.meta, (meta) => {
|
|
265
|
+
if (meta.name && this.appOriginalName == meta.name) {
|
|
266
|
+
const name = (0, interactive_1.getAppName)((0, first_1.default)((0, split_1.default)(meta.name, '◈')), appSuffix);
|
|
267
|
+
if (!this.appNameMapping[this.appOriginalName]) {
|
|
268
|
+
this.appNameMapping[this.appOriginalName] = name;
|
|
269
|
+
}
|
|
270
|
+
meta.name = name;
|
|
198
271
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
case 'name':
|
|
202
|
-
return (0, map_1.default)(locations, (location) => {
|
|
203
|
-
if (location.meta) {
|
|
204
|
-
location.meta = (0, map_1.default)(location.meta, (meta) => {
|
|
205
|
-
if (meta.name) {
|
|
206
|
-
const name = `${(0, first_1.default)((0, split_1.default)(meta.name, '◈'))}◈${appSuffix}`;
|
|
207
|
-
if (!this.appNameMapping[this.appOriginalName]) {
|
|
208
|
-
this.appNameMapping[this.appOriginalName] = name;
|
|
209
|
-
}
|
|
210
|
-
meta.name = name;
|
|
211
|
-
}
|
|
212
|
-
return meta;
|
|
213
|
-
});
|
|
272
|
+
else if (meta.name) {
|
|
273
|
+
meta.name = (0, interactive_1.getAppName)((0, first_1.default)((0, split_1.default)(meta.name, '◈')), appSuffix + (+index + 1));
|
|
214
274
|
}
|
|
215
|
-
return
|
|
275
|
+
return meta;
|
|
216
276
|
});
|
|
217
|
-
|
|
277
|
+
}
|
|
278
|
+
return location;
|
|
279
|
+
});
|
|
218
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* The function `appCreationCallback` handles the creation of a new app and handles any conflicts or
|
|
283
|
+
* errors that may occur during the process.
|
|
284
|
+
* @param {any} app - The `app` parameter is an object representing the app that is being created. It
|
|
285
|
+
* contains various properties such as `uid` (unique identifier), `name`, and other app-specific
|
|
286
|
+
* details.
|
|
287
|
+
* @param {any} response - The `response` parameter is an object that contains the response received
|
|
288
|
+
* from an API call. It may have properties such as `statusText` and `message`.
|
|
289
|
+
* @param {number} appSuffix - The `appSuffix` parameter is a number that is used to generate a
|
|
290
|
+
* unique suffix for the app name in case of a name conflict. It is incremented each time a name
|
|
291
|
+
* conflict occurs to ensure that the new app name is unique.
|
|
292
|
+
* @returns a Promise.
|
|
293
|
+
*/
|
|
219
294
|
async appCreationCallback(app, response, appSuffix) {
|
|
220
295
|
const { statusText, message } = response || {};
|
|
221
296
|
if (message) {
|
|
222
297
|
if ((0, toLower_1.default)(statusText) === 'conflict') {
|
|
223
298
|
const updatedApp = await (0, utils_1.handleNameConflict)(app, appSuffix, this.importConfig);
|
|
224
|
-
return this.
|
|
299
|
+
return this.createPrivateApp(updatedApp, appSuffix + 1, true);
|
|
225
300
|
}
|
|
226
301
|
else {
|
|
227
302
|
(0, log_1.trace)(response, 'error', true);
|
|
@@ -251,19 +326,19 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
251
326
|
* @returns {Promise<void>}
|
|
252
327
|
*/
|
|
253
328
|
async installApps(app) {
|
|
254
|
-
var _a, _b
|
|
329
|
+
var _a, _b;
|
|
255
330
|
let updateParam;
|
|
256
331
|
const { configuration, server_configuration } = app;
|
|
257
332
|
const currentStackApp = (0, find_1.default)(this.installedApps, { manifest: { uid: (_a = app === null || app === void 0 ? void 0 : app.manifest) === null || _a === void 0 ? void 0 : _a.uid } });
|
|
258
333
|
if (!currentStackApp) {
|
|
259
334
|
// NOTE install new app
|
|
260
|
-
const
|
|
261
|
-
|
|
335
|
+
const installation = await this.installApp(this.importConfig,
|
|
336
|
+
// NOTE if it's private app it should get uid from mapper else will use manifest uid
|
|
337
|
+
this.appUidMapping[app.manifest.uid] || app.manifest.uid);
|
|
262
338
|
if (installation.installation_uid) {
|
|
263
|
-
const
|
|
264
|
-
const appName = this.appNameMapping[appManifestName] ? this.appNameMapping[appManifestName] : appManifestName;
|
|
339
|
+
const appName = (_b = this.appNameMapping[app.manifest.name]) !== null && _b !== void 0 ? _b : app.manifest.name;
|
|
265
340
|
(0, utils_1.log)(this.importConfig, `${appName} app installed successfully.!`, 'success');
|
|
266
|
-
await (0, utils_1.makeRedirectUrlCall)(installation,
|
|
341
|
+
await (0, utils_1.makeRedirectUrlCall)(installation, appName, this.importConfig);
|
|
267
342
|
this.installationUidMapping[app.uid] = installation.installation_uid;
|
|
268
343
|
updateParam = Object.assign(Object.assign({ manifest: app.manifest }, installation), { configuration, server_configuration });
|
|
269
344
|
}
|
|
@@ -285,42 +360,51 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
285
360
|
}
|
|
286
361
|
}
|
|
287
362
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
363
|
+
* The `updateAppsConfig` function updates the configuration and server configuration of an app in a
|
|
364
|
+
* marketplace.
|
|
365
|
+
* @param {Installation} app - The `app` parameter is an object that represents an installation of an
|
|
366
|
+
* app. It contains the following properties:
|
|
290
367
|
*/
|
|
291
368
|
async updateAppsConfig(app) {
|
|
292
|
-
const
|
|
293
|
-
const { uid, configuration, server_configuration } = app;
|
|
369
|
+
const { installation_uid, configuration, server_configuration } = app;
|
|
294
370
|
if (!(0, isEmpty_1.default)(configuration)) {
|
|
295
|
-
|
|
371
|
+
await this.appSdk
|
|
372
|
+
.marketplace(this.importConfig.org_uid)
|
|
373
|
+
.installation(installation_uid)
|
|
374
|
+
.setConfiguration(this.nodeCrypto.decrypt(configuration))
|
|
375
|
+
.then(({ data }) => {
|
|
376
|
+
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
377
|
+
(0, log_1.trace)(data, 'error', true);
|
|
378
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
(0, utils_1.log)(this.importConfig, `${app.manifest.name} app config updated successfully.!`, 'success');
|
|
382
|
+
}
|
|
383
|
+
})
|
|
384
|
+
.catch((error) => {
|
|
385
|
+
(0, log_1.trace)(error, 'error', true);
|
|
386
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
387
|
+
});
|
|
296
388
|
}
|
|
297
389
|
if (!(0, isEmpty_1.default)(server_configuration)) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
390
|
+
await this.appSdk
|
|
391
|
+
.marketplace(this.importConfig.org_uid)
|
|
392
|
+
.installation(installation_uid)
|
|
393
|
+
.setServerConfig(this.nodeCrypto.decrypt(server_configuration))
|
|
394
|
+
.then(({ data }) => {
|
|
395
|
+
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
396
|
+
(0, log_1.trace)(data, 'error', true);
|
|
397
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'error');
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
(0, utils_1.log)(this.importConfig, `${app.manifest.name} app server config updated successfully.!`, 'info');
|
|
401
|
+
}
|
|
402
|
+
})
|
|
403
|
+
.catch((error) => {
|
|
404
|
+
(0, log_1.trace)(error, 'error', true);
|
|
405
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
406
|
+
});
|
|
302
407
|
}
|
|
303
|
-
// TODO migrate this HTTP API call into SDK
|
|
304
|
-
// NOTE Use updateAppConfig(this.sdkClient, this.importConfig, app, payload) utility when migrating to SDK call;
|
|
305
|
-
return this.appSdkAxiosInstance.axiosInstance
|
|
306
|
-
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload, {
|
|
307
|
-
headers: {
|
|
308
|
-
organization_uid: this.importConfig.org_uid,
|
|
309
|
-
},
|
|
310
|
-
})
|
|
311
|
-
.then(({ data }) => {
|
|
312
|
-
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
313
|
-
(0, log_1.trace)(data, 'error', true);
|
|
314
|
-
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
(0, utils_1.log)(this.importConfig, `${app.manifest.name} app config updated successfully.!`, 'success');
|
|
318
|
-
}
|
|
319
|
-
})
|
|
320
|
-
.catch((error) => {
|
|
321
|
-
(0, log_1.trace)(error, 'error', true);
|
|
322
|
-
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
323
|
-
});
|
|
324
408
|
}
|
|
325
409
|
}
|
|
326
410
|
exports.default = ImportMarketplaceApps;
|
|
@@ -38,6 +38,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
38
38
|
return Promise.resolve();
|
|
39
39
|
}
|
|
40
40
|
this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config));
|
|
41
|
+
this.config.developerHubBaseUrl = this.developerHubBaseUrl;
|
|
41
42
|
this.client = await managementSDKClient({ endpoint: this.developerHubBaseUrl });
|
|
42
43
|
this.appSdkAxiosInstance = await managementSDKClient({
|
|
43
44
|
host: this.developerHubBaseUrl.split('://').pop()
|
|
@@ -122,7 +123,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
122
123
|
}
|
|
123
124
|
// NOTE install all private apps which is not available for stack.
|
|
124
125
|
await this.handleAllPrivateAppsCreationProcess();
|
|
125
|
-
const installedApps = await getAllStackSpecificApps(this.
|
|
126
|
+
const installedApps = await getAllStackSpecificApps(this.config);
|
|
126
127
|
log(this.config, 'Starting marketplace app installation', 'success');
|
|
127
128
|
for (let app of this.marketplaceApps) {
|
|
128
129
|
await this.installApps(app, installedApps);
|
|
@@ -139,7 +140,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
139
140
|
const listOfNewMeta = [];
|
|
140
141
|
const listOfOldMeta = [];
|
|
141
142
|
const extensionUidMap = {};
|
|
142
|
-
const allInstalledApps = (await getAllStackSpecificApps(this.
|
|
143
|
+
const allInstalledApps = (await getAllStackSpecificApps(this.config)) || [];
|
|
143
144
|
for (const app of this.marketplaceApps) {
|
|
144
145
|
listOfOldMeta.push(..._.map((_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations, 'meta').flat());
|
|
145
146
|
}
|
|
@@ -14,6 +14,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
|
|
|
14
14
|
management_token?: string;
|
|
15
15
|
apiKey: string;
|
|
16
16
|
forceStopMarketplaceAppsPrompt: boolean;
|
|
17
|
+
skipPrivateAppRecreationIfExist: boolean;
|
|
17
18
|
auth_token?: string;
|
|
18
19
|
branchName?: string;
|
|
19
20
|
securedAssets?: boolean;
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/index.js
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
type AppLocation = 'cs.cm.stack.config' | 'cs.cm.stack.dashboard' | 'cs.cm.stack.sidebar' | 'cs.cm.stack.custom_field' | 'cs.cm.stack.rte' | 'cs.cm.stack.asset_sidebar' | 'cs.org.config';
|
|
2
|
+
interface ExtensionMeta {
|
|
3
|
+
uid?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
signed: boolean;
|
|
8
|
+
extension_uid?: string;
|
|
9
|
+
data_type?: string;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
width?: number;
|
|
12
|
+
blur?: boolean;
|
|
13
|
+
default_width?: 'full' | 'half';
|
|
14
|
+
}
|
|
15
|
+
interface Extension {
|
|
16
|
+
type: AppLocation;
|
|
17
|
+
meta: ExtensionMeta[];
|
|
18
|
+
}
|
|
19
|
+
interface LocationConfiguration {
|
|
20
|
+
signed: boolean;
|
|
21
|
+
base_url: string;
|
|
22
|
+
locations: Extension[];
|
|
23
|
+
}
|
|
24
|
+
interface AnyProperty {
|
|
25
|
+
[propName: string]: any;
|
|
26
|
+
}
|
|
27
|
+
type Manifest = {
|
|
28
|
+
uid: string;
|
|
29
|
+
name: string;
|
|
30
|
+
icon?: string;
|
|
31
|
+
hosting?: any;
|
|
32
|
+
version?: number;
|
|
33
|
+
description: string;
|
|
34
|
+
organization_uid: string;
|
|
35
|
+
framework_version?: string;
|
|
36
|
+
oauth?: any;
|
|
37
|
+
webhook?: any;
|
|
38
|
+
ui_location: LocationConfiguration;
|
|
39
|
+
target_type: 'stack' | 'organization';
|
|
40
|
+
visibility: 'private' | 'public' | 'public_unlisted';
|
|
41
|
+
} & AnyProperty;
|
|
42
|
+
type Installation = {
|
|
43
|
+
uid: string;
|
|
44
|
+
status: string;
|
|
45
|
+
manifest: Manifest;
|
|
46
|
+
configuration: any;
|
|
47
|
+
server_configuration: any;
|
|
48
|
+
target: {
|
|
49
|
+
type: string;
|
|
50
|
+
uid: string;
|
|
51
|
+
};
|
|
52
|
+
ui_location: LocationConfiguration;
|
|
53
|
+
} & AnyProperty;
|
|
54
|
+
export { Installation, Manifest };
|
|
@@ -234,7 +234,8 @@ const lookupAssets = function (data, mappedAssetUids, mappedAssetUrls, assetUidM
|
|
|
234
234
|
assetUrls.forEach(function (assetUrl) {
|
|
235
235
|
let mappedAssetUrl = mappedAssetUrls[assetUrl];
|
|
236
236
|
if (typeof mappedAssetUrl !== 'undefined') {
|
|
237
|
-
|
|
237
|
+
const escapedAssetUrl = assetUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
238
|
+
entry = entry.replace(new RegExp(escapedAssetUrl, 'img'), mappedAssetUrl);
|
|
238
239
|
matchedUrls.push(mappedAssetUrl);
|
|
239
240
|
}
|
|
240
241
|
else {
|
|
@@ -244,7 +245,8 @@ const lookupAssets = function (data, mappedAssetUids, mappedAssetUrls, assetUidM
|
|
|
244
245
|
assetUids.forEach(function (assetUid) {
|
|
245
246
|
let uid = mappedAssetUids[assetUid];
|
|
246
247
|
if (typeof uid !== 'undefined') {
|
|
247
|
-
|
|
248
|
+
const escapedAssetUid = assetUid.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
249
|
+
entry = entry.replace(new RegExp(escapedAssetUid, 'img'), uid);
|
|
248
250
|
matchedUids.push(assetUid);
|
|
249
251
|
}
|
|
250
252
|
else {
|
|
@@ -7,4 +7,4 @@ export declare const lookupEntries: (data: {
|
|
|
7
7
|
}, mappedUids: Record<string, any>, uidMapperPath: string) => any;
|
|
8
8
|
export declare const removeUidsFromJsonRteFields: (entry: Record<string, any>, ctSchema?: Record<string, any>[]) => Record<string, any>;
|
|
9
9
|
export declare const removeEntryRefsFromJSONRTE: (entry: Record<string, any>, ctSchema?: Record<string, any>[]) => Record<string, any>;
|
|
10
|
-
export declare const restoreJsonRteEntryRefs: (entry: Record<string, any>, sourceStackEntry: any, ctSchema: any, { mappedAssetUids, mappedAssetUrls }: any) => Record<string, any>;
|
|
10
|
+
export declare const restoreJsonRteEntryRefs: (entry: Record<string, any>, sourceStackEntry: any, ctSchema: any, { uidMapper, mappedAssetUids, mappedAssetUrls }: any) => Record<string, any>;
|