@contentstack/cli-cm-import 1.28.0 → 2.0.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +5 -7
  2. package/lib/commands/cm/stacks/import.d.ts +2 -0
  3. package/lib/commands/cm/stacks/import.js +46 -11
  4. package/lib/config/index.js +0 -1
  5. package/lib/import/module-importer.d.ts +2 -2
  6. package/lib/import/module-importer.js +9 -25
  7. package/lib/import/modules/assets.d.ts +6 -0
  8. package/lib/import/modules/assets.js +102 -25
  9. package/lib/import/modules/base-class.d.ts +17 -0
  10. package/lib/import/modules/base-class.js +45 -0
  11. package/lib/import/modules/content-types.d.ts +7 -10
  12. package/lib/import/modules/content-types.js +132 -68
  13. package/lib/import/modules/custom-roles.d.ts +6 -2
  14. package/lib/import/modules/custom-roles.js +80 -69
  15. package/lib/import/modules/entries.d.ts +7 -0
  16. package/lib/import/modules/entries.js +278 -163
  17. package/lib/import/modules/environments.d.ts +3 -0
  18. package/lib/import/modules/environments.js +69 -38
  19. package/lib/import/modules/extensions.d.ts +3 -0
  20. package/lib/import/modules/extensions.js +99 -64
  21. package/lib/import/modules/global-fields.d.ts +8 -1
  22. package/lib/import/modules/global-fields.js +123 -63
  23. package/lib/import/modules/index.d.ts +1 -0
  24. package/lib/import/modules/index.js +1 -0
  25. package/lib/import/modules/labels.d.ts +3 -0
  26. package/lib/import/modules/labels.js +104 -54
  27. package/lib/import/modules/locales.d.ts +15 -4
  28. package/lib/import/modules/locales.js +194 -94
  29. package/lib/import/modules/marketplace-apps.d.ts +6 -3
  30. package/lib/import/modules/marketplace-apps.js +177 -102
  31. package/lib/import/modules/personalize.d.ts +11 -4
  32. package/lib/import/modules/personalize.js +138 -47
  33. package/lib/import/modules/stack.d.ts +6 -0
  34. package/lib/import/modules/stack.js +71 -27
  35. package/lib/import/modules/taxonomies.d.ts +4 -2
  36. package/lib/import/modules/taxonomies.js +60 -46
  37. package/lib/import/modules/variant-entries.d.ts +7 -4
  38. package/lib/import/modules/variant-entries.js +76 -35
  39. package/lib/import/modules/webhooks.d.ts +3 -0
  40. package/lib/import/modules/webhooks.js +71 -40
  41. package/lib/import/modules/workflows.d.ts +3 -0
  42. package/lib/import/modules/workflows.js +98 -48
  43. package/lib/types/default-config.d.ts +0 -1
  44. package/lib/types/import-config.d.ts +0 -1
  45. package/lib/types/index.d.ts +1 -12
  46. package/lib/utils/backup-handler.js +1 -2
  47. package/lib/utils/constants.d.ts +243 -0
  48. package/lib/utils/constants.js +264 -0
  49. package/lib/utils/import-config-handler.js +2 -7
  50. package/lib/utils/import-path-resolver.d.ts +1 -1
  51. package/lib/utils/import-path-resolver.js +5 -5
  52. package/lib/utils/index.d.ts +1 -1
  53. package/lib/utils/index.js +6 -2
  54. package/lib/utils/marketplace-app-helper.js +3 -8
  55. package/lib/utils/progress-strategy-registry.d.ts +7 -0
  56. package/lib/utils/progress-strategy-registry.js +72 -0
  57. package/lib/utils/setup-branch.js +1 -1
  58. package/oclif.manifest.json +2 -2
  59. package/package.json +2 -2
  60. package/lib/import/modules-js/assets.d.ts +0 -33
  61. package/lib/import/modules-js/assets.js +0 -428
  62. package/lib/import/modules-js/content-types.d.ts +0 -34
  63. package/lib/import/modules-js/content-types.js +0 -204
  64. package/lib/import/modules-js/custom-roles.d.ts +0 -15
  65. package/lib/import/modules-js/custom-roles.js +0 -143
  66. package/lib/import/modules-js/entries.d.ts +0 -54
  67. package/lib/import/modules-js/entries.js +0 -1280
  68. package/lib/import/modules-js/environments.d.ts +0 -13
  69. package/lib/import/modules-js/environments.js +0 -85
  70. package/lib/import/modules-js/extensions.d.ts +0 -18
  71. package/lib/import/modules-js/extensions.js +0 -86
  72. package/lib/import/modules-js/global-fields.d.ts +0 -13
  73. package/lib/import/modules-js/global-fields.js +0 -106
  74. package/lib/import/modules-js/index.d.ts +0 -1
  75. package/lib/import/modules-js/index.js +0 -33
  76. package/lib/import/modules-js/labels.d.ts +0 -20
  77. package/lib/import/modules-js/labels.js +0 -148
  78. package/lib/import/modules-js/locales.d.ts +0 -24
  79. package/lib/import/modules-js/locales.js +0 -196
  80. package/lib/import/modules-js/marketplace-apps.d.ts +0 -63
  81. package/lib/import/modules-js/marketplace-apps.js +0 -429
  82. package/lib/import/modules-js/webhooks.d.ts +0 -17
  83. package/lib/import/modules-js/webhooks.js +0 -85
  84. package/lib/import/modules-js/workflows.d.ts +0 -19
  85. package/lib/import/modules-js/workflows.js +0 -170
  86. package/lib/utils/log.d.ts +0 -12
  87. package/lib/utils/log.js +0 -31
@@ -1,429 +0,0 @@
1
- /*!
2
- * Contentstack Export
3
- * Copyright (c) 2024 Contentstack LLC
4
- * MIT Licensed
5
- */
6
- const fs = require('fs');
7
- const _ = require('lodash');
8
- const path = require('path');
9
- const chalk = require('chalk');
10
- const mkdirp = require('mkdirp');
11
- const { cliux, HttpClient, NodeCrypto, managementSDKClient, isAuthenticated, HttpClientDecorator, OauthDecorator, } = require('@contentstack/cli-utilities');
12
- const { log, formatError, fileHelper: { readFileSync, writeFile }, } = require('../../utils');
13
- const { trace } = require('../../utils/log');
14
- const { default: config } = require('../../config');
15
- const { getAllStackSpecificApps } = require('../../utils/marketplace-app-helper');
16
- module.exports = class ImportMarketplaceApps {
17
- constructor(importConfig, stackAPIClient) {
18
- this.appUidMapping = {};
19
- this.appNameMapping = {};
20
- this.marketplaceApps = [];
21
- this.installationUidMapping = {};
22
- this.developerHubBaseUrl = null;
23
- this.marketplaceAppFolderPath = '';
24
- this.marketplaceAppConfig = config.modules.marketplace_apps;
25
- this.config = _.merge(config, importConfig);
26
- this.stackAPIClient = stackAPIClient;
27
- }
28
- async start() {
29
- this.mapperDirPath = path.resolve(this.config.data, 'mapper', 'marketplace_apps');
30
- this.uidMapperPath = path.join(this.mapperDirPath, 'uid-mapping.json');
31
- this.marketplaceAppFolderPath = path.resolve(this.config.data, this.marketplaceAppConfig.dirName);
32
- this.marketplaceApps = readFileSync(path.resolve(this.marketplaceAppFolderPath, this.marketplaceAppConfig.fileName));
33
- if (_.isEmpty(this.marketplaceApps)) {
34
- return Promise.resolve();
35
- }
36
- else if (!isAuthenticated()) {
37
- cliux.print('\nWARNING!!! To import Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in\n', { color: 'yellow' });
38
- return Promise.resolve();
39
- }
40
- this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config));
41
- this.config.developerHubBaseUrl = this.developerHubBaseUrl;
42
- this.client = await managementSDKClient({ endpoint: this.developerHubBaseUrl });
43
- this.appSdkAxiosInstance = await managementSDKClient({
44
- host: this.developerHubBaseUrl.split('://').pop()
45
- });
46
- await this.getOrgUid();
47
- const httpClient = new HttpClient();
48
- if (!this.config.auth_token) {
49
- this.httpClient = new OauthDecorator(httpClient);
50
- const headers = await this.httpClient.preHeadersCheck(this.config);
51
- this.httpClient = this.httpClient.headers(headers);
52
- }
53
- else {
54
- this.httpClient = new HttpClientDecorator(httpClient);
55
- this.httpClient.headers(this.config);
56
- }
57
- if (!fs.existsSync(this.mapperDirPath)) {
58
- mkdirp.sync(this.mapperDirPath);
59
- }
60
- return this.startInstallation();
61
- }
62
- async getOrgUid() {
63
- const tempAPIClient = await managementSDKClient({ host: this.config.host });
64
- const tempStackData = await tempAPIClient
65
- .stack({ api_key: this.config.target_stack })
66
- .fetch()
67
- .catch((error) => {
68
- console.log(error);
69
- });
70
- if (tempStackData === null || tempStackData === void 0 ? void 0 : tempStackData.org_uid) {
71
- this.config.org_uid = tempStackData.org_uid;
72
- }
73
- }
74
- async getAndValidateEncryptionKey(defaultValue, retry = 1) {
75
- let appConfig = _.find(this.marketplaceApps, ({ configuration, server_configuration }) => !_.isEmpty(configuration) || !_.isEmpty(server_configuration));
76
- if (!appConfig) {
77
- return defaultValue;
78
- }
79
- const encryptionKey = await cliux.inquire({
80
- type: 'input',
81
- name: 'name',
82
- default: defaultValue,
83
- validate: (key) => {
84
- if (!key)
85
- return "Encryption key can't be empty.";
86
- return true;
87
- },
88
- message: 'Enter Marketplace app configurations encryption key',
89
- });
90
- try {
91
- appConfig = !_.isEmpty(appConfig.configuration) ? appConfig.configuration : appConfig.server_configuration;
92
- this.nodeCrypto = new NodeCrypto({ encryptionKey });
93
- this.nodeCrypto.decrypt(appConfig);
94
- }
95
- catch (error) {
96
- if (retry < this.config.getEncryptionKeyMaxRetry && error.code === 'ERR_OSSL_EVP_BAD_DECRYPT') {
97
- cliux.print(`Provided encryption key is not valid or your data might be corrupted.! attempt(${retry}/${this.config.getEncryptionKeyMaxRetry})`, { color: 'red' });
98
- // NOTE max retry limit is 3
99
- return this.getAndValidateEncryptionKey(encryptionKey, retry + 1);
100
- }
101
- else {
102
- cliux.print(`Maximum retry limit exceeded. Closing the process, please try again.! attempt(${retry}/${this.config.getEncryptionKeyMaxRetry})`, { color: 'red' });
103
- process.exit(1);
104
- }
105
- }
106
- return encryptionKey;
107
- }
108
- /**
109
- * @method startInstallation
110
- * @returns {Promise<void>}
111
- */
112
- async startInstallation() {
113
- const cryptoArgs = {};
114
- if (this.config.marketplaceAppEncryptionKey) {
115
- cryptoArgs['encryptionKey'] = this.config.marketplaceAppEncryptionKey;
116
- }
117
- if (this.config.forceStopMarketplaceAppsPrompt) {
118
- cryptoArgs['encryptionKey'] = this.config.marketplaceAppEncryptionKey;
119
- this.nodeCrypto = new NodeCrypto(cryptoArgs);
120
- }
121
- else {
122
- await this.getAndValidateEncryptionKey(this.config.marketplaceAppEncryptionKey);
123
- }
124
- // NOTE install all private apps which is not available for stack.
125
- await this.handleAllPrivateAppsCreationProcess();
126
- const installedApps = await getAllStackSpecificApps(this.config);
127
- log(this.config, 'Starting marketplace app installation', 'success');
128
- for (let app of this.marketplaceApps) {
129
- await this.installApps(app, installedApps);
130
- }
131
- const uidMapper = await this.generateUidMapper();
132
- await writeFile(this.uidMapperPath, {
133
- app_uid: this.appUidMapping,
134
- extension_uid: uidMapper || {},
135
- installation_uid: this.installationUidMapping,
136
- });
137
- }
138
- async generateUidMapper() {
139
- var _a, _b;
140
- const listOfNewMeta = [];
141
- const listOfOldMeta = [];
142
- const extensionUidMap = {};
143
- const allInstalledApps = (await getAllStackSpecificApps(this.config)) || [];
144
- for (const app of this.marketplaceApps) {
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());
146
- }
147
- for (const app of allInstalledApps) {
148
- listOfNewMeta.push(..._.map((_b = app === null || app === void 0 ? void 0 : app.ui_location) === null || _b === void 0 ? void 0 : _b.locations, 'meta').flat());
149
- }
150
- for (const { extension_uid, name, path, uid, data_type } of _.filter(listOfOldMeta, 'name')) {
151
- const meta = _.find(listOfNewMeta, { name, path }) ||
152
- _.find(listOfNewMeta, { name: this.appNameMapping[name], path }) ||
153
- _.find(listOfNewMeta, { name, uid, data_type });
154
- if (meta) {
155
- extensionUidMap[extension_uid] = meta.extension_uid;
156
- }
157
- }
158
- return extensionUidMap;
159
- }
160
- /**
161
- * @method handleAllPrivateAppsCreationProcess
162
- * @param {Object} options
163
- * @returns {Promise<void>}
164
- */
165
- async handleAllPrivateAppsCreationProcess() {
166
- const privateApps = _.filter(this.marketplaceApps, { manifest: { visibility: 'private' } });
167
- if (_.isEmpty(privateApps)) {
168
- return Promise.resolve();
169
- }
170
- await this.getConfirmationToCreateApps(privateApps);
171
- log(this.config, 'Starting developer hub private apps re-creation', 'success');
172
- for (let app of privateApps) {
173
- // NOTE keys can be passed to install new app in the developer hub
174
- app.manifest = _.pick(app.manifest, ['uid', 'name', 'description', 'icon', 'target_type', 'webhook', 'oauth']);
175
- this.appOriginalName = app.manifest.name;
176
- await this.createPrivateApps(Object.assign({ oauth: app.oauth, webhook: app.webhook, ui_location: app.ui_location }, app.manifest));
177
- }
178
- this.appOriginalName = undefined;
179
- }
180
- async getConfirmationToCreateApps(privateApps) {
181
- if (!this.config.forceStopMarketplaceAppsPrompt) {
182
- if (!(await cliux.confirm(chalk.yellow(`WARNING!!! The listed apps are private apps that are not available in the destination stack: \n\n${_.map(privateApps, ({ manifest: { name } }, index) => `${String(index + 1)}) ${name}`).join('\n')}\n\nWould you like to re-create the private app and then proceed with the installation? (y/n)`)))) {
183
- if (await cliux.confirm(chalk.yellow(`\nWARNING!!! Canceling the app re-creation may break the content type and entry import. Would you like to proceed without re-create the private app? (y/n)`))) {
184
- return Promise.resolve(true);
185
- }
186
- if (!(await cliux.confirm(chalk.yellow('\nWould you like to re-create the private app and then proceed with the installation? (y/n)')))) {
187
- process.exit();
188
- }
189
- }
190
- }
191
- }
192
- async createPrivateApps(app, uidCleaned = false, appSuffix = 1) {
193
- var _a;
194
- let locations = (_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations;
195
- if (!uidCleaned && !_.isEmpty(locations)) {
196
- app.ui_location.locations = this.updateManifestUILocations(locations, 'uid');
197
- }
198
- else if (uidCleaned && !_.isEmpty(locations)) {
199
- app.ui_location.locations = this.updateManifestUILocations(locations, 'name', appSuffix);
200
- }
201
- if (app.name > 20) {
202
- app.name = app.name.slice(0, 20);
203
- }
204
- const response = await this.client
205
- .organization(this.config.org_uid)
206
- .app()
207
- .create(_.omit(app, ['uid']))
208
- .catch((error) => error);
209
- return this.appCreationCallback(app, response, appSuffix);
210
- }
211
- async appCreationCallback(app, response, appSuffix) {
212
- const { statusText, message } = response || {};
213
- if (message) {
214
- if (_.toLower(statusText) === 'conflict') {
215
- return this.handleNameConflict(app, appSuffix);
216
- }
217
- else {
218
- log(this.config, formatError(message), 'error');
219
- if (this.config.forceStopMarketplaceAppsPrompt)
220
- return Promise.resolve();
221
- if (await cliux.confirm(chalk.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)'))) {
222
- Promise.resolve();
223
- }
224
- else {
225
- process.exit();
226
- }
227
- }
228
- }
229
- else if (response.uid) {
230
- // NOTE new app installation
231
- log(this.config, `${response.name} app created successfully.!`, 'success');
232
- this.appUidMapping[app.uid] = response.uid;
233
- this.appNameMapping[this.appOriginalName] = response.name;
234
- }
235
- }
236
- async handleNameConflict(app, appSuffix) {
237
- const appName = this.config.forceStopMarketplaceAppsPrompt
238
- ? this.getAppName(app.name, appSuffix)
239
- : await cliux.inquire({
240
- type: 'input',
241
- name: 'name',
242
- validate: this.validateAppName,
243
- default: this.getAppName(app.name, appSuffix),
244
- message: `${app.name} app already exist. Enter a new name to create an app.?`,
245
- });
246
- app.name = appName;
247
- return this.createPrivateApps(app, true, appSuffix + 1);
248
- }
249
- updateManifestUILocations(locations, type = 'uid', appSuffix = 1) {
250
- switch (type) {
251
- case 'uid':
252
- return _.map(locations, (location) => {
253
- if (location.meta) {
254
- location.meta = _.map(location.meta, (meta) => _.omit(meta, ['uid']));
255
- }
256
- return location;
257
- });
258
- case 'name':
259
- return _.map(locations, (location) => {
260
- if (location.meta) {
261
- location.meta = _.map(location.meta, (meta) => {
262
- if (meta.name) {
263
- const name = `${_.first(_.split(meta.name, '◈'))}◈${appSuffix}`;
264
- if (!this.appNameMapping[this.appOriginalName]) {
265
- this.appNameMapping[this.appOriginalName] = name;
266
- }
267
- meta.name = name;
268
- }
269
- return meta;
270
- });
271
- }
272
- return location;
273
- });
274
- }
275
- }
276
- getAppName(name, appSuffix = 1) {
277
- if (name.length >= 19)
278
- name = name.slice(0, 18);
279
- name = `${_.first(_.split(name, '◈'))}◈${appSuffix}`;
280
- return name;
281
- }
282
- /**
283
- * @method installApps
284
- *
285
- * @param {Record<string, any>} app
286
- * @param {Record<string, any>[]} installedApps
287
- * @returns {Promise<void>}
288
- */
289
- async installApps(app, installedApps) {
290
- let updateParam;
291
- let installation;
292
- const { configuration, server_configuration } = app;
293
- const currentStackApp = _.find(installedApps, { manifest: { uid: app.manifest.uid } });
294
- if (!currentStackApp) {
295
- // NOTE install new app
296
- installation = await this.client
297
- .organization(this.config.org_uid)
298
- .app(this.appUidMapping[app.manifest.uid] || app.manifest.uid)
299
- .install({ targetUid: this.config.target_stack, targetType: 'stack' })
300
- .catch((error) => error);
301
- if (installation.installation_uid) {
302
- let appName = this.appNameMapping[app.manifest.name]
303
- ? this.appNameMapping[app.manifest.name]
304
- : app.manifest.name;
305
- log(this.config, `${appName} app installed successfully.!`, 'success');
306
- await this.makeRedirectUrlCall(installation, app.manifest.name);
307
- this.installationUidMapping[app.uid] = installation.installation_uid;
308
- updateParam = Object.assign(Object.assign({ manifest: app.manifest }, installation), { configuration, server_configuration });
309
- }
310
- else if (installation.message) {
311
- trace(installation, 'error', true);
312
- log(this.config, formatError(installation.message), 'success');
313
- await this.confirmToCloseProcess(installation);
314
- }
315
- }
316
- else if (!_.isEmpty(configuration) || !_.isEmpty(server_configuration)) {
317
- log(this.config, `${app.manifest.name} is already installed`, 'success');
318
- updateParam = await this.ifAppAlreadyExist(app, currentStackApp);
319
- }
320
- if (!this.appUidMapping[app.manifest.uid]) {
321
- this.appUidMapping[app.manifest.uid] = currentStackApp ? currentStackApp.manifest.uid : app.manifest.uid;
322
- }
323
- // NOTE update configurations
324
- if (updateParam && (!_.isEmpty(updateParam.configuration) || !_.isEmpty(updateParam.server_configuration))) {
325
- await this.updateAppsConfig(updateParam);
326
- }
327
- }
328
- async makeRedirectUrlCall(response, appName) {
329
- if (response.redirect_url) {
330
- log(this.config, `${appName} - OAuth api call started.!`, 'info');
331
- await new HttpClient({ maxRedirects: 20, maxBodyLength: Infinity })
332
- .get(response.redirect_url)
333
- .then(async ({ response }) => {
334
- if (_.includes([501, 403], response.status)) {
335
- trace(response, 'error', true); // NOTE Log complete stack and hide on UI
336
- log(this.config, `${appName} - ${response.statusText}, OAuth api call failed.!`, 'error');
337
- log(this.config, formatError(response), 'error');
338
- await this.confirmToCloseProcess({ message: response.data });
339
- }
340
- else {
341
- log(this.config, `${appName} - OAuth api call completed.!`, 'success');
342
- }
343
- })
344
- .catch((error) => {
345
- trace(error, 'error', true);
346
- if (_.includes([501, 403], error.status)) {
347
- log(this.config, formatError(error), 'error');
348
- }
349
- });
350
- }
351
- }
352
- async ifAppAlreadyExist(app, currentStackApp) {
353
- let updateParam;
354
- const { manifest: { name }, configuration, server_configuration, } = app;
355
- if (!_.isEmpty(configuration) || !_.isEmpty(server_configuration)) {
356
- cliux.print(`\nWARNING!!! The ${name} app already exists and it may have its own configuration. But the current app you install has its own configuration which is used internally to manage content.\n`, { color: 'yellow' });
357
- const configOption = this.config.forceStopMarketplaceAppsPrompt
358
- ? 'Update it with the new configuration.'
359
- : await cliux.inquire({
360
- choices: [
361
- 'Update it with the new configuration.',
362
- 'Do not update the configuration (WARNING!!! If you do not update the configuration, there may be some issues with the content which you import).',
363
- 'Exit',
364
- ],
365
- type: 'list',
366
- name: 'value',
367
- message: 'Choose the option to proceed',
368
- });
369
- if (configOption === 'Exit') {
370
- process.exit();
371
- }
372
- else if (configOption === 'Update it with the new configuration.') {
373
- updateParam = Object.assign(Object.assign({ manifest: app.manifest }, currentStackApp), { configuration, server_configuration });
374
- }
375
- }
376
- return updateParam;
377
- }
378
- async confirmToCloseProcess(installation) {
379
- cliux.print(`\nWARNING!!! ${formatError(installation.message)}\n`, { color: 'yellow' });
380
- if (!this.config.forceStopMarketplaceAppsPrompt) {
381
- if (!(await cliux.confirm(chalk.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)')))) {
382
- process.exit();
383
- }
384
- }
385
- }
386
- /**
387
- * @method updateAppsConfig
388
- * @param {Object<{ data, app }>} param
389
- * @returns {Promise<void>}
390
- */
391
- updateAppsConfig(app) {
392
- const payload = {};
393
- const { uid, configuration, server_configuration } = app;
394
- if (!_.isEmpty(configuration)) {
395
- payload['configuration'] = this.nodeCrypto.decrypt(configuration);
396
- }
397
- if (!_.isEmpty(server_configuration)) {
398
- payload['server_configuration'] = this.nodeCrypto.decrypt(server_configuration);
399
- }
400
- if (_.isEmpty(app) || _.isEmpty(payload) || !uid) {
401
- return Promise.resolve();
402
- }
403
- return this.appSdkAxiosInstance.axiosInstance
404
- .put(`${this.developerHubBaseUrl}/installations/${uid}`, payload, {
405
- headers: {
406
- organization_uid: this.config.org_uid
407
- },
408
- })
409
- .then(({ data }) => {
410
- if (data.message) {
411
- trace(data, 'error', true);
412
- log(this.config, formatError(data.message), 'success');
413
- }
414
- else {
415
- log(this.config, `${app.manifest.name} app config updated successfully.!`, 'success');
416
- }
417
- })
418
- .catch((error) => {
419
- trace(data, 'error', true);
420
- log(this.config, formatError(error), 'error');
421
- });
422
- }
423
- validateAppName(name) {
424
- if (name.length < 3 || name.length > 20) {
425
- return 'The app name should be within 3-20 characters long.';
426
- }
427
- return true;
428
- }
429
- };
@@ -1,17 +0,0 @@
1
- export = ImportWebhooks;
2
- declare class ImportWebhooks {
3
- constructor(importConfig: any, stackAPIClient: any);
4
- config: any;
5
- fails: any[];
6
- success: any[];
7
- webUidMapper: {};
8
- webhooksConfig: {
9
- dirName: string;
10
- fileName: string;
11
- };
12
- reqConcurrency: number;
13
- stackAPIClient: any;
14
- start(): Promise<any>;
15
- webhooks: any;
16
- }
17
- import Promise = require("bluebird");
@@ -1,85 +0,0 @@
1
- /*!
2
- * Contentstack Import
3
- * Copyright (c) 2024 Contentstack LLC
4
- * MIT Licensed
5
- */
6
- const mkdirp = require('mkdirp');
7
- const fs = require('fs');
8
- const path = require('path');
9
- const Promise = require('bluebird');
10
- const chalk = require('chalk');
11
- const { isEmpty, merge } = require('lodash');
12
- let { default: config } = require('../../config');
13
- const { fileHelper, log, formatError } = require('../../utils');
14
- module.exports = class ImportWebhooks {
15
- constructor(importConfig, stackAPIClient) {
16
- this.fails = [];
17
- this.success = [];
18
- this.webUidMapper = {};
19
- this.webhooksConfig = config.modules.webhooks;
20
- this.reqConcurrency = config.concurrency || config.fetchConcurrency;
21
- this.config = merge(config, importConfig);
22
- this.stackAPIClient = stackAPIClient;
23
- }
24
- start() {
25
- log(this.config, chalk.white('Migrating webhooks'), 'success');
26
- const self = this;
27
- let webMapperPath = path.resolve(this.config.data, 'mapper', 'webhooks');
28
- let webFailsPath = path.resolve(this.config.data, 'mapper', 'webhooks', 'fails.json');
29
- let webSuccessPath = path.resolve(this.config.data, 'mapper', 'webhooks', 'success.json');
30
- let webUidMapperPath = path.resolve(this.config.data, 'mapper', 'webhooks', 'uid-mapping.json');
31
- let webhooksFolderPath = path.resolve(this.config.data, this.webhooksConfig.dirName);
32
- this.webhooks = fileHelper.readFileSync(path.resolve(webhooksFolderPath, this.webhooksConfig.fileName));
33
- if (fs.existsSync(webUidMapperPath)) {
34
- self.webUidMapper = fileHelper.readFileSync(webUidMapperPath);
35
- self.webUidMapper = self.webUidMapper || {};
36
- }
37
- mkdirp.sync(webMapperPath);
38
- return new Promise(function (resolve, reject) {
39
- if (self.webhooks == undefined || isEmpty(self.webhooks)) {
40
- log(self.config, chalk.white('No Webhooks Found'), 'success');
41
- return resolve({ empty: true });
42
- }
43
- let webUids = Object.keys(self.webhooks);
44
- return Promise.map(webUids, function (webUid) {
45
- let web = self.webhooks[webUid];
46
- if (self.config.importWebhookStatus !== 'current' || self.config.importWebhookStatus === 'disable') {
47
- web.disabled = true;
48
- }
49
- if (!self.webUidMapper.hasOwnProperty(webUid)) {
50
- let requestOption = { json: { webhook: web } };
51
- return self.stackAPIClient
52
- .webhook()
53
- .create(requestOption.json)
54
- .then(function (response) {
55
- self.success.push(response);
56
- self.webUidMapper[webUid] = response.uid;
57
- fileHelper.writeFileSync(webUidMapperPath, self.webUidMapper);
58
- })
59
- .catch(function (err) {
60
- let error = JSON.parse(err.message);
61
- self.fails.push(web);
62
- log(self.config, `Webhooks '${web.name}' failed to be import.\n ${formatError(error)}`, 'error');
63
- });
64
- }
65
- else {
66
- // the webhooks has already been created
67
- log(self.config, chalk.white("The Webhooks: '" + web.name + "' already exists. Skipping it to avoid duplicates!"), 'success');
68
- }
69
- // import 2 webhooks at a time
70
- }, { concurrency: self.reqConcurrency })
71
- .then(function () {
72
- // webhooks have imported successfully
73
- fileHelper.writeFileSync(webSuccessPath, self.success);
74
- log(self.config, chalk.green('Webhooks have been imported successfully!'), 'success');
75
- return resolve();
76
- })
77
- .catch(function (error) {
78
- // error while importing environments
79
- fileHelper.writeFileSync(webFailsPath, self.fails);
80
- log(self.config, `Webhooks import failed. ${formatError(error)}`, 'error');
81
- return reject(error);
82
- });
83
- });
84
- }
85
- };
@@ -1,19 +0,0 @@
1
- export = importWorkflows;
2
- declare class importWorkflows {
3
- constructor(importConfig: any, stackAPIClient: any);
4
- fails: any[];
5
- success: any[];
6
- workflowUidMapper: {};
7
- workflowConfig: {
8
- dirName: string;
9
- fileName: string;
10
- invalidKeys: string[];
11
- };
12
- reqConcurrency: number;
13
- config: any;
14
- stackAPIClient: any;
15
- start(): Promise<any>;
16
- workflows: any;
17
- updateNextAvailableStagesUid(workflow: any, newWorkflowStages: any, oldWorkflowStages: any): any;
18
- }
19
- import Promise = require("bluebird");