@contentstack/cli-cm-import 1.6.0 → 1.7.1

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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/lib/commands/cm/stacks/import.js +1 -1
  3. package/lib/config/index.js +24 -1
  4. package/lib/import/modules/base-class.d.ts +3 -2
  5. package/lib/import/modules/base-class.js +53 -0
  6. package/lib/import/modules/content-types.d.ts +56 -0
  7. package/lib/import/modules/content-types.js +186 -0
  8. package/lib/import/modules/custom-roles.d.ts +37 -0
  9. package/lib/import/modules/custom-roles.js +171 -0
  10. package/lib/import/modules/environments.d.ts +27 -0
  11. package/lib/import/modules/environments.js +106 -0
  12. package/lib/import/modules/extensions.d.ts +27 -0
  13. package/lib/import/modules/extensions.js +106 -0
  14. package/lib/import/modules/global-fields.d.ts +34 -0
  15. package/lib/import/modules/global-fields.js +99 -0
  16. package/lib/import/modules/labels.d.ts +34 -0
  17. package/lib/import/modules/labels.js +171 -0
  18. package/lib/import/modules/locales.js +0 -8
  19. package/lib/import/modules/marketplace-apps.d.ts +51 -0
  20. package/lib/import/modules/marketplace-apps.js +309 -0
  21. package/lib/import/modules/webhooks.d.ts +27 -0
  22. package/lib/import/modules/webhooks.js +110 -0
  23. package/lib/import/modules-js/custom-roles.js +2 -0
  24. package/lib/import/modules-js/entries.js +8 -2
  25. package/lib/import/modules-js/extensions.d.ts +1 -0
  26. package/lib/import/modules-js/marketplace-apps.js +11 -11
  27. package/lib/types/default-config.d.ts +13 -0
  28. package/lib/types/import-config.d.ts +1 -0
  29. package/lib/types/index.d.ts +33 -0
  30. package/lib/types/index.js +2 -0
  31. package/lib/utils/content-type-helper.d.ts +3 -1
  32. package/lib/utils/content-type-helper.js +3 -1
  33. package/lib/utils/extension-helper.d.ts +0 -5
  34. package/lib/utils/extension-helper.js +23 -11
  35. package/lib/utils/index.d.ts +1 -1
  36. package/lib/utils/index.js +11 -1
  37. package/lib/utils/interactive.d.ts +5 -0
  38. package/lib/utils/interactive.js +66 -1
  39. package/lib/utils/marketplace-app-helper.d.ts +13 -1
  40. package/lib/utils/marketplace-app-helper.js +127 -15
  41. package/oclif.manifest.json +1 -1
  42. package/package.json +6 -6
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
+ const find_1 = tslib_1.__importDefault(require("lodash/find"));
6
+ const map_1 = tslib_1.__importDefault(require("lodash/map"));
7
+ const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
8
+ const first_1 = tslib_1.__importDefault(require("lodash/first"));
9
+ const split_1 = tslib_1.__importDefault(require("lodash/split"));
10
+ const toLower_1 = tslib_1.__importDefault(require("lodash/toLower"));
11
+ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
12
+ const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
13
+ const node_path_1 = require("node:path");
14
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
15
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
16
+ const config_1 = tslib_1.__importDefault(require("../../config"));
17
+ const utils_1 = require("../../utils");
18
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
19
+ const interactive_1 = require("../../utils/interactive");
20
+ class ImportMarketplaceApps extends base_class_1.default {
21
+ constructor({ importConfig, stackAPIClient }) {
22
+ super({ importConfig, stackAPIClient });
23
+ this.marketPlaceAppConfig = config_1.default.modules.marketplace_apps;
24
+ this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'marketplace_apps');
25
+ this.marketPlaceFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.marketPlaceAppConfig.dirName);
26
+ this.marketPlaceUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
27
+ this.httpClient = new cli_utilities_1.HttpClient();
28
+ this.appNameMapping = {};
29
+ this.appUidMapping = {};
30
+ this.appOrginalName = undefined;
31
+ this.installedApps = [];
32
+ this.installationUidMapping = {};
33
+ }
34
+ /**
35
+ * @method start
36
+ * @returns {Promise<void>} Promise<void>
37
+ */
38
+ async start() {
39
+ (0, utils_1.log)(this.importConfig, 'Migrating marketplace apps', 'info');
40
+ if (utils_1.fileHelper.fileExistsSync(this.marketPlaceFolderPath)) {
41
+ this.marketplaceApps = utils_1.fsUtil.readFile((0, node_path_1.join)(this.marketPlaceFolderPath, this.marketPlaceAppConfig.fileName), true);
42
+ }
43
+ else {
44
+ (0, utils_1.log)(this.importConfig, `No such file or directory - '${this.marketPlaceFolderPath}'`, 'error');
45
+ return;
46
+ }
47
+ if ((0, isEmpty_1.default)(this.marketplaceApps)) {
48
+ return Promise.resolve();
49
+ }
50
+ else if (!(0, cli_utilities_1.isAuthenticated)()) {
51
+ 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' });
52
+ return Promise.resolve();
53
+ }
54
+ await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
55
+ this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.importConfig));
56
+ this.sdkClient = await (0, cli_utilities_1.managementSDKClient)({ endpoint: this.developerHubBaseUrl });
57
+ this.importConfig.org_uid = await (0, utils_1.getOrgUid)(this.importConfig);
58
+ await this.setHttpClient();
59
+ await this.startInstallation();
60
+ (0, utils_1.log)(this.importConfig, 'Marketplace apps have been imported successfully!', 'success');
61
+ }
62
+ async setHttpClient() {
63
+ if (!this.importConfig.auth_token) {
64
+ this.httpClient = new cli_utilities_1.OauthDecorator(this.httpClient);
65
+ const headers = await this.httpClient.preHeadersCheck(this.importConfig);
66
+ this.httpClient = this.httpClient.headers(headers);
67
+ }
68
+ else {
69
+ this.httpClient = new cli_utilities_1.HttpClientDecorator(this.httpClient);
70
+ this.httpClient.headers(this.importConfig);
71
+ }
72
+ }
73
+ /**
74
+ * @method startInstallation
75
+ * @returns {Promise<void>}
76
+ */
77
+ async startInstallation() {
78
+ const cryptoArgs = { encryptionKey: '' };
79
+ if (this.importConfig.marketplaceAppEncryptionKey) {
80
+ cryptoArgs['encryptionKey'] = this.importConfig.marketplaceAppEncryptionKey;
81
+ }
82
+ if (this.importConfig.forceStopMarketplaceAppsPrompt) {
83
+ cryptoArgs['encryptionKey'] = this.importConfig.marketplaceAppEncryptionKey;
84
+ this.nodeCrypto = new cli_utilities_1.NodeCrypto(cryptoArgs);
85
+ }
86
+ else {
87
+ await this.getAndValidateEncryptionKey(this.importConfig.marketplaceAppEncryptionKey);
88
+ }
89
+ // NOTE install all private apps which is not available for stack.
90
+ await this.handleAllPrivateAppsCreationProcess();
91
+ this.installedApps = await (0, utils_1.getAllStackSpecificApps)(this.developerHubBaseUrl, this.httpClient, this.importConfig);
92
+ (0, utils_1.log)(this.importConfig, 'Starting marketplace app installation', 'success');
93
+ for (let app of this.marketplaceApps) {
94
+ await this.installApps(app);
95
+ }
96
+ const uidMapper = await this.generateUidMapper();
97
+ utils_1.fsUtil.writeFile(this.marketPlaceUidMapperPath, {
98
+ app_uid: this.appUidMapping,
99
+ extension_uid: uidMapper || {},
100
+ installation_uid: this.installationUidMapping,
101
+ });
102
+ }
103
+ async generateUidMapper() {
104
+ var _a, _b;
105
+ const listOfNewMeta = [];
106
+ const listOfOldMeta = [];
107
+ const extensionUidMap = {};
108
+ this.installedApps = await (0, utils_1.getAllStackSpecificApps)(this.developerHubBaseUrl, this.httpClient, this.importConfig);
109
+ for (const app of this.marketplaceApps) {
110
+ listOfOldMeta.push(...(0, map_1.default)((_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations, 'meta').flat());
111
+ }
112
+ for (const app of this.installedApps) {
113
+ 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());
114
+ }
115
+ for (const { extension_uid, name, path, uid, data_type } of (0, filter_1.default)(listOfOldMeta, 'name')) {
116
+ const meta = (0, find_1.default)(listOfNewMeta, { name, path }) ||
117
+ (0, find_1.default)(listOfNewMeta, { name: this.appNameMapping[name], path }) ||
118
+ (0, find_1.default)(listOfNewMeta, { name, uid, data_type });
119
+ if (meta) {
120
+ extensionUidMap[extension_uid] = meta.extension_uid;
121
+ }
122
+ }
123
+ return extensionUidMap;
124
+ }
125
+ async getAndValidateEncryptionKey(defaultValue, retry = 1) {
126
+ let appConfig = (0, find_1.default)(this.marketplaceApps, ({ configuration, server_configuration }) => !(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration));
127
+ if (!appConfig) {
128
+ return defaultValue;
129
+ }
130
+ const encryptionKey = await (0, interactive_1.askEncryptionKey)(defaultValue);
131
+ try {
132
+ appConfig = !(0, isEmpty_1.default)(appConfig.configuration) ? appConfig.configuration : appConfig.server_configuration;
133
+ this.nodeCrypto = new cli_utilities_1.NodeCrypto({ encryptionKey });
134
+ this.nodeCrypto.decrypt(appConfig);
135
+ }
136
+ catch (error) {
137
+ if (retry < this.importConfig.getEncryptionKeyMaxRetry && error.code === 'ERR_OSSL_EVP_BAD_DECRYPT') {
138
+ cli_utilities_1.cliux.print(`Provided encryption key is not valid or your data might be corrupted.! attempt(${retry}/${this.importConfig.getEncryptionKeyMaxRetry})`, { color: 'red' });
139
+ // NOTE max retry limit is 3
140
+ return this.getAndValidateEncryptionKey(encryptionKey, retry + 1);
141
+ }
142
+ else {
143
+ cli_utilities_1.cliux.print(`Maximum retry limit exceeded. Closing the process, please try again.! attempt(${retry}/${this.importConfig.getEncryptionKeyMaxRetry})`, { color: 'red' });
144
+ process.exit(1);
145
+ }
146
+ }
147
+ return encryptionKey;
148
+ }
149
+ /**
150
+ * @method handleAllPrivateAppsCreationProcess
151
+ * @returns {Promise<void>}
152
+ */
153
+ async handleAllPrivateAppsCreationProcess() {
154
+ const privateApps = (0, filter_1.default)(this.marketplaceApps, { manifest: { visibility: 'private' } });
155
+ if ((0, isEmpty_1.default)(privateApps)) {
156
+ return Promise.resolve();
157
+ }
158
+ await (0, utils_1.getConfirmationToCreateApps)(privateApps, this.importConfig);
159
+ (0, utils_1.log)(this.importConfig, 'Starting developer hub private apps re-creation', 'success');
160
+ for (let app of privateApps) {
161
+ // NOTE keys can be passed to install new app in the developer hub
162
+ app.manifest = (0, pick_1.default)(app.manifest, ['uid', 'name', 'description', 'icon', 'target_type', 'webhook', 'oauth']);
163
+ this.appOrginalName = app.manifest.name;
164
+ const obj = {
165
+ oauth: app.oauth,
166
+ webhook: app.webhook,
167
+ ui_location: app.ui_location,
168
+ };
169
+ await this.createPrivateApps(Object.assign(Object.assign({}, obj), app.manifest));
170
+ }
171
+ this.appOrginalName = undefined;
172
+ }
173
+ async createPrivateApps(app, uidCleaned = false, appSuffix = 1) {
174
+ let locations = app.ui_location && app.ui_location.locations;
175
+ if (!uidCleaned && !(0, isEmpty_1.default)(locations)) {
176
+ app.ui_location.locations = await this.updateManifestUILocations(locations, 'uid');
177
+ }
178
+ else if (uidCleaned && !(0, isEmpty_1.default)(locations)) {
179
+ app.ui_location.locations = await this.updateManifestUILocations(locations, 'name', appSuffix);
180
+ }
181
+ if (app.name > 20) {
182
+ app.name = app.name.slice(0, 20);
183
+ }
184
+ const response = await (0, utils_1.createPrivateApp)(this.sdkClient, this.importConfig, app);
185
+ return this.appCreationCallback(app, response, appSuffix);
186
+ }
187
+ async updateManifestUILocations(locations, type = 'uid', appSuffix = 1) {
188
+ switch (type) {
189
+ case 'uid':
190
+ return (0, map_1.default)(locations, (location) => {
191
+ if (location.meta) {
192
+ location.meta = (0, map_1.default)(location.meta, (meta) => (0, omit_1.default)(meta, ['uid']));
193
+ }
194
+ return location;
195
+ });
196
+ case 'name':
197
+ return (0, map_1.default)(locations, (location) => {
198
+ if (location.meta) {
199
+ location.meta = (0, map_1.default)(location.meta, (meta) => {
200
+ if (meta.name) {
201
+ const name = `${(0, first_1.default)((0, split_1.default)(meta.name, '◈'))}◈${appSuffix}`;
202
+ if (!this.appNameMapping[this.appOrginalName]) {
203
+ this.appNameMapping[this.appOrginalName] = name;
204
+ }
205
+ meta.name = name;
206
+ }
207
+ return meta;
208
+ });
209
+ }
210
+ return location;
211
+ });
212
+ }
213
+ }
214
+ async appCreationCallback(app, response, appSuffix) {
215
+ const { statusText, message } = response || {};
216
+ if (message) {
217
+ if ((0, toLower_1.default)(statusText) === 'conflict') {
218
+ const updatedApp = await (0, utils_1.handleNameConflict)(app, appSuffix, this.importConfig);
219
+ return this.createPrivateApps(updatedApp, true, appSuffix + 1);
220
+ }
221
+ else {
222
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(message), 'error');
223
+ if (this.importConfig.forceStopMarketplaceAppsPrompt)
224
+ return Promise.resolve();
225
+ 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)'))) {
226
+ Promise.resolve();
227
+ }
228
+ else {
229
+ process.exit();
230
+ }
231
+ }
232
+ }
233
+ else if (response.uid) {
234
+ // NOTE new app installation
235
+ (0, utils_1.log)(this.importConfig, `${response.name} app created successfully.!`, 'success');
236
+ this.appUidMapping[app.uid] = response.uid;
237
+ this.appNameMapping[this.appOrginalName] = response.name;
238
+ }
239
+ }
240
+ /**
241
+ * @method installApps
242
+ * @returns {Void}
243
+ */
244
+ async installApps(app) {
245
+ var _a, _b, _c, _d;
246
+ let updateParam;
247
+ const { configuration, server_configuration } = app;
248
+ 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 } });
249
+ if (!currentStackApp) {
250
+ // NOTE install new app
251
+ const mappedUid = this.appUidMapping[(_b = app === null || app === void 0 ? void 0 : app.manifest) === null || _b === void 0 ? void 0 : _b.uid];
252
+ const installation = await (0, utils_1.installApp)(this.sdkClient, this.importConfig, (_c = app === null || app === void 0 ? void 0 : app.manifest) === null || _c === void 0 ? void 0 : _c.uid, mappedUid);
253
+ if (installation.installation_uid) {
254
+ const appManifestName = (_d = app === null || app === void 0 ? void 0 : app.manifest) === null || _d === void 0 ? void 0 : _d.name;
255
+ const appName = this.appNameMapping[appManifestName] ? this.appNameMapping[appManifestName] : appManifestName;
256
+ (0, utils_1.log)(this.importConfig, `${appName} app installed successfully.!`, 'success');
257
+ await (0, utils_1.makeRedirectUrlCall)(installation, appManifestName, this.importConfig);
258
+ this.installationUidMapping[app.uid] = installation.installation_uid;
259
+ updateParam = Object.assign(Object.assign({ manifest: app.manifest }, installation), { configuration, server_configuration });
260
+ }
261
+ else if (installation.message) {
262
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(installation.message), 'success');
263
+ await (0, utils_1.confirmToCloseProcess)(installation, this.importConfig);
264
+ }
265
+ }
266
+ else if (!(0, isEmpty_1.default)(configuration) || !(0, isEmpty_1.default)(server_configuration)) {
267
+ (0, utils_1.log)(this.importConfig, `${app.manifest.name} is already installed`, 'success');
268
+ updateParam = await (0, utils_1.ifAppAlreadyExist)(app, currentStackApp, this.importConfig);
269
+ }
270
+ if (!this.appUidMapping[app.manifest.uid]) {
271
+ this.appUidMapping[app.manifest.uid] = currentStackApp ? currentStackApp.manifest.uid : app.manifest.uid;
272
+ }
273
+ // NOTE update configurations
274
+ if (updateParam && (!(0, isEmpty_1.default)(updateParam.configuration) || !(0, isEmpty_1.default)(updateParam.server_configuration))) {
275
+ await this.updateAppsConfig(updateParam);
276
+ }
277
+ }
278
+ /**
279
+ * @method updateAppsConfig
280
+ * @returns {Promise<void>}
281
+ */
282
+ async updateAppsConfig(app) {
283
+ const payload = { configuration: {}, server_configuration: {} };
284
+ const { uid, configuration, server_configuration } = app;
285
+ if (!(0, isEmpty_1.default)(configuration)) {
286
+ payload['configuration'] = this.nodeCrypto.decrypt(configuration);
287
+ }
288
+ if (!(0, isEmpty_1.default)(server_configuration)) {
289
+ payload['server_configuration'] = this.nodeCrypto.decrypt(server_configuration);
290
+ }
291
+ if ((0, isEmpty_1.default)(app) || (0, isEmpty_1.default)(payload) || !uid) {
292
+ return Promise.resolve();
293
+ }
294
+ // TODO migrate this HTTP API call into SDK
295
+ // NOTE Use updateAppConfig(this.sdkClient, this.importConfig, app, payload) utility when migrating to SDK call;
296
+ return this.httpClient
297
+ .put(`${this.developerHubBaseUrl}/installations/${uid}`, payload)
298
+ .then(({ data }) => {
299
+ if (data.message) {
300
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
301
+ }
302
+ else {
303
+ (0, utils_1.log)(this.importConfig, `${app.manifest.name} app config updated successfully.!`, 'success');
304
+ }
305
+ })
306
+ .catch((error) => (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error'));
307
+ }
308
+ }
309
+ exports.default = ImportMarketplaceApps;
@@ -0,0 +1,27 @@
1
+ import BaseClass, { ApiOptions } from './base-class';
2
+ import { ModuleClassParams } from '../../types';
3
+ export default class ImportWebhooks extends BaseClass {
4
+ private mapperDirPath;
5
+ private webhooksFolderPath;
6
+ private webhookUidMapperPath;
7
+ private createdWebhooksPath;
8
+ private failedWebhooksPath;
9
+ private webhooksConfig;
10
+ private webhooks;
11
+ private webhookUidMapper;
12
+ private createdWebhooks;
13
+ private failedWebhooks;
14
+ constructor({ importConfig, stackAPIClient }: ModuleClassParams);
15
+ /**
16
+ * @method start
17
+ * @returns {Promise<void>} Promise<void>
18
+ */
19
+ start(): Promise<void>;
20
+ importWebhooks(): Promise<string>;
21
+ /**
22
+ * @method serializeWebhooks
23
+ * @param {ApiOptions} apiOptions ApiOptions
24
+ * @returns {ApiOptions} ApiOptions
25
+ */
26
+ serializeWebhooks(apiOptions: ApiOptions): ApiOptions;
27
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
+ const values_1 = tslib_1.__importDefault(require("lodash/values"));
6
+ const node_path_1 = require("node:path");
7
+ const config_1 = tslib_1.__importDefault(require("../../config"));
8
+ const utils_1 = require("../../utils");
9
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
10
+ class ImportWebhooks extends base_class_1.default {
11
+ constructor({ importConfig, stackAPIClient }) {
12
+ super({ importConfig, stackAPIClient });
13
+ this.webhooksConfig = config_1.default.modules.webhooks;
14
+ this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'webhooks');
15
+ this.webhooksFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.webhooksConfig.dirName);
16
+ this.webhookUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
17
+ this.createdWebhooksPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
18
+ this.failedWebhooksPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
19
+ this.webhooks = {};
20
+ this.failedWebhooks = [];
21
+ this.createdWebhooks = [];
22
+ this.webhookUidMapper = {};
23
+ }
24
+ /**
25
+ * @method start
26
+ * @returns {Promise<void>} Promise<void>
27
+ */
28
+ async start() {
29
+ var _a, _b;
30
+ (0, utils_1.log)(this.importConfig, 'Migrating webhooks', 'info');
31
+ //Step1 check folder exists or not
32
+ if (utils_1.fileHelper.fileExistsSync(this.webhooksFolderPath)) {
33
+ this.webhooks = utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhooksFolderPath, 'webhooks.json'), true);
34
+ }
35
+ else {
36
+ (0, utils_1.log)(this.importConfig, `No such file or directory - '${this.webhooksFolderPath}'`, 'error');
37
+ return;
38
+ }
39
+ //create webhooks in mapper directory
40
+ await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
41
+ this.webhookUidMapper = utils_1.fileHelper.fileExistsSync(this.webhookUidMapperPath)
42
+ ? utils_1.fsUtil.readFile((0, node_path_1.join)(this.webhookUidMapperPath), true)
43
+ : {};
44
+ await this.importWebhooks();
45
+ if ((_a = this.createdWebhooks) === null || _a === void 0 ? void 0 : _a.length) {
46
+ utils_1.fsUtil.writeFile(this.createdWebhooksPath, this.createdWebhooks);
47
+ }
48
+ if ((_b = this.failedWebhooks) === null || _b === void 0 ? void 0 : _b.length) {
49
+ utils_1.fsUtil.writeFile(this.failedWebhooksPath, this.failedWebhooks);
50
+ }
51
+ (0, utils_1.log)(this.importConfig, 'Webhooks have been imported successfully!', 'success');
52
+ }
53
+ async importWebhooks() {
54
+ if (this.webhooks === undefined || (0, isEmpty_1.default)(this.webhooks)) {
55
+ (0, utils_1.log)(this.importConfig, 'No Webhook Found', 'info');
56
+ return (0, node_path_1.resolve)();
57
+ }
58
+ const apiContent = (0, values_1.default)(this.webhooks);
59
+ const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
60
+ this.createdWebhooks.push(response);
61
+ this.webhookUidMapper[uid] = response.uid;
62
+ (0, utils_1.log)(this.importConfig, `Webhook '${name}' imported successfully`, 'success');
63
+ utils_1.fsUtil.writeFile(this.webhookUidMapperPath, this.webhookUidMapper);
64
+ };
65
+ const onReject = ({ error, apiData }) => {
66
+ var _a;
67
+ const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
68
+ const { name } = apiData;
69
+ if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
70
+ (0, utils_1.log)(this.importConfig, `Webhook '${name}' already exists`, 'info');
71
+ }
72
+ else {
73
+ this.failedWebhooks.push(apiData);
74
+ (0, utils_1.log)(this.importConfig, `Webhook '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
75
+ }
76
+ };
77
+ await this.makeConcurrentCall({
78
+ apiContent,
79
+ processName: 'create webhooks',
80
+ apiParams: {
81
+ serializeData: this.serializeWebhooks.bind(this),
82
+ reject: onReject.bind(this),
83
+ resolve: onSuccess.bind(this),
84
+ entity: 'create-webhooks',
85
+ includeParamOnCompletion: true,
86
+ },
87
+ concurrencyLimit: config_1.default.fetchConcurrency || 1,
88
+ }, undefined, false);
89
+ }
90
+ /**
91
+ * @method serializeWebhooks
92
+ * @param {ApiOptions} apiOptions ApiOptions
93
+ * @returns {ApiOptions} ApiOptions
94
+ */
95
+ serializeWebhooks(apiOptions) {
96
+ const { apiData: webhook } = apiOptions;
97
+ if (this.webhookUidMapper.hasOwnProperty(webhook.uid)) {
98
+ (0, utils_1.log)(this.importConfig, `Webhook '${webhook.name}' already exists. Skipping it to avoid duplicates!`, 'info');
99
+ apiOptions.entity = undefined;
100
+ }
101
+ else {
102
+ if (this.importConfig.importWebhookStatus === 'disable' || this.importConfig.importWebhookStatus !== 'current') {
103
+ webhook.disabled = true;
104
+ }
105
+ apiOptions.apiData = webhook;
106
+ }
107
+ return apiOptions;
108
+ }
109
+ }
110
+ exports.default = ImportWebhooks;
@@ -39,9 +39,11 @@ module.exports = class ImportCustomRoles {
39
39
  }
40
40
  self.customRolesUids = Object.keys(self.customRoles);
41
41
  self.localesUidMap = await getLocalesUidMap(self.stackAPIClient, self.config, self.customRolesLocales);
42
+ self.environmentsUidMap = {};
42
43
  if (fs.existsSync(environmentsUidMapperFolderPath)) {
43
44
  self.environmentsUidMap = fileHelper.readFileSync(path.resolve(environmentsUidMapperFolderPath, 'uid-mapping.json'));
44
45
  }
46
+ self.entriesUidMap = {};
45
47
  if (fs.existsSync(entriesUidMapperFolderPath)) {
46
48
  self.entriesUidMap = fileHelper.readFileSync(path.resolve(entriesUidMapperFolderPath, 'uid-mapping.json'));
47
49
  }
@@ -619,7 +619,7 @@ module.exports = class ImportEntries {
619
619
  // empty function
620
620
  })
621
621
  .catch((_error) => {
622
- addlogs(this.config, formatError(error), 'error');
622
+ addlogs(this.config, formatError(_error), 'error');
623
623
  reject(`Failed suppress content type ${schema.uid} reference fields`);
624
624
  });
625
625
  // update 5 content types at a time
@@ -786,10 +786,15 @@ module.exports = class ImportEntries {
786
786
  return new Promise((resolve, reject) => {
787
787
  if (schema.field_rules) {
788
788
  let fieldRuleLength = schema.field_rules.length;
789
+ const fieldDatatypeMap = {};
790
+ for (let i = 0; i < schema.schema.length; i++) {
791
+ const field = schema.schema[i].uid;
792
+ fieldDatatypeMap[field] = schema.schema[i].data_type;
793
+ }
789
794
  for (let k = 0; k < fieldRuleLength; k++) {
790
795
  let fieldRuleConditionLength = schema.field_rules[k].conditions.length;
791
796
  for (let i = 0; i < fieldRuleConditionLength; i++) {
792
- if (schema.field_rules[k].conditions[i].operand_field === 'reference') {
797
+ if (fieldDatatypeMap[schema.field_rules[k].conditions[i].operand_field] === 'reference') {
793
798
  let fieldRulesValue = schema.field_rules[k].conditions[i].value;
794
799
  let fieldRulesArray = fieldRulesValue.split('.');
795
800
  let updatedValue = [];
@@ -824,6 +829,7 @@ module.exports = class ImportEntries {
824
829
  })
825
830
  .catch((error) => {
826
831
  log(this.config, `failed to update the field rules ${formatError(error)}`);
832
+ return reject(error);
827
833
  });
828
834
  });
829
835
  }
@@ -7,6 +7,7 @@ declare class ImportExtensions {
7
7
  extensionsConfig: {
8
8
  dirName: string;
9
9
  fileName: string;
10
+ validKeys: string[];
10
11
  };
11
12
  reqConcurrency: number;
12
13
  config: any;
@@ -141,8 +141,10 @@ module.exports = class ImportMarketplaceApps {
141
141
  for (const app of allInstalledApps) {
142
142
  listOfNewMeta.push(..._.map(app.ui_location && app.ui_location.locations, 'meta').flat());
143
143
  }
144
- for (const { extension_uid, name, path } of _.filter(listOfOldMeta, 'name')) {
145
- const meta = _.find(listOfNewMeta, { name, path }) || _.find(listOfNewMeta, { name: this.appNameMapping[name], path });
144
+ for (const { extension_uid, name, path, uid, data_type } of _.filter(listOfOldMeta, 'name')) {
145
+ const meta = _.find(listOfNewMeta, { name, path }) ||
146
+ _.find(listOfNewMeta, { name: this.appNameMapping[name], path }) ||
147
+ _.find(listOfNewMeta, { name, uid, data_type });
146
148
  if (meta) {
147
149
  extensionUidMapp[extension_uid] = meta.extension_uid;
148
150
  }
@@ -386,15 +388,13 @@ module.exports = class ImportMarketplaceApps {
386
388
  if (_.isEmpty(app) || _.isEmpty(payload) || !uid) {
387
389
  return Promise.resolve();
388
390
  }
389
- let installation = this.client
390
- .organization(this.config.org_uid)
391
- .app(app.manifest.uid)
392
- .installation(uid);
393
- installation = Object.assign(installation, payload);
394
- return installation
395
- .update()
396
- .then(async (data) => {
397
- if (data) {
391
+ return this.httpClient
392
+ .put(`${this.developerHubBaseUrl}/installations/${uid}`, payload)
393
+ .then(({ data }) => {
394
+ if (data.message) {
395
+ log(this.config, formatError(data.message), 'success');
396
+ }
397
+ else {
398
398
  log(this.config, `${app.manifest.name} app config updated successfully.!`, 'success');
399
399
  }
400
400
  })
@@ -28,6 +28,7 @@ export default interface DefaultConfig {
28
28
  extensions: {
29
29
  dirName: string;
30
30
  fileName: string;
31
+ validKeys: string[];
31
32
  };
32
33
  webhooks: {
33
34
  dirName: string;
@@ -73,6 +74,12 @@ export default interface DefaultConfig {
73
74
  validKeys: string[];
74
75
  limit: number;
75
76
  };
77
+ 'content-types': {
78
+ dirName: string;
79
+ fileName: string;
80
+ validKeys: string[];
81
+ limit: number;
82
+ };
76
83
  entries: {
77
84
  dirName: string;
78
85
  fileName: string;
@@ -86,6 +93,12 @@ export default interface DefaultConfig {
86
93
  validKeys: string[];
87
94
  limit: number;
88
95
  };
96
+ 'global-fields': {
97
+ dirName: string;
98
+ fileName: string;
99
+ validKeys: string[];
100
+ limit: number;
101
+ };
89
102
  stack: {
90
103
  dirName: string;
91
104
  fileName: string;
@@ -40,6 +40,7 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
40
40
  backupConcurrency?: number;
41
41
  authtoken?: string;
42
42
  destinationStackName?: string;
43
+ org_uid?: string;
43
44
  }
44
45
  type branch = {
45
46
  uid: string;
@@ -26,5 +26,38 @@ export type ModuleClassParams = {
26
26
  importConfig: ImportConfig;
27
27
  moduleName: Modules;
28
28
  };
29
+ export interface Extensions {
30
+ dirName: string;
31
+ fileName: string;
32
+ dependencies?: Modules[];
33
+ }
34
+ export interface MarketplaceAppsConfig {
35
+ dirName: string;
36
+ fileName: string;
37
+ dependencies?: Modules[];
38
+ }
39
+ export interface EnvironmentConfig {
40
+ dirName: string;
41
+ fileName: string;
42
+ dependencies?: Modules[];
43
+ }
44
+ export interface LabelConfig {
45
+ dirName: string;
46
+ fileName: string;
47
+ }
48
+ export interface WebhookConfig {
49
+ dirName: string;
50
+ fileName: string;
51
+ }
52
+ export interface WorkflowConfig {
53
+ dirName: string;
54
+ fileName: string;
55
+ invalidKeys: string[];
56
+ }
57
+ export interface CustomRoleConfig {
58
+ dirName: string;
59
+ fileName: string;
60
+ customRolesLocalesFileName: string;
61
+ }
29
62
  export { default as DefaultConfig } from './default-config';
30
63
  export { default as ImportConfig } from './import-config';
@@ -1,2 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ ;
4
+ ;
@@ -46,4 +46,6 @@ export declare const schemaTemplate: {
46
46
  * MIT Licensed
47
47
  */
48
48
  export declare const suppressSchemaReference: (schema: any, flag: any) => void;
49
- export declare const removeReferenceFields: (schema: any, flag: any, stackAPIClient: any) => Promise<void>;
49
+ export declare const removeReferenceFields: (schema: any, flag: {
50
+ supressed: boolean;
51
+ }, stackAPIClient: any) => Promise<boolean | void>;
@@ -79,7 +79,7 @@ const suppressSchemaReference = function (schema, flag) {
79
79
  }
80
80
  };
81
81
  exports.suppressSchemaReference = suppressSchemaReference;
82
- const removeReferenceFields = async function (schema, flag, stackAPIClient) {
82
+ const removeReferenceFields = async function (schema, flag = { supressed: false }, stackAPIClient) {
83
83
  for (let i = 0; i < schema.length; i++) {
84
84
  if (schema[i].data_type === 'group') {
85
85
  await (0, exports.removeReferenceFields)(schema[i].schema, flag, stackAPIClient);
@@ -128,6 +128,7 @@ const removeReferenceFields = async function (schema, flag, stackAPIClient) {
128
128
  });
129
129
  }
130
130
  }
131
+ return true;
131
132
  }
132
133
  else if (
133
134
  // handling entry references in json rte
@@ -137,6 +138,7 @@ const removeReferenceFields = async function (schema, flag, stackAPIClient) {
137
138
  schema[i].reference_to.length > 1) {
138
139
  flag.supressed = true;
139
140
  schema[i].reference_to = ['sys_assets'];
141
+ return true;
140
142
  }
141
143
  }
142
144
  };