@contentstack/cli-cm-export 1.0.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 +64 -51
- package/src/commands/cm/stacks/export.js +10 -3
- package/src/config/default.js +21 -1
- package/src/lib/export/assets.js +254 -228
- package/src/lib/export/content-types.js +72 -101
- package/src/lib/export/custom-roles.js +106 -0
- 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 +153 -0
- package/src/lib/export/stack.js +35 -22
- package/src/lib/export/webhooks.js +59 -54
- package/src/lib/export/workflows.js +94 -55
- 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 +61 -0
- package/src/lib/util/setup-branches.js +5 -7
|
@@ -4,77 +4,74 @@
|
|
|
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
10
|
|
|
11
|
-
const stack = require('../util/contentstack-management-sdk');
|
|
12
11
|
const helper = require('../util/helper');
|
|
13
12
|
const { addlogs } = require('../util/log');
|
|
14
|
-
|
|
13
|
+
const { formatError } = require('../util');
|
|
15
14
|
let config = require('../../config/default');
|
|
16
|
-
const
|
|
17
|
-
const validKeys = config.modules.globalfields.validKeys;
|
|
18
|
-
let globalfieldsFolderPath;
|
|
19
|
-
const globalfieldsConfig = config.modules.globalfields;
|
|
20
|
-
function ExportGlobalFields() {
|
|
21
|
-
this.global_fields = [];
|
|
22
|
-
this.requestOptions = {
|
|
23
|
-
qs: {
|
|
24
|
-
include_count: true,
|
|
25
|
-
asc: 'updated_at',
|
|
26
|
-
limit: limit,
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
this.master = {};
|
|
30
|
-
this.globalfields = {};
|
|
31
|
-
}
|
|
15
|
+
const stack = require('../util/contentstack-management-sdk');
|
|
32
16
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
17
|
+
module.exports = class ExportGlobalFields {
|
|
18
|
+
limit = 100;
|
|
19
|
+
config = {};
|
|
20
|
+
global_fields = [];
|
|
21
|
+
master = {};
|
|
22
|
+
globalfields = {};
|
|
23
|
+
requestOptions = {};
|
|
24
|
+
globalfieldsFolderPath;
|
|
25
|
+
globalfieldsConfig = config.modules.globalfields;
|
|
26
|
+
validKeys = config.modules.globalfields.validKeys;
|
|
27
|
+
|
|
28
|
+
constructor(credentialConfig) {
|
|
29
|
+
this.requestOptions = {
|
|
30
|
+
qs: {
|
|
31
|
+
skip: 0,
|
|
32
|
+
limit: this.limit,
|
|
33
|
+
asc: 'updated_at',
|
|
34
|
+
include_count: true,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
this.config = { ...config, ...credentialConfig };
|
|
38
|
+
this.globalfieldsFolderPath = path.resolve(
|
|
39
|
+
this.config.data,
|
|
40
|
+
this.config.branchName || '',
|
|
41
|
+
this.globalfieldsConfig.dirName,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
start() {
|
|
41
46
|
const self = this;
|
|
42
|
-
|
|
47
|
+
// Create folder for Global Fields
|
|
48
|
+
mkdirp.sync(self.globalfieldsFolderPath);
|
|
49
|
+
addlogs(self.config, 'Starting Global Fields export', 'success');
|
|
50
|
+
|
|
43
51
|
return new Promise(function (resolve, reject) {
|
|
44
52
|
try {
|
|
45
53
|
return self
|
|
46
|
-
.getGlobalFields(
|
|
54
|
+
.getGlobalFields(0, self.config)
|
|
47
55
|
.then(function (result) {
|
|
48
56
|
if (!result) {
|
|
49
|
-
return self
|
|
50
|
-
.writeGlobalFields()
|
|
51
|
-
.then(() => {
|
|
52
|
-
return resolve();
|
|
53
|
-
})
|
|
54
|
-
.catch((error) => {
|
|
55
|
-
return reject(error);
|
|
56
|
-
});
|
|
57
|
+
return self.writeGlobalFields().then(resolve).catch(reject);
|
|
57
58
|
}
|
|
58
59
|
return resolve();
|
|
59
60
|
})
|
|
60
|
-
.catch(
|
|
61
|
-
return reject(error);
|
|
62
|
-
});
|
|
61
|
+
.catch(reject);
|
|
63
62
|
} catch (error) {
|
|
63
|
+
addlogs(self.config, error, 'error');
|
|
64
64
|
return reject(error);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
|
-
}
|
|
68
|
-
getGlobalFields: function (skip, globalFieldConfig) {
|
|
69
|
-
const self = this;
|
|
70
|
-
if (typeof skip !== 'number') {
|
|
71
|
-
skip = 0;
|
|
72
|
-
self.requestOptions.qs.skip = skip;
|
|
73
|
-
} else {
|
|
74
|
-
self.requestOptions.qs.skip = skip;
|
|
75
|
-
}
|
|
67
|
+
}
|
|
76
68
|
|
|
69
|
+
getGlobalFields(skip, globalFieldConfig) {
|
|
70
|
+
const self = this;
|
|
77
71
|
let client = stack.Client(globalFieldConfig);
|
|
72
|
+
|
|
73
|
+
self.requestOptions.qs.skip = skip;
|
|
74
|
+
|
|
78
75
|
return new Promise(function (resolve, reject) {
|
|
79
76
|
client
|
|
80
77
|
.stack({
|
|
@@ -92,14 +89,14 @@ ExportGlobalFields.prototype = {
|
|
|
92
89
|
}
|
|
93
90
|
globalFieldResponse.items.forEach(function (globalField) {
|
|
94
91
|
for (const key in globalField) {
|
|
95
|
-
if (validKeys.indexOf(key) === -1) {
|
|
92
|
+
if (self.validKeys.indexOf(key) === -1) {
|
|
96
93
|
delete globalField[key];
|
|
97
94
|
}
|
|
98
95
|
}
|
|
99
96
|
self.global_fields.push(globalField);
|
|
100
97
|
});
|
|
101
98
|
|
|
102
|
-
skip += limit;
|
|
99
|
+
skip += self.limit;
|
|
103
100
|
|
|
104
101
|
if (skip > globalFieldResponse.count) {
|
|
105
102
|
return resolve();
|
|
@@ -107,19 +104,25 @@ ExportGlobalFields.prototype = {
|
|
|
107
104
|
|
|
108
105
|
return self.getGlobalFields(skip, globalFieldConfig).then(resolve).catch(reject);
|
|
109
106
|
} catch (error) {
|
|
110
|
-
|
|
107
|
+
addlogs(globalFieldConfig, chalk.red(`Failed to export global-fields ${formatError(error)}`), 'error');
|
|
108
|
+
reject(error);
|
|
111
109
|
}
|
|
112
110
|
});
|
|
113
111
|
});
|
|
114
|
-
}
|
|
115
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
writeGlobalFields() {
|
|
116
115
|
const self = this;
|
|
117
|
-
return new Promise(function (resolve) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
return new Promise(function (resolve, reject) {
|
|
117
|
+
try {
|
|
118
|
+
helper.writeFileSync(path.join(self.globalfieldsFolderPath, self.globalfieldsConfig.fileName), self.global_fields);
|
|
119
|
+
addlogs(self.config, chalk.green('Global Fields export completed successfully'), 'success');
|
|
120
|
+
|
|
121
|
+
resolve();
|
|
122
|
+
} catch (error) {
|
|
123
|
+
addlogs(self.config, error, 'error');
|
|
124
|
+
reject(error);
|
|
125
|
+
}
|
|
121
126
|
});
|
|
122
|
-
}
|
|
127
|
+
}
|
|
123
128
|
};
|
|
124
|
-
|
|
125
|
-
module.exports = new ExportGlobalFields();
|
package/src/lib/export/labels.js
CHANGED
|
@@ -4,69 +4,69 @@
|
|
|
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
|
let helper = require('../util/helper');
|
|
12
13
|
let { addlogs } = require('../util/log');
|
|
13
|
-
|
|
14
|
+
const { formatError } = require('../util');
|
|
15
|
+
const config = require('../../config/default');
|
|
14
16
|
const stack = require('../util/contentstack-management-sdk');
|
|
15
|
-
let config = require('../../config/default');
|
|
16
|
-
let labelConfig = config.modules.labels;
|
|
17
|
-
let client;
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
headers: config.headers,
|
|
23
|
-
json: true,
|
|
24
|
-
};
|
|
25
|
-
this.labels = {};
|
|
26
|
-
}
|
|
18
|
+
module.exports = class ExportLabels {
|
|
19
|
+
labels = {};
|
|
20
|
+
labelConfig = config.modules.labels;
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
let self = this;
|
|
32
|
-
config = credentialConfig;
|
|
33
|
-
client = stack.Client(config);
|
|
34
|
-
let labelsFolderPath = path.resolve(config.data, config.branchName || '', labelConfig.dirName);
|
|
35
|
-
// Create locale folder
|
|
36
|
-
mkdirp.sync(labelsFolderPath);
|
|
37
|
-
return new Promise(function (resolve, reject) {
|
|
38
|
-
return client
|
|
39
|
-
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
40
|
-
.label()
|
|
41
|
-
.query()
|
|
42
|
-
.find()
|
|
43
|
-
.then((response) => {
|
|
44
|
-
if (response.items.length !== 0) {
|
|
45
|
-
response.items.forEach(function (label) {
|
|
46
|
-
addlogs(config, label.name + ' labels was exported successfully', 'success');
|
|
47
|
-
self.labels[label.uid] = label;
|
|
48
|
-
let deleteItems = config.modules.labels.invalidKeys;
|
|
49
|
-
deleteItems.forEach((e) => delete label[e]);
|
|
50
|
-
});
|
|
51
|
-
addlogs(config, chalk.green('All the labels have been exported successfully'), 'success');
|
|
52
|
-
} else {
|
|
53
|
-
addlogs(config, 'No labels found', 'success');
|
|
54
|
-
}
|
|
55
|
-
helper.writeFile(path.join(labelsFolderPath, labelConfig.fileName), self.labels);
|
|
56
|
-
return resolve();
|
|
57
|
-
})
|
|
58
|
-
.catch(function (error) {
|
|
59
|
-
if (error.statusCode === 401) {
|
|
60
|
-
addlogs(
|
|
61
|
-
config,
|
|
62
|
-
chalk.red('You are not allowed to export label, Unless you provide email and password in config', 'error'),
|
|
63
|
-
);
|
|
64
|
-
return resolve();
|
|
65
|
-
}
|
|
66
|
-
addlogs(config, error, 'error');
|
|
67
|
-
return reject();
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
};
|
|
22
|
+
constructor(credentialConfig) {
|
|
23
|
+
this.config = merge(config, credentialConfig);
|
|
24
|
+
}
|
|
71
25
|
|
|
72
|
-
|
|
26
|
+
start() {
|
|
27
|
+
addlogs(this.config, 'Starting labels export', 'success');
|
|
28
|
+
|
|
29
|
+
const self = this;
|
|
30
|
+
const client = stack.Client(this.config);
|
|
31
|
+
let labelsFolderPath = path.resolve(config.data, this.config.branchName || '', self.labelConfig.dirName);
|
|
32
|
+
// Create locale folder
|
|
33
|
+
mkdirp.sync(labelsFolderPath);
|
|
34
|
+
return new Promise(function (resolve, reject) {
|
|
35
|
+
return client
|
|
36
|
+
.stack({ api_key: self.config.source_stack, management_token: self.config.management_token })
|
|
37
|
+
.label()
|
|
38
|
+
.query()
|
|
39
|
+
.find()
|
|
40
|
+
.then((response) => {
|
|
41
|
+
if (response.items.length !== 0) {
|
|
42
|
+
response.items.forEach(function (label) {
|
|
43
|
+
addlogs(self.config, label.name + ' labels was exported successfully', 'success');
|
|
44
|
+
self.labels[label.uid] = label;
|
|
45
|
+
let deleteItems = self.config.modules.labels.invalidKeys;
|
|
46
|
+
deleteItems.forEach((e) => delete label[e]);
|
|
47
|
+
});
|
|
48
|
+
addlogs(self.config, chalk.green('All the labels have been exported successfully'), 'success');
|
|
49
|
+
} else {
|
|
50
|
+
addlogs(self.config, 'No labels found', 'success');
|
|
51
|
+
}
|
|
52
|
+
helper.writeFileSync(path.join(labelsFolderPath, self.labelConfig.fileName), self.labels);
|
|
53
|
+
resolve();
|
|
54
|
+
})
|
|
55
|
+
.catch(function (error) {
|
|
56
|
+
if (error.statusCode === 401) {
|
|
57
|
+
addlogs(
|
|
58
|
+
self.config,
|
|
59
|
+
chalk.red(
|
|
60
|
+
'You are not allowed to export label, Unless you provide email and password in config',
|
|
61
|
+
'error',
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
return resolve();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
addlogs(self.config, formatError(error), 'error');
|
|
68
|
+
reject();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
@@ -1,103 +1,69 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Contentstack Export
|
|
3
|
-
* Copyright (c) 2019 Contentstack LLC
|
|
4
|
-
* MIT Licensed
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const mkdirp = require('mkdirp');
|
|
8
1
|
const path = require('path');
|
|
9
2
|
const chalk = require('chalk');
|
|
10
|
-
|
|
11
|
-
const helper = require('../util/helper');
|
|
3
|
+
const fileHelper = require('../util/helper');
|
|
12
4
|
const { addlogs } = require('../util/log');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
$nin: [masterLocale.code],
|
|
5
|
+
class LocaleExport {
|
|
6
|
+
constructor(exportConfig, stackAPIClient) {
|
|
7
|
+
this.stackAPIClient = stackAPIClient;
|
|
8
|
+
this.exportConfig = exportConfig;
|
|
9
|
+
this.localeConfig = exportConfig.modules.locales;
|
|
10
|
+
this.qs = {
|
|
11
|
+
include_count: true,
|
|
12
|
+
asc: 'updated_at',
|
|
13
|
+
query: {
|
|
14
|
+
code: {
|
|
15
|
+
$nin: [exportConfig.master_locale.code],
|
|
16
|
+
},
|
|
26
17
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
this.locales = {};
|
|
33
|
-
}
|
|
18
|
+
only: {
|
|
19
|
+
BASE: this.localeConfig.requiredKeys,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
34
22
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
config = credentialConfig;
|
|
40
|
-
self.localesFolderPath = path.resolve(config.data, config.branchName || '', localeConfig.dirName);
|
|
41
|
-
mkdirp.sync(self.localesFolderPath);
|
|
42
|
-
client = stack.Client(config);
|
|
43
|
-
const apiDetails = {
|
|
44
|
-
limit: 100,
|
|
45
|
-
skip: 0,
|
|
46
|
-
include_count: true,
|
|
23
|
+
this.localesPath = path.resolve(exportConfig.data, exportConfig.branchName || '', this.localeConfig.dirName);
|
|
24
|
+
this.locales = {};
|
|
25
|
+
this.fetchConcurrency = this.localeConfig.fetchConcurrency || this.exportConfig.fetchConcurrency;
|
|
26
|
+
this.writeConcurrency = this.localeConfig.writeConcurrency || this.exportConfig.writeConcurrency;
|
|
47
27
|
}
|
|
48
|
-
return self.getLocales(apiDetails)
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
ExportLocales.prototype.getLocales = function (apiDetails) {
|
|
53
|
-
let self = this
|
|
54
|
-
|
|
55
|
-
return new Promise(function (resolve, reject) {
|
|
56
|
-
client
|
|
57
|
-
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
58
|
-
.locale()
|
|
59
|
-
.query({ ...self.qs, ...apiDetails })
|
|
60
|
-
.find()
|
|
61
|
-
.then((localeResponse) => {
|
|
62
|
-
if (localeResponse.items.length !== 0) {
|
|
63
|
-
localeResponse.items.forEach(function (locale) {
|
|
64
|
-
addlogs(config, locale.name + ' locale was exported successfully', 'success');
|
|
65
|
-
for (const key in locale) {
|
|
66
|
-
if (requiredKeys.indexOf(key) === -1) {
|
|
67
|
-
delete locale[key];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
self.locales[locale.uid] = locale;
|
|
71
|
-
});
|
|
72
28
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.catch((error) => {
|
|
86
|
-
console.log('Get locales errror', error && error.message);
|
|
87
|
-
});
|
|
29
|
+
async start() {
|
|
30
|
+
try {
|
|
31
|
+
addlogs(this.exportConfig, 'Starting locale export', 'success');
|
|
32
|
+
await fileHelper.makeDirectory(this.localesPath);
|
|
33
|
+
await this.getLocales();
|
|
34
|
+
await fileHelper.writeFile(path.join(this.localesPath, this.localeConfig.fileName), this.locales);
|
|
35
|
+
addlogs(this.exportConfig, 'Completed locale export', 'success');
|
|
36
|
+
} catch (error) {
|
|
37
|
+
addlogs(this.exportConfig, chalk.red(`Failed to export locales ${formatError(error)}`), 'error');
|
|
38
|
+
throw new Error('Failed to export locales');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
42
|
+
async getLocales(skip = 0) {
|
|
43
|
+
if (skip) {
|
|
44
|
+
this.qs.skip = skip;
|
|
45
|
+
}
|
|
46
|
+
let localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find();
|
|
47
|
+
if (Array.isArray(localesFetchResponse.items) && localesFetchResponse.items.length > 0) {
|
|
48
|
+
this.sanitizeAttribs(localesFetchResponse.items);
|
|
49
|
+
skip += this.localeConfig.limit || 100;
|
|
50
|
+
if (skip > localesFetchResponse.count) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return await this.getLocales(skip);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
93
56
|
|
|
57
|
+
sanitizeAttribs(locales) {
|
|
58
|
+
locales.forEach((locale) => {
|
|
59
|
+
for (let key in locale) {
|
|
60
|
+
if (this.localeConfig.requiredKeys.indexOf(key) === -1) {
|
|
61
|
+
delete locale[key];
|
|
94
62
|
}
|
|
95
|
-
}
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
});
|
|
63
|
+
}
|
|
64
|
+
this.locales[locale.uid] = locale;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
101
67
|
}
|
|
102
68
|
|
|
103
|
-
module.exports =
|
|
69
|
+
module.exports = LocaleExport;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Contentstack Export
|
|
3
|
+
* Copyright (c) 2019 Contentstack LLC
|
|
4
|
+
* MIT Licensed
|
|
5
|
+
*/
|
|
6
|
+
const _ = require('lodash');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const mkdirp = require('mkdirp');
|
|
10
|
+
const eachOf = require('async/eachOf');
|
|
11
|
+
const { cliux, HttpClient, NodeCrypto } = require('@contentstack/cli-utilities');
|
|
12
|
+
|
|
13
|
+
const { formatError } = require('../util');
|
|
14
|
+
let config = require('../../config/default');
|
|
15
|
+
const { writeFile } = require('../util/helper');
|
|
16
|
+
const { addlogs: log } = require('../util/log');
|
|
17
|
+
let stack = require('../util/contentstack-management-sdk');
|
|
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();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
log(this.config, 'Starting marketplace app export', 'success');
|
|
42
|
+
this.marketplaceAppPath = path.resolve(
|
|
43
|
+
this.config.data,
|
|
44
|
+
this.config.branchName || '',
|
|
45
|
+
this.marketplaceAppConfig.dirName,
|
|
46
|
+
);
|
|
47
|
+
mkdirp.sync(this.marketplaceAppPath);
|
|
48
|
+
|
|
49
|
+
return this.exportInstalledExtensions();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exportInstalledExtensions = () => {
|
|
53
|
+
const self = this;
|
|
54
|
+
|
|
55
|
+
return new Promise(async function (resolve, reject) {
|
|
56
|
+
getInstalledExtensions(self.config)
|
|
57
|
+
.then(async (items) => {
|
|
58
|
+
const installedApps = _.map(
|
|
59
|
+
_.filter(items, 'app_uid'),
|
|
60
|
+
({ uid, title, app_uid, app_installation_uid, type }) => ({
|
|
61
|
+
title,
|
|
62
|
+
uid,
|
|
63
|
+
app_uid,
|
|
64
|
+
app_installation_uid,
|
|
65
|
+
type,
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
const headers = {
|
|
69
|
+
authtoken: self.config.auth_token,
|
|
70
|
+
organization_uid: self.config.org_uid,
|
|
71
|
+
};
|
|
72
|
+
const httpClient = new HttpClient().headers(headers);
|
|
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
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
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
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
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
|
+
};
|