@contentstack/cli-cm-export 1.1.0 → 1.2.0
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 -2
- package/oclif.manifest.json +1 -1
- package/package.json +14 -5
- package/src/app.js +52 -45
- package/src/commands/cm/stacks/export.js +3 -3
- package/src/config/default.js +8 -6
- package/src/lib/export/assets.js +254 -228
- package/src/lib/export/content-types.js +72 -101
- package/src/lib/export/custom-roles.js +83 -68
- package/src/lib/export/entries.js +168 -225
- package/src/lib/export/environments.js +57 -52
- package/src/lib/export/extensions.js +50 -46
- package/src/lib/export/global-fields.js +64 -61
- package/src/lib/export/labels.js +57 -57
- package/src/lib/export/locales.js +57 -91
- package/src/lib/export/marketplace-apps.js +120 -121
- package/src/lib/export/stack.js +22 -24
- package/src/lib/export/webhooks.js +59 -54
- package/src/lib/export/workflows.js +86 -78
- package/src/lib/util/export-flags.js +7 -8
- package/src/lib/util/helper.js +83 -2
- package/src/lib/util/index.js +36 -1
- package/src/lib/util/log.js +6 -3
- package/src/lib/util/marketplace-app-helper.js +25 -6
- package/src/lib/util/setup-branches.js +5 -7
|
@@ -3,152 +3,151 @@
|
|
|
3
3
|
* Copyright (c) 2019 Contentstack LLC
|
|
4
4
|
* MIT Licensed
|
|
5
5
|
*/
|
|
6
|
-
const _ = require('lodash')
|
|
6
|
+
const _ = require('lodash');
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const chalk = require('chalk');
|
|
9
9
|
const mkdirp = require('mkdirp');
|
|
10
10
|
const eachOf = require('async/eachOf');
|
|
11
|
-
const { cliux,
|
|
11
|
+
const { cliux, HttpClient, NodeCrypto } = require('@contentstack/cli-utilities');
|
|
12
12
|
|
|
13
|
+
const { formatError } = require('../util');
|
|
13
14
|
let config = require('../../config/default');
|
|
14
15
|
const { writeFile } = require('../util/helper');
|
|
15
16
|
const { addlogs: log } = require('../util/log');
|
|
16
17
|
let stack = require('../util/contentstack-management-sdk');
|
|
17
|
-
const { getInstalledExtensions } = require('../util/marketplace-app-helper')
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
config = credentialConfig;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
const { getDeveloperHubUrl, getInstalledExtensions } = require('../util/marketplace-app-helper');
|
|
19
|
+
|
|
20
|
+
module.exports = class ExportMarketplaceApps {
|
|
21
|
+
config;
|
|
22
|
+
marketplaceAppPath = null;
|
|
23
|
+
developerHubBaseUrl = null;
|
|
24
|
+
marketplaceAppConfig = config.modules.marketplace_apps;
|
|
25
|
+
|
|
26
|
+
constructor(credentialConfig) {
|
|
27
|
+
this.config = credentialConfig;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async start() {
|
|
31
|
+
this.developerHubBaseUrl = await getDeveloperHubUrl();
|
|
32
|
+
|
|
33
|
+
if (!this.config.auth_token) {
|
|
34
|
+
cliux.print(
|
|
35
|
+
'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in',
|
|
36
|
+
{ color: 'yellow' },
|
|
37
|
+
);
|
|
38
|
+
return Promise.resolve();
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
log(
|
|
41
|
+
log(this.config, 'Starting marketplace app export', 'success');
|
|
36
42
|
this.marketplaceAppPath = path.resolve(
|
|
37
|
-
config.data,
|
|
38
|
-
|
|
43
|
+
this.config.data,
|
|
44
|
+
this.config.branchName || '',
|
|
45
|
+
this.marketplaceAppConfig.dirName,
|
|
39
46
|
);
|
|
40
47
|
mkdirp.sync(this.marketplaceAppPath);
|
|
41
48
|
|
|
42
|
-
return this.exportInstalledExtensions()
|
|
49
|
+
return this.exportInstalledExtensions();
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
const self = this
|
|
52
|
+
exportInstalledExtensions = () => {
|
|
53
|
+
const self = this;
|
|
47
54
|
|
|
48
55
|
return new Promise(async function (resolve, reject) {
|
|
49
|
-
getInstalledExtensions(config)
|
|
56
|
+
getInstalledExtensions(self.config)
|
|
50
57
|
.then(async (items) => {
|
|
51
58
|
const installedApps = _.map(
|
|
52
59
|
_.filter(items, 'app_uid'),
|
|
53
|
-
({ uid, title, app_uid, app_installation_uid, type }) => ({
|
|
54
|
-
|
|
60
|
+
({ uid, title, app_uid, app_installation_uid, type }) => ({
|
|
61
|
+
title,
|
|
62
|
+
uid,
|
|
63
|
+
app_uid,
|
|
64
|
+
app_installation_uid,
|
|
65
|
+
type,
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
55
68
|
const headers = {
|
|
56
|
-
authtoken: config.auth_token,
|
|
57
|
-
organization_uid: config.org_uid
|
|
58
|
-
}
|
|
69
|
+
authtoken: self.config.auth_token,
|
|
70
|
+
organization_uid: self.config.org_uid,
|
|
71
|
+
};
|
|
59
72
|
const httpClient = new HttpClient().headers(headers);
|
|
60
|
-
const nodeCrypto = new NodeCrypto()
|
|
61
|
-
const developerHubApps =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!_.isEmpty(configuration)) {
|
|
92
|
-
installedApps[index]['configuration'] = nodeCrypto.encrypt(configuration)
|
|
93
|
-
}
|
|
94
|
-
if (!_.isEmpty(server_configuration)) {
|
|
95
|
-
installedApps[index]['server_configuration'] = nodeCrypto.encrypt(server_configuration)
|
|
73
|
+
const nodeCrypto = new NodeCrypto();
|
|
74
|
+
const developerHubApps =
|
|
75
|
+
(await httpClient
|
|
76
|
+
.get(`${self.developerHubBaseUrl}/apps`)
|
|
77
|
+
.then(({ data: { data } }) => data)
|
|
78
|
+
.catch((err) => {
|
|
79
|
+
console.log(err);
|
|
80
|
+
})) || [];
|
|
81
|
+
|
|
82
|
+
eachOf(
|
|
83
|
+
_.uniqBy(installedApps, 'app_uid'),
|
|
84
|
+
(app, _key, cb) => {
|
|
85
|
+
log(self.config, `Exporting ${app.title} app and it's config.`, 'success');
|
|
86
|
+
const listOfIndexToBeUpdated = _.map(installedApps, ({ app_uid }, index) =>
|
|
87
|
+
app_uid === app.app_uid ? index : undefined,
|
|
88
|
+
).filter((val) => val !== undefined);
|
|
89
|
+
|
|
90
|
+
httpClient
|
|
91
|
+
.get(`${self.developerHubBaseUrl}/installations/${app.app_installation_uid}/installationData`)
|
|
92
|
+
.then(({ data: result }) => {
|
|
93
|
+
const { data, error } = result;
|
|
94
|
+
const developerHubApp = _.find(developerHubApps, { uid: app.app_uid });
|
|
95
|
+
|
|
96
|
+
_.forEach(listOfIndexToBeUpdated, (index, i) => {
|
|
97
|
+
if (developerHubApp) {
|
|
98
|
+
installedApps[index]['visibility'] = developerHubApp.visibility;
|
|
99
|
+
installedApps[index]['manifest'] = _.pick(
|
|
100
|
+
developerHubApp,
|
|
101
|
+
['name', 'description', 'icon', 'target_type', 'ui_location', 'webhook', 'oauth'], // NOTE keys can be passed to install new app in the developer hub
|
|
102
|
+
);
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
if (
|
|
99
|
-
|
|
105
|
+
if (_.has(data, 'configuration') || _.has(data, 'server_configuration')) {
|
|
106
|
+
const { configuration, server_configuration } = data;
|
|
107
|
+
|
|
108
|
+
if (!_.isEmpty(configuration)) {
|
|
109
|
+
installedApps[index]['configuration'] = nodeCrypto.encrypt(configuration);
|
|
110
|
+
}
|
|
111
|
+
if (!_.isEmpty(server_configuration)) {
|
|
112
|
+
installedApps[index]['server_configuration'] = nodeCrypto.encrypt(server_configuration);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (i === 0) {
|
|
116
|
+
log(self.config, `Exported ${app.title} app and it's config.`, 'success');
|
|
117
|
+
}
|
|
118
|
+
} else if (error) {
|
|
119
|
+
console.log(error);
|
|
120
|
+
if (i === 0) {
|
|
121
|
+
log(self.config, `Error on exporting ${app.title} app and it's config.`, 'error');
|
|
122
|
+
}
|
|
100
123
|
}
|
|
101
|
-
}
|
|
102
|
-
console.log(error)
|
|
103
|
-
if (i === 0) {
|
|
104
|
-
log(config, `Error on exporting ${app.title} app and it's config.`, 'error')
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
})
|
|
124
|
+
});
|
|
108
125
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
installedApps
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (!developerHubBaseUrl) {
|
|
138
|
-
developerHubBaseUrl = await cliux.inquire({
|
|
139
|
-
type: 'input',
|
|
140
|
-
name: 'name',
|
|
141
|
-
validate: (url) => {
|
|
142
|
-
if (!url) return 'Developer-hub URL cant be empty.'
|
|
143
|
-
|
|
144
|
-
return true
|
|
145
|
-
},
|
|
146
|
-
message: `Enter the developer-hub base URL for the ${name} region - `,
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return developerHubBaseUrl.startsWith('http') ? developerHubBaseUrl : `https://${developerHubBaseUrl}`
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
module.exports = new exportMarketplaceApps();
|
|
126
|
+
cb();
|
|
127
|
+
})
|
|
128
|
+
.catch((err) => {
|
|
129
|
+
addlogs(self.config, `Failed to export ${app.title} app config ${formatError(error)}`, 'error');
|
|
130
|
+
console.log(err);
|
|
131
|
+
cb();
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
() => {
|
|
135
|
+
if (!_.isEmpty(installedApps)) {
|
|
136
|
+
writeFile(path.join(self.marketplaceAppPath, self.marketplaceAppConfig.fileName), installedApps);
|
|
137
|
+
|
|
138
|
+
log(self.config, chalk.green('All the marketplace apps have been exported successfully'), 'success');
|
|
139
|
+
} else {
|
|
140
|
+
log(self.config, 'No marketplace apps found', 'success');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
resolve();
|
|
144
|
+
},
|
|
145
|
+
);
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
addlogs(self.config, `Failed to export marketplace-apps ${formatError(error)}`, 'error');
|
|
149
|
+
reject(error);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
};
|
package/src/lib/export/stack.js
CHANGED
|
@@ -4,19 +4,16 @@
|
|
|
4
4
|
* MIT Licensed
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var path = require('path');
|
|
10
|
-
|
|
11
|
-
var app = require('../../app');
|
|
12
|
-
var helper = require('../util/helper');
|
|
13
|
-
var { addlogs } = require('../util/log');
|
|
14
|
-
const stack = require('../util/contentstack-management-sdk');
|
|
7
|
+
let path = require('path');
|
|
8
|
+
let mkdirp = require('mkdirp');
|
|
15
9
|
|
|
10
|
+
let helper = require('../util/helper');
|
|
11
|
+
let { addlogs } = require('../util/log');
|
|
16
12
|
let config = require('../../config/default');
|
|
13
|
+
const stack = require('../util/contentstack-management-sdk');
|
|
17
14
|
|
|
18
|
-
var stackConfig = config.modules.stack;
|
|
19
15
|
let client;
|
|
16
|
+
let stackConfig = config.modules.stack;
|
|
20
17
|
|
|
21
18
|
function ExportStack() {
|
|
22
19
|
this.requestOption = {
|
|
@@ -29,7 +26,7 @@ function ExportStack() {
|
|
|
29
26
|
ExportStack.prototype.start = async function (credentialConfig) {
|
|
30
27
|
config = credentialConfig;
|
|
31
28
|
client = stack.Client(config);
|
|
32
|
-
const self = this
|
|
29
|
+
const self = this;
|
|
33
30
|
|
|
34
31
|
// NOTE get org uid
|
|
35
32
|
if (config.auth_token) {
|
|
@@ -37,11 +34,12 @@ ExportStack.prototype.start = async function (credentialConfig) {
|
|
|
37
34
|
.stack({ api_key: config.source_stack, authtoken: config.auth_token })
|
|
38
35
|
.fetch()
|
|
39
36
|
.catch((error) => {
|
|
40
|
-
console.log(error)
|
|
41
|
-
})
|
|
37
|
+
console.log(error);
|
|
38
|
+
});
|
|
42
39
|
|
|
43
40
|
if (stack && stack.org_uid) {
|
|
44
|
-
config.org_uid = stack.org_uid
|
|
41
|
+
config.org_uid = stack.org_uid;
|
|
42
|
+
config.sourceStackName = stack.name;
|
|
45
43
|
}
|
|
46
44
|
}
|
|
47
45
|
|
|
@@ -50,8 +48,8 @@ ExportStack.prototype.start = async function (credentialConfig) {
|
|
|
50
48
|
limit: 100,
|
|
51
49
|
skip: 0,
|
|
52
50
|
include_count: true,
|
|
53
|
-
}
|
|
54
|
-
return self.getLocales(apiDetails)
|
|
51
|
+
};
|
|
52
|
+
return self.getLocales(apiDetails);
|
|
55
53
|
} else if (config.preserveStackVersion) {
|
|
56
54
|
addlogs(config, 'Exporting stack details', 'success');
|
|
57
55
|
let stackFolderPath = path.resolve(config.data, stackConfig.dirName);
|
|
@@ -74,12 +72,12 @@ ExportStack.prototype.start = async function (credentialConfig) {
|
|
|
74
72
|
};
|
|
75
73
|
|
|
76
74
|
ExportStack.prototype.getLocales = function (apiDetails) {
|
|
77
|
-
let self = this
|
|
75
|
+
let self = this;
|
|
78
76
|
return new Promise((resolve, reject) => {
|
|
79
77
|
const result = client
|
|
80
78
|
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
81
79
|
.locale()
|
|
82
|
-
.query(apiDetails)
|
|
80
|
+
.query(apiDetails);
|
|
83
81
|
|
|
84
82
|
result
|
|
85
83
|
.find()
|
|
@@ -90,11 +88,11 @@ ExportStack.prototype.getLocales = function (apiDetails) {
|
|
|
90
88
|
}
|
|
91
89
|
});
|
|
92
90
|
apiDetails.skip += apiDetails.limit;
|
|
93
|
-
if (masterLocalObj) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
else {
|
|
91
|
+
if (masterLocalObj) {
|
|
92
|
+
return resolve(masterLocalObj);
|
|
93
|
+
} else if (apiDetails.skip <= response.count) {
|
|
94
|
+
return resolve(self.getLocales(apiDetails));
|
|
95
|
+
} else {
|
|
98
96
|
return reject('Master locale not found');
|
|
99
97
|
}
|
|
100
98
|
})
|
|
@@ -102,6 +100,6 @@ ExportStack.prototype.getLocales = function (apiDetails) {
|
|
|
102
100
|
return reject(error);
|
|
103
101
|
});
|
|
104
102
|
});
|
|
105
|
-
}
|
|
103
|
+
};
|
|
106
104
|
|
|
107
|
-
module.exports =
|
|
105
|
+
module.exports = ExportStack;
|
|
@@ -4,72 +4,77 @@
|
|
|
4
4
|
* MIT Licensed
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const mkdirp = require('mkdirp');
|
|
8
7
|
const path = require('path');
|
|
9
8
|
const chalk = require('chalk');
|
|
9
|
+
const mkdirp = require('mkdirp');
|
|
10
|
+
const { merge } = require('lodash');
|
|
10
11
|
|
|
11
12
|
const helper = require('../util/helper');
|
|
13
|
+
const { formatError } = require('../util');
|
|
12
14
|
const { addlogs } = require('../util/log');
|
|
13
|
-
|
|
14
|
-
let config = require('../../config/default');
|
|
15
|
+
const config = require('../../config/default');
|
|
15
16
|
const stack = require('../util/contentstack-management-sdk');
|
|
16
|
-
const webhooksConfig = config.modules.webhooks;
|
|
17
|
-
let client;
|
|
18
17
|
|
|
19
18
|
// Create folder for environments
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
module.exports = class ExportWebhooks {
|
|
21
|
+
config;
|
|
22
|
+
master = {};
|
|
23
|
+
webhooks = {};
|
|
24
|
+
requestOptions = {
|
|
23
25
|
include_count: true,
|
|
24
26
|
asc: 'updated_at',
|
|
25
27
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
webhooksConfig = config.modules.webhooks;
|
|
29
|
+
|
|
30
|
+
constructor(credentialConfig) {
|
|
31
|
+
this.config = merge(config, credentialConfig);
|
|
32
|
+
}
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
start() {
|
|
35
|
+
addlogs(this.config, 'Starting webhooks export', 'success');
|
|
36
|
+
|
|
37
|
+
const self = this;
|
|
38
|
+
const client = stack.Client(this.config);
|
|
39
|
+
const webhooksFolderPath = path.resolve(
|
|
40
|
+
this.config.data,
|
|
41
|
+
this.config.branchName || '',
|
|
42
|
+
self.webhooksConfig.dirName,
|
|
43
|
+
);
|
|
44
|
+
mkdirp.sync(webhooksFolderPath);
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
client
|
|
47
|
+
.stack({ api_key: self.config.source_stack, management_token: self.config.management_token })
|
|
48
|
+
.webhook()
|
|
49
|
+
.fetchAll(self.requestOptions)
|
|
50
|
+
.then((webhooks) => {
|
|
51
|
+
if (webhooks.items.length !== 0) {
|
|
52
|
+
for (let i = 0, total = webhooks.count; i < total; i++) {
|
|
53
|
+
const webUid = webhooks.items[i].uid;
|
|
54
|
+
self.master[webUid] = '';
|
|
55
|
+
self.webhooks[webUid] = webhooks.items[i];
|
|
56
|
+
delete self.webhooks[webUid].uid;
|
|
57
|
+
delete self.webhooks[webUid].SYS_ACL;
|
|
58
|
+
}
|
|
59
|
+
helper.writeFileSync(path.join(webhooksFolderPath, self.webhooksConfig.fileName), self.webhooks);
|
|
60
|
+
addlogs(self.config, chalk.green('All the webhooks have been exported successfully'), 'success');
|
|
61
|
+
return resolve();
|
|
62
|
+
}
|
|
63
|
+
addlogs(self.config, 'No webhooks found', 'success');
|
|
64
|
+
resolve();
|
|
65
|
+
})
|
|
66
|
+
.catch(function (error) {
|
|
67
|
+
if (error.statusCode === 401) {
|
|
68
|
+
addlogs(
|
|
69
|
+
self.config,
|
|
70
|
+
chalk.red('You are not allowed to export webhooks, Unless you provide email and password in config'),
|
|
71
|
+
'error',
|
|
72
|
+
);
|
|
73
|
+
return resolve();
|
|
52
74
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return resolve();
|
|
59
|
-
})
|
|
60
|
-
.catch(function (error) {
|
|
61
|
-
if (error.statusCode === 401) {
|
|
62
|
-
addlogs(
|
|
63
|
-
config,
|
|
64
|
-
chalk.red('You are not allowed to export webhooks, Unless you provide email and password in config'),
|
|
65
|
-
'error',
|
|
66
|
-
);
|
|
67
|
-
return resolve();
|
|
68
|
-
}
|
|
69
|
-
addlogs(config, error, 'error');
|
|
70
|
-
return reject();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
75
|
+
addlogs(self.config, formatError(error), 'error');
|
|
76
|
+
reject('Failed export webhooks');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
73
80
|
};
|
|
74
|
-
|
|
75
|
-
module.exports = new ExportWebhooks();
|