@contentstack/cli-cm-export 1.2.1 → 1.2.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 +2 -1
- package/oclif.manifest.json +1 -1
- package/package.json +8 -8
- package/src/app.js +5 -4
- package/src/commands/cm/stacks/export.js +7 -0
- package/src/config/default.js +2 -0
- package/src/lib/export/marketplace-apps.js +91 -70
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.
|
|
41
|
+
@contentstack/cli-cm-export/1.2.2 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
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.2.
|
|
1
|
+
{"version":"1.2.2","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.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-command": "^1.0.
|
|
9
|
-
"@contentstack/cli-utilities": "^1.0.
|
|
10
|
-
"@contentstack/management": "^1.
|
|
8
|
+
"@contentstack/cli-command": "^1.0.3",
|
|
9
|
+
"@contentstack/cli-utilities": "^1.0.4",
|
|
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,8 +24,8 @@
|
|
|
24
24
|
"winston": "^3.7.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@contentstack/cli-auth": "^1.0.
|
|
28
|
-
"@contentstack/cli-config": "^1.0.
|
|
27
|
+
"@contentstack/cli-auth": "^1.0.4",
|
|
28
|
+
"@contentstack/cli-config": "^1.0.3",
|
|
29
29
|
"@contentstack/cli-dev-dependencies": "^1.0.0",
|
|
30
30
|
"@oclif/dev-cli": "^1.22.2",
|
|
31
31
|
"@oclif/plugin-help": "^5.1.12",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"eslint": "^8.18.0",
|
|
38
38
|
"eslint-config-oclif": "^3.1.0",
|
|
39
39
|
"globby": "^10.0.2",
|
|
40
|
-
"mocha": "
|
|
41
|
-
"nyc": "^
|
|
40
|
+
"mocha": "10.1.0",
|
|
41
|
+
"nyc": "^15.1.0",
|
|
42
42
|
"sinon": "^9.0.2"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
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,
|
|
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(
|
|
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,
|
|
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'];
|
package/src/config/default.js
CHANGED
|
@@ -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 {
|
|
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
|
|
68
|
-
|
|
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
|
-
|
|
102
|
+
log(self.config, err, 'error');
|
|
79
103
|
})) || [];
|
|
80
104
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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 (
|
|
105
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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');
|