@contentstack/cli-cm-export 1.10.1 → 1.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
48
48
  $ csdx COMMAND
49
49
  running command...
50
50
  $ csdx (--version)
51
- @contentstack/cli-cm-export/1.10.1 linux-x64 node-v18.18.2
51
+ @contentstack/cli-cm-export/1.10.3 linux-x64 node-v18.19.0
52
52
  $ csdx --help [COMMAND]
53
53
  USAGE
54
54
  $ csdx COMMAND
@@ -1,18 +1,52 @@
1
- import { NodeCrypto } from '@contentstack/cli-utilities';
2
- import BaseClass from './base-class';
3
- import { ModuleClassParams } from '../../types';
4
- export default class ExportMarketplaceApps extends BaseClass {
5
- private httpClient;
6
- private marketplaceAppConfig;
7
- private listOfApps;
8
- private installedApps;
1
+ import { NodeCrypto, ContentstackMarketplaceClient } from '@contentstack/cli-utilities';
2
+ import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation } from '../../types';
3
+ export default class ExportMarketplaceApps {
4
+ protected marketplaceAppConfig: MarketplaceAppsConfig;
5
+ protected installedApps: Installation[];
9
6
  developerHubBaseUrl: string;
10
7
  marketplaceAppPath: string;
11
8
  nodeCrypto: NodeCrypto;
12
- constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
9
+ appSdk: ContentstackMarketplaceClient;
10
+ exportConfig: ExportConfig;
11
+ constructor({ exportConfig }: Omit<ModuleClassParams, 'stackAPIClient' | 'moduleName'>);
13
12
  start(): Promise<void>;
14
- setHttpClient(): Promise<void>;
15
- getAllStackSpecificApps(skip?: number): Promise<any>;
16
- exportInstalledExtensions(): Promise<void>;
13
+ /**
14
+ * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
15
+ * library if it is available.
16
+ */
17
+ exportApps(): Promise<any>;
18
+ /**
19
+ * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed
20
+ * marketplace apps.
21
+ */
22
+ getAppManifestAndAppConfig(): Promise<void>;
23
+ /**
24
+ * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the
25
+ * `manifest` property of the corresponding installed app.
26
+ * @param {number} index - The `index` parameter is a number that represents the position of the app
27
+ * in an array or list. It is used to identify the specific app in the `installedApps` array.
28
+ * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the
29
+ * installation details of an app. It contains information such as the UID (unique identifier) of the
30
+ * app's manifest.
31
+ */
32
+ getPrivateAppsManifest(index: number, appInstallation: Installation): Promise<void>;
33
+ /**
34
+ * The function `getAppConfigurations` exports the configuration of an app installation and encrypts
35
+ * the server configuration if it exists.
36
+ * @param {number} index - The `index` parameter is a number that represents the index of the app
37
+ * installation in an array or list. It is used to identify the specific app installation that needs
38
+ * to be processed or accessed.
39
+ * @param {any} appInstallation - The `appInstallation` parameter is an object that represents the
40
+ * installation details of an app. It contains information such as the app's manifest, unique
41
+ * identifier (uid), and other installation data.
42
+ */
17
43
  getAppConfigurations(index: number, appInstallation: any): Promise<void>;
44
+ /**
45
+ * The function `getStackSpecificApps` retrieves a collection of marketplace apps specific to a stack
46
+ * and stores them in the `installedApps` array.
47
+ * @param [skip=0] - The `skip` parameter is used to determine the number of items to skip in the API
48
+ * response. It is used for pagination purposes, allowing you to fetch a specific range of items from
49
+ * the API. In this code, it is initially set to 0, indicating that no items should be skipped in
50
+ */
51
+ getStackSpecificApps(skip?: number): Promise<void>;
18
52
  }
@@ -4,19 +4,17 @@ const tslib_1 = require("tslib");
4
4
  const map_1 = tslib_1.__importDefault(require("lodash/map"));
5
5
  const has_1 = tslib_1.__importDefault(require("lodash/has"));
6
6
  const find_1 = tslib_1.__importDefault(require("lodash/find"));
7
+ const omitBy_1 = tslib_1.__importDefault(require("lodash/omitBy"));
7
8
  const entries_1 = tslib_1.__importDefault(require("lodash/entries"));
8
9
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
9
10
  const node_path_1 = require("node:path");
10
11
  const cli_utilities_1 = require("@contentstack/cli-utilities");
11
12
  const utils_1 = require("../../utils");
12
- const base_class_1 = tslib_1.__importDefault(require("./base-class"));
13
- class ExportMarketplaceApps extends base_class_1.default {
14
- constructor({ exportConfig, stackAPIClient }) {
15
- super({ exportConfig, stackAPIClient });
16
- this.httpClient = new cli_utilities_1.HttpClient();
17
- this.marketplaceAppConfig = exportConfig.modules.marketplace_apps;
18
- this.listOfApps = [];
13
+ class ExportMarketplaceApps {
14
+ constructor({ exportConfig }) {
19
15
  this.installedApps = [];
16
+ this.exportConfig = exportConfig;
17
+ this.marketplaceAppConfig = exportConfig.modules.marketplace_apps;
20
18
  }
21
19
  async start() {
22
20
  if (!(0, cli_utilities_1.isAuthenticated)()) {
@@ -28,48 +26,42 @@ class ExportMarketplaceApps extends base_class_1.default {
28
26
  await utils_1.fsUtil.makeDirectory(this.marketplaceAppPath);
29
27
  this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.exportConfig));
30
28
  this.exportConfig.org_uid = await (0, utils_1.getOrgUid)(this.exportConfig);
31
- await this.setHttpClient();
32
- await this.getAllStackSpecificApps();
33
- this.installedApps = this.listOfApps;
34
- await this.exportInstalledExtensions();
35
- }
36
- async setHttpClient() {
37
- if (!this.exportConfig.auth_token) {
38
- this.httpClient = new cli_utilities_1.OauthDecorator(this.httpClient);
39
- const headers = await this.httpClient.preHeadersCheck(this.exportConfig);
40
- this.httpClient = this.httpClient.headers(headers);
41
- }
42
- else {
43
- this.httpClient = new cli_utilities_1.HttpClientDecorator(this.httpClient);
44
- this.httpClient.headers(this.exportConfig);
45
- }
29
+ // NOTE init marketplace app sdk
30
+ const host = this.developerHubBaseUrl.split('://').pop();
31
+ this.appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({ host });
32
+ await this.exportApps();
46
33
  }
47
- async getAllStackSpecificApps(skip = 0) {
48
- const data = await (0, utils_1.getStackSpecificApps)({
49
- developerHubBaseUrl: this.developerHubBaseUrl,
50
- config: this.exportConfig,
51
- skip,
52
- });
53
- const { data: apps, count } = data;
54
- if (!this.nodeCrypto && (0, find_1.default)(apps, (app) => !(0, isEmpty_1.default)(app.configuration))) {
34
+ /**
35
+ * The function `exportApps` encrypts the configuration of installed apps using a Node.js crypto
36
+ * library if it is available.
37
+ */
38
+ async exportApps() {
39
+ await this.getStackSpecificApps();
40
+ await this.getAppManifestAndAppConfig();
41
+ if (!this.nodeCrypto && (0, find_1.default)(this.installedApps, (app) => !(0, isEmpty_1.default)(app.configuration))) {
55
42
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
56
43
  }
57
- const stackApps = (0, map_1.default)(apps, (app) => {
44
+ this.installedApps = (0, map_1.default)(this.installedApps, (app) => {
58
45
  if ((0, has_1.default)(app, 'configuration')) {
59
46
  app['configuration'] = this.nodeCrypto.encrypt(app.configuration);
60
47
  }
61
48
  return app;
62
49
  });
63
- this.listOfApps = [...this.listOfApps, ...stackApps];
64
- if (count - (skip + 50) > 0) {
65
- return await this.getAllStackSpecificApps(skip + 50);
66
- }
67
50
  }
68
- async exportInstalledExtensions() {
51
+ /**
52
+ * The function `getAppManifestAndAppConfig` exports the manifest and configurations of installed
53
+ * marketplace apps.
54
+ */
55
+ async getAppManifestAndAppConfig() {
69
56
  if ((0, isEmpty_1.default)(this.installedApps)) {
70
57
  (0, utils_1.log)(this.exportConfig, 'No marketplace apps found', 'info');
71
58
  }
72
59
  else {
60
+ for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
61
+ if (app.manifest.visibility === 'private') {
62
+ await this.getPrivateAppsManifest(+index, app);
63
+ }
64
+ }
73
65
  for (const [index, app] of (0, entries_1.default)(this.installedApps)) {
74
66
  await this.getAppConfigurations(+index, app);
75
67
  }
@@ -77,24 +69,54 @@ class ExportMarketplaceApps extends base_class_1.default {
77
69
  (0, utils_1.log)(this.exportConfig, 'All the marketplace apps have been exported successfully', 'info');
78
70
  }
79
71
  }
80
- async getAppConfigurations(index, appInstallation) {
81
- var _a, _b;
82
- const sdkClient = await (0, cli_utilities_1.managementSDKClient)({
83
- host: this.developerHubBaseUrl.split('://').pop(),
72
+ /**
73
+ * The function `getPrivateAppsManifest` fetches the manifest of a private app and assigns it to the
74
+ * `manifest` property of the corresponding installed app.
75
+ * @param {number} index - The `index` parameter is a number that represents the position of the app
76
+ * in an array or list. It is used to identify the specific app in the `installedApps` array.
77
+ * @param {App} appInstallation - The `appInstallation` parameter is an object that represents the
78
+ * installation details of an app. It contains information such as the UID (unique identifier) of the
79
+ * app's manifest.
80
+ */
81
+ async getPrivateAppsManifest(index, appInstallation) {
82
+ const manifest = await this.appSdk
83
+ .marketplace(this.exportConfig.org_uid)
84
+ .app(appInstallation.manifest.uid)
85
+ .fetch({ include_oauth: true })
86
+ .catch((error) => {
87
+ (0, utils_1.log)(this.exportConfig, error, 'error');
84
88
  });
89
+ if (manifest) {
90
+ this.installedApps[index].manifest = manifest;
91
+ }
92
+ }
93
+ /**
94
+ * The function `getAppConfigurations` exports the configuration of an app installation and encrypts
95
+ * the server configuration if it exists.
96
+ * @param {number} index - The `index` parameter is a number that represents the index of the app
97
+ * installation in an array or list. It is used to identify the specific app installation that needs
98
+ * to be processed or accessed.
99
+ * @param {any} appInstallation - The `appInstallation` parameter is an object that represents the
100
+ * installation details of an app. It contains information such as the app's manifest, unique
101
+ * identifier (uid), and other installation data.
102
+ */
103
+ async getAppConfigurations(index, appInstallation) {
104
+ var _a;
85
105
  const appName = (_a = appInstallation === null || appInstallation === void 0 ? void 0 : appInstallation.manifest) === null || _a === void 0 ? void 0 : _a.name;
86
106
  (0, utils_1.log)(this.exportConfig, `Exporting ${appName} app and it's config.`, 'info');
87
- await sdkClient
88
- .organization(this.exportConfig.org_uid)
89
- .app((_b = appInstallation === null || appInstallation === void 0 ? void 0 : appInstallation.manifest) === null || _b === void 0 ? void 0 : _b.uid)
90
- .installation(appInstallation === null || appInstallation === void 0 ? void 0 : appInstallation.uid)
107
+ await this.appSdk
108
+ .marketplace(this.exportConfig.org_uid)
109
+ .installation(appInstallation.uid)
91
110
  .installationData()
92
111
  .then(async (result) => {
93
112
  const { data, error } = result;
94
- if ((0, has_1.default)(data, 'server_configuration')) {
95
- if (!this.nodeCrypto && (0, has_1.default)(data, 'server_configuration')) {
113
+ if ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration')) {
114
+ if (!this.nodeCrypto && ((0, has_1.default)(data, 'server_configuration') || (0, has_1.default)(data, 'configuration'))) {
96
115
  this.nodeCrypto = await (0, utils_1.createNodeCryptoInstance)(this.exportConfig);
97
116
  }
117
+ if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.configuration)) {
118
+ this.installedApps[index]['configuration'] = this.nodeCrypto.encrypt(data.configuration);
119
+ }
98
120
  if (!(0, isEmpty_1.default)(data === null || data === void 0 ? void 0 : data.server_configuration)) {
99
121
  this.installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration);
100
122
  (0, utils_1.log)(this.exportConfig, `Exported ${appName} app and it's config.`, 'success');
@@ -113,5 +135,35 @@ class ExportMarketplaceApps extends base_class_1.default {
113
135
  (0, utils_1.log)(this.exportConfig, error, 'error');
114
136
  });
115
137
  }
138
+ /**
139
+ * The function `getStackSpecificApps` retrieves a collection of marketplace apps specific to a stack
140
+ * and stores them in the `installedApps` array.
141
+ * @param [skip=0] - The `skip` parameter is used to determine the number of items to skip in the API
142
+ * response. It is used for pagination purposes, allowing you to fetch a specific range of items from
143
+ * the API. In this code, it is initially set to 0, indicating that no items should be skipped in
144
+ */
145
+ async getStackSpecificApps(skip = 0) {
146
+ const collection = await this.appSdk
147
+ .marketplace(this.exportConfig.org_uid)
148
+ .installation()
149
+ .fetchAll({ target_uids: this.exportConfig.source_stack, skip })
150
+ .catch((error) => {
151
+ (0, utils_1.log)(this.exportConfig, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error');
152
+ (0, utils_1.log)(this.exportConfig, error, 'error');
153
+ });
154
+ if (collection) {
155
+ const { items: apps, count } = collection;
156
+ // NOTE Remove all the chain functions
157
+ const installation = (0, map_1.default)(apps, (app) => (0, omitBy_1.default)(app, (val, _key) => {
158
+ if (val instanceof Function)
159
+ return true;
160
+ return false;
161
+ }));
162
+ this.installedApps = this.installedApps.concat(installation);
163
+ if (count - (skip + 50) > 0) {
164
+ await this.getStackSpecificApps(skip + 50);
165
+ }
166
+ }
167
+ }
116
168
  }
117
169
  exports.default = ExportMarketplaceApps;
@@ -106,3 +106,4 @@ export interface TermsConfig {
106
106
  }
107
107
  export { default as DefaultConfig } from './default-config';
108
108
  export { default as ExportConfig } from './export-config';
109
+ export * from './marketplace-app';
@@ -1,2 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./marketplace-app"), exports);
@@ -0,0 +1,54 @@
1
+ type AppLocation = 'cs.cm.stack.config' | 'cs.cm.stack.dashboard' | 'cs.cm.stack.sidebar' | 'cs.cm.stack.custom_field' | 'cs.cm.stack.rte' | 'cs.cm.stack.asset_sidebar' | 'cs.org.config';
2
+ interface ExtensionMeta {
3
+ uid?: string;
4
+ name?: string;
5
+ description?: string;
6
+ path?: string;
7
+ signed: boolean;
8
+ extension_uid?: string;
9
+ data_type?: string;
10
+ enabled?: boolean;
11
+ width?: number;
12
+ blur?: boolean;
13
+ default_width?: 'full' | 'half';
14
+ }
15
+ interface Extension {
16
+ type: AppLocation;
17
+ meta: ExtensionMeta[];
18
+ }
19
+ interface LocationConfiguration {
20
+ signed: boolean;
21
+ base_url: string;
22
+ locations: Extension[];
23
+ }
24
+ interface AnyProperty {
25
+ [propName: string]: any;
26
+ }
27
+ type Manifest = {
28
+ uid: string;
29
+ name: string;
30
+ icon?: string;
31
+ hosting?: any;
32
+ version?: number;
33
+ description: string;
34
+ organization_uid: string;
35
+ framework_version?: string;
36
+ oauth?: any;
37
+ webhook?: any;
38
+ ui_location: LocationConfiguration;
39
+ target_type: 'stack' | 'organization';
40
+ visibility: 'private' | 'public' | 'public_unlisted';
41
+ } & AnyProperty;
42
+ type Installation = {
43
+ uid: string;
44
+ status: string;
45
+ manifest: Manifest;
46
+ configuration: any;
47
+ server_configuration: any;
48
+ target: {
49
+ type: string;
50
+ uid: string;
51
+ };
52
+ ui_location: LocationConfiguration;
53
+ } & AnyProperty;
54
+ export { Installation, Manifest };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -22,7 +22,7 @@ const setupConfig = async (exportCmdFlags) => {
22
22
  config.data = config.exportDir;
23
23
  const managementTokenAlias = exportCmdFlags['management-token-alias'] || exportCmdFlags['alias'];
24
24
  if (managementTokenAlias) {
25
- const { token, apiKey } = cli_utilities_1.configHandler.get(`tokens.${managementTokenAlias}`);
25
+ const { token, apiKey } = cli_utilities_1.configHandler.get(`tokens.${managementTokenAlias}`) || {};
26
26
  config.management_token = token;
27
27
  config.apiKey = apiKey;
28
28
  if (!config.management_token) {
@@ -3,8 +3,3 @@ import { ExportConfig } from '../types';
3
3
  export declare const getDeveloperHubUrl: (exportConfig: ExportConfig) => Promise<any>;
4
4
  export declare function getOrgUid(config: ExportConfig): Promise<string>;
5
5
  export declare function createNodeCryptoInstance(config: ExportConfig): Promise<NodeCrypto>;
6
- export declare const getStackSpecificApps: (params: {
7
- developerHubBaseUrl: string;
8
- config: ExportConfig;
9
- skip: number;
10
- }) => Promise<any>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getStackSpecificApps = exports.createNodeCryptoInstance = exports.getOrgUid = exports.getDeveloperHubUrl = void 0;
3
+ exports.createNodeCryptoInstance = exports.getOrgUid = exports.getDeveloperHubUrl = void 0;
4
4
  const cli_utilities_1 = require("@contentstack/cli-utilities");
5
5
  const utils_1 = require("../utils");
6
6
  const interactive_1 = require("./interactive");
@@ -45,18 +45,3 @@ async function createNodeCryptoInstance(config) {
45
45
  return new cli_utilities_1.NodeCrypto(cryptoArgs);
46
46
  }
47
47
  exports.createNodeCryptoInstance = createNodeCryptoInstance;
48
- const getStackSpecificApps = async (params) => {
49
- const { developerHubBaseUrl, config, skip } = params;
50
- const appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
51
- endpoint: developerHubBaseUrl,
52
- });
53
- return appSdkAxiosInstance.axiosInstance
54
- .get(`${developerHubBaseUrl}/installations?target_uids=${config.source_stack}&skip=${skip}`, {
55
- headers: {
56
- organization_uid: config.org_uid,
57
- },
58
- })
59
- .then((data) => data.data)
60
- .catch((error) => (0, utils_1.log)(config, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error'));
61
- };
62
- exports.getStackSpecificApps = getStackSpecificApps;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.10.1",
2
+ "version": "1.10.3",
3
3
  "commands": {
4
4
  "cm:stacks:export": {
5
5
  "id": "cm:stacks:export",
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-export",
3
3
  "description": "Contentstack CLI plugin to export content from stack",
4
- "version": "1.10.1",
4
+ "version": "1.10.3",
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.7",
9
+ "@contentstack/cli-utilities": "~1.5.9",
10
10
  "@oclif/core": "^2.9.3",
11
11
  "async": "^3.2.4",
12
12
  "big-json": "^3.2.0",
@@ -28,7 +28,7 @@
28
28
  "@contentstack/cli-config": "~1.4.15",
29
29
  "@contentstack/cli-dev-dependencies": "~1.2.4",
30
30
  "@oclif/plugin-help": "^5.1.19",
31
- "@oclif/test": "^1.2.6",
31
+ "@oclif/test": "^2.5.6",
32
32
  "@types/big-json": "^3.2.0",
33
33
  "@types/mkdirp": "^1.0.2",
34
34
  "@types/progress-stream": "^2.0.2",
@@ -98,4 +98,4 @@
98
98
  }
99
99
  },
100
100
  "repository": "https://github.com/contentstack/cli"
101
- }
101
+ }