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