@contentstack/cli-cm-import 1.8.4 → 1.9.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 +1 -1
- package/bin/dev +4 -15
- package/lib/commands/cm/stacks/import.js +5 -2
- package/lib/config/index.js +2 -16
- package/lib/import/module-importer.js +2 -5
- package/lib/import/modules/assets.js +5 -2
- package/lib/import/modules/base-class.js +29 -14
- package/lib/import/modules/custom-roles.d.ts +1 -1
- package/lib/import/modules/custom-roles.js +12 -7
- package/lib/import/modules/entries.js +119 -68
- package/lib/import/modules/environments.d.ts +1 -1
- package/lib/import/modules/environments.js +3 -4
- package/lib/import/modules/extensions.js +3 -4
- package/lib/import/modules/global-fields.js +3 -2
- package/lib/import/modules/labels.d.ts +2 -2
- package/lib/import/modules/labels.js +6 -7
- package/lib/import/modules/marketplace-apps.d.ts +1 -0
- package/lib/import/modules/marketplace-apps.js +11 -5
- package/lib/import/modules/webhooks.d.ts +1 -1
- package/lib/import/modules/webhooks.js +3 -4
- package/lib/import/modules/workflows.js +6 -6
- package/lib/import/modules-js/marketplace-apps.d.ts +1 -0
- package/lib/import/modules-js/marketplace-apps.js +9 -2
- package/lib/types/default-config.d.ts +0 -2
- package/lib/types/import-config.d.ts +1 -0
- package/lib/utils/asset-helper.d.ts +1 -1
- package/lib/utils/backup-handler.js +37 -17
- package/lib/utils/entries-helper.d.ts +6 -3
- package/lib/utils/entries-helper.js +11 -10
- package/lib/utils/import-config-handler.js +7 -0
- package/lib/utils/logger.js +1 -1
- package/lib/utils/marketplace-app-helper.js +9 -2
- package/oclif.manifest.json +1 -1
- package/package.json +5 -4
|
@@ -4,13 +4,12 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
8
7
|
const utils_1 = require("../../utils");
|
|
9
8
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
9
|
class ImportEnvironments extends base_class_1.default {
|
|
11
10
|
constructor({ importConfig, stackAPIClient }) {
|
|
12
11
|
super({ importConfig, stackAPIClient });
|
|
13
|
-
this.environmentsConfig =
|
|
12
|
+
this.environmentsConfig = importConfig.modules.environments;
|
|
14
13
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'environments');
|
|
15
14
|
this.environmentsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.environmentsConfig.dirName);
|
|
16
15
|
this.envUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -51,7 +50,7 @@ class ImportEnvironments extends base_class_1.default {
|
|
|
51
50
|
async importEnvironments() {
|
|
52
51
|
if (this.environments === undefined || (0, isEmpty_1.default)(this.environments)) {
|
|
53
52
|
(0, utils_1.log)(this.importConfig, 'No Environment Found', 'info');
|
|
54
|
-
return
|
|
53
|
+
return;
|
|
55
54
|
}
|
|
56
55
|
const apiContent = (0, values_1.default)(this.environments);
|
|
57
56
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
@@ -83,7 +82,7 @@ class ImportEnvironments extends base_class_1.default {
|
|
|
83
82
|
entity: 'create-environments',
|
|
84
83
|
includeParamOnCompletion: true,
|
|
85
84
|
},
|
|
86
|
-
concurrencyLimit:
|
|
85
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 2,
|
|
87
86
|
}, undefined, false);
|
|
88
87
|
}
|
|
89
88
|
/**
|
|
@@ -4,13 +4,12 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
8
7
|
const utils_1 = require("../../utils");
|
|
9
8
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
9
|
class ImportExtensions extends base_class_1.default {
|
|
11
10
|
constructor({ importConfig, stackAPIClient }) {
|
|
12
11
|
super({ importConfig, stackAPIClient });
|
|
13
|
-
this.extensionsConfig =
|
|
12
|
+
this.extensionsConfig = importConfig.modules.extensions;
|
|
14
13
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'extensions');
|
|
15
14
|
this.extensionsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.extensionsConfig.dirName);
|
|
16
15
|
this.extUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -51,7 +50,7 @@ class ImportExtensions extends base_class_1.default {
|
|
|
51
50
|
async importExtensions() {
|
|
52
51
|
if (this.extensions === undefined || (0, isEmpty_1.default)(this.extensions)) {
|
|
53
52
|
(0, utils_1.log)(this.importConfig, 'No Extensions Found', 'info');
|
|
54
|
-
return
|
|
53
|
+
return;
|
|
55
54
|
}
|
|
56
55
|
const apiContent = (0, values_1.default)(this.extensions);
|
|
57
56
|
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
|
|
@@ -83,7 +82,7 @@ class ImportExtensions extends base_class_1.default {
|
|
|
83
82
|
entity: 'create-extensions',
|
|
84
83
|
includeParamOnCompletion: true,
|
|
85
84
|
},
|
|
86
|
-
concurrencyLimit:
|
|
85
|
+
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
87
86
|
}, undefined, false);
|
|
88
87
|
}
|
|
89
88
|
/**
|
|
@@ -72,8 +72,9 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
72
72
|
async createGFs({ apiParams, element: globalField, isLastRequest, }) {
|
|
73
73
|
return new Promise(async (resolve, reject) => {
|
|
74
74
|
(0, utils_1.lookupExtension)(this.config, globalField.schema, this.config.preserveStackVersion, this.installedExtensions);
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
let flag = { supressed: false };
|
|
76
|
+
await (0, utils_1.removeReferenceFields)(globalField.schema, flag, this.stackAPIClient);
|
|
77
|
+
if (flag.supressed) {
|
|
77
78
|
this.pendingGFs.push(globalField.uid);
|
|
78
79
|
}
|
|
79
80
|
return this.stack
|
|
@@ -17,7 +17,7 @@ export default class Importlabels extends BaseClass {
|
|
|
17
17
|
* @returns {Promise<void>} Promise<void>
|
|
18
18
|
*/
|
|
19
19
|
start(): Promise<void>;
|
|
20
|
-
importlabels(): Promise<
|
|
20
|
+
importlabels(): Promise<void>;
|
|
21
21
|
/**
|
|
22
22
|
* @method serializelabels
|
|
23
23
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
@@ -30,5 +30,5 @@ export default class Importlabels extends BaseClass {
|
|
|
30
30
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
31
31
|
* @returns {ApiOptions} ApiOptions
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
serializeUpdateLabels(apiOptions: ApiOptions): ApiOptions;
|
|
34
34
|
}
|
|
@@ -5,13 +5,12 @@ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
|
5
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
6
|
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
7
7
|
const node_path_1 = require("node:path");
|
|
8
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
9
8
|
const utils_1 = require("../../utils");
|
|
10
9
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
11
10
|
class Importlabels extends base_class_1.default {
|
|
12
11
|
constructor({ importConfig, stackAPIClient }) {
|
|
13
12
|
super({ importConfig, stackAPIClient });
|
|
14
|
-
this.labelsConfig =
|
|
13
|
+
this.labelsConfig = importConfig.modules.labels;
|
|
15
14
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'labels');
|
|
16
15
|
this.labelsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.labelsConfig.dirName);
|
|
17
16
|
this.labelUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -56,7 +55,7 @@ class Importlabels extends base_class_1.default {
|
|
|
56
55
|
async importlabels() {
|
|
57
56
|
if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
|
|
58
57
|
(0, utils_1.log)(this.importConfig, 'No Label Found', 'info');
|
|
59
|
-
return
|
|
58
|
+
return;
|
|
60
59
|
}
|
|
61
60
|
const apiContent = (0, values_1.default)(this.labels);
|
|
62
61
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
@@ -86,7 +85,7 @@ class Importlabels extends base_class_1.default {
|
|
|
86
85
|
entity: 'create-labels',
|
|
87
86
|
includeParamOnCompletion: true,
|
|
88
87
|
},
|
|
89
|
-
concurrencyLimit:
|
|
88
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
90
89
|
}, undefined, false);
|
|
91
90
|
}
|
|
92
91
|
/**
|
|
@@ -124,13 +123,13 @@ class Importlabels extends base_class_1.default {
|
|
|
124
123
|
apiContent,
|
|
125
124
|
processName: 'update labels',
|
|
126
125
|
apiParams: {
|
|
127
|
-
serializeData: this.
|
|
126
|
+
serializeData: this.serializeUpdateLabels.bind(this),
|
|
128
127
|
reject: onReject.bind(this),
|
|
129
128
|
resolve: onSuccess.bind(this),
|
|
130
129
|
entity: 'update-labels',
|
|
131
130
|
includeParamOnCompletion: true,
|
|
132
131
|
},
|
|
133
|
-
concurrencyLimit:
|
|
132
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
134
133
|
}, undefined, false);
|
|
135
134
|
}
|
|
136
135
|
}
|
|
@@ -139,7 +138,7 @@ class Importlabels extends base_class_1.default {
|
|
|
139
138
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
140
139
|
* @returns {ApiOptions} ApiOptions
|
|
141
140
|
*/
|
|
142
|
-
|
|
141
|
+
serializeUpdateLabels(apiOptions) {
|
|
143
142
|
var _a, _b;
|
|
144
143
|
const { apiData: label } = apiOptions;
|
|
145
144
|
const labelUid = label.uid;
|
|
@@ -16,6 +16,7 @@ export default class ImportMarketplaceApps extends BaseClass {
|
|
|
16
16
|
developerHubBaseUrl: string;
|
|
17
17
|
sdkClient: ContentstackClient;
|
|
18
18
|
nodeCrypto: NodeCrypto;
|
|
19
|
+
appSdkAxiosInstance: any;
|
|
19
20
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
20
21
|
/**
|
|
21
22
|
* @method start
|
|
@@ -13,14 +13,13 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
|
13
13
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
14
14
|
const toLower_1 = tslib_1.__importDefault(require("lodash/toLower"));
|
|
15
15
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
16
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
17
16
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
18
17
|
const interactive_1 = require("../../utils/interactive");
|
|
19
18
|
const utils_1 = require("../../utils");
|
|
20
19
|
class ImportMarketplaceApps extends base_class_1.default {
|
|
21
20
|
constructor({ importConfig, stackAPIClient }) {
|
|
22
21
|
super({ importConfig, stackAPIClient });
|
|
23
|
-
this.marketPlaceAppConfig =
|
|
22
|
+
this.marketPlaceAppConfig = importConfig.modules.marketplace_apps;
|
|
24
23
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'marketplace_apps');
|
|
25
24
|
this.marketPlaceFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.marketPlaceAppConfig.dirName);
|
|
26
25
|
this.marketPlaceUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -54,6 +53,9 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
54
53
|
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
55
54
|
this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.importConfig));
|
|
56
55
|
this.sdkClient = await (0, cli_utilities_1.managementSDKClient)({ endpoint: this.developerHubBaseUrl });
|
|
56
|
+
this.appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
|
|
57
|
+
host: this.developerHubBaseUrl.split('://').pop()
|
|
58
|
+
});
|
|
57
59
|
this.importConfig.org_uid = await (0, utils_1.getOrgUid)(this.importConfig);
|
|
58
60
|
await this.setHttpClient();
|
|
59
61
|
await this.startInstallation();
|
|
@@ -298,10 +300,14 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
298
300
|
}
|
|
299
301
|
// TODO migrate this HTTP API call into SDK
|
|
300
302
|
// NOTE Use updateAppConfig(this.sdkClient, this.importConfig, app, payload) utility when migrating to SDK call;
|
|
301
|
-
return this.
|
|
302
|
-
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload
|
|
303
|
+
return this.appSdkAxiosInstance.axiosInstance
|
|
304
|
+
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload, {
|
|
305
|
+
headers: {
|
|
306
|
+
organization_uid: this.importConfig.org_uid,
|
|
307
|
+
},
|
|
308
|
+
})
|
|
303
309
|
.then(({ data }) => {
|
|
304
|
-
if (data.message) {
|
|
310
|
+
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
305
311
|
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
|
|
306
312
|
}
|
|
307
313
|
else {
|
|
@@ -17,7 +17,7 @@ export default class ImportWebhooks extends BaseClass {
|
|
|
17
17
|
* @returns {Promise<void>} Promise<void>
|
|
18
18
|
*/
|
|
19
19
|
start(): Promise<void>;
|
|
20
|
-
importWebhooks(): Promise<
|
|
20
|
+
importWebhooks(): Promise<void>;
|
|
21
21
|
/**
|
|
22
22
|
* @method serializeWebhooks
|
|
23
23
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
@@ -4,13 +4,12 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
8
7
|
const utils_1 = require("../../utils");
|
|
9
8
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
9
|
class ImportWebhooks extends base_class_1.default {
|
|
11
10
|
constructor({ importConfig, stackAPIClient }) {
|
|
12
11
|
super({ importConfig, stackAPIClient });
|
|
13
|
-
this.webhooksConfig =
|
|
12
|
+
this.webhooksConfig = importConfig.modules.webhooks;
|
|
14
13
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'webhooks');
|
|
15
14
|
this.webhooksFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.webhooksConfig.dirName);
|
|
16
15
|
this.webhookUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -53,7 +52,7 @@ class ImportWebhooks extends base_class_1.default {
|
|
|
53
52
|
async importWebhooks() {
|
|
54
53
|
if (this.webhooks === undefined || (0, isEmpty_1.default)(this.webhooks)) {
|
|
55
54
|
(0, utils_1.log)(this.importConfig, 'No Webhook Found', 'info');
|
|
56
|
-
return
|
|
55
|
+
return;
|
|
57
56
|
}
|
|
58
57
|
const apiContent = (0, values_1.default)(this.webhooks);
|
|
59
58
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
@@ -84,7 +83,7 @@ class ImportWebhooks extends base_class_1.default {
|
|
|
84
83
|
entity: 'create-webhooks',
|
|
85
84
|
includeParamOnCompletion: true,
|
|
86
85
|
},
|
|
87
|
-
concurrencyLimit:
|
|
86
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
88
87
|
}, undefined, false);
|
|
89
88
|
}
|
|
90
89
|
/**
|
|
@@ -10,13 +10,12 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
|
|
|
10
10
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
11
11
|
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
12
12
|
const findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex"));
|
|
13
|
-
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
14
13
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
15
14
|
const utils_1 = require("../../utils");
|
|
16
15
|
class ImportWorkflows extends base_class_1.default {
|
|
17
16
|
constructor({ importConfig, stackAPIClient }) {
|
|
18
17
|
super({ importConfig, stackAPIClient });
|
|
19
|
-
this.workflowsConfig =
|
|
18
|
+
this.workflowsConfig = importConfig.modules.workflows;
|
|
20
19
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'workflows');
|
|
21
20
|
this.workflowsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.workflowsConfig.dirName);
|
|
22
21
|
this.workflowUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
@@ -99,10 +98,11 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
99
98
|
utils_1.fsUtil.writeFile(this.workflowUidMapperPath, this.workflowUidMapper);
|
|
100
99
|
};
|
|
101
100
|
const onReject = ({ error, apiData }) => {
|
|
102
|
-
var _a;
|
|
101
|
+
var _a, _b;
|
|
103
102
|
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
104
103
|
const { name } = apiData;
|
|
105
|
-
|
|
104
|
+
const workflowExists = ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) || ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b['workflow.name']);
|
|
105
|
+
if (workflowExists) {
|
|
106
106
|
(0, utils_1.log)(this.importConfig, `Workflow '${name}' already exists`, 'info');
|
|
107
107
|
}
|
|
108
108
|
else {
|
|
@@ -125,7 +125,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
125
125
|
entity: 'create-workflows',
|
|
126
126
|
includeParamOnCompletion: true,
|
|
127
127
|
},
|
|
128
|
-
concurrencyLimit:
|
|
128
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
129
129
|
}, undefined, false);
|
|
130
130
|
}
|
|
131
131
|
updateNextAvailableStagesUid(workflow, newWorkflowStages, oldWorkflowStages) {
|
|
@@ -209,7 +209,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
209
209
|
includeParamOnCompletion: true,
|
|
210
210
|
additionalInfo: { workflowUid: workflow.uid, stageIndex },
|
|
211
211
|
},
|
|
212
|
-
concurrencyLimit:
|
|
212
|
+
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
213
213
|
}, undefined, false);
|
|
214
214
|
}
|
|
215
215
|
stageIndex++;
|
|
@@ -19,6 +19,7 @@ declare class ImportMarketplaceApps {
|
|
|
19
19
|
start(): Promise<void>;
|
|
20
20
|
mapperDirPath: string;
|
|
21
21
|
uidMapperPath: string;
|
|
22
|
+
appSdkAxiosInstance: any;
|
|
22
23
|
getOrgUid(): Promise<void>;
|
|
23
24
|
getAndValidateEncryptionKey(defaultValue: any, retry?: number): any;
|
|
24
25
|
nodeCrypto: NodeCrypto;
|
|
@@ -38,6 +38,9 @@ module.exports = class ImportMarketplaceApps {
|
|
|
38
38
|
}
|
|
39
39
|
this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config));
|
|
40
40
|
this.client = await managementSDKClient({ endpoint: this.developerHubBaseUrl });
|
|
41
|
+
this.appSdkAxiosInstance = await managementSDKClient({
|
|
42
|
+
host: this.developerHubBaseUrl.split('://').pop()
|
|
43
|
+
});
|
|
41
44
|
await this.getOrgUid();
|
|
42
45
|
const httpClient = new HttpClient();
|
|
43
46
|
if (!this.config.auth_token) {
|
|
@@ -392,8 +395,12 @@ module.exports = class ImportMarketplaceApps {
|
|
|
392
395
|
if (_.isEmpty(app) || _.isEmpty(payload) || !uid) {
|
|
393
396
|
return Promise.resolve();
|
|
394
397
|
}
|
|
395
|
-
return this.
|
|
396
|
-
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload
|
|
398
|
+
return this.appSdkAxiosInstance.axiosInstance
|
|
399
|
+
.put(`${this.developerHubBaseUrl}/installations/${uid}`, payload, {
|
|
400
|
+
headers: {
|
|
401
|
+
organization_uid: this.config.org_uid
|
|
402
|
+
},
|
|
403
|
+
})
|
|
397
404
|
.then(({ data }) => {
|
|
398
405
|
if (data.message) {
|
|
399
406
|
log(this.config, formatError(data.message), 'success');
|
|
@@ -128,7 +128,6 @@ export default interface DefaultConfig {
|
|
|
128
128
|
stacks: string;
|
|
129
129
|
labels: string;
|
|
130
130
|
};
|
|
131
|
-
updatedModules: string[];
|
|
132
131
|
rateLimit: number;
|
|
133
132
|
preserveStackVersion: boolean;
|
|
134
133
|
entriesPublish: boolean;
|
|
@@ -139,6 +138,5 @@ export default interface DefaultConfig {
|
|
|
139
138
|
developerHubBaseUrl: string;
|
|
140
139
|
marketplaceAppEncryptionKey: string;
|
|
141
140
|
getEncryptionKeyMaxRetry: number;
|
|
142
|
-
useNewModuleStructure: boolean;
|
|
143
141
|
createBackupDir?: string;
|
|
144
142
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import Bluebird from 'bluebird';
|
|
2
|
-
import { ImportConfig } from '
|
|
2
|
+
import { ImportConfig } from '../types';
|
|
3
3
|
export declare const uploadAssetHelper: (config: ImportConfig, req: any, fsPath: string, RETRY?: number) => Bluebird<unknown>;
|
|
4
4
|
export declare const lookupAssets: (data: Record<string, any>, mappedAssetUids: Record<string, any>, mappedAssetUrls: Record<string, any>, assetUidMapperPath: string, installedExtensions: Record<string, any>[]) => any;
|
|
@@ -2,33 +2,38 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const path = tslib_1.__importStar(require("path"));
|
|
5
|
-
const
|
|
5
|
+
const fs_extra_1 = require("fs-extra");
|
|
6
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
7
|
const index_1 = require("./index");
|
|
7
8
|
function setupBackupDir(importConfig) {
|
|
8
9
|
return new Promise(async (resolve, reject) => {
|
|
9
10
|
if (importConfig.hasOwnProperty('useBackedupDir')) {
|
|
10
11
|
return resolve(importConfig.useBackedupDir);
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
let backupDirPath
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const subDir = isSubDirectory(importConfig);
|
|
14
|
+
let backupDirPath;
|
|
15
|
+
if (subDir) {
|
|
16
|
+
backupDirPath = path.resolve(importConfig.contentDir, '..', '_backup_' + Math.floor(Math.random() * 1000));
|
|
17
|
+
if (importConfig.createBackupDir) {
|
|
18
|
+
cli_utilities_1.cliux.print(`Warning!!! Provided backup directory path is a sub directory of the content directory, Cannot copy to a sub directory. Hence new backup directory created - ${backupDirPath}`, {
|
|
19
|
+
color: 'yellow',
|
|
20
|
+
});
|
|
17
21
|
}
|
|
18
|
-
index_1.fileHelper.makeDirectory(importConfig.createBackupDir);
|
|
19
|
-
backupDirPath = importConfig.createBackupDir;
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
else {
|
|
24
|
+
//NOTE: If the backup folder's directory is provided, create it at that location; otherwise, the default path (working directory).
|
|
25
|
+
backupDirPath = path.join(process.cwd(), '_backup_' + Math.floor(Math.random() * 1000));
|
|
26
|
+
if (importConfig.createBackupDir) {
|
|
27
|
+
if (index_1.fileHelper.fileExistsSync(importConfig.createBackupDir)) {
|
|
28
|
+
index_1.fileHelper.removeDirSync(importConfig.createBackupDir);
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
index_1.fileHelper.makeDirectory(importConfig.createBackupDir);
|
|
31
|
+
backupDirPath = importConfig.createBackupDir;
|
|
32
|
+
}
|
|
29
33
|
}
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
if (backupDirPath) {
|
|
35
|
+
cli_utilities_1.cliux.print('Copying content to the backup directory...');
|
|
36
|
+
return (0, fs_extra_1.copy)(importConfig.contentDir, backupDirPath, (error) => {
|
|
32
37
|
if (error) {
|
|
33
38
|
return reject(error);
|
|
34
39
|
}
|
|
@@ -38,3 +43,18 @@ function setupBackupDir(importConfig) {
|
|
|
38
43
|
});
|
|
39
44
|
}
|
|
40
45
|
exports.default = setupBackupDir;
|
|
46
|
+
/**
|
|
47
|
+
* Check whether provided backup directory path is sub directory or not
|
|
48
|
+
* @param importConfig
|
|
49
|
+
* @returns
|
|
50
|
+
*/
|
|
51
|
+
function isSubDirectory(importConfig) {
|
|
52
|
+
const parent = importConfig.contentDir;
|
|
53
|
+
const child = importConfig.createBackupDir ? importConfig.createBackupDir : process.cwd();
|
|
54
|
+
const relative = path.relative(parent, child);
|
|
55
|
+
if (relative) {
|
|
56
|
+
return relative && !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
57
|
+
}
|
|
58
|
+
//true if both parent and child have same path
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Entries lookup
|
|
3
3
|
*/
|
|
4
|
-
export declare const lookupEntries: (data:
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export declare const lookupEntries: (data: {
|
|
5
|
+
content_type: any;
|
|
6
|
+
entry: any;
|
|
7
|
+
}, mappedUids: Record<string, any>, uidMapperPath: string) => any;
|
|
8
|
+
export declare const removeUidsFromJsonRteFields: (entry: Record<string, any>, ctSchema?: Record<string, any>[]) => Record<string, any>;
|
|
9
|
+
export declare const removeEntryRefsFromJSONRTE: (entry: Record<string, any>, ctSchema?: Record<string, any>[]) => Record<string, any>;
|
|
7
10
|
export declare const restoreJsonRteEntryRefs: (entry: Record<string, any>, sourceStackEntry: any, ctSchema: any, { mappedAssetUids, mappedAssetUrls }: any) => Record<string, any>;
|
|
@@ -94,7 +94,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
const find = function (schema = [], _entry) {
|
|
97
|
-
for (let i = 0, _i = schema.length; i < _i; i++) {
|
|
97
|
+
for (let i = 0, _i = schema === null || schema === void 0 ? void 0 : schema.length; i < _i; i++) {
|
|
98
98
|
switch (schema[i].data_type) {
|
|
99
99
|
case 'reference':
|
|
100
100
|
if (Array.isArray(schema[i].reference_to)) {
|
|
@@ -134,7 +134,7 @@ const lookupEntries = function (data, mappedUids, uidMapperPath) {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
|
-
function findEntryIdsFromJsonRte(entry, ctSchema) {
|
|
137
|
+
function findEntryIdsFromJsonRte(entry, ctSchema = []) {
|
|
138
138
|
for (const element of ctSchema) {
|
|
139
139
|
switch (element.data_type) {
|
|
140
140
|
case 'blocks': {
|
|
@@ -249,7 +249,7 @@ function findUidsInNewRefFields(entry, uids) {
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
|
-
const removeUidsFromJsonRteFields = (entry, ctSchema) => {
|
|
252
|
+
const removeUidsFromJsonRteFields = (entry, ctSchema = []) => {
|
|
253
253
|
for (const element of ctSchema) {
|
|
254
254
|
switch (element.data_type) {
|
|
255
255
|
case 'blocks': {
|
|
@@ -339,7 +339,7 @@ function removeUidsFromChildren(children) {
|
|
|
339
339
|
return children;
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
|
-
const removeEntryRefsFromJSONRTE = (entry, ctSchema) => {
|
|
342
|
+
const removeEntryRefsFromJSONRTE = (entry, ctSchema = []) => {
|
|
343
343
|
for (const element of ctSchema) {
|
|
344
344
|
switch (element.data_type) {
|
|
345
345
|
case 'blocks': {
|
|
@@ -379,7 +379,8 @@ const removeEntryRefsFromJSONRTE = (entry, ctSchema) => {
|
|
|
379
379
|
let entryReferences = jsonRteData.children.filter((e) => doEntryReferencesExist(e));
|
|
380
380
|
if (entryReferences.length > 0) {
|
|
381
381
|
jsonRteData.children = jsonRteData.children.filter((e) => !doEntryReferencesExist(e));
|
|
382
|
-
if (jsonRteData.children.length === 0) {
|
|
382
|
+
if (jsonRteData.children.length === 0) {
|
|
383
|
+
// empty children array are no longer acceptable by the API, a default structure must be there
|
|
383
384
|
jsonRteData.children.push(JSON.parse(structuredPTag));
|
|
384
385
|
}
|
|
385
386
|
return jsonRteData; // return jsonRteData without entry references
|
|
@@ -432,14 +433,14 @@ function doEntryReferencesExist(element) {
|
|
|
432
433
|
function isEntryRef(element) {
|
|
433
434
|
return element.type === 'reference' && element.attrs.type === 'entry';
|
|
434
435
|
}
|
|
435
|
-
const restoreJsonRteEntryRefs = (entry, sourceStackEntry, ctSchema, { mappedAssetUids, mappedAssetUrls }) => {
|
|
436
|
+
const restoreJsonRteEntryRefs = (entry, sourceStackEntry, ctSchema = [], { mappedAssetUids, mappedAssetUrls }) => {
|
|
436
437
|
// let mappedAssetUids = fileHelper.readFileSync(this.mappedAssetUidPath) || {};
|
|
437
438
|
// let mappedAssetUrls = fileHelper.readFileSync(this.mappedAssetUrlPath) || {};
|
|
438
439
|
for (const element of ctSchema) {
|
|
439
440
|
switch (element.data_type) {
|
|
440
441
|
case 'blocks': {
|
|
441
442
|
if (entry[element.uid]) {
|
|
442
|
-
if (element.multiple) {
|
|
443
|
+
if (element.multiple && Array.isArray(entry[element.uid])) {
|
|
443
444
|
entry[element.uid] = entry[element.uid].map((e, eIndex) => {
|
|
444
445
|
let key = Object.keys(e).pop();
|
|
445
446
|
let subBlock = element.blocks.filter((block) => block.uid === key).pop();
|
|
@@ -457,7 +458,7 @@ const restoreJsonRteEntryRefs = (entry, sourceStackEntry, ctSchema, { mappedAsse
|
|
|
457
458
|
case 'global_field':
|
|
458
459
|
case 'group': {
|
|
459
460
|
if (entry[element.uid]) {
|
|
460
|
-
if (element.multiple) {
|
|
461
|
+
if (element.multiple && Array.isArray(entry[element.uid])) {
|
|
461
462
|
entry[element.uid] = entry[element.uid].map((e, eIndex) => {
|
|
462
463
|
let sourceStackElement = sourceStackEntry[element.uid][eIndex];
|
|
463
464
|
e = (0, exports.restoreJsonRteEntryRefs)(e, sourceStackElement, element.schema, { mappedAssetUids, mappedAssetUrls });
|
|
@@ -476,7 +477,7 @@ const restoreJsonRteEntryRefs = (entry, sourceStackEntry, ctSchema, { mappedAsse
|
|
|
476
477
|
}
|
|
477
478
|
case 'json': {
|
|
478
479
|
if (entry[element.uid] && element.field_metadata.rich_text_type) {
|
|
479
|
-
if (element.multiple) {
|
|
480
|
+
if (element.multiple && Array.isArray(entry[element.uid])) {
|
|
480
481
|
entry[element.uid] = entry[element.uid].map((field, index) => {
|
|
481
482
|
// i am facing a Maximum call stack exceeded issue,
|
|
482
483
|
// probably because of this loop operation
|
|
@@ -543,7 +544,7 @@ function setDirtyTrue(jsonRteChild) {
|
|
|
543
544
|
}
|
|
544
545
|
delete jsonRteChild.uid;
|
|
545
546
|
if (jsonRteChild.children && jsonRteChild.children.length > 0) {
|
|
546
|
-
jsonRteChild.children = jsonRteChild.children.map((subElement) =>
|
|
547
|
+
jsonRteChild.children = jsonRteChild.children.map((subElement) => setDirtyTrue(subElement));
|
|
547
548
|
}
|
|
548
549
|
}
|
|
549
550
|
return jsonRteChild;
|
|
@@ -24,6 +24,13 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
24
24
|
config.contentDir = path.resolve(config.contentDir);
|
|
25
25
|
//Note to support the old key
|
|
26
26
|
config.data = config.contentDir;
|
|
27
|
+
if ((0, file_helper_1.fileExistsSync)(path.join(config.contentDir, 'export-info.json'))) {
|
|
28
|
+
config.contentVersion =
|
|
29
|
+
((await (0, file_helper_1.readFile)(path.join(config.contentDir, 'export-info.json'))) || {}).contentVersion || 2;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
config.contentVersion = 1;
|
|
33
|
+
}
|
|
27
34
|
const managementTokenAlias = importCmdFlags['management-token-alias'] || importCmdFlags['alias'];
|
|
28
35
|
if (managementTokenAlias) {
|
|
29
36
|
const { token, apiKey } = cli_utilities_1.configHandler.get(`tokens.${managementTokenAlias}`);
|
package/lib/utils/logger.js
CHANGED
|
@@ -55,7 +55,7 @@ let successTransport;
|
|
|
55
55
|
let errorTransport;
|
|
56
56
|
function init(_logPath) {
|
|
57
57
|
if (!logger || !errorLogger) {
|
|
58
|
-
var logsDir = path.resolve(_logPath, 'logs', '
|
|
58
|
+
var logsDir = path.resolve(_logPath, 'logs', 'import');
|
|
59
59
|
// Create dir if doesn't already exist
|
|
60
60
|
mkdirp_1.default.sync(logsDir);
|
|
61
61
|
successTransport = {
|
|
@@ -13,8 +13,15 @@ const interactive_1 = require("./interactive");
|
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const interactive_2 = require("../utils/interactive");
|
|
15
15
|
const getAllStackSpecificApps = async (developerHubBaseUrl, httpClient, config) => {
|
|
16
|
-
|
|
17
|
-
.
|
|
16
|
+
const appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
|
|
17
|
+
host: developerHubBaseUrl.split('://').pop()
|
|
18
|
+
});
|
|
19
|
+
return await appSdkAxiosInstance.axiosInstance
|
|
20
|
+
.get(`${developerHubBaseUrl}/installations?target_uids=${config.target_stack}`, {
|
|
21
|
+
headers: {
|
|
22
|
+
organization_uid: config.org_uid,
|
|
23
|
+
},
|
|
24
|
+
})
|
|
18
25
|
.then(({ data }) => data.data)
|
|
19
26
|
.catch((error) => (0, logger_1.log)(config, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error'));
|
|
20
27
|
};
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-import",
|
|
3
3
|
"description": "Contentstack CLI plugin to import content into stack",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.9.0",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
+
"@contentstack/management": "~1.10.2",
|
|
8
9
|
"@contentstack/cli-command": "~1.2.12",
|
|
9
10
|
"@contentstack/cli-utilities": "~1.5.2",
|
|
10
|
-
"@contentstack/management": "~1.10.0",
|
|
11
11
|
"@oclif/core": "^2.9.3",
|
|
12
12
|
"big-json": "^3.2.0",
|
|
13
13
|
"bluebird": "^3.7.2",
|
|
14
14
|
"chalk": "^4.1.2",
|
|
15
15
|
"debug": "^4.1.0",
|
|
16
|
+
"fs-extra": "^11.1.1",
|
|
16
17
|
"lodash": "^4.17.20",
|
|
17
18
|
"marked": "^4.0.17",
|
|
18
19
|
"merge": "^2.1.1",
|
|
19
20
|
"mkdirp": "^1.0.4",
|
|
20
|
-
"ncp": "^2.0.0",
|
|
21
21
|
"promise-limit": "^2.7.0",
|
|
22
22
|
"tslib": "^2.4.1",
|
|
23
23
|
"winston": "^3.7.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@oclif/test": "^1.2.6",
|
|
27
|
+
"@types/big-json": "^3.2.0",
|
|
27
28
|
"@types/bluebird": "^3.5.38",
|
|
28
29
|
"@types/chai": "^4.2.18",
|
|
30
|
+
"@types/fs-extra": "^11.0.1",
|
|
29
31
|
"@types/mkdirp": "^1.0.2",
|
|
30
32
|
"@types/mocha": "^8.2.2",
|
|
31
|
-
"@types/ncp": "^2.0.5",
|
|
32
33
|
"@types/node": "^14.14.32",
|
|
33
34
|
"@types/sinon": "^10.0.2",
|
|
34
35
|
"@types/tar": "^4.0.3",
|