@contentstack/cli-cm-import 1.12.1 → 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 CHANGED
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
47
47
  $ csdx COMMAND
48
48
  running command...
49
49
  $ csdx (--version)
50
- @contentstack/cli-cm-import/1.12.1 linux-x64 node-v18.19.0
50
+ @contentstack/cli-cm-import/1.12.2 linux-x64 node-v18.19.0
51
51
  $ csdx --help [COMMAND]
52
52
  USAGE
53
53
  $ csdx COMMAND
@@ -82,6 +82,7 @@ FLAGS
82
82
  --import-webhook-status=<option> [default: disable] [optional] Webhook state
83
83
  <options: disable|current>
84
84
  --replace-existing Replaces the existing module in the target stack.
85
+ --skip-app-recreation [optional] Skip private apps recreation if already exist
85
86
  --skip-existing Skips the module exists warning messages.
86
87
 
87
88
  DESCRIPTION
@@ -129,6 +130,7 @@ FLAGS
129
130
  --import-webhook-status=<option> [default: disable] [optional] Webhook state
130
131
  <options: disable|current>
131
132
  --replace-existing Replaces the existing module in the target stack.
133
+ --skip-app-recreation [optional] Skip private apps recreation if already exist
132
134
  --skip-existing Skips the module exists warning messages.
133
135
 
134
136
  DESCRIPTION
@@ -108,6 +108,9 @@ ImportCommand.flags = {
108
108
  required: false,
109
109
  description: '[optional] Override marketplace prompts',
110
110
  }),
111
+ 'skip-app-recreation': cli_utilities_1.flags.boolean({
112
+ description: '[optional] Skip private apps recreation if already exist',
113
+ }),
111
114
  'replace-existing': cli_utilities_1.flags.boolean({
112
115
  required: false,
113
116
  description: 'Replaces the existing module in the target stack.',
@@ -1,18 +1,31 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var _a;
3
26
  Object.defineProperty(exports, "__esModule", { value: true });
4
- const tslib_1 = require("tslib");
5
- const cli_utilities_1 = require("@contentstack/cli-utilities");
6
- const node_path_1 = require("node:path");
7
- const modules_js_1 = tslib_1.__importDefault(require("../modules-js"));
8
27
  async function startModuleImport(modulePayload) {
9
- var _a;
10
- // Todo: Remove below code when auto detect mechanism implemented for old and new module
11
- if (modulePayload.moduleName === 'assets' &&
12
- !new cli_utilities_1.FsUtility({ basePath: (0, node_path_1.join)((_a = modulePayload.importConfig) === null || _a === void 0 ? void 0 : _a.backupDir, 'assets') }).isNewFsStructure) {
13
- return (0, modules_js_1.default)(modulePayload);
14
- }
15
- const { default: ModuleRunner } = await (_a = `./${modulePayload.moduleName}`, Promise.resolve().then(() => tslib_1.__importStar(require(_a))));
28
+ const { default: ModuleRunner } = await (_a = `./${modulePayload.moduleName}`, Promise.resolve().then(() => __importStar(require(_a))));
16
29
  const moduleRunner = new ModuleRunner(modulePayload);
17
30
  return moduleRunner.start();
18
31
  }
@@ -1,43 +1,113 @@
1
- import { NodeCrypto, ContentstackClient } from '@contentstack/cli-utilities';
2
- import BaseClass from './base-class';
3
- import { ModuleClassParams } from '../../types';
4
- export default class ImportMarketplaceApps extends BaseClass {
1
+ import { NodeCrypto, ContentstackMarketplaceClient } from '@contentstack/cli-utilities';
2
+ import { ModuleClassParams, ImportConfig, Installation, Manifest } from '../../types';
3
+ export default class ImportMarketplaceApps {
4
+ importConfig: ImportConfig;
5
5
  private mapperDirPath;
6
6
  private marketPlaceFolderPath;
7
7
  private marketPlaceUidMapperPath;
8
8
  private marketPlaceAppConfig;
9
9
  private marketplaceApps;
10
- private httpClient;
11
10
  private appNameMapping;
12
11
  private appUidMapping;
13
12
  private installationUidMapping;
14
13
  private installedApps;
15
14
  private appOriginalName;
16
15
  developerHubBaseUrl: string;
17
- sdkClient: ContentstackClient;
18
16
  nodeCrypto: NodeCrypto;
19
- appSdkAxiosInstance: any;
20
- constructor({ importConfig, stackAPIClient }: ModuleClassParams);
17
+ appSdk: ContentstackMarketplaceClient;
18
+ constructor({ importConfig }: ModuleClassParams);
21
19
  /**
22
- * @method start
23
- * @returns {Promise<void>} Promise<void>
20
+ * This function starts the process of importing marketplace apps.
21
+ * @returns The function `start()` returns a `Promise<void>`.
24
22
  */
25
23
  start(): Promise<void>;
26
- setHttpClient(): Promise<void>;
27
24
  /**
28
- * @method startInstallation
29
- * @returns {Promise<void>}
25
+ * The function `importMarketplaceApps` installs marketplace apps, handles private app creation,
26
+ * validates app installation, and generates a UID mapper.
27
+ */
28
+ importMarketplaceApps(): Promise<void>;
29
+ /**
30
+ * The function `generateUidMapper` generates a mapping of extension UIDs from old metadata to new
31
+ * metadata based on the installed and marketplace apps.
32
+ * @returns The function `generateUidMapper` returns a Promise that resolves to a `Record<string,
33
+ * unknown>`.
30
34
  */
31
- startInstallation(): Promise<void>;
32
35
  generateUidMapper(): Promise<Record<string, unknown>>;
36
+ /**
37
+ * The function `getAndValidateEncryptionKey` retrieves and validates an encryption key, with the
38
+ * option to retry a specified number of times.
39
+ * @param {string} defaultValue - The defaultValue parameter is a string that represents the default
40
+ * encryption key value to use if no valid encryption key is found in the marketplaceApps
41
+ * configuration.
42
+ * @param [retry=1] - The `retry` parameter is an optional parameter that specifies the number of
43
+ * times the function should retry getting and validating the encryption key if it fails. The default
44
+ * value is 1, meaning that if the function fails to get and validate the encryption key on the first
45
+ * attempt, it will not retry.
46
+ * @returns The function `getAndValidateEncryptionKey` returns a Promise that resolves to the
47
+ * encryption key.
48
+ */
33
49
  getAndValidateEncryptionKey(defaultValue: string, retry?: number): Promise<any>;
34
50
  /**
35
- * @method handleAllPrivateAppsCreationProcess
36
- * @returns {Promise<void>}
51
+ * The function `handleAllPrivateAppsCreationProcess` handles the creation process for all private
52
+ * apps in a developer hub, including checking for existing apps, getting confirmation from the user,
53
+ * and creating the apps if necessary.
54
+ * @returns a Promise that resolves to void.
37
55
  */
38
56
  handleAllPrivateAppsCreationProcess(): Promise<void>;
39
- createPrivateApps(app: any, uidCleaned?: boolean, appSuffix?: number): Promise<any>;
40
- updateManifestUILocations(locations: any, type?: string, appSuffix?: number): Promise<any[]>;
57
+ /**
58
+ * The function checks if a private app exists in the developer hub.
59
+ * @param {App} app - The `app` parameter is an object representing an application. It likely has
60
+ * properties such as `uid` which is a unique identifier for the app.
61
+ * @returns a boolean value. It returns true if the installation object is not empty, and false if
62
+ * the installation object is empty.
63
+ */
64
+ isPrivateAppExistInDeveloperHub(app: Installation): Promise<boolean>;
65
+ /**
66
+ * The function creates a private app in a marketplace, with an optional suffix for the app name and
67
+ * an option to update the UI location.
68
+ * @param {Manifest} app - The `app` parameter is an object that represents the manifest of the app
69
+ * being created. It contains various properties such as `name`, `ui_location`, and `uid`.
70
+ * @param [appSuffix=1] - The appSuffix parameter is an optional parameter that specifies a suffix to
71
+ * be added to the app's UI location. It is used when updating the UI location of the app.
72
+ * @param [updateUiLocation=false] - A boolean value indicating whether to update the UI location of
73
+ * the app.
74
+ * @returns the result of the `appCreationCallback` function, which takes in the `app`, `response`,
75
+ * and `appSuffix` as arguments.
76
+ */
77
+ createPrivateApp(app: Manifest, appSuffix?: number, updateUiLocation?: boolean): Promise<any>;
78
+ /**
79
+ * The function installs an app from a marketplace onto a target stack.
80
+ * @param {ImportConfig} config - The `config` parameter is an object that contains the configuration
81
+ * for the installation. It likely includes information such as the target stack UID and other
82
+ * relevant details.
83
+ * @param {string} [appManifestUid] - The `appManifestUid` parameter is the unique identifier of the
84
+ * app manifest. It is used to specify which app to install from the marketplace.
85
+ * @returns a Promise that resolves to an object.
86
+ */
87
+ installApp(config: ImportConfig, appManifestUid?: string): Promise<any>;
88
+ /**
89
+ * The function updates the names of locations in a manifest UI based on a given app suffix.
90
+ * @param {any} locations - An array of objects representing different locations in a manifest file.
91
+ * Each object has a "meta" property which is an array of objects representing metadata for that
92
+ * location.
93
+ * @param [appSuffix=1] - The `appSuffix` parameter is an optional parameter that specifies a suffix
94
+ * to be added to the app name. It is set to 1 by default.
95
+ * @returns The function `updateManifestUILocations` returns an updated array of `locations`.
96
+ */
97
+ updateManifestUILocations(locations: any, appSuffix?: number): any[];
98
+ /**
99
+ * The function `appCreationCallback` handles the creation of a new app and handles any conflicts or
100
+ * errors that may occur during the process.
101
+ * @param {any} app - The `app` parameter is an object representing the app that is being created. It
102
+ * contains various properties such as `uid` (unique identifier), `name`, and other app-specific
103
+ * details.
104
+ * @param {any} response - The `response` parameter is an object that contains the response received
105
+ * from an API call. It may have properties such as `statusText` and `message`.
106
+ * @param {number} appSuffix - The `appSuffix` parameter is a number that is used to generate a
107
+ * unique suffix for the app name in case of a name conflict. It is incremented each time a name
108
+ * conflict occurs to ensure that the new app name is unique.
109
+ * @returns a Promise.
110
+ */
41
111
  appCreationCallback(app: any, response: any, appSuffix: number): Promise<any>;
42
112
  /**
43
113
  * @method installApps
@@ -48,8 +118,10 @@ export default class ImportMarketplaceApps extends BaseClass {
48
118
  */
49
119
  installApps(app: any): Promise<void>;
50
120
  /**
51
- * @method updateAppsConfig
52
- * @returns {Promise<void>}
121
+ * The `updateAppsConfig` function updates the configuration and server configuration of an app in a
122
+ * marketplace.
123
+ * @param {Installation} app - The `app` parameter is an object that represents an installation of an
124
+ * app. It contains the following properties:
53
125
  */
54
- updateAppsConfig(app: any): Promise<void>;
126
+ updateAppsConfig(app: Installation): Promise<void>;
55
127
  }
@@ -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 extends base_class_1.default {
21
- constructor({ importConfig, stackAPIClient }) {
22
- super({ importConfig, stackAPIClient });
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
- * @method start
36
- * @returns {Promise<void>} Promise<void>
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.sdkClient = await (0, cli_utilities_1.managementSDKClient)({ endpoint: this.developerHubBaseUrl });
57
- this.appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
58
- host: this.developerHubBaseUrl.split('://').pop(),
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
- await this.setHttpClient();
62
- await this.startInstallation();
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
- * @method startInstallation
78
- * @returns {Promise<void>}
64
+ * The function `importMarketplaceApps` installs marketplace apps, handles private app creation,
65
+ * validates app installation, and generates a UID mapper.
79
66
  */
80
- async startInstallation() {
81
- const cryptoArgs = { encryptionKey: '' };
82
- if (this.importConfig.marketplaceAppEncryptionKey) {
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
- this.installedApps = await (0, utils_1.getAllStackSpecificApps)(this.developerHubBaseUrl, this.httpClient, this.importConfig);
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
- this.installedApps =
112
- (await (0, utils_1.getAllStackSpecificApps)(this.developerHubBaseUrl, this.httpClient, this.importConfig)) || [];
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, name, path, uid, data_type } of (0, filter_1.default)(listOfOldMeta, 'name')) {
120
- const meta = (0, find_1.default)(listOfNewMeta, { name, path }) ||
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
- * @method handleAllPrivateAppsCreationProcess
155
- * @returns {Promise<void>}
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
- app.manifest = (0, pick_1.default)(app.manifest, ['uid', 'name', 'description', 'icon', 'target_type', 'webhook', 'oauth']);
167
- this.appOriginalName = app.manifest.name;
168
- const obj = {
169
- oauth: app.oauth,
170
- webhook: app.webhook,
171
- ui_location: app.ui_location,
172
- };
173
- await this.createPrivateApps(Object.assign(Object.assign({}, obj), app.manifest));
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
- async createPrivateApps(app, uidCleaned = false, appSuffix = 1) {
178
- var _a;
179
- let locations = (_a = app === null || app === void 0 ? void 0 : app.ui_location) === null || _a === void 0 ? void 0 : _a.locations;
180
- if (!uidCleaned && !(0, isEmpty_1.default)(locations)) {
181
- app.ui_location.locations = await this.updateManifestUILocations(locations, 'uid');
182
- }
183
- else if (uidCleaned && !(0, isEmpty_1.default)(locations)) {
184
- app.ui_location.locations = await this.updateManifestUILocations(locations, 'name', appSuffix);
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 (0, utils_1.createPrivateApp)(this.sdkClient, this.importConfig, app);
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
- async updateManifestUILocations(locations, type = 'uid', appSuffix = 1) {
193
- switch (type) {
194
- case 'uid':
195
- return (0, map_1.default)(locations, (location) => {
196
- if (location.meta) {
197
- location.meta = (0, map_1.default)(location.meta, (meta) => (0, omit_1.default)(meta, ['uid']));
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
- return location;
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 location;
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.createPrivateApps(updatedApp, true, appSuffix + 1);
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, _c, _d;
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 mappedUid = this.appUidMapping[(_b = app === null || app === void 0 ? void 0 : app.manifest) === null || _b === void 0 ? void 0 : _b.uid];
261
- 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);
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 appManifestName = (_d = app === null || app === void 0 ? void 0 : app.manifest) === null || _d === void 0 ? void 0 : _d.name;
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, appManifestName, this.importConfig);
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
- * @method updateAppsConfig
289
- * @returns {Promise<void>}
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 payload = { configuration: {}, server_configuration: {} };
293
- const { uid, configuration, server_configuration } = app;
369
+ const { installation_uid, configuration, server_configuration } = app;
294
370
  if (!(0, isEmpty_1.default)(configuration)) {
295
- payload['configuration'] = this.nodeCrypto.decrypt(configuration);
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
- payload['server_configuration'] = this.nodeCrypto.decrypt(server_configuration);
299
- }
300
- if ((0, isEmpty_1.default)(app) || (0, isEmpty_1.default)(payload) || !uid) {
301
- return Promise.resolve();
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;
@@ -147,6 +147,7 @@ class ImportWorkflows extends base_class_1.default {
147
147
  name: workflow.name,
148
148
  branches: workflow.branches,
149
149
  workflow_stages: newWorkflowStages,
150
+ content_types: workflow.content_types
150
151
  });
151
152
  return updateWorkflow.update();
152
153
  }
@@ -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.developerHubBaseUrl, this.httpClient, this.config);
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.developerHubBaseUrl, this.httpClient, this.config)) || [];
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
  }
@@ -163,6 +163,7 @@ module.exports = class importWorkflows {
163
163
  name: workflow.name,
164
164
  branches: workflow.branches,
165
165
  workflow_stages: newWorkflowStages,
166
+ content_types: workflow.content_types
166
167
  });
167
168
  return updateWorkflow.update();
168
169
  }
@@ -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;
@@ -73,3 +73,4 @@ export interface TermsConfig {
73
73
  export { default as DefaultConfig } from './default-config';
74
74
  export { default as ImportConfig } from './import-config';
75
75
  export * from './entries';
76
+ export * from './marketplace-app';
@@ -2,3 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./entries"), exports);
5
+ tslib_1.__exportStar(require("./marketplace-app"), exports);
@@ -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 };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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
- entry = entry.replace(new RegExp(assetUrl, 'img'), mappedAssetUrl);
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
- entry = entry.replace(new RegExp(assetUid, 'img'), uid);
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 {
@@ -198,10 +198,8 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
198
198
  let entry = JSON.stringify(data.entry);
199
199
  uids.forEach(function (uid) {
200
200
  if (mappedUids.hasOwnProperty(uid)) {
201
- // NOTE g: matches the pattern multiple times
202
- // NOTE i: makes the regex case insensitive
203
- // NOTE m: enables multi-line mode. Where ^ and $ match the start and end of the entire string. Without this, multi-line strings match the beginning and end of each line.
204
- entry = entry.replace(new RegExp(uid, 'img'), mappedUids[uid]);
201
+ const escapedUid = uid.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
202
+ entry = entry.replace(new RegExp(escapedUid, 'img'), mappedUids[uid]);
205
203
  mapped.push(uid);
206
204
  }
207
205
  else {
@@ -62,6 +62,7 @@ const setupConfig = async (importCmdFlags) => {
62
62
  config.source_stack = config.apiKey;
63
63
  config.importWebhookStatus = importCmdFlags['import-webhook-status'];
64
64
  config.forceStopMarketplaceAppsPrompt = importCmdFlags.yes;
65
+ config.skipPrivateAppRecreationIfExist = importCmdFlags['skip-app-recreation'];
65
66
  if (importCmdFlags['branch']) {
66
67
  config.branchName = importCmdFlags['branch'];
67
68
  config.branchDir = path.join(config.contentDir, config.branchName);
@@ -5,7 +5,7 @@ export { fsUtil } from './file-helper';
5
5
  export { default as backupHandler } from './backup-handler';
6
6
  export { log, unlinkFileLogger } from './logger';
7
7
  export { uploadAssetHelper, lookupAssets } from './asset-helper';
8
- export { getDeveloperHubUrl, getOrgUid, getConfirmationToCreateApps, createPrivateApp, handleNameConflict, installApp, makeRedirectUrlCall, confirmToCloseProcess, getAllStackSpecificApps, ifAppAlreadyExist, updateAppConfig, } from './marketplace-app-helper';
8
+ export { getDeveloperHubUrl, getOrgUid, getConfirmationToCreateApps, handleNameConflict, makeRedirectUrlCall, confirmToCloseProcess, getAllStackSpecificApps, ifAppAlreadyExist, } from './marketplace-app-helper';
9
9
  export { schemaTemplate, suppressSchemaReference, removeReferenceFields } from './content-type-helper';
10
10
  export { lookupExtension } from './extension-helper';
11
11
  export { lookupEntries, removeUidsFromJsonRteFields, removeEntryRefsFromJSONRTE, restoreJsonRteEntryRefs, } from './entries-helper';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lookUpTerms = exports.lookUpTaxonomy = exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.updateAppConfig = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.installApp = exports.handleNameConflict = exports.createPrivateApp = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = void 0;
3
+ exports.lookUpTerms = exports.lookUpTaxonomy = exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  exports.interactive = tslib_1.__importStar(require("./interactive"));
6
6
  var import_config_handler_1 = require("./import-config-handler");
@@ -20,14 +20,11 @@ var marketplace_app_helper_1 = require("./marketplace-app-helper");
20
20
  Object.defineProperty(exports, "getDeveloperHubUrl", { enumerable: true, get: function () { return marketplace_app_helper_1.getDeveloperHubUrl; } });
21
21
  Object.defineProperty(exports, "getOrgUid", { enumerable: true, get: function () { return marketplace_app_helper_1.getOrgUid; } });
22
22
  Object.defineProperty(exports, "getConfirmationToCreateApps", { enumerable: true, get: function () { return marketplace_app_helper_1.getConfirmationToCreateApps; } });
23
- Object.defineProperty(exports, "createPrivateApp", { enumerable: true, get: function () { return marketplace_app_helper_1.createPrivateApp; } });
24
23
  Object.defineProperty(exports, "handleNameConflict", { enumerable: true, get: function () { return marketplace_app_helper_1.handleNameConflict; } });
25
- Object.defineProperty(exports, "installApp", { enumerable: true, get: function () { return marketplace_app_helper_1.installApp; } });
26
24
  Object.defineProperty(exports, "makeRedirectUrlCall", { enumerable: true, get: function () { return marketplace_app_helper_1.makeRedirectUrlCall; } });
27
25
  Object.defineProperty(exports, "confirmToCloseProcess", { enumerable: true, get: function () { return marketplace_app_helper_1.confirmToCloseProcess; } });
28
26
  Object.defineProperty(exports, "getAllStackSpecificApps", { enumerable: true, get: function () { return marketplace_app_helper_1.getAllStackSpecificApps; } });
29
27
  Object.defineProperty(exports, "ifAppAlreadyExist", { enumerable: true, get: function () { return marketplace_app_helper_1.ifAppAlreadyExist; } });
30
- Object.defineProperty(exports, "updateAppConfig", { enumerable: true, get: function () { return marketplace_app_helper_1.updateAppConfig; } });
31
28
  var content_type_helper_1 = require("./content-type-helper");
32
29
  Object.defineProperty(exports, "schemaTemplate", { enumerable: true, get: function () { return content_type_helper_1.schemaTemplate; } });
33
30
  Object.defineProperty(exports, "suppressSchemaReference", { enumerable: true, get: function () { return content_type_helper_1.suppressSchemaReference; } });
@@ -1,16 +1,9 @@
1
- import { HttpClient, ContentstackClient } from '@contentstack/cli-utilities';
2
- import { ImportConfig } from '../types';
3
- export declare const getAllStackSpecificApps: (developerHubBaseUrl: string, httpClient: HttpClient, config: ImportConfig) => Promise<any>;
1
+ import { ImportConfig, Installation } from '../types';
2
+ export declare const getAllStackSpecificApps: (config: ImportConfig, skip?: number, listOfApps?: Installation[]) => Promise<Installation[]>;
4
3
  export declare const getDeveloperHubUrl: (config: ImportConfig) => Promise<string>;
5
4
  export declare const getOrgUid: (config: ImportConfig) => Promise<string>;
6
5
  export declare const getConfirmationToCreateApps: (privateApps: any, config: ImportConfig) => Promise<boolean>;
7
- export declare const createPrivateApp: (client: ContentstackClient, config: ImportConfig, app: any) => Promise<any>;
8
- export declare const installApp: (client: ContentstackClient, config: ImportConfig, appManifestUid?: string, mappedUid?: string) => Promise<any>;
9
6
  export declare const handleNameConflict: (app: any, appSuffix: number, config: ImportConfig) => Promise<any>;
10
7
  export declare const makeRedirectUrlCall: (response: any, appName: string, config: ImportConfig) => Promise<void>;
11
8
  export declare const confirmToCloseProcess: (installation: any, config: ImportConfig) => Promise<void>;
12
9
  export declare const ifAppAlreadyExist: (app: any, currentStackApp: any, config: ImportConfig) => Promise<{}>;
13
- export declare const updateAppConfig: (client: ContentstackClient, config: ImportConfig, app: any, payload: {
14
- configuration: Record<string, unknown>;
15
- server_configuration: Record<string, unknown>;
16
- }) => Promise<any>;
@@ -1,33 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateAppConfig = exports.ifAppAlreadyExist = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.installApp = exports.createPrivateApp = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.getAllStackSpecificApps = void 0;
3
+ exports.ifAppAlreadyExist = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.handleNameConflict = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.getAllStackSpecificApps = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const map_1 = tslib_1.__importDefault(require("lodash/map"));
7
- const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
7
+ const omitBy_1 = tslib_1.__importDefault(require("lodash/omitBy"));
8
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
8
9
  const includes_1 = tslib_1.__importDefault(require("lodash/includes"));
9
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
10
10
  const cli_utilities_1 = require("@contentstack/cli-utilities");
11
11
  const logger_1 = require("./logger");
12
12
  const log_1 = require("../utils/log");
13
13
  const utils_1 = require("../utils");
14
14
  const interactive_1 = require("./interactive");
15
15
  const interactive_2 = require("../utils/interactive");
16
- const getAllStackSpecificApps = async (developerHubBaseUrl, httpClient, config) => {
17
- const appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
18
- host: developerHubBaseUrl.split('://').pop(),
16
+ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
17
+ const appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({
18
+ host: config.developerHubBaseUrl.split('://').pop(),
19
19
  });
20
- return await appSdkAxiosInstance.axiosInstance
21
- .get(`${developerHubBaseUrl}/installations?target_uids=${config.target_stack}`, {
22
- headers: {
23
- organization_uid: config.org_uid,
24
- },
25
- })
26
- .then(({ data }) => data.data)
20
+ const collection = await appSdk
21
+ .marketplace(config.org_uid)
22
+ .installation()
23
+ .fetchAll({ target_uids: config.target_stack, skip })
27
24
  .catch((error) => {
28
25
  (0, log_1.trace)(error, 'error', true);
29
26
  (0, logger_1.log)(config, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error');
30
27
  });
28
+ if (collection) {
29
+ const { items: apps, count } = collection;
30
+ // NOTE Remove all the chain functions
31
+ const installation = (0, map_1.default)(apps, (app) => (0, omitBy_1.default)(app, (val, _key) => {
32
+ if (val instanceof Function)
33
+ return true;
34
+ return false;
35
+ }));
36
+ listOfApps = listOfApps.concat(installation);
37
+ if (count - (skip + 50) > 0) {
38
+ return await (0, exports.getAllStackSpecificApps)(config, skip + 50, listOfApps);
39
+ }
40
+ }
41
+ return listOfApps;
31
42
  };
32
43
  exports.getAllStackSpecificApps = getAllStackSpecificApps;
33
44
  const getDeveloperHubUrl = async (config) => {
@@ -64,24 +75,6 @@ const getConfirmationToCreateApps = async (privateApps, config) => {
64
75
  }
65
76
  };
66
77
  exports.getConfirmationToCreateApps = getConfirmationToCreateApps;
67
- const createPrivateApp = async (client, config, app) => {
68
- const privateApp = (0, omit_1.default)(app, ['uid']);
69
- return await client
70
- .organization(config.org_uid)
71
- .app()
72
- .create(privateApp)
73
- .catch((error) => error);
74
- };
75
- exports.createPrivateApp = createPrivateApp;
76
- const installApp = async (client, config, appManifestUid, mappedUid) => {
77
- const appUid = mappedUid || appManifestUid;
78
- return await client
79
- .organization(config.org_uid)
80
- .app(appUid)
81
- .install({ targetUid: config.target_stack, targetType: 'stack' })
82
- .catch((error) => error);
83
- };
84
- exports.installApp = installApp;
85
78
  const handleNameConflict = async (app, appSuffix, config) => {
86
79
  const appName = config.forceStopMarketplaceAppsPrompt
87
80
  ? (0, interactive_2.getAppName)(app.name, appSuffix)
@@ -142,19 +135,3 @@ const ifAppAlreadyExist = async (app, currentStackApp, config) => {
142
135
  return updateParam;
143
136
  };
144
137
  exports.ifAppAlreadyExist = ifAppAlreadyExist;
145
- const updateAppConfig = async (client, config, app, payload) => {
146
- var _a;
147
- let installation = client.organization(config.org_uid).app((_a = app === null || app === void 0 ? void 0 : app.manifest) === null || _a === void 0 ? void 0 : _a.uid).installation(app === null || app === void 0 ? void 0 : app.uid);
148
- installation = Object.assign(installation, payload);
149
- return await installation
150
- .update()
151
- .then((data) => {
152
- var _a;
153
- (0, logger_1.log)(config, `${(_a = app === null || app === void 0 ? void 0 : app.manifest) === null || _a === void 0 ? void 0 : _a.name} app config updated successfully.!`, 'success');
154
- })
155
- .catch((error) => {
156
- (0, log_1.trace)(error, 'error', true);
157
- (0, logger_1.log)(config, `Failed to update app config.${(0, utils_1.formatError)(error)}`, 'error');
158
- });
159
- };
160
- exports.updateAppConfig = updateAppConfig;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.12.1",
2
+ "version": "1.12.2",
3
3
  "commands": {
4
4
  "cm:stacks:import": {
5
5
  "id": "cm:stacks:import",
@@ -123,6 +123,12 @@
123
123
  "required": false,
124
124
  "allowNo": false
125
125
  },
126
+ "skip-app-recreation": {
127
+ "name": "skip-app-recreation",
128
+ "type": "boolean",
129
+ "description": "[optional] Skip private apps recreation if already exist",
130
+ "allowNo": false
131
+ },
126
132
  "replace-existing": {
127
133
  "name": "replace-existing",
128
134
  "type": "boolean",
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-import",
3
3
  "description": "Contentstack CLI plugin to import content into stack",
4
- "version": "1.12.1",
4
+ "version": "1.12.2",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
8
  "@contentstack/cli-command": "~1.2.16",
9
- "@contentstack/cli-utilities": "~1.5.8",
10
- "@contentstack/management": "~1.12.0",
9
+ "@contentstack/cli-utilities": "~1.5.9",
10
+ "@contentstack/management": "~1.13.0",
11
11
  "@oclif/core": "^2.9.3",
12
12
  "axios": "^1.6.0",
13
13
  "big-json": "^3.2.0",