@contentstack/cli-cm-export 1.0.0 → 1.1.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 +3 -3
- package/src/app.js +24 -18
- package/src/commands/cm/stacks/export.js +7 -0
- package/src/config/default.js +19 -1
- package/src/lib/export/custom-roles.js +91 -0
- package/src/lib/export/marketplace-apps.js +154 -0
- package/src/lib/export/stack.js +16 -1
- package/src/lib/export/workflows.js +46 -15
- package/src/lib/util/marketplace-app-helper.js +42 -0
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.
|
|
41
|
+
@contentstack/cli-cm-export/1.1.0 darwin-arm64 node-v16.17.0
|
|
42
42
|
$ csdx --help [COMMAND]
|
|
43
43
|
USAGE
|
|
44
44
|
$ csdx COMMAND
|
|
@@ -83,5 +83,5 @@ EXAMPLES
|
|
|
83
83
|
csdx cm:stacks:export --branch [optional] branch name
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
_See code: [src/commands/cm/stacks/export.js](https://github.com/contentstack/cli/blob/v1.
|
|
86
|
+
_See code: [src/commands/cm/stacks/export.js](https://github.com/contentstack/cli/blob/v1.1.0/packages/contentstack-export/src/commands/cm/stacks/export.js)_
|
|
87
87
|
<!-- commandsstop -->
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.
|
|
1
|
+
{"version":"1.1.0","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":[]}}}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-export",
|
|
3
3
|
"description": "Contentstack CLI plugin to export content from stack",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
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.
|
|
8
|
+
"@contentstack/cli-command": "^1.0.1",
|
|
9
|
+
"@contentstack/cli-utilities": "^1.0.2",
|
|
10
10
|
"@contentstack/management": "^1.3.0",
|
|
11
11
|
"@oclif/command": "^1.8.16",
|
|
12
12
|
"@oclif/config": "^1.18.3",
|
package/src/app.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-redeclare */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var { addlogs, unlinkFileLogger } = require('./lib/util/log');
|
|
5
|
-
const setupBranches = require('./lib/util/setup-branches');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
const path = require('path');
|
|
6
4
|
const chalk = require('chalk');
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const util = require('./lib/util');
|
|
6
|
+
const login = require('./lib/util/login');
|
|
7
|
+
const setupBranches = require('./lib/util/setup-branches');
|
|
8
|
+
const { addlogs, unlinkFileLogger } = require('./lib/util/log');
|
|
9
9
|
|
|
10
10
|
exports.initial = async function (config) {
|
|
11
11
|
return new Promise(async function (resolve, reject) {
|
|
@@ -17,7 +17,8 @@ exports.initial = async function (config) {
|
|
|
17
17
|
|
|
18
18
|
const fetchBranchAndExport = async () => {
|
|
19
19
|
await setupBranches(config, config.branchName);
|
|
20
|
-
|
|
20
|
+
let types = config.modules.types;
|
|
21
|
+
|
|
21
22
|
if (Array.isArray(config.branches) && config.branches.length > 0) {
|
|
22
23
|
for (let branch of config.branches) {
|
|
23
24
|
config.branchName = branch.uid;
|
|
@@ -75,7 +76,7 @@ exports.initial = async function (config) {
|
|
|
75
76
|
});
|
|
76
77
|
};
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
const singleExport = async (moduleName, types, config, branchName) => {
|
|
79
80
|
try {
|
|
80
81
|
if (types.indexOf(moduleName) > -1) {
|
|
81
82
|
let iterateList;
|
|
@@ -86,10 +87,13 @@ var singleExport = async (moduleName, types, config, branchName) => {
|
|
|
86
87
|
}
|
|
87
88
|
iterateList.push(moduleName);
|
|
88
89
|
|
|
89
|
-
for (
|
|
90
|
-
|
|
91
|
-
const result = await exportedModule.start(config, branchName)
|
|
92
|
-
|
|
90
|
+
for (const element of iterateList) {
|
|
91
|
+
let exportedModule = require('./lib/export/' + element);
|
|
92
|
+
const result = await exportedModule.start(config, branchName)
|
|
93
|
+
.catch((error) => {
|
|
94
|
+
console.log(error && error.message)
|
|
95
|
+
});
|
|
96
|
+
if (result && element === 'stack') {
|
|
93
97
|
let master_locale = {
|
|
94
98
|
master_locale: { code: result.code },
|
|
95
99
|
};
|
|
@@ -110,14 +114,16 @@ var singleExport = async (moduleName, types, config, branchName) => {
|
|
|
110
114
|
}
|
|
111
115
|
};
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
// eslint-disable-next-line no-async-promise-executor
|
|
117
|
+
const allExport = async (config, types, branchName) => {
|
|
115
118
|
return new Promise(async (resolve, reject) => {
|
|
116
119
|
try {
|
|
117
|
-
for (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
for (const type of types) {
|
|
121
|
+
const exportedModule = require('./lib/export/' + type);
|
|
122
|
+
const result = await exportedModule.start(config, branchName)
|
|
123
|
+
.catch((error) => {
|
|
124
|
+
console.log(error && error.message)
|
|
125
|
+
});
|
|
126
|
+
|
|
121
127
|
if (result && type === 'stack') {
|
|
122
128
|
let master_locale = { master_locale: { code: result.code } };
|
|
123
129
|
config = _.merge(config, master_locale);
|
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
parametersWithAuthToken,
|
|
11
11
|
withoutParametersWithAuthToken,
|
|
12
12
|
} = require('../../../lib/util/export-flags');
|
|
13
|
+
const config = require('../../../config/default');
|
|
13
14
|
const { configHandler } = require('@contentstack/cli-utilities');
|
|
14
15
|
|
|
15
16
|
class ExportCommand extends Command {
|
|
@@ -32,6 +33,12 @@ class ExportCommand extends Command {
|
|
|
32
33
|
|
|
33
34
|
if (alias) {
|
|
34
35
|
let managementTokens = this.getToken(alias);
|
|
36
|
+
|
|
37
|
+
if (alias) {
|
|
38
|
+
const listOfTokens = configHandler.get('tokens');
|
|
39
|
+
config.management_token_data = listOfTokens[alias];
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
if (managementTokens) {
|
|
36
43
|
if (extConfig) {
|
|
37
44
|
await configWithMToken(
|
package/src/config/default.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
versioning: false,
|
|
3
3
|
host: 'https://api.contentstack.io/v3',
|
|
4
|
+
developerHubUrls: {
|
|
5
|
+
// NOTE CDA url used as developer-hub url mapper to avoid conflict if user used any custom name
|
|
6
|
+
'https://api.contentstack.io': 'https://developerhub-api.contentstack.com',
|
|
7
|
+
'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com',
|
|
8
|
+
'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com',
|
|
9
|
+
'https://stag-api.csnonprod.com': 'https://stag-developerhub-api.csnonprod.com'
|
|
10
|
+
},
|
|
4
11
|
// use below hosts for eu region
|
|
5
12
|
// host:'https://eu-api.contentstack.com/v3',
|
|
6
13
|
// use below hosts for azure-na region
|
|
@@ -15,15 +22,22 @@ module.exports = {
|
|
|
15
22
|
'webhooks',
|
|
16
23
|
'global-fields',
|
|
17
24
|
'content-types',
|
|
25
|
+
'custom-roles',
|
|
18
26
|
'workflows',
|
|
19
27
|
'entries',
|
|
20
28
|
'labels',
|
|
29
|
+
'marketplace-apps'
|
|
21
30
|
],
|
|
22
31
|
locales: {
|
|
23
32
|
dirName: 'locales',
|
|
24
33
|
fileName: 'locales.json',
|
|
25
34
|
requiredKeys: ['code', 'uid', 'name', 'fallback_locale'],
|
|
26
35
|
},
|
|
36
|
+
customRoles: {
|
|
37
|
+
dirName: 'custom-roles',
|
|
38
|
+
fileName: 'custom-roles.json',
|
|
39
|
+
customRolesLocalesFileName: 'custom-roles-locales.json',
|
|
40
|
+
},
|
|
27
41
|
environments: {
|
|
28
42
|
dirName: 'environments',
|
|
29
43
|
fileName: 'environments.json',
|
|
@@ -101,6 +115,10 @@ module.exports = {
|
|
|
101
115
|
dependency: {
|
|
102
116
|
entries: ['stack', 'locales', 'content-types'],
|
|
103
117
|
},
|
|
118
|
+
marketplace_apps: {
|
|
119
|
+
dirName: 'marketplace_apps',
|
|
120
|
+
fileName: 'marketplace_apps.json'
|
|
121
|
+
}
|
|
104
122
|
},
|
|
105
123
|
languagesCode: [
|
|
106
124
|
'af-za',
|
|
@@ -326,5 +344,5 @@ module.exports = {
|
|
|
326
344
|
webhooks: '/webhooks/',
|
|
327
345
|
stacks: '/stacks/',
|
|
328
346
|
},
|
|
329
|
-
preserveStackVersion: false
|
|
347
|
+
preserveStackVersion: false
|
|
330
348
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const mkdirp = require('mkdirp');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
const helper = require('../util/helper');
|
|
8
|
+
const { addlogs } = require('../util/log');
|
|
9
|
+
|
|
10
|
+
const stack = require('../util/contentstack-management-sdk');
|
|
11
|
+
let config = require('../../config/default');
|
|
12
|
+
const rolesConfig = config.modules.customRoles;
|
|
13
|
+
|
|
14
|
+
const EXISTING_ROLES = {
|
|
15
|
+
Admin: 1,
|
|
16
|
+
Developer: 1,
|
|
17
|
+
'Content Manager': 1,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function ExportCustomRoles() {
|
|
21
|
+
this.client = null;
|
|
22
|
+
this.roles = {};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
ExportCustomRoles.prototype.start = async function (credentialConfig) {
|
|
26
|
+
try {
|
|
27
|
+
addlogs(config, 'Starting roles export', 'success');
|
|
28
|
+
let self = this;
|
|
29
|
+
this.roles = {};
|
|
30
|
+
config = credentialConfig;
|
|
31
|
+
this.client = stack.Client(config);
|
|
32
|
+
|
|
33
|
+
const rolesFolderPath = path.resolve(config.data, config.branchName || '', rolesConfig.dirName);
|
|
34
|
+
mkdirp.sync(rolesFolderPath);
|
|
35
|
+
|
|
36
|
+
const roles = await this.client
|
|
37
|
+
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
38
|
+
.role()
|
|
39
|
+
.fetchAll({ include_rules: true, include_permissions: true });
|
|
40
|
+
|
|
41
|
+
const customRoles = roles.items.filter(role => !EXISTING_ROLES[role.name]);
|
|
42
|
+
|
|
43
|
+
if (!customRoles.length) {
|
|
44
|
+
addlogs(config, 'No custom roles were found in the Stack', 'success');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
await getCustomRolesLocales(customRoles, path.join(rolesFolderPath, rolesConfig.customRolesLocalesFileName), this.client, config);
|
|
49
|
+
self.customRoles = {};
|
|
50
|
+
customRoles.forEach(role => {
|
|
51
|
+
addlogs(config, role.name + ' role was exported successfully', 'success');
|
|
52
|
+
self.customRoles[role.uid] = role;
|
|
53
|
+
});
|
|
54
|
+
helper.writeFile(path.join(rolesFolderPath, rolesConfig.fileName), self.customRoles);
|
|
55
|
+
addlogs(config, chalk.green('All the custom roles have been exported successfully'), 'success');
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (error.statusCode === 401) {
|
|
58
|
+
addlogs(config, chalk.red('You are not allowed to export roles, Unless you provide email and password in config'), 'error');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
addlogs(config, 'Error occurred in exporting roles. ' + error && error.message, 'error');
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
async function getCustomRolesLocales(customRoles, customRolesLocalesFilepath, client, config) {
|
|
67
|
+
const localesMap = {};
|
|
68
|
+
for (const role of customRoles) {
|
|
69
|
+
const rulesLocales = role.rules.find(rule => rule.module === 'locale');
|
|
70
|
+
if (rulesLocales.locales && rulesLocales.locales.length) {
|
|
71
|
+
rulesLocales.locales.forEach(locale => {
|
|
72
|
+
localesMap[locale] = 1;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (Object.keys(localesMap).length) {
|
|
78
|
+
const locales = await client.stack({ api_key: config.source_stack, management_token: config.management_token }).locale().query({}).find();
|
|
79
|
+
const sourceLocalesMap = {};
|
|
80
|
+
for (const locale of locales.items) {
|
|
81
|
+
sourceLocalesMap[locale.uid] = locale;
|
|
82
|
+
}
|
|
83
|
+
for (const locale in localesMap) {
|
|
84
|
+
delete sourceLocalesMap[locale]['stackHeaders'];
|
|
85
|
+
localesMap[locale] = sourceLocalesMap[locale];
|
|
86
|
+
}
|
|
87
|
+
helper.writeFile(customRolesLocalesFilepath, localesMap);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = new ExportCustomRoles();
|
|
@@ -0,0 +1,154 @@
|
|
|
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, configHandler, HttpClient, NodeCrypto } = require('@contentstack/cli-utilities');
|
|
12
|
+
|
|
13
|
+
let config = require('../../config/default');
|
|
14
|
+
const { writeFile } = require('../util/helper');
|
|
15
|
+
const { addlogs: log } = require('../util/log');
|
|
16
|
+
let stack = require('../util/contentstack-management-sdk');
|
|
17
|
+
const { getInstalledExtensions } = require('../util/marketplace-app-helper')
|
|
18
|
+
|
|
19
|
+
let client
|
|
20
|
+
let marketplaceAppConfig = config.modules.marketplace_apps;
|
|
21
|
+
|
|
22
|
+
function exportMarketplaceApps() {
|
|
23
|
+
this.marketplaceAppPath = null
|
|
24
|
+
this.developerHuBaseUrl = null
|
|
25
|
+
this.start = async (credentialConfig) => {
|
|
26
|
+
config = credentialConfig;
|
|
27
|
+
client = stack.Client(config);
|
|
28
|
+
this.developerHuBaseUrl = await this.getDeveloperHubUrl()
|
|
29
|
+
|
|
30
|
+
if (!config.auth_token) {
|
|
31
|
+
cliux.print('WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' })
|
|
32
|
+
return Promise.resolve()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
log(credentialConfig, 'Starting marketplace app export', 'success');
|
|
36
|
+
this.marketplaceAppPath = path.resolve(
|
|
37
|
+
config.data, config.branchName || '',
|
|
38
|
+
marketplaceAppConfig.dirName
|
|
39
|
+
);
|
|
40
|
+
mkdirp.sync(this.marketplaceAppPath);
|
|
41
|
+
|
|
42
|
+
return this.exportInstalledExtensions()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.exportInstalledExtensions = () => {
|
|
46
|
+
const self = this
|
|
47
|
+
|
|
48
|
+
return new Promise(async function (resolve, reject) {
|
|
49
|
+
getInstalledExtensions(config)
|
|
50
|
+
.then(async (items) => {
|
|
51
|
+
const installedApps = _.map(
|
|
52
|
+
_.filter(items, 'app_uid'),
|
|
53
|
+
({ uid, title, app_uid, app_installation_uid, type }) => ({ title, uid, app_uid, app_installation_uid, type })
|
|
54
|
+
)
|
|
55
|
+
const headers = {
|
|
56
|
+
authtoken: config.auth_token,
|
|
57
|
+
organization_uid: config.org_uid
|
|
58
|
+
}
|
|
59
|
+
const httpClient = new HttpClient().headers(headers);
|
|
60
|
+
const nodeCrypto = new NodeCrypto()
|
|
61
|
+
const developerHubApps = await httpClient.get(`${self.developerHuBaseUrl}/apps`)
|
|
62
|
+
.then(({ data: { data } }) => data)
|
|
63
|
+
.catch(err => {
|
|
64
|
+
console.log(err)
|
|
65
|
+
}) || []
|
|
66
|
+
|
|
67
|
+
eachOf(_.uniqBy(installedApps, 'app_uid'), (app, _key, cb) => {
|
|
68
|
+
log(config, `Exporting ${app.title} app and it's config.`, 'success')
|
|
69
|
+
const listOfIndexToBeUpdated = _.map(
|
|
70
|
+
installedApps,
|
|
71
|
+
({ app_uid }, index) => (app_uid === app.app_uid ? index : undefined)
|
|
72
|
+
).filter(val => val !== undefined)
|
|
73
|
+
|
|
74
|
+
httpClient.get(`${self.developerHuBaseUrl}/installations/${app.app_installation_uid}/installationData`)
|
|
75
|
+
.then(({ data: result }) => {
|
|
76
|
+
const { data, error } = result
|
|
77
|
+
const developerHubApp = _.find(developerHubApps, { uid: app.app_uid })
|
|
78
|
+
|
|
79
|
+
_.forEach(listOfIndexToBeUpdated, (index, i) => {
|
|
80
|
+
if (developerHubApp) {
|
|
81
|
+
installedApps[index]['visibility'] = developerHubApp.visibility
|
|
82
|
+
installedApps[index]['manifest'] = _.pick(
|
|
83
|
+
developerHubApp,
|
|
84
|
+
['name', 'description', 'icon', 'target_type', 'ui_location', 'webhook', 'oauth'] // NOTE keys can be passed to install new app in the developer hub
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (_.has(data, 'configuration') || _.has(data, 'server_configuration')) {
|
|
89
|
+
const { configuration, server_configuration } = data
|
|
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)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (i === 0) {
|
|
99
|
+
log(config, `Exported ${app.title} app and it's config.`, 'success')
|
|
100
|
+
}
|
|
101
|
+
} else if (error) {
|
|
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
|
+
})
|
|
108
|
+
|
|
109
|
+
cb()
|
|
110
|
+
})
|
|
111
|
+
.catch(err => {
|
|
112
|
+
console.log(err)
|
|
113
|
+
cb()
|
|
114
|
+
})
|
|
115
|
+
}, () => {
|
|
116
|
+
if (!_.isEmpty(installedApps)) {
|
|
117
|
+
writeFile(
|
|
118
|
+
path.join(self.marketplaceAppPath, marketplaceAppConfig.fileName),
|
|
119
|
+
installedApps
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
log(config, chalk.green('All the marketplace apps have been exported successfully'), 'success')
|
|
123
|
+
} else {
|
|
124
|
+
log(config, 'No marketplace apps found', 'success')
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
resolve()
|
|
128
|
+
})
|
|
129
|
+
}).catch(reject)
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.getDeveloperHubUrl = async () => {
|
|
134
|
+
const { cma, name } = configHandler.get('region') || {}
|
|
135
|
+
let developerHubBaseUrl = config.developerHubUrls[cma]
|
|
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();
|
package/src/lib/export/stack.js
CHANGED
|
@@ -26,10 +26,25 @@ function ExportStack() {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
ExportStack.prototype.start = function (credentialConfig) {
|
|
29
|
+
ExportStack.prototype.start = async function (credentialConfig) {
|
|
30
30
|
config = credentialConfig;
|
|
31
31
|
client = stack.Client(config);
|
|
32
32
|
const self = this
|
|
33
|
+
|
|
34
|
+
// NOTE get org uid
|
|
35
|
+
if (config.auth_token) {
|
|
36
|
+
const stack = await client
|
|
37
|
+
.stack({ api_key: config.source_stack, authtoken: config.auth_token })
|
|
38
|
+
.fetch()
|
|
39
|
+
.catch((error) => {
|
|
40
|
+
console.log(error)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (stack && stack.org_uid) {
|
|
44
|
+
config.org_uid = stack.org_uid
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
if (!config.preserveStackVersion && !config.hasOwnProperty('master_locale')) {
|
|
34
49
|
const apiDetails = {
|
|
35
50
|
limit: 100,
|
|
@@ -29,26 +29,25 @@ ExportWorkFlows.prototype.start = function (credentialConfig) {
|
|
|
29
29
|
|
|
30
30
|
let workflowsFolderPath = path.resolve(config.data, config.branchName || '', workFlowConfig.dirName);
|
|
31
31
|
mkdirp.sync(workflowsFolderPath);
|
|
32
|
-
return new Promise(function (resolve) {
|
|
32
|
+
return new Promise(function (resolve, reject) {
|
|
33
33
|
return client
|
|
34
34
|
.stack({ api_key: config.source_stack, management_token: config.management_token })
|
|
35
35
|
.workflow()
|
|
36
36
|
.fetchAll()
|
|
37
|
-
.then((response) => {
|
|
38
|
-
|
|
39
|
-
response.items.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
.then(async (response) => {
|
|
38
|
+
try {
|
|
39
|
+
if (response.items.length) {
|
|
40
|
+
await getWorkflowsData(self, response.items);
|
|
41
|
+
addlogs(config, chalk.green('All the workflow have been exported successfully'), 'success');
|
|
42
|
+
}
|
|
43
|
+
if (!response.items.length) {
|
|
44
|
+
addlogs(config, 'No workflow were found in the Stack', 'success');
|
|
45
|
+
}
|
|
46
|
+
helper.writeFile(path.join(workflowsFolderPath, workFlowConfig.fileName), self.workflows);
|
|
47
|
+
return resolve();
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return reject(error);
|
|
49
50
|
}
|
|
50
|
-
helper.writeFile(path.join(workflowsFolderPath, workFlowConfig.fileName), self.workflows);
|
|
51
|
-
return resolve();
|
|
52
51
|
})
|
|
53
52
|
.catch(function (error) {
|
|
54
53
|
if (error.statusCode === 401) {
|
|
@@ -67,4 +66,36 @@ ExportWorkFlows.prototype.start = function (credentialConfig) {
|
|
|
67
66
|
});
|
|
68
67
|
};
|
|
69
68
|
|
|
69
|
+
const getWorkflowsData = async (self, workflows) => {
|
|
70
|
+
try {
|
|
71
|
+
for (const workflow of workflows) {
|
|
72
|
+
addlogs(config, workflow.name + ' workflow was exported successfully', 'success');
|
|
73
|
+
await getWorkflowRoles(workflow);
|
|
74
|
+
self.workflows[workflow.uid] = workflow;
|
|
75
|
+
let deleteItems = config.modules.workflows.invalidKeys;
|
|
76
|
+
deleteItems.forEach((e) => delete workflow[e]);
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const getWorkflowRoles = async (workflow) => {
|
|
84
|
+
try {
|
|
85
|
+
for (const stage of workflow.workflow_stages) {
|
|
86
|
+
if (stage.SYS_ACL.roles.uids.length) {
|
|
87
|
+
for (let i = 0; i < stage.SYS_ACL.roles.uids.length; i++) {
|
|
88
|
+
const roleUid = stage.SYS_ACL.roles.uids[i];
|
|
89
|
+
const roleData = await client.stack({ api_key: config.source_stack, management_token: config.management_token }).role(roleUid).fetch({ include_rules: true, include_permissions: true });
|
|
90
|
+
stage.SYS_ACL.roles.uids[i] = roleData;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.log('Error getting roles', error && error.message);
|
|
96
|
+
addlogs(config, 'Error fetching roles in export workflows task.', 'error');
|
|
97
|
+
throw { message: 'Error fetching roles in export workflows task.' };
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
70
101
|
module.exports = new ExportWorkFlows();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const sdk = require('./contentstack-management-sdk');
|
|
2
|
+
const { HttpClient } = require('@contentstack/cli-utilities');
|
|
3
|
+
|
|
4
|
+
const getInstalledExtensions = (config) => {
|
|
5
|
+
const client = sdk.Client(config)
|
|
6
|
+
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const queryRequestOptions = {
|
|
9
|
+
include_marketplace_extensions: true
|
|
10
|
+
}
|
|
11
|
+
const {
|
|
12
|
+
management_token_data: { apiKey: api_key, token: management_token } = { apiKey: config.source_stack },
|
|
13
|
+
auth_token
|
|
14
|
+
} = config || { management_token_data: {} }
|
|
15
|
+
|
|
16
|
+
if (api_key && management_token) {
|
|
17
|
+
client
|
|
18
|
+
.stack({ api_key, management_token })
|
|
19
|
+
.extension()
|
|
20
|
+
.query(queryRequestOptions)
|
|
21
|
+
.find()
|
|
22
|
+
.then(({ items }) => resolve(items))
|
|
23
|
+
.catch(reject)
|
|
24
|
+
} else if (api_key && auth_token) {
|
|
25
|
+
const headers = {
|
|
26
|
+
api_key,
|
|
27
|
+
authtoken: auth_token
|
|
28
|
+
}
|
|
29
|
+
const httpClient = new HttpClient().headers(headers);
|
|
30
|
+
const baseUrl = config.host.startsWith('http')
|
|
31
|
+
? config.host
|
|
32
|
+
: `https://${config.host}/v3`;
|
|
33
|
+
httpClient.get(`${baseUrl}/extensions/?include_marketplace_extensions=true`)
|
|
34
|
+
.then(({ data: { extensions } }) => resolve(extensions))
|
|
35
|
+
.catch(reject)
|
|
36
|
+
} else {
|
|
37
|
+
resolve([])
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { getInstalledExtensions }
|