@contentstack/cli-cm-export 1.2.3 → 1.3.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 +74 -22
- package/oclif.manifest.json +128 -1
- package/package.json +8 -9
- package/src/app.js +30 -32
- package/src/commands/cm/stacks/export.js +1 -1
- package/src/lib/export/assets.js +201 -194
- package/src/lib/export/custom-roles.js +7 -16
- package/src/lib/export/entries.js +6 -1
- package/src/lib/export/environments.js +6 -7
- package/src/lib/export/extensions.js +6 -7
- package/src/lib/export/global-fields.js +12 -12
- package/src/lib/export/labels.js +8 -11
- package/src/lib/export/marketplace-apps.js +100 -100
- package/src/lib/export/stack.js +78 -84
- package/src/lib/export/webhooks.js +4 -9
- package/src/lib/export/workflows.js +11 -11
- package/src/lib/util/helper.js +16 -25
- package/src/lib/util/login.js +59 -55
- package/src/lib/util/marketplace-app-helper.js +3 -40
- package/src/lib/util/setup-branches.js +14 -12
- package/src/lib/util/contentstack-management-sdk.js +0 -39
|
@@ -37,6 +37,11 @@ class EntriesExport {
|
|
|
37
37
|
}
|
|
38
38
|
const entryRequestOptions = this.createRequestObjects(locales, contentTypes);
|
|
39
39
|
for (let requestOption of entryRequestOptions) {
|
|
40
|
+
addlogs(
|
|
41
|
+
this.exportConfig,
|
|
42
|
+
`Starting export of entries of content_type - ${requestOption.content_type} locale - ${requestOption.locale}`,
|
|
43
|
+
'info',
|
|
44
|
+
);
|
|
40
45
|
await fileHelper.makeDirectory(path.join(this.entriesRootPath, requestOption.content_type));
|
|
41
46
|
const entries = await this.getEntries(requestOption);
|
|
42
47
|
let entriesFilePath = path.join(
|
|
@@ -44,7 +49,7 @@ class EntriesExport {
|
|
|
44
49
|
requestOption.content_type,
|
|
45
50
|
requestOption.locale + '.json',
|
|
46
51
|
);
|
|
47
|
-
await fileHelper.
|
|
52
|
+
await fileHelper.writeLargeFile(entriesFilePath, entries);
|
|
48
53
|
addlogs(
|
|
49
54
|
this.exportConfig,
|
|
50
55
|
`Exported entries of type ${requestOption.content_type} locale ${requestOption.locale}`,
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const chalk = require('chalk');
|
|
8
8
|
const mkdirp = require('mkdirp');
|
|
9
|
+
const { merge } = require('lodash');
|
|
9
10
|
|
|
10
11
|
const helper = require('../util/helper');
|
|
11
12
|
const { addlogs } = require('../util/log');
|
|
12
13
|
const { formatError } = require('../util');
|
|
13
|
-
let stack = require('../util/contentstack-management-sdk');
|
|
14
14
|
|
|
15
15
|
module.exports = class ExportEnvironments {
|
|
16
16
|
config = {};
|
|
@@ -24,13 +24,13 @@ module.exports = class ExportEnvironments {
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
constructor(
|
|
28
|
-
this.
|
|
27
|
+
constructor(exportConfig, stackAPIClient) {
|
|
28
|
+
this.stackAPIClient = stackAPIClient;
|
|
29
|
+
this.config = merge(this.config, exportConfig);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
start() {
|
|
32
33
|
const self = this;
|
|
33
|
-
const client = stack.Client(self.config);
|
|
34
34
|
const environmentConfig = self.config.modules.environments;
|
|
35
35
|
const environmentsFolderPath = path.resolve(
|
|
36
36
|
self.config.data,
|
|
@@ -43,15 +43,14 @@ module.exports = class ExportEnvironments {
|
|
|
43
43
|
addlogs(self.config, 'Starting environment export', 'success');
|
|
44
44
|
|
|
45
45
|
return new Promise(function (resolve, reject) {
|
|
46
|
-
|
|
47
|
-
.stack({ api_key: self.config.source_stack, management_token: self.config.management_token })
|
|
46
|
+
self.stackAPIClient
|
|
48
47
|
.environment()
|
|
49
48
|
.query(self.requestOptions.qs)
|
|
50
49
|
.find()
|
|
51
50
|
.then((environmentResponse) => {
|
|
52
51
|
if (environmentResponse.items.length !== 0) {
|
|
53
52
|
for (let i = 0, total = environmentResponse.count; i < total; i++) {
|
|
54
|
-
|
|
53
|
+
const envUid = environmentResponse.items[i].uid;
|
|
55
54
|
self.master[envUid] = '';
|
|
56
55
|
self.environments[envUid] = environmentResponse.items[i];
|
|
57
56
|
delete self.environments[envUid].uid;
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
const mkdirp = require('mkdirp');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const chalk = require('chalk');
|
|
10
|
+
const { merge } = require('lodash');
|
|
10
11
|
|
|
11
12
|
const helper = require('../util/helper');
|
|
12
13
|
const { addlogs } = require('../util/log');
|
|
13
14
|
const { formatError } = require('../util');
|
|
14
15
|
let config = require('../../config/default');
|
|
15
|
-
const stack = require('../util/contentstack-management-sdk');
|
|
16
16
|
|
|
17
17
|
module.exports = class ExportExtensions {
|
|
18
18
|
master = {};
|
|
@@ -23,8 +23,9 @@ module.exports = class ExportExtensions {
|
|
|
23
23
|
include_count: true,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
constructor(
|
|
27
|
-
this.
|
|
26
|
+
constructor(exportConfig, stackAPIClient) {
|
|
27
|
+
this.stackAPIClient = stackAPIClient;
|
|
28
|
+
this.config = merge(config, exportConfig);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
start() {
|
|
@@ -38,17 +39,15 @@ module.exports = class ExportExtensions {
|
|
|
38
39
|
);
|
|
39
40
|
// Create folder for extensions
|
|
40
41
|
mkdirp.sync(extensionsFolderPath);
|
|
41
|
-
let client = stack.Client(this.config);
|
|
42
42
|
return new Promise(function (resolve, reject) {
|
|
43
|
-
|
|
44
|
-
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
43
|
+
self.stackAPIClient
|
|
45
44
|
.extension()
|
|
46
45
|
.query(self.queryRequestOptions)
|
|
47
46
|
.find()
|
|
48
47
|
.then((extension) => {
|
|
49
48
|
if (extension.items.length !== 0) {
|
|
50
49
|
for (let i = 0, total = extension.count; i < total; i++) {
|
|
51
|
-
|
|
50
|
+
const extUid = extension.items[i].uid;
|
|
52
51
|
self.master[extUid] = '';
|
|
53
52
|
self.extensions[extUid] = extension.items[i];
|
|
54
53
|
delete self.extensions[extUid].uid;
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const chalk = require('chalk');
|
|
9
9
|
const mkdirp = require('mkdirp');
|
|
10
|
+
const { merge } = require('lodash');
|
|
10
11
|
|
|
11
12
|
const helper = require('../util/helper');
|
|
12
13
|
const { addlogs } = require('../util/log');
|
|
13
14
|
const { formatError } = require('../util');
|
|
14
15
|
let config = require('../../config/default');
|
|
15
|
-
const stack = require('../util/contentstack-management-sdk');
|
|
16
16
|
|
|
17
17
|
module.exports = class ExportGlobalFields {
|
|
18
18
|
limit = 100;
|
|
@@ -25,7 +25,7 @@ module.exports = class ExportGlobalFields {
|
|
|
25
25
|
globalfieldsConfig = config.modules.globalfields;
|
|
26
26
|
validKeys = config.modules.globalfields.validKeys;
|
|
27
27
|
|
|
28
|
-
constructor(
|
|
28
|
+
constructor(exportConfig, stackAPIClient) {
|
|
29
29
|
this.requestOptions = {
|
|
30
30
|
qs: {
|
|
31
31
|
skip: 0,
|
|
@@ -34,7 +34,8 @@ module.exports = class ExportGlobalFields {
|
|
|
34
34
|
include_count: true,
|
|
35
35
|
},
|
|
36
36
|
};
|
|
37
|
-
this.
|
|
37
|
+
this.stackAPIClient = stackAPIClient;
|
|
38
|
+
this.config = merge(config, exportConfig);
|
|
38
39
|
this.globalfieldsFolderPath = path.resolve(
|
|
39
40
|
this.config.data,
|
|
40
41
|
this.config.branchName || '',
|
|
@@ -68,16 +69,9 @@ module.exports = class ExportGlobalFields {
|
|
|
68
69
|
|
|
69
70
|
getGlobalFields(skip, globalFieldConfig) {
|
|
70
71
|
const self = this;
|
|
71
|
-
let client = stack.Client(globalFieldConfig);
|
|
72
|
-
|
|
73
72
|
self.requestOptions.qs.skip = skip;
|
|
74
|
-
|
|
75
73
|
return new Promise(function (resolve, reject) {
|
|
76
|
-
|
|
77
|
-
.stack({
|
|
78
|
-
api_key: globalFieldConfig.source_stack,
|
|
79
|
-
management_token: globalFieldConfig.management_token,
|
|
80
|
-
})
|
|
74
|
+
self.stackAPIClient
|
|
81
75
|
.globalField()
|
|
82
76
|
.query(self.requestOptions.qs)
|
|
83
77
|
.find()
|
|
@@ -107,6 +101,9 @@ module.exports = class ExportGlobalFields {
|
|
|
107
101
|
addlogs(globalFieldConfig, chalk.red(`Failed to export global-fields ${formatError(error)}`), 'error');
|
|
108
102
|
reject(error);
|
|
109
103
|
}
|
|
104
|
+
})
|
|
105
|
+
.catch((error) => {
|
|
106
|
+
reject(error);
|
|
110
107
|
});
|
|
111
108
|
});
|
|
112
109
|
}
|
|
@@ -115,7 +112,10 @@ module.exports = class ExportGlobalFields {
|
|
|
115
112
|
const self = this;
|
|
116
113
|
return new Promise(function (resolve, reject) {
|
|
117
114
|
try {
|
|
118
|
-
helper.writeFileSync(
|
|
115
|
+
helper.writeFileSync(
|
|
116
|
+
path.join(self.globalfieldsFolderPath, self.globalfieldsConfig.fileName),
|
|
117
|
+
self.global_fields,
|
|
118
|
+
);
|
|
119
119
|
addlogs(self.config, chalk.green('Global Fields export completed successfully'), 'success');
|
|
120
120
|
|
|
121
121
|
resolve();
|
package/src/lib/export/labels.js
CHANGED
|
@@ -9,31 +9,28 @@ const chalk = require('chalk');
|
|
|
9
9
|
const mkdirp = require('mkdirp');
|
|
10
10
|
const { merge } = require('lodash');
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const helper = require('../util/helper');
|
|
13
|
+
const { addlogs } = require('../util/log');
|
|
14
14
|
const { formatError } = require('../util');
|
|
15
15
|
const config = require('../../config/default');
|
|
16
|
-
const stack = require('../util/contentstack-management-sdk');
|
|
17
16
|
|
|
18
17
|
module.exports = class ExportLabels {
|
|
19
18
|
labels = {};
|
|
20
19
|
labelConfig = config.modules.labels;
|
|
21
20
|
|
|
22
|
-
constructor(
|
|
23
|
-
this.
|
|
21
|
+
constructor(exportConfig, stackAPIClient) {
|
|
22
|
+
this.stackAPIClient = stackAPIClient;
|
|
23
|
+
this.config = merge(config, exportConfig);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
start() {
|
|
27
27
|
addlogs(this.config, 'Starting labels export', 'success');
|
|
28
|
-
|
|
29
28
|
const self = this;
|
|
30
|
-
const
|
|
31
|
-
let labelsFolderPath = path.resolve(config.data, this.config.branchName || '', self.labelConfig.dirName);
|
|
29
|
+
const labelsFolderPath = path.resolve(config.data, this.config.branchName || '', self.labelConfig.dirName);
|
|
32
30
|
// Create locale folder
|
|
33
31
|
mkdirp.sync(labelsFolderPath);
|
|
34
32
|
return new Promise(function (resolve, reject) {
|
|
35
|
-
return
|
|
36
|
-
.stack({ api_key: self.config.source_stack, management_token: self.config.management_token })
|
|
33
|
+
return self.stackAPIClient
|
|
37
34
|
.label()
|
|
38
35
|
.query()
|
|
39
36
|
.find()
|
|
@@ -42,7 +39,7 @@ module.exports = class ExportLabels {
|
|
|
42
39
|
response.items.forEach(function (label) {
|
|
43
40
|
addlogs(self.config, label.name + ' labels was exported successfully', 'success');
|
|
44
41
|
self.labels[label.uid] = label;
|
|
45
|
-
|
|
42
|
+
const deleteItems = self.config.modules.labels.invalidKeys;
|
|
46
43
|
deleteItems.forEach((e) => delete label[e]);
|
|
47
44
|
});
|
|
48
45
|
addlogs(self.config, chalk.green('All the labels have been exported successfully'), 'success');
|
|
@@ -7,17 +7,18 @@ const _ = require('lodash');
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
const chalk = require('chalk');
|
|
9
9
|
const mkdirp = require('mkdirp');
|
|
10
|
-
const
|
|
11
|
-
const { cliux, HttpClient, NodeCrypto } = require('@contentstack/cli-utilities');
|
|
10
|
+
const { cliux, HttpClient, NodeCrypto, managementSDKClient } = require('@contentstack/cli-utilities');
|
|
12
11
|
|
|
13
12
|
const { formatError } = require('../util');
|
|
14
|
-
|
|
15
|
-
const { writeFileSync } = require('../util/helper');
|
|
13
|
+
const config = require('../../config/default');
|
|
16
14
|
const { addlogs: log } = require('../util/log');
|
|
17
|
-
const {
|
|
15
|
+
const { writeFileSync } = require('../util/helper');
|
|
16
|
+
const { getDeveloperHubUrl } = require('../util/marketplace-app-helper');
|
|
18
17
|
|
|
19
18
|
module.exports = class ExportMarketplaceApps {
|
|
19
|
+
client;
|
|
20
20
|
config;
|
|
21
|
+
httpClient;
|
|
21
22
|
nodeCrypto;
|
|
22
23
|
marketplaceAppPath = null;
|
|
23
24
|
developerHubBaseUrl = null;
|
|
@@ -38,6 +39,13 @@ module.exports = class ExportMarketplaceApps {
|
|
|
38
39
|
return Promise.resolve();
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
await this.getOrgUid();
|
|
43
|
+
|
|
44
|
+
this.httpClient = new HttpClient().headers({
|
|
45
|
+
authtoken: this.config.auth_token,
|
|
46
|
+
organization_uid: this.config.org_uid,
|
|
47
|
+
});
|
|
48
|
+
|
|
41
49
|
log(this.config, 'Starting marketplace app export', 'success');
|
|
42
50
|
this.marketplaceAppPath = path.resolve(
|
|
43
51
|
this.config.data,
|
|
@@ -49,6 +57,22 @@ module.exports = class ExportMarketplaceApps {
|
|
|
49
57
|
return this.exportInstalledExtensions();
|
|
50
58
|
}
|
|
51
59
|
|
|
60
|
+
async getOrgUid() {
|
|
61
|
+
if (this.config.auth_token) {
|
|
62
|
+
const tempAPIClient = await managementSDKClient({ host: this.config.host });
|
|
63
|
+
const tempStackData = await tempAPIClient
|
|
64
|
+
.stack({ api_key: this.config.source_stack })
|
|
65
|
+
.fetch()
|
|
66
|
+
.catch((error) => {
|
|
67
|
+
console.log(error);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (tempStackData && tempStackData.org_uid) {
|
|
71
|
+
this.config.org_uid = tempStackData.org_uid;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
52
76
|
async createNodeCryptoInstance() {
|
|
53
77
|
const cryptoArgs = {};
|
|
54
78
|
|
|
@@ -71,103 +95,79 @@ module.exports = class ExportMarketplaceApps {
|
|
|
71
95
|
this.nodeCrypto = new NodeCrypto(cryptoArgs);
|
|
72
96
|
}
|
|
73
97
|
|
|
74
|
-
exportInstalledExtensions
|
|
75
|
-
const
|
|
76
|
-
const headers = {
|
|
77
|
-
authtoken: self.config.auth_token,
|
|
78
|
-
organization_uid: self.config.org_uid,
|
|
79
|
-
};
|
|
80
|
-
const httpClient = new HttpClient().headers(headers);
|
|
81
|
-
|
|
82
|
-
return new Promise(async function (resolve, reject) {
|
|
83
|
-
getInstalledExtensions(self.config)
|
|
84
|
-
.then(async (items) => {
|
|
85
|
-
const installedApps = _.map(
|
|
86
|
-
_.filter(items, 'app_uid'),
|
|
87
|
-
({ uid, title, app_uid, app_installation_uid, type }) => ({
|
|
88
|
-
title,
|
|
89
|
-
uid,
|
|
90
|
-
app_uid,
|
|
91
|
-
app_installation_uid,
|
|
92
|
-
type,
|
|
93
|
-
}),
|
|
94
|
-
);
|
|
95
|
-
const uniqApps = _.uniqBy(installedApps, 'app_uid');
|
|
96
|
-
|
|
97
|
-
const developerHubApps =
|
|
98
|
-
(await httpClient
|
|
99
|
-
.get(`${self.developerHubBaseUrl}/apps`)
|
|
100
|
-
.then(({ data: { data } }) => data)
|
|
101
|
-
.catch((err) => {
|
|
102
|
-
log(self.config, err, 'error');
|
|
103
|
-
})) || [];
|
|
104
|
-
|
|
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);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (i === 0) {
|
|
141
|
-
log(self.config, `Exported ${app.title} app and it's config.`, 'success');
|
|
142
|
-
}
|
|
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
|
-
}
|
|
149
|
-
});
|
|
150
|
-
})
|
|
151
|
-
.catch((err) => {
|
|
152
|
-
log(self.config, `Failed to export ${app.title} app config ${formatError(error)}`, 'error');
|
|
153
|
-
console.log(err);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
98
|
+
async exportInstalledExtensions() {
|
|
99
|
+
const installedApps = (await this.getAllStackSpecificApps()) || [];
|
|
156
100
|
|
|
157
|
-
|
|
158
|
-
|
|
101
|
+
if (!_.isEmpty(installedApps)) {
|
|
102
|
+
for (const [index, app] of _.entries(installedApps)) {
|
|
103
|
+
await this.getAppConfigurations(installedApps, [+index, app]);
|
|
104
|
+
}
|
|
159
105
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
106
|
+
await writeFileSync(path.join(this.marketplaceAppPath, this.marketplaceAppConfig.fileName), installedApps);
|
|
107
|
+
|
|
108
|
+
log(this.config, chalk.green('All the marketplace apps have been exported successfully'), 'success');
|
|
109
|
+
} else {
|
|
110
|
+
log(this.config, 'No marketplace apps found', 'success');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getAllStackSpecificApps(listOfApps = [], skip = 0) {
|
|
115
|
+
return this.httpClient
|
|
116
|
+
.get(`${this.developerHubBaseUrl}/installations?target_uids=${this.config.source_stack}&skip=${skip}`)
|
|
117
|
+
.then(async ({ data }) => {
|
|
118
|
+
const { data: apps, count } = data;
|
|
119
|
+
|
|
120
|
+
if (!this.nodeCrypto && _.find(apps, (app) => !_.isEmpty(app.configuration))) {
|
|
121
|
+
await this.createNodeCryptoInstance();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
listOfApps.push(
|
|
125
|
+
..._.map(apps, (app) => {
|
|
126
|
+
if (_.has(app, 'configuration')) {
|
|
127
|
+
app['configuration'] = this.nodeCrypto.encrypt(app.configuration || configuration);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return app;
|
|
131
|
+
}),
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
if (count - (skip + 50) > 0) {
|
|
135
|
+
return await this.getAllStackSpecificApps(listOfApps, skip + 50);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return listOfApps;
|
|
139
|
+
})
|
|
140
|
+
.catch((error) => {
|
|
141
|
+
log(self.config, `Failed to export marketplace-apps ${formatError(error)}`, 'error');
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getAppConfigurations(installedApps, [index, app]) {
|
|
146
|
+
const appName = app.manifest.name;
|
|
147
|
+
log(this.config, `Exporting ${appName} app and it's config.`, 'success');
|
|
148
|
+
|
|
149
|
+
return this.httpClient
|
|
150
|
+
.get(`${this.developerHubBaseUrl}/installations/${app.uid}/installationData`)
|
|
151
|
+
.then(async ({ data: result }) => {
|
|
152
|
+
const { data, error } = result;
|
|
153
|
+
|
|
154
|
+
if (_.has(data, 'server_configuration')) {
|
|
155
|
+
if (!this.nodeCrypto && _.has(data, 'server_configuration')) {
|
|
156
|
+
await this.createNodeCryptoInstance();
|
|
163
157
|
}
|
|
164
158
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
159
|
+
if (!_.isEmpty(data.server_configuration)) {
|
|
160
|
+
installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration);
|
|
161
|
+
log(this.config, `Exported ${appName} app and it's config.`, 'success');
|
|
162
|
+
} else {
|
|
163
|
+
log(this.config, `Exported ${appName} app`, 'success');
|
|
164
|
+
}
|
|
165
|
+
} else if (error) {
|
|
166
|
+
log(this.config, `Error on exporting ${appName} app and it's config.`, 'error');
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
.catch((err) => {
|
|
170
|
+
log(this.config, `Failed to export ${appName} app config ${formatError(err)}`, 'error');
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
173
|
};
|
package/src/lib/export/stack.js
CHANGED
|
@@ -4,102 +4,96 @@
|
|
|
4
4
|
* MIT Licensed
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const mkdirp = require('mkdirp');
|
|
9
|
+
const { merge } = require('lodash');
|
|
10
|
+
const helper = require('../util/helper');
|
|
11
|
+
const { addlogs } = require('../util/log');
|
|
12
|
+
const config = require('../../config/default');
|
|
13
|
+
const { managementSDKClient } = require('@contentstack/cli-utilities');
|
|
14
|
+
module.exports = class ExportStack {
|
|
15
|
+
stackConfig = config.modules.stack;
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
constructor(exportConfig, stackAPIClient, APIClient) {
|
|
18
|
+
this.config = merge(config, exportConfig);
|
|
19
|
+
this.stackAPIClient = stackAPIClient;
|
|
20
|
+
this.APIClient = APIClient;
|
|
21
|
+
this.requestOption = {
|
|
22
|
+
uri: this.config.host + this.config.apis.stacks,
|
|
23
|
+
headers: this.config.headers,
|
|
24
|
+
json: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
async start() {
|
|
29
|
+
const self = this;
|
|
30
|
+
if (self.config.auth_token) {
|
|
31
|
+
const tempAPIClient = await managementSDKClient({ host: config.host });
|
|
32
|
+
const tempStackData = await tempAPIClient
|
|
33
|
+
.stack({ api_key: self.config.source_stack })
|
|
34
|
+
.fetch()
|
|
35
|
+
.catch((error) => {
|
|
36
|
+
console.log(error);
|
|
37
|
+
});
|
|
17
38
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
}
|
|
39
|
+
if (tempStackData && tempStackData.org_uid) {
|
|
40
|
+
self.config.org_uid = tempStackData.org_uid;
|
|
41
|
+
self.config.sourceStackName = tempStackData.name;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
25
44
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
if (!self.config.preserveStackVersion && !self.config.hasOwnProperty('master_locale')) {
|
|
46
|
+
const apiDetails = {
|
|
47
|
+
limit: 100,
|
|
48
|
+
skip: 0,
|
|
49
|
+
include_count: true,
|
|
50
|
+
};
|
|
51
|
+
return self.getLocales(apiDetails);
|
|
52
|
+
} else if (self.config.preserveStackVersion) {
|
|
53
|
+
addlogs(self.config, 'Exporting stack details', 'success');
|
|
54
|
+
let stackFolderPath = path.resolve(self.config.data, stackConfig.dirName);
|
|
55
|
+
let stackContentsFile = path.resolve(stackFolderPath, stackConfig.fileName);
|
|
30
56
|
|
|
31
|
-
|
|
32
|
-
if (config.auth_token) {
|
|
33
|
-
const stack = await client
|
|
34
|
-
.stack({ api_key: config.source_stack, authtoken: config.auth_token })
|
|
35
|
-
.fetch()
|
|
36
|
-
.catch((error) => {
|
|
37
|
-
console.log(error);
|
|
38
|
-
});
|
|
57
|
+
mkdirp.sync(stackFolderPath);
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
return self.APIClient.stack({ api_key: self.config.source_stack })
|
|
61
|
+
.fetch()
|
|
62
|
+
.then((response) => {
|
|
63
|
+
helper.writeFile(stackContentsFile, response);
|
|
64
|
+
addlogs(self.config, 'Exported stack details successfully!', 'success');
|
|
65
|
+
return resolve(response);
|
|
66
|
+
})
|
|
67
|
+
.catch(reject);
|
|
68
|
+
});
|
|
43
69
|
}
|
|
44
70
|
}
|
|
45
71
|
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
limit: 100,
|
|
49
|
-
skip: 0,
|
|
50
|
-
include_count: true,
|
|
51
|
-
};
|
|
52
|
-
return self.getLocales(apiDetails);
|
|
53
|
-
} else if (config.preserveStackVersion) {
|
|
54
|
-
addlogs(config, 'Exporting stack details', 'success');
|
|
55
|
-
let stackFolderPath = path.resolve(config.data, stackConfig.dirName);
|
|
56
|
-
let stackContentsFile = path.resolve(stackFolderPath, stackConfig.fileName);
|
|
57
|
-
|
|
58
|
-
mkdirp.sync(stackFolderPath);
|
|
59
|
-
|
|
72
|
+
getLocales(apiDetails) {
|
|
73
|
+
const self = this;
|
|
60
74
|
return new Promise((resolve, reject) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
const result = self.stackAPIClient.locale().query(apiDetails);
|
|
76
|
+
|
|
77
|
+
result
|
|
78
|
+
.find()
|
|
64
79
|
.then((response) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
const masterLocalObj = response.items.find((obj) => {
|
|
81
|
+
if (obj.fallback_locale === null) {
|
|
82
|
+
return obj;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
apiDetails.skip += apiDetails.limit;
|
|
86
|
+
if (masterLocalObj) {
|
|
87
|
+
return resolve(masterLocalObj);
|
|
88
|
+
} else if (apiDetails.skip <= response.count) {
|
|
89
|
+
return resolve(self.getLocales(apiDetails));
|
|
90
|
+
} else {
|
|
91
|
+
return reject('Master locale not found');
|
|
92
|
+
}
|
|
68
93
|
})
|
|
69
|
-
.catch(
|
|
94
|
+
.catch((error) => {
|
|
95
|
+
return reject(error);
|
|
96
|
+
});
|
|
70
97
|
});
|
|
71
98
|
}
|
|
72
99
|
};
|
|
73
|
-
|
|
74
|
-
ExportStack.prototype.getLocales = function (apiDetails) {
|
|
75
|
-
let self = this;
|
|
76
|
-
return new Promise((resolve, reject) => {
|
|
77
|
-
const result = client
|
|
78
|
-
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
79
|
-
.locale()
|
|
80
|
-
.query(apiDetails);
|
|
81
|
-
|
|
82
|
-
result
|
|
83
|
-
.find()
|
|
84
|
-
.then((response) => {
|
|
85
|
-
const masterLocalObj = response.items.find((obj) => {
|
|
86
|
-
if (obj.fallback_locale === null) {
|
|
87
|
-
return obj;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
apiDetails.skip += apiDetails.limit;
|
|
91
|
-
if (masterLocalObj) {
|
|
92
|
-
return resolve(masterLocalObj);
|
|
93
|
-
} else if (apiDetails.skip <= response.count) {
|
|
94
|
-
return resolve(self.getLocales(apiDetails));
|
|
95
|
-
} else {
|
|
96
|
-
return reject('Master locale not found');
|
|
97
|
-
}
|
|
98
|
-
})
|
|
99
|
-
.catch((error) => {
|
|
100
|
-
return reject(error);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
module.exports = ExportStack;
|