@contentstack/cli-cm-export 1.2.1 → 1.2.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
@@ -38,7 +38,7 @@ $ npm install -g @contentstack/cli-cm-export
38
38
  $ csdx COMMAND
39
39
  running command...
40
40
  $ csdx (-v|--version|version)
41
- @contentstack/cli-cm-export/1.2.1 darwin-arm64 node-v18.11.0
41
+ @contentstack/cli-cm-export/1.2.3 linux-x64 node-v16.18.1
42
42
  $ csdx --help [COMMAND]
43
43
  USAGE
44
44
  $ csdx COMMAND
@@ -68,6 +68,7 @@ OPTIONS
68
68
  -k, --stack-api-key=stack-api-key API key of the source stack
69
69
  -m, --module=module [optional] specific module name
70
70
  -t, --content-types=content-types [optional] content type
71
+ -y, --yes [optional] Override marketplace apps related prompts
71
72
  --secured-assets [optional] use when assets are secured
72
73
 
73
74
  ALIASES
@@ -1 +1 @@
1
- {"version":"1.2.1","commands":{"cm:stacks:export":{"id":"cm:stacks:export","description":"Export content from a stack","usage":"cm:stacks:export [-c <value>] [-k <value>] [-d <value>] [-a <value>] [--module <value>] [--content-types <value>] [--branch <value>] [--secured-assets]","pluginName":"@contentstack/cli-cm-export","pluginType":"core","aliases":["cm:export"],"examples":["csdx cm:stacks:export --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:export --config <path/to/config/dir>","csdx cm:stacks:export --alias <management_token_alias>","csdx cm:stacks:export --alias <management_token_alias> --data-dir <path/to/export/destination/dir>","csdx cm:stacks:export --alias <management_token_alias> --config <path/to/config/file>","csdx cm:stacks:export --module <single module name>","csdx cm:stacks:export --branch [optional] branch name"],"flags":{"config":{"name":"config","type":"option","char":"c","description":"[optional] path of the config"},"stack-uid":{"name":"stack-uid","type":"option","char":"s","description":"API key of the source stack","hidden":true},"stack-api-key":{"name":"stack-api-key","type":"option","char":"k","description":"API key of the source stack"},"data":{"name":"data","type":"option","description":"path or location to store the data","hidden":true},"data-dir":{"name":"data-dir","type":"option","char":"d","description":"path or location to store the data"},"alias":{"name":"alias","type":"option","char":"a","description":"alias of the management token"},"management-token-alias":{"name":"management-token-alias","type":"option","description":"alias of the management token","hidden":true},"auth-token":{"name":"auth-token","type":"boolean","char":"A","description":"to use auth token","hidden":true,"allowNo":false},"module":{"name":"module","type":"option","char":"m","description":"[optional] specific module name"},"content-types":{"name":"content-types","type":"option","char":"t","description":"[optional] content type"},"branch":{"name":"branch","type":"option","char":"B","description":"[optional] branch name"},"secured-assets":{"name":"secured-assets","type":"boolean","description":"[optional] use when assets are secured","allowNo":false}},"args":[]}}}
1
+ {"version":"1.2.3","commands":{"cm:stacks:export":{"id":"cm:stacks:export","description":"Export content from a stack","usage":"cm:stacks:export [-c <value>] [-k <value>] [-d <value>] [-a <value>] [--module <value>] [--content-types <value>] [--branch <value>] [--secured-assets]","pluginName":"@contentstack/cli-cm-export","pluginType":"core","aliases":["cm:export"],"examples":["csdx cm:stacks:export --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir>","csdx cm:stacks:export --config <path/to/config/dir>","csdx cm:stacks:export --alias <management_token_alias>","csdx cm:stacks:export --alias <management_token_alias> --data-dir <path/to/export/destination/dir>","csdx cm:stacks:export --alias <management_token_alias> --config <path/to/config/file>","csdx cm:stacks:export --module <single module name>","csdx cm:stacks:export --branch [optional] branch name"],"flags":{"config":{"name":"config","type":"option","char":"c","description":"[optional] path of the config"},"stack-uid":{"name":"stack-uid","type":"option","char":"s","description":"API key of the source stack","hidden":true},"stack-api-key":{"name":"stack-api-key","type":"option","char":"k","description":"API key of the source stack"},"data":{"name":"data","type":"option","description":"path or location to store the data","hidden":true},"data-dir":{"name":"data-dir","type":"option","char":"d","description":"path or location to store the data"},"alias":{"name":"alias","type":"option","char":"a","description":"alias of the management token"},"management-token-alias":{"name":"management-token-alias","type":"option","description":"alias of the management token","hidden":true},"auth-token":{"name":"auth-token","type":"boolean","char":"A","description":"to use auth token","hidden":true,"allowNo":false},"module":{"name":"module","type":"option","char":"m","description":"[optional] specific module name"},"content-types":{"name":"content-types","type":"option","char":"t","description":"[optional] content type"},"branch":{"name":"branch","type":"option","char":"B","description":"[optional] branch name"},"secured-assets":{"name":"secured-assets","type":"boolean","description":"[optional] use when assets are secured","allowNo":false},"yes":{"name":"yes","type":"boolean","char":"y","description":"[optional] Override marketplace apps related prompts","required":false,"allowNo":false}},"args":[]}}}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-export",
3
3
  "description": "Contentstack CLI plugin to export content from stack",
4
- "version": "1.2.1",
4
+ "version": "1.2.3",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-command": "^1.0.2",
9
- "@contentstack/cli-utilities": "^1.0.3",
10
- "@contentstack/management": "^1.3.0",
8
+ "@contentstack/cli-command": "^1.0.4",
9
+ "@contentstack/cli-utilities": "^1.0.5",
10
+ "@contentstack/management": "^1.6.0",
11
11
  "@oclif/command": "^1.8.16",
12
12
  "@oclif/config": "^1.18.3",
13
13
  "async": "^3.2.4",
@@ -24,11 +24,10 @@
24
24
  "winston": "^3.7.2"
25
25
  },
26
26
  "devDependencies": {
27
- "@contentstack/cli-auth": "^1.0.3",
28
- "@contentstack/cli-config": "^1.0.2",
27
+ "@contentstack/cli-auth": "^1.0.6",
28
+ "@contentstack/cli-config": "^1.0.4",
29
29
  "@contentstack/cli-dev-dependencies": "^1.0.0",
30
30
  "@oclif/dev-cli": "^1.22.2",
31
- "@oclif/plugin-help": "^5.1.12",
32
31
  "@oclif/test": "^1.2.6",
33
32
  "assert": "^2.0.0",
34
33
  "chai": "^4.2.0",
@@ -37,8 +36,8 @@
37
36
  "eslint": "^8.18.0",
38
37
  "eslint-config-oclif": "^3.1.0",
39
38
  "globby": "^10.0.2",
40
- "mocha": "^10.0.0",
41
- "nyc": "^14.1.1",
39
+ "mocha": "10.1.0",
40
+ "nyc": "^15.1.0",
42
41
  "sinon": "^9.0.2"
43
42
  },
44
43
  "engines": {
@@ -68,9 +67,6 @@
68
67
  "oclif": {
69
68
  "commands": "./src/commands",
70
69
  "bin": "csdx",
71
- "devPlugins": [
72
- "@oclif/plugin-help"
73
- ],
74
70
  "repositoryPrefix": "<%- repo %>/blob/main/packages/contentstack-export/<%- commandPath %>"
75
71
  },
76
72
  "csdxConfig": {
package/src/app.js CHANGED
@@ -73,13 +73,12 @@ exports.initial = async function (config) {
73
73
  } else {
74
74
  addlogs(config, `${formatError(error)}`, 'error');
75
75
  }
76
- // reject(error);
77
76
  });
78
77
  } else if (config.management_token) {
79
78
  try {
80
79
  await fetchBranchAndExport();
81
80
  } catch (error) {
82
- addlogs(config, `${formatError(error)}`, 'error');
81
+ addlogs(config, formatError(error), 'error');
83
82
  }
84
83
  resolve();
85
84
  }
@@ -140,13 +139,15 @@ const allExport = async (config, types, branchName) => {
140
139
  }
141
140
  addlogs(
142
141
  config,
143
- chalk.green('The content of the ' + config.source_stack + ' has been exported successfully!'),
142
+ chalk.green(
143
+ 'The content of stack ' + (config.sourceStackName || config.source_stack) + ' has been exported successfully!',
144
+ ),
144
145
  'success',
145
146
  );
146
147
  addlogs(config, 'The log for this is stored at ' + path.join(config.data, 'logs', 'export'), 'success');
147
148
  return true;
148
149
  } catch (error) {
149
- addlogs(config, `${formatError(error)}`, 'error');
150
+ addlogs(config, formatError(error), 'error');
150
151
  addlogs(
151
152
  config,
152
153
  chalk.red('Failed to migrate stack: ' + config.source_stack + '. Please check error logs for more info'),
@@ -31,6 +31,8 @@ class ExportCommand extends Command {
31
31
  host.cma = cmaHost[1];
32
32
  host.cda = cdaHost[1];
33
33
 
34
+ config.forceStopMarketplaceAppsPrompt = exportCommandFlags.yes;
35
+
34
36
  if (alias) {
35
37
  let managementTokens = this.getToken(alias);
36
38
 
@@ -177,6 +179,11 @@ ExportCommand.flags = {
177
179
  'secured-assets': flags.boolean({
178
180
  description: '[optional] use when assets are secured',
179
181
  }),
182
+ yes: flags.boolean({
183
+ char: 'y',
184
+ required: false,
185
+ description: '[optional] Override marketplace apps related prompts',
186
+ }),
180
187
  };
181
188
 
182
189
  ExportCommand.aliases = ['cm:export'];
@@ -347,4 +347,6 @@ module.exports = {
347
347
  preserveStackVersion: false,
348
348
  fetchConcurrency: 5,
349
349
  writeConcurrency: 5,
350
+ developerHubBaseUrl: '',
351
+ marketplaceAppEncryptionKey: 'nF2ejRQcTv',
350
352
  };
@@ -12,22 +12,23 @@ const { cliux, HttpClient, NodeCrypto } = require('@contentstack/cli-utilities')
12
12
 
13
13
  const { formatError } = require('../util');
14
14
  let config = require('../../config/default');
15
- const { writeFile } = require('../util/helper');
15
+ const { writeFileSync } = require('../util/helper');
16
16
  const { addlogs: log } = require('../util/log');
17
17
  const { getDeveloperHubUrl, getInstalledExtensions } = require('../util/marketplace-app-helper');
18
18
 
19
19
  module.exports = class ExportMarketplaceApps {
20
20
  config;
21
+ nodeCrypto;
21
22
  marketplaceAppPath = null;
22
23
  developerHubBaseUrl = null;
23
24
  marketplaceAppConfig = config.modules.marketplace_apps;
24
25
 
25
26
  constructor(credentialConfig) {
26
- this.config = credentialConfig;
27
+ this.config = _.merge(config, credentialConfig);
27
28
  }
28
29
 
29
30
  async start() {
30
- this.developerHubBaseUrl = await getDeveloperHubUrl();
31
+ this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl());
31
32
 
32
33
  if (!this.config.auth_token) {
33
34
  cliux.print(
@@ -48,8 +49,35 @@ module.exports = class ExportMarketplaceApps {
48
49
  return this.exportInstalledExtensions();
49
50
  }
50
51
 
52
+ async createNodeCryptoInstance() {
53
+ const cryptoArgs = {};
54
+
55
+ if (this.config.forceStopMarketplaceAppsPrompt) {
56
+ cryptoArgs['encryptionKey'] = this.config.marketplaceAppEncryptionKey;
57
+ } else {
58
+ cryptoArgs['encryptionKey'] = await cliux.inquire({
59
+ type: 'input',
60
+ name: 'name',
61
+ default: this.config.marketplaceAppEncryptionKey,
62
+ validate: (url) => {
63
+ if (!url) return "Encryption key can't be empty.";
64
+
65
+ return true;
66
+ },
67
+ message: 'Enter marketplace app configurations encryption key',
68
+ });
69
+ }
70
+
71
+ this.nodeCrypto = new NodeCrypto(cryptoArgs);
72
+ }
73
+
51
74
  exportInstalledExtensions = () => {
52
75
  const self = this;
76
+ const headers = {
77
+ authtoken: self.config.auth_token,
78
+ organization_uid: self.config.org_uid,
79
+ };
80
+ const httpClient = new HttpClient().headers(headers);
53
81
 
54
82
  return new Promise(async function (resolve, reject) {
55
83
  getInstalledExtensions(self.config)
@@ -64,84 +92,77 @@ module.exports = class ExportMarketplaceApps {
64
92
  type,
65
93
  }),
66
94
  );
67
- const headers = {
68
- authtoken: self.config.auth_token,
69
- organization_uid: self.config.org_uid,
70
- };
71
- const httpClient = new HttpClient().headers(headers);
72
- const nodeCrypto = new NodeCrypto();
95
+ const uniqApps = _.uniqBy(installedApps, 'app_uid');
96
+
73
97
  const developerHubApps =
74
98
  (await httpClient
75
99
  .get(`${self.developerHubBaseUrl}/apps`)
76
100
  .then(({ data: { data } }) => data)
77
101
  .catch((err) => {
78
- console.log(err);
102
+ log(self.config, err, 'error');
79
103
  })) || [];
80
104
 
81
- eachOf(
82
- _.uniqBy(installedApps, 'app_uid'),
83
- (app, _key, cb) => {
84
- log(self.config, `Exporting ${app.title} app and it's config.`, 'success');
85
- const listOfIndexToBeUpdated = _.map(installedApps, ({ app_uid }, index) =>
86
- app_uid === app.app_uid ? index : undefined,
87
- ).filter((val) => val !== undefined);
88
-
89
- httpClient
90
- .get(`${self.developerHubBaseUrl}/installations/${app.app_installation_uid}/installationData`)
91
- .then(({ data: result }) => {
92
- const { data, error } = result;
93
- const developerHubApp = _.find(developerHubApps, { uid: app.app_uid });
94
-
95
- _.forEach(listOfIndexToBeUpdated, (index, i) => {
96
- if (developerHubApp) {
97
- installedApps[index]['visibility'] = developerHubApp.visibility;
98
- installedApps[index]['manifest'] = _.pick(
99
- developerHubApp,
100
- ['name', 'description', 'icon', 'target_type', 'ui_location', 'webhook', 'oauth'], // NOTE keys can be passed to install new app in the developer hub
101
- );
105
+ for (const app of uniqApps) {
106
+ log(self.config, `Exporting ${app.title} app and it's config.`, 'success');
107
+ const listOfIndexToBeUpdated = _.map(installedApps, ({ app_uid }, index) =>
108
+ app_uid === app.app_uid ? index : undefined,
109
+ ).filter((val) => val !== undefined);
110
+
111
+ await httpClient
112
+ .get(`${self.developerHubBaseUrl}/installations/${app.app_installation_uid}/installationData`)
113
+ .then(async ({ data: result }) => {
114
+ const { data, error } = result;
115
+ const developerHubApp = _.find(developerHubApps, { uid: app.app_uid });
116
+
117
+ if ((_.has(data, 'configuration') || _.has(data, 'server_configuration')) && !self.nodeCrypto) {
118
+ await self.createNodeCryptoInstance();
119
+ }
120
+
121
+ _.forEach(listOfIndexToBeUpdated, (index, i) => {
122
+ if (developerHubApp) {
123
+ installedApps[index]['visibility'] = developerHubApp.visibility;
124
+ installedApps[index]['manifest'] = _.pick(
125
+ developerHubApp,
126
+ ['name', 'description', 'icon', 'target_type', 'ui_location', 'webhook', 'oauth'], // NOTE keys can be passed to install new app in the developer hub
127
+ );
128
+ }
129
+
130
+ if (_.has(data, 'configuration') || _.has(data, 'server_configuration')) {
131
+ const { configuration, server_configuration } = data;
132
+
133
+ if (!_.isEmpty(configuration)) {
134
+ installedApps[index]['configuration'] = self.nodeCrypto.encrypt(configuration);
135
+ }
136
+ if (!_.isEmpty(server_configuration)) {
137
+ installedApps[index]['server_configuration'] = self.nodeCrypto.encrypt(server_configuration);
102
138
  }
103
139
 
104
- if (_.has(data, 'configuration') || _.has(data, 'server_configuration')) {
105
- const { configuration, server_configuration } = data;
106
-
107
- if (!_.isEmpty(configuration)) {
108
- installedApps[index]['configuration'] = nodeCrypto.encrypt(configuration);
109
- }
110
- if (!_.isEmpty(server_configuration)) {
111
- installedApps[index]['server_configuration'] = nodeCrypto.encrypt(server_configuration);
112
- }
113
-
114
- if (i === 0) {
115
- log(self.config, `Exported ${app.title} app and it's config.`, 'success');
116
- }
117
- } else if (error) {
118
- console.log(error);
119
- if (i === 0) {
120
- log(self.config, `Error on exporting ${app.title} app and it's config.`, 'error');
121
- }
140
+ if (i === 0) {
141
+ log(self.config, `Exported ${app.title} app and it's config.`, 'success');
122
142
  }
123
- });
124
-
125
- cb();
126
- })
127
- .catch((err) => {
128
- log(self.config, `Failed to export ${app.title} app config ${formatError(error)}`, 'error');
129
- console.log(err);
130
- cb();
143
+ } else if (error) {
144
+ console.log(error);
145
+ if (i === 0) {
146
+ log(self.config, `Error on exporting ${app.title} app and it's config.`, 'error');
147
+ }
148
+ }
131
149
  });
132
- },
133
- () => {
134
- if (!_.isEmpty(installedApps)) {
135
- writeFile(path.join(self.marketplaceAppPath, self.marketplaceAppConfig.fileName), installedApps);
136
-
137
- log(self.config, chalk.green('All the marketplace apps have been exported successfully'), 'success');
138
- } else {
139
- log(self.config, 'No marketplace apps found', 'success');
140
- }
141
-
142
- resolve();
143
- },
144
- );
150
+ })
151
+ .catch((err) => {
152
+ log(self.config, `Failed to export ${app.title} app config ${formatError(error)}`, 'error');
153
+ console.log(err);
154
+ });
155
+ }
156
+
157
+ if (!_.isEmpty(installedApps)) {
158
+ await writeFileSync(path.join(self.marketplaceAppPath, self.marketplaceAppConfig.fileName), installedApps);
159
+
160
+ log(self.config, chalk.green('All the marketplace apps have been exported successfully'), 'success');
161
+ } else {
162
+ log(self.config, 'No marketplace apps found', 'success');
163
+ }
164
+
165
+ resolve();
145
166
  })
146
167
  .catch((error) => {
147
168
  log(self.config, `Failed to export marketplace-apps ${formatError(error)}`, 'error');