@contentstack/cli-cm-export 1.20.2 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/commands/cm/stacks/export.js +15 -6
- package/lib/config/index.js +0 -2
- package/lib/export/module-exporter.js +37 -38
- package/lib/export/modules/assets.js +71 -14
- package/lib/export/modules/base-class.d.ts +17 -0
- package/lib/export/modules/base-class.js +45 -0
- package/lib/export/modules/content-types.js +30 -8
- package/lib/export/modules/custom-roles.js +61 -21
- package/lib/export/modules/entries.d.ts +2 -0
- package/lib/export/modules/entries.js +137 -37
- package/lib/export/modules/environments.js +45 -20
- package/lib/export/modules/extensions.js +42 -17
- package/lib/export/modules/global-fields.d.ts +1 -1
- package/lib/export/modules/global-fields.js +24 -6
- package/lib/export/modules/index.d.ts +1 -0
- package/lib/export/modules/index.js +1 -0
- package/lib/export/modules/labels.js +43 -16
- package/lib/export/modules/locales.js +31 -12
- package/lib/export/modules/marketplace-apps.d.ts +5 -2
- package/lib/export/modules/marketplace-apps.js +95 -25
- package/lib/export/modules/personalize.d.ts +12 -2
- package/lib/export/modules/personalize.js +181 -46
- package/lib/export/modules/stack.js +83 -28
- package/lib/export/modules/taxonomies.d.ts +4 -9
- package/lib/export/modules/taxonomies.js +123 -75
- package/lib/export/modules/webhooks.js +40 -17
- package/lib/export/modules/workflows.js +57 -20
- package/lib/types/default-config.d.ts +0 -2
- package/lib/types/index.d.ts +1 -1
- package/lib/utils/common-helper.d.ts +1 -2
- package/lib/utils/common-helper.js +1 -12
- package/lib/utils/constants.d.ts +147 -0
- package/lib/utils/constants.js +160 -0
- package/lib/utils/export-config-handler.js +2 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +6 -1
- package/lib/utils/marketplace-app-helper.d.ts +1 -0
- package/lib/utils/marketplace-app-helper.js +21 -12
- package/lib/utils/progress-strategy-registry.d.ts +7 -0
- package/lib/utils/progress-strategy-registry.js +98 -0
- package/messages/index.json +4 -2
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
- package/lib/export/modules-js/assets.d.ts +0 -43
- package/lib/export/modules-js/assets.js +0 -396
- package/lib/export/modules-js/content-types.d.ts +0 -21
- package/lib/export/modules-js/content-types.js +0 -76
- package/lib/export/modules-js/custom-roles.d.ts +0 -21
- package/lib/export/modules-js/custom-roles.js +0 -76
- package/lib/export/modules-js/entries.d.ts +0 -18
- package/lib/export/modules-js/entries.js +0 -143
- package/lib/export/modules-js/environments.d.ts +0 -16
- package/lib/export/modules-js/environments.js +0 -62
- package/lib/export/modules-js/extensions.d.ts +0 -18
- package/lib/export/modules-js/extensions.js +0 -57
- package/lib/export/modules-js/global-fields.d.ts +0 -22
- package/lib/export/modules-js/global-fields.js +0 -108
- package/lib/export/modules-js/index.d.ts +0 -2
- package/lib/export/modules-js/index.js +0 -31
- package/lib/export/modules-js/labels.d.ts +0 -14
- package/lib/export/modules-js/labels.js +0 -56
- package/lib/export/modules-js/locales.d.ts +0 -23
- package/lib/export/modules-js/locales.js +0 -68
- package/lib/export/modules-js/marketplace-apps.d.ts +0 -21
- package/lib/export/modules-js/marketplace-apps.js +0 -132
- package/lib/export/modules-js/stack.d.ts +0 -18
- package/lib/export/modules-js/stack.js +0 -91
- package/lib/export/modules-js/webhooks.d.ts +0 -18
- package/lib/export/modules-js/webhooks.js +0 -60
- package/lib/export/modules-js/workflows.d.ts +0 -16
- package/lib/export/modules-js/workflows.js +0 -89
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const path = tslib_1.__importStar(require("path"));
|
|
5
5
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
|
-
const utils_1 = require("../../utils");
|
|
7
6
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
8
|
class LocaleExport extends base_class_1.default {
|
|
9
9
|
constructor({ exportConfig, stackAPIClient }) {
|
|
10
10
|
super({ exportConfig, stackAPIClient });
|
|
@@ -21,26 +21,40 @@ class LocaleExport extends base_class_1.default {
|
|
|
21
21
|
this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(exportConfig.data), (0, cli_utilities_1.sanitizePath)(exportConfig.branchName || ''), (0, cli_utilities_1.sanitizePath)(this.localeConfig.dirName));
|
|
22
22
|
this.locales = {};
|
|
23
23
|
this.masterLocale = {};
|
|
24
|
-
this.exportConfig.context.module =
|
|
24
|
+
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.LOCALES;
|
|
25
|
+
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.LOCALES];
|
|
25
26
|
}
|
|
26
27
|
async start() {
|
|
27
28
|
try {
|
|
28
29
|
cli_utilities_1.log.debug('Starting locales export process...', this.exportConfig.context);
|
|
29
|
-
|
|
30
|
-
await
|
|
31
|
-
|
|
30
|
+
// Get locales count and setup with loading spinner
|
|
31
|
+
const [totalCount] = await this.withLoadingSpinner('LOCALES: Analyzing locales...', async () => {
|
|
32
|
+
await utils_1.fsUtil.makeDirectory(this.localesPath);
|
|
33
|
+
cli_utilities_1.log.debug(`Locales path: ${this.localesPath}`, this.exportConfig.context);
|
|
34
|
+
const countResponse = await this.stackAPIClient
|
|
35
|
+
.locale()
|
|
36
|
+
.query(Object.assign(Object.assign({}, this.qs), { include_count: true, limit: 1 }))
|
|
37
|
+
.find();
|
|
38
|
+
return [countResponse.count || 0];
|
|
39
|
+
});
|
|
40
|
+
// Create simple progress manager with total count
|
|
41
|
+
const progress = this.createSimpleProgress(this.currentModuleName, totalCount);
|
|
42
|
+
// Fetch locales
|
|
43
|
+
progress.updateStatus('Fetching locale definitions...');
|
|
32
44
|
await this.getLocales();
|
|
33
|
-
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales`, this.exportConfig.context);
|
|
45
|
+
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.locales || {}).length} locales and ${Object.keys(this.masterLocale || {}).length} master locales`, this.exportConfig.context);
|
|
34
46
|
const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName);
|
|
35
47
|
const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName);
|
|
36
48
|
cli_utilities_1.log.debug(`Writing locales to: ${localesFilePath}`, this.exportConfig.context);
|
|
37
49
|
utils_1.fsUtil.writeFile(localesFilePath, this.locales);
|
|
38
50
|
cli_utilities_1.log.debug(`Writing master locale to: ${masterLocaleFilePath}`, this.exportConfig.context);
|
|
39
51
|
utils_1.fsUtil.writeFile(masterLocaleFilePath, this.masterLocale);
|
|
40
|
-
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LOCALES_EXPORT_COMPLETE', Object.keys(this.locales).length, Object.keys(this.masterLocale).length), this.exportConfig.context);
|
|
52
|
+
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('LOCALES_EXPORT_COMPLETE', Object.keys(this.locales || {}).length, Object.keys(this.masterLocale || {}).length), this.exportConfig.context);
|
|
53
|
+
this.completeProgress(true);
|
|
41
54
|
}
|
|
42
55
|
catch (error) {
|
|
43
56
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
57
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Locales export failed');
|
|
44
58
|
throw error;
|
|
45
59
|
}
|
|
46
60
|
}
|
|
@@ -71,22 +85,27 @@ class LocaleExport extends base_class_1.default {
|
|
|
71
85
|
sanitizeAttribs(locales) {
|
|
72
86
|
cli_utilities_1.log.debug(`Sanitizing ${locales.length} locales`, this.exportConfig.context);
|
|
73
87
|
locales.forEach((locale) => {
|
|
74
|
-
var _a, _b;
|
|
88
|
+
var _a, _b, _c, _d;
|
|
75
89
|
for (let key in locale) {
|
|
76
90
|
if (this.localeConfig.requiredKeys.indexOf(key) === -1) {
|
|
77
91
|
delete locale[key];
|
|
78
92
|
}
|
|
79
93
|
}
|
|
80
|
-
|
|
94
|
+
let uid = locale.uid;
|
|
95
|
+
if (((_b = (_a = this.exportConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code) === (locale === null || locale === void 0 ? void 0 : locale.code)) {
|
|
81
96
|
cli_utilities_1.log.debug(`Adding locale ${locale.uid} to master locale`, this.exportConfig.context);
|
|
82
|
-
this.masterLocale[
|
|
97
|
+
this.masterLocale[uid] = locale;
|
|
98
|
+
// Track progress for master locale
|
|
99
|
+
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, `master-locale: ${uid}`);
|
|
83
100
|
}
|
|
84
101
|
else {
|
|
85
102
|
cli_utilities_1.log.debug(`Adding locale ${locale.uid} to regular locales`, this.exportConfig.context);
|
|
86
|
-
this.locales[
|
|
103
|
+
this.locales[uid] = locale;
|
|
104
|
+
// Track progress for regular locale
|
|
105
|
+
(_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(true, `locale: ${uid}`);
|
|
87
106
|
}
|
|
88
107
|
});
|
|
89
|
-
cli_utilities_1.log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${Object.keys(this.locales).length}`, this.exportConfig.context);
|
|
108
|
+
cli_utilities_1.log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale || {}).length}, Regular locales: ${Object.keys(this.locales || {}).length}`, this.exportConfig.context);
|
|
90
109
|
}
|
|
91
110
|
}
|
|
92
111
|
exports.default = LocaleExport;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Command } from '@contentstack/cli-command';
|
|
2
2
|
import { NodeCrypto, ContentstackMarketplaceClient } from '@contentstack/cli-utilities';
|
|
3
|
+
import BaseClass from './base-class';
|
|
3
4
|
import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation } from '../../types';
|
|
4
|
-
export default class ExportMarketplaceApps {
|
|
5
|
+
export default class ExportMarketplaceApps extends BaseClass {
|
|
5
6
|
protected marketplaceAppConfig: MarketplaceAppsConfig;
|
|
6
7
|
protected installedApps: Installation[];
|
|
7
8
|
developerHubBaseUrl: string;
|
|
@@ -11,8 +12,10 @@ export default class ExportMarketplaceApps {
|
|
|
11
12
|
exportConfig: ExportConfig;
|
|
12
13
|
command: Command;
|
|
13
14
|
query: Record<string, any>;
|
|
14
|
-
constructor({ exportConfig }:
|
|
15
|
+
constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
|
|
15
16
|
start(): Promise<void>;
|
|
17
|
+
setupPaths(): Promise<void>;
|
|
18
|
+
getAppsCount(): Promise<number>;
|
|
16
19
|
/**
|
|
17
20
|
* The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
|
|
18
21
|
* library if it is available.
|
|
@@ -9,20 +9,71 @@ const entries_1 = tslib_1.__importDefault(require("lodash/entries"));
|
|
|
9
9
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
10
10
|
const node_path_1 = require("node:path");
|
|
11
11
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
12
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
12
13
|
const utils_1 = require("../../utils");
|
|
13
|
-
class ExportMarketplaceApps {
|
|
14
|
-
constructor({ exportConfig }) {
|
|
14
|
+
class ExportMarketplaceApps extends base_class_1.default {
|
|
15
|
+
constructor({ exportConfig, stackAPIClient }) {
|
|
16
|
+
super({ exportConfig, stackAPIClient });
|
|
15
17
|
this.installedApps = [];
|
|
16
18
|
this.exportConfig = exportConfig;
|
|
17
19
|
this.marketplaceAppConfig = exportConfig.modules.marketplace_apps;
|
|
18
|
-
this.exportConfig.context.module =
|
|
20
|
+
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.MARKETPLACE_APPS;
|
|
21
|
+
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.MARKETPLACE_APPS];
|
|
19
22
|
}
|
|
20
23
|
async start() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
try {
|
|
25
|
+
cli_utilities_1.log.debug('Starting marketplace apps export process...', this.exportConfig.context);
|
|
26
|
+
if (!(0, cli_utilities_1.isAuthenticated)()) {
|
|
27
|
+
cli_utilities_1.cliux.print('WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' });
|
|
28
|
+
return Promise.resolve();
|
|
29
|
+
}
|
|
30
|
+
// Initial setup and analysis with loading spinner
|
|
31
|
+
const [appsCount] = await this.withLoadingSpinner('MARKETPLACE-APPS: Analyzing marketplace apps...', async () => {
|
|
32
|
+
await this.setupPaths();
|
|
33
|
+
const appsCount = await this.getAppsCount();
|
|
34
|
+
return [appsCount];
|
|
35
|
+
});
|
|
36
|
+
if (appsCount === 0) {
|
|
37
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Handle encryption key prompt BEFORE starting progress
|
|
41
|
+
if (!this.exportConfig.forceStopMarketplaceAppsPrompt) {
|
|
42
|
+
cli_utilities_1.log.debug('Validating security configuration before progress start', this.exportConfig.context);
|
|
43
|
+
cli_utilities_1.cliux.print('\n');
|
|
44
|
+
await (0, utils_1.askEncryptionKey)(this.exportConfig);
|
|
45
|
+
this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
|
|
46
|
+
cli_utilities_1.cliux.print('\n');
|
|
47
|
+
}
|
|
48
|
+
// Create nested progress manager
|
|
49
|
+
const progress = this.createNestedProgress(this.currentModuleName);
|
|
50
|
+
// Add processes based on what we found
|
|
51
|
+
progress.addProcess(utils_1.PROCESS_NAMES.FETCH_APPS, appsCount);
|
|
52
|
+
progress.addProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST, appsCount); // Manifests and configurations
|
|
53
|
+
// Fetch stack specific apps
|
|
54
|
+
progress
|
|
55
|
+
.startProcess(utils_1.PROCESS_NAMES.FETCH_APPS)
|
|
56
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_APPS].FETCHING, utils_1.PROCESS_NAMES.FETCH_APPS);
|
|
57
|
+
await this.exportApps();
|
|
58
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.FETCH_APPS, true);
|
|
59
|
+
// Process apps (manifests and configurations)
|
|
60
|
+
if (this.installedApps.length > 0) {
|
|
61
|
+
progress
|
|
62
|
+
.startProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST)
|
|
63
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
|
|
64
|
+
await this.getAppManifestAndAppConfig();
|
|
65
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST, true);
|
|
66
|
+
}
|
|
67
|
+
this.completeProgress(true);
|
|
68
|
+
cli_utilities_1.log.success('Marketplace apps export completed successfully', this.exportConfig.context);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
cli_utilities_1.log.debug('Error occurred during marketplace apps export', this.exportConfig.context);
|
|
72
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
73
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Marketplace apps export failed');
|
|
25
74
|
}
|
|
75
|
+
}
|
|
76
|
+
async setupPaths() {
|
|
26
77
|
this.marketplaceAppPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.marketplaceAppConfig.dirName);
|
|
27
78
|
cli_utilities_1.log.debug(`Marketplace apps folder path: ${this.marketplaceAppPath}`, this.exportConfig.context);
|
|
28
79
|
await utils_1.fsUtil.makeDirectory(this.marketplaceAppPath);
|
|
@@ -36,30 +87,41 @@ class ExportMarketplaceApps {
|
|
|
36
87
|
const host = this.developerHubBaseUrl.split('://').pop();
|
|
37
88
|
cli_utilities_1.log.debug(`Initializing marketplace SDK with host: ${host}`, this.exportConfig.context);
|
|
38
89
|
this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
|
|
39
|
-
|
|
40
|
-
|
|
90
|
+
}
|
|
91
|
+
async getAppsCount() {
|
|
92
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
93
|
+
cli_utilities_1.log.debug('Fetching marketplace apps count...', this.exportConfig.context);
|
|
94
|
+
try {
|
|
95
|
+
const externalQuery = (_a = this.exportConfig.query) === null || _a === void 0 ? void 0 : _a.modules['marketplace-apps'];
|
|
96
|
+
if (externalQuery) {
|
|
97
|
+
if (((_c = (_b = externalQuery.app_uid) === null || _b === void 0 ? void 0 : _b.$in) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
98
|
+
this.query.app_uids = externalQuery.app_uid.$in.join(',');
|
|
99
|
+
}
|
|
100
|
+
if (((_e = (_d = externalQuery.installation_uid) === null || _d === void 0 ? void 0 : _d.$in) === null || _e === void 0 ? void 0 : _e.length) > 0) {
|
|
101
|
+
this.query.installation_uids = (_g = (_f = externalQuery.installation_uid) === null || _f === void 0 ? void 0 : _f.$in) === null || _g === void 0 ? void 0 : _g.join(',');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const collection = await this.appSdk
|
|
105
|
+
.marketplace(this.exportConfig.org_uid)
|
|
106
|
+
.installation()
|
|
107
|
+
.fetchAll(Object.assign(Object.assign({}, this.query), { limit: 1, skip: 0 }));
|
|
108
|
+
const count = (collection === null || collection === void 0 ? void 0 : collection.count) || 0;
|
|
109
|
+
cli_utilities_1.log.debug(`Total marketplace apps count: ${count}`, this.exportConfig.context);
|
|
110
|
+
return count;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
cli_utilities_1.log.debug('Failed to fetch marketplace apps count', this.exportConfig.context);
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
41
116
|
}
|
|
42
117
|
/**
|
|
43
118
|
* The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
|
|
44
119
|
* library if it is available.
|
|
45
120
|
*/
|
|
46
121
|
async exportApps() {
|
|
47
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
48
122
|
cli_utilities_1.log.debug('Starting apps export process...', this.exportConfig.context);
|
|
49
|
-
// currently support only app_uids or installation_uids
|
|
50
|
-
const externalQuery = (_a = this.exportConfig.query) === null || _a === void 0 ? void 0 : _a.modules['marketplace-apps'];
|
|
51
|
-
if (externalQuery) {
|
|
52
|
-
if (((_c = (_b = externalQuery.app_uid) === null || _b === void 0 ? void 0 : _b.$in) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
53
|
-
this.query.app_uids = externalQuery.app_uid.$in.join(',');
|
|
54
|
-
}
|
|
55
|
-
if (((_e = (_d = externalQuery.installation_uid) === null || _d === void 0 ? void 0 : _d.$in) === null || _e === void 0 ? void 0 : _e.length) > 0) {
|
|
56
|
-
this.query.installation_uids = (_g = (_f = externalQuery.installation_uid) === null || _f === void 0 ? void 0 : _f.$in) === null || _g === void 0 ? void 0 : _g.join(',');
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
123
|
await this.getStackSpecificApps();
|
|
60
124
|
cli_utilities_1.log.debug(`Retrieved ${this.installedApps.length} stack-specific apps`, this.exportConfig.context);
|
|
61
|
-
await this.getAppManifestAndAppConfig();
|
|
62
|
-
cli_utilities_1.log.debug('Completed app manifest and configuration processing', this.exportConfig.context);
|
|
63
125
|
if (!this.nodeCrypto && (0, find_1.default)(this.installedApps, (app) => !(0, isEmpty_1.default)(app.configuration))) {
|
|
64
126
|
cli_utilities_1.log.debug('Initializing NodeCrypto for app configuration encryption', this.exportConfig.context);
|
|
65
127
|
this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
|
|
@@ -79,7 +141,7 @@ class ExportMarketplaceApps {
|
|
|
79
141
|
* marketplace apps.
|
|
80
142
|
*/
|
|
81
143
|
async getAppManifestAndAppConfig() {
|
|
82
|
-
var _a;
|
|
144
|
+
var _a, _b, _c;
|
|
83
145
|
if ((0, isEmpty_1.default)(this.installedApps)) {
|
|
84
146
|
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context);
|
|
85
147
|
}
|
|
@@ -94,11 +156,13 @@ class ExportMarketplaceApps {
|
|
|
94
156
|
for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
|
|
95
157
|
cli_utilities_1.log.debug(`Processing app configurations: ${((_a = app.manifest) === null || _a === void 0 ? void 0 : _a.name) || app.uid}`, this.exportConfig.context);
|
|
96
158
|
await this.getAppConfigurations(+index, app);
|
|
159
|
+
// Track progress for each app processed
|
|
160
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `app: ${((_c = app.manifest) === null || _c === void 0 ? void 0 : _c.name) || app.uid}`, null, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
|
|
97
161
|
}
|
|
98
162
|
const marketplaceAppsFilePath = (0, node_path_1.resolve)(this.marketplaceAppPath, this.marketplaceAppConfig.fileName);
|
|
99
163
|
cli_utilities_1.log.debug(`Writing marketplace apps to: ${marketplaceAppsFilePath}`, this.exportConfig.context);
|
|
100
164
|
utils_1.fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps);
|
|
101
|
-
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), this.exportConfig.context);
|
|
165
|
+
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps || {}).length), this.exportConfig.context);
|
|
102
166
|
}
|
|
103
167
|
}
|
|
104
168
|
/**
|
|
@@ -147,12 +211,13 @@ class ExportMarketplaceApps {
|
|
|
147
211
|
.installation(appInstallation.uid)
|
|
148
212
|
.installationData()
|
|
149
213
|
.then(async (result) => {
|
|
214
|
+
var _a;
|
|
150
215
|
const { data, error } = result;
|
|
151
216
|
if ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration')) {
|
|
152
217
|
cli_utilities_1.log.debug(`Found configuration data for app: ${app}`, this.exportConfig.context);
|
|
153
218
|
if (!this.nodeCrypto && ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration'))) {
|
|
154
|
-
cli_utilities_1.log.debug(`Initializing NodeCrypto for app: ${app}`, this.exportConfig.context);
|
|
155
219
|
this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
|
|
220
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, utils_1.PROCESS_NAMES.FETCH_CONFIG_MANIFEST);
|
|
156
221
|
}
|
|
157
222
|
if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.configuration)) {
|
|
158
223
|
cli_utilities_1.log.debug(`Encrypting configuration for app: ${app}`, this.exportConfig.context);
|
|
@@ -204,6 +269,11 @@ class ExportMarketplaceApps {
|
|
|
204
269
|
return false;
|
|
205
270
|
}));
|
|
206
271
|
cli_utilities_1.log.debug(`Processed ${installation.length} app installations`, this.exportConfig.context);
|
|
272
|
+
// Track progress for each app fetched
|
|
273
|
+
installation.forEach((app) => {
|
|
274
|
+
var _a, _b;
|
|
275
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `app: ${((_b = app.manifest) === null || _b === void 0 ? void 0 : _b.name) || app.uid}`, null, utils_1.PROCESS_NAMES.FETCH_APPS);
|
|
276
|
+
});
|
|
207
277
|
this.installedApps = this.installedApps.concat(installation);
|
|
208
278
|
if (count - (skip + 50) > 0) {
|
|
209
279
|
cli_utilities_1.log.debug(`Continuing to fetch apps with skip: ${skip + 50}`, this.exportConfig.context);
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { AnyProperty } from '@contentstack/cli-variants';
|
|
2
|
+
import BaseClass from './base-class';
|
|
2
3
|
import { ModuleClassParams, ExportConfig } from '../../types';
|
|
3
|
-
export default class ExportPersonalize {
|
|
4
|
+
export default class ExportPersonalize extends BaseClass {
|
|
4
5
|
exportConfig: ExportConfig;
|
|
5
6
|
personalizeConfig: {
|
|
6
7
|
dirName: string;
|
|
7
8
|
baseURL: Record<string, string>;
|
|
8
9
|
} & AnyProperty;
|
|
9
|
-
|
|
10
|
+
private readonly moduleInstanceMapper;
|
|
11
|
+
private readonly moduleDisplayMapper;
|
|
12
|
+
constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
|
|
10
13
|
start(): Promise<void>;
|
|
14
|
+
private validatePersonalizeSetup;
|
|
15
|
+
private validateProjectConnectivity;
|
|
16
|
+
private getPersonalizeModuleCount;
|
|
17
|
+
private addProjectProcess;
|
|
18
|
+
private addModuleProcesses;
|
|
19
|
+
private exportProjects;
|
|
20
|
+
private exportModules;
|
|
11
21
|
}
|
|
@@ -1,70 +1,205 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
const cli_variants_1 = require("@contentstack/cli-variants");
|
|
4
5
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
7
|
+
const utils_1 = require("../../utils");
|
|
8
|
+
class ExportPersonalize extends base_class_1.default {
|
|
9
|
+
constructor({ exportConfig, stackAPIClient }) {
|
|
10
|
+
super({ exportConfig, stackAPIClient });
|
|
11
|
+
this.moduleInstanceMapper = {
|
|
12
|
+
events: cli_variants_1.ExportEvents,
|
|
13
|
+
attributes: cli_variants_1.ExportAttributes,
|
|
14
|
+
audiences: cli_variants_1.ExportAudiences,
|
|
15
|
+
experiences: cli_variants_1.ExportExperiences,
|
|
16
|
+
};
|
|
17
|
+
this.moduleDisplayMapper = {
|
|
18
|
+
events: utils_1.PROCESS_NAMES.PERSONALIZE_EVENTS,
|
|
19
|
+
attributes: utils_1.PROCESS_NAMES.PERSONALIZE_ATTRIBUTES,
|
|
20
|
+
audiences: utils_1.PROCESS_NAMES.PERSONALIZE_AUDIENCES,
|
|
21
|
+
experiences: utils_1.PROCESS_NAMES.PERSONALIZE_EXPERIENCES,
|
|
22
|
+
};
|
|
7
23
|
this.exportConfig = exportConfig;
|
|
8
24
|
this.personalizeConfig = exportConfig.modules.personalize;
|
|
9
|
-
this.exportConfig.context.module =
|
|
25
|
+
this.exportConfig.context.module = utils_1.MODULE_CONTEXTS.PERSONALIZE;
|
|
26
|
+
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.PERSONALIZE];
|
|
10
27
|
}
|
|
11
28
|
async start() {
|
|
12
29
|
try {
|
|
13
30
|
cli_utilities_1.log.debug('Starting personalize export process...', this.exportConfig.context);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
const [canProceed, projectCount, moduleCount] = await this.withLoadingSpinner('PERSONALIZE: Analyzing personalization configuration and connectivity...', async () => {
|
|
32
|
+
// Step 1: Basic validation (URL, tokens)
|
|
33
|
+
const basicValidation = this.validatePersonalizeSetup();
|
|
34
|
+
if (!basicValidation) {
|
|
35
|
+
return [false, 0, 0];
|
|
36
|
+
}
|
|
37
|
+
// Step 2: Check actual project connectivity
|
|
38
|
+
const projectCount = await this.validateProjectConnectivity();
|
|
39
|
+
if (projectCount === 0) {
|
|
40
|
+
cli_utilities_1.log.info('No Personalize Project connected with the given stack', this.exportConfig.context);
|
|
41
|
+
this.exportConfig.personalizationEnabled = false;
|
|
42
|
+
return [false, 0, 0];
|
|
43
|
+
}
|
|
44
|
+
// Step 3: Get module count only if projects exist
|
|
45
|
+
const moduleCount = this.getPersonalizeModuleCount();
|
|
46
|
+
cli_utilities_1.log.debug(`Personalize validation - canProceed: true, projectCount: ${projectCount}, moduleCount: ${moduleCount}`, this.exportConfig.context);
|
|
47
|
+
// Enable personalization since we have connected projects
|
|
48
|
+
this.exportConfig.personalizationEnabled = true;
|
|
49
|
+
return [true, projectCount, moduleCount];
|
|
50
|
+
});
|
|
51
|
+
if (!canProceed) {
|
|
24
52
|
return;
|
|
25
53
|
}
|
|
26
|
-
cli_utilities_1.log.debug(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
36
|
-
const order = this.exportConfig.modules.personalize
|
|
37
|
-
.exportOrder;
|
|
38
|
-
cli_utilities_1.log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context);
|
|
39
|
-
for (const module of order) {
|
|
40
|
-
cli_utilities_1.log.debug(`Processing personalize module: ${module}`, this.exportConfig.context);
|
|
41
|
-
if (moduleMapper[module]) {
|
|
42
|
-
cli_utilities_1.log.debug(`Starting export for module: ${module}`, this.exportConfig.context);
|
|
43
|
-
await moduleMapper[module].start();
|
|
44
|
-
cli_utilities_1.log.debug(`Completed export for module: ${module}`, this.exportConfig.context);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
cli_utilities_1.log.debug(`Module not implemented: ${module}`, this.exportConfig.context);
|
|
48
|
-
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context);
|
|
49
|
-
}
|
|
54
|
+
cli_utilities_1.log.debug(`Creating personalize progress with projectCount: ${projectCount}, moduleCount: ${moduleCount}`, this.exportConfig.context);
|
|
55
|
+
const progress = this.createNestedProgress(this.currentModuleName);
|
|
56
|
+
this.addProjectProcess(progress, projectCount);
|
|
57
|
+
this.addModuleProcesses(progress, moduleCount);
|
|
58
|
+
try {
|
|
59
|
+
await this.exportProjects(progress);
|
|
60
|
+
if (moduleCount > 0) {
|
|
61
|
+
cli_utilities_1.log.debug('Processing personalize modules...', this.exportConfig.context);
|
|
62
|
+
await this.exportModules(progress);
|
|
50
63
|
}
|
|
51
|
-
|
|
64
|
+
else {
|
|
65
|
+
cli_utilities_1.log.debug('No personalize modules configured for processing', this.exportConfig.context);
|
|
66
|
+
}
|
|
67
|
+
this.completeProgress(true);
|
|
68
|
+
cli_utilities_1.log.success('Personalize export completed successfully', this.exportConfig.context);
|
|
52
69
|
}
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
catch (moduleError) {
|
|
71
|
+
if (moduleError === 'Forbidden') {
|
|
72
|
+
cli_utilities_1.log.debug('Personalize access forbidden, personalization not enabled', this.exportConfig.context);
|
|
73
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context);
|
|
74
|
+
this.exportConfig.personalizationEnabled = false;
|
|
75
|
+
this.completeProgress(true); // considered successful even if skipped
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
cli_utilities_1.log.debug('Error occurred during personalize module processing', this.exportConfig.context);
|
|
79
|
+
this.completeProgress(false, (moduleError === null || moduleError === void 0 ? void 0 : moduleError.message) || 'Personalize module processing failed');
|
|
80
|
+
throw moduleError;
|
|
81
|
+
}
|
|
55
82
|
}
|
|
56
83
|
}
|
|
57
84
|
catch (error) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
cli_utilities_1.log.debug('Error occurred during personalize export', this.exportConfig.context);
|
|
86
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
87
|
+
this.exportConfig.personalizationEnabled = false;
|
|
88
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Personalize export failed');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
validatePersonalizeSetup() {
|
|
92
|
+
if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) {
|
|
93
|
+
cli_utilities_1.log.debug(`Personalize URL not set for region: ${this.exportConfig.region.name}`, this.exportConfig.context);
|
|
94
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context);
|
|
95
|
+
this.exportConfig.personalizationEnabled = false;
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (this.exportConfig.management_token) {
|
|
99
|
+
cli_utilities_1.log.debug('Management token detected, skipping personalize export', this.exportConfig.context);
|
|
100
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context);
|
|
101
|
+
this.exportConfig.personalizationEnabled = false;
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
async validateProjectConnectivity() {
|
|
107
|
+
try {
|
|
108
|
+
// Create a temporary ExportProjects instance to check connectivity
|
|
109
|
+
const tempProjectsExporter = new cli_variants_1.ExportProjects(this.exportConfig);
|
|
110
|
+
// Initialize and fetch projects
|
|
111
|
+
await tempProjectsExporter.init();
|
|
112
|
+
// talisman-ignore-line
|
|
113
|
+
const projectsData = await tempProjectsExporter.projects({ connectedStackApiKey: this.exportConfig.apiKey });
|
|
114
|
+
const projectCount = (projectsData === null || projectsData === void 0 ? void 0 : projectsData.length) || 0;
|
|
115
|
+
cli_utilities_1.log.debug(`Found ${projectCount} connected projects`, this.exportConfig.context);
|
|
116
|
+
return projectCount;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
cli_utilities_1.log.debug(`Error checking project connectivity: ${error}`, this.exportConfig.context);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
getPersonalizeModuleCount() {
|
|
124
|
+
var _a, _b;
|
|
125
|
+
const order = (_b = (_a = this.exportConfig.modules) === null || _a === void 0 ? void 0 : _a.personalize) === null || _b === void 0 ? void 0 : _b.exportOrder;
|
|
126
|
+
return Array.isArray(order) ? order.length : 0;
|
|
127
|
+
}
|
|
128
|
+
addProjectProcess(progress, projectCount) {
|
|
129
|
+
progress.addProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS, projectCount);
|
|
130
|
+
cli_utilities_1.log.debug(`Added ${utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS} process with count: ${projectCount}`, this.exportConfig.context);
|
|
131
|
+
}
|
|
132
|
+
addModuleProcesses(progress, moduleCount) {
|
|
133
|
+
if (moduleCount > 0) {
|
|
134
|
+
// talisman-ignore-start
|
|
135
|
+
const order = this.exportConfig.modules.personalize
|
|
136
|
+
.exportOrder;
|
|
137
|
+
// talisman-ignore-end
|
|
138
|
+
cli_utilities_1.log.debug(`Adding ${order.length} personalize module processes: ${order.join(', ')}`, this.exportConfig.context);
|
|
139
|
+
for (const module of order) {
|
|
140
|
+
const processName = this.moduleDisplayMapper[module];
|
|
141
|
+
progress.addProcess(processName, 1);
|
|
142
|
+
cli_utilities_1.log.debug(`Added ${processName} process to personalize progress`, this.exportConfig.context);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
cli_utilities_1.log.debug('No personalize modules to add to progress', this.exportConfig.context);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async exportProjects(progress) {
|
|
150
|
+
progress
|
|
151
|
+
.startProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS)
|
|
152
|
+
.updateStatus(utils_1.PROCESS_STATUS[utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS].EXPORTING, utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS);
|
|
153
|
+
cli_utilities_1.log.debug('Starting projects export for personalization...', this.exportConfig.context);
|
|
154
|
+
const projectsExporter = new cli_variants_1.ExportProjects(this.exportConfig);
|
|
155
|
+
projectsExporter.setParentProgressManager(progress);
|
|
156
|
+
await projectsExporter.start();
|
|
157
|
+
progress.completeProcess(utils_1.PROCESS_NAMES.PERSONALIZE_PROJECTS, true);
|
|
158
|
+
}
|
|
159
|
+
async exportModules(progress) {
|
|
160
|
+
var _a, _b, _c;
|
|
161
|
+
// Set parent progress for all module instances
|
|
162
|
+
Object.entries(this.moduleInstanceMapper).forEach(([_, ModuleClass]) => {
|
|
163
|
+
const instance = new ModuleClass(this.exportConfig);
|
|
164
|
+
instance.setParentProgressManager(progress);
|
|
165
|
+
});
|
|
166
|
+
// talisman-ignore-start
|
|
167
|
+
const order = this.exportConfig.modules.personalize
|
|
168
|
+
.exportOrder;
|
|
169
|
+
// talisman-ignore-end
|
|
170
|
+
cli_utilities_1.log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context);
|
|
171
|
+
for (const module of order) {
|
|
172
|
+
cli_utilities_1.log.debug(`Processing personalize module: ${module}`, this.exportConfig.context);
|
|
173
|
+
const processName = this.moduleDisplayMapper[module];
|
|
174
|
+
const ModuleClass = this.moduleInstanceMapper[module];
|
|
175
|
+
if (ModuleClass) {
|
|
176
|
+
progress
|
|
177
|
+
.startProcess(processName)
|
|
178
|
+
.updateStatus(((_a = utils_1.PROCESS_STATUS[processName]) === null || _a === void 0 ? void 0 : _a.EXPORTING) || `Exporting ${module}...`, processName);
|
|
179
|
+
cli_utilities_1.log.debug(`Starting export for module: ${module}`, this.exportConfig.context);
|
|
180
|
+
if (this.exportConfig.personalizationEnabled) {
|
|
181
|
+
const exporter = new ModuleClass(this.exportConfig);
|
|
182
|
+
exporter.setParentProgressManager(progress);
|
|
183
|
+
await exporter.start();
|
|
184
|
+
progress.completeProcess(processName, true);
|
|
185
|
+
cli_utilities_1.log.debug(`Completed export for module: ${module}`, this.exportConfig.context);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
cli_utilities_1.log.debug(`Skipping ${module} - personalization not enabled`, this.exportConfig.context);
|
|
189
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `${module} skipped (no project)`, null, processName);
|
|
190
|
+
progress.completeProcess(processName, true);
|
|
191
|
+
cli_utilities_1.log.info(`Skipped ${module} export - no personalize project found`, this.exportConfig.context);
|
|
192
|
+
}
|
|
61
193
|
}
|
|
62
194
|
else {
|
|
63
|
-
cli_utilities_1.log.debug(
|
|
64
|
-
(
|
|
195
|
+
cli_utilities_1.log.debug(`Module not implemented: ${module}`, this.exportConfig.context);
|
|
196
|
+
progress.startProcess(processName).updateStatus(`Module not implemented: ${module}`, processName);
|
|
197
|
+
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `module: ${module}`, 'Module not implemented', processName);
|
|
198
|
+
progress.completeProcess(processName, false);
|
|
199
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context);
|
|
65
200
|
}
|
|
66
|
-
this.exportConfig.personalizationEnabled = false;
|
|
67
201
|
}
|
|
202
|
+
cli_utilities_1.log.debug('Completed all personalize module processing', this.exportConfig.context);
|
|
68
203
|
}
|
|
69
204
|
}
|
|
70
205
|
exports.default = ExportPersonalize;
|