@contentstack/cli-cm-import 1.6.0 → 1.7.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/lib/commands/cm/stacks/import.js +1 -1
- package/lib/config/index.js +24 -1
- package/lib/import/modules/base-class.d.ts +3 -2
- package/lib/import/modules/base-class.js +53 -0
- package/lib/import/modules/content-types.d.ts +56 -0
- package/lib/import/modules/content-types.js +186 -0
- package/lib/import/modules/custom-roles.d.ts +37 -0
- package/lib/import/modules/custom-roles.js +171 -0
- package/lib/import/modules/environments.d.ts +27 -0
- package/lib/import/modules/environments.js +106 -0
- package/lib/import/modules/extensions.d.ts +27 -0
- package/lib/import/modules/extensions.js +106 -0
- package/lib/import/modules/global-fields.d.ts +34 -0
- package/lib/import/modules/global-fields.js +99 -0
- package/lib/import/modules/labels.d.ts +34 -0
- package/lib/import/modules/labels.js +171 -0
- package/lib/import/modules/locales.js +0 -8
- package/lib/import/modules/marketplace-apps.d.ts +51 -0
- package/lib/import/modules/marketplace-apps.js +297 -0
- package/lib/import/modules/webhooks.d.ts +27 -0
- package/lib/import/modules/webhooks.js +110 -0
- package/lib/import/modules-js/custom-roles.js +2 -0
- package/lib/import/modules-js/entries.js +1 -1
- package/lib/import/modules-js/extensions.d.ts +1 -0
- package/lib/import/modules-js/marketplace-apps.js +2 -2
- package/lib/types/default-config.d.ts +13 -0
- package/lib/types/import-config.d.ts +1 -0
- package/lib/types/index.d.ts +33 -0
- package/lib/types/index.js +2 -0
- package/lib/utils/content-type-helper.d.ts +3 -1
- package/lib/utils/content-type-helper.js +3 -1
- package/lib/utils/extension-helper.d.ts +0 -5
- package/lib/utils/extension-helper.js +23 -11
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +11 -1
- package/lib/utils/interactive.d.ts +5 -0
- package/lib/utils/interactive.js +66 -1
- package/lib/utils/marketplace-app-helper.d.ts +13 -1
- package/lib/utils/marketplace-app-helper.js +127 -15
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
|
+
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
8
|
+
const utils_1 = require("../../utils");
|
|
9
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
|
+
class ImportEnvironments extends base_class_1.default {
|
|
11
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
12
|
+
super({ importConfig, stackAPIClient });
|
|
13
|
+
this.environmentsConfig = config_1.default.modules.environments;
|
|
14
|
+
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'environments');
|
|
15
|
+
this.environmentsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.environmentsConfig.dirName);
|
|
16
|
+
this.envUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
17
|
+
this.envSuccessPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
|
|
18
|
+
this.envFailsPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
|
|
19
|
+
this.envFailed = [];
|
|
20
|
+
this.envSuccess = [];
|
|
21
|
+
this.envUidMapper = {};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @method start
|
|
25
|
+
* @returns {Promise<void>} Promise<void>
|
|
26
|
+
*/
|
|
27
|
+
async start() {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
(0, utils_1.log)(this.importConfig, 'Migrating environments', 'info');
|
|
30
|
+
//Step1 check folder exists or not
|
|
31
|
+
if (utils_1.fileHelper.fileExistsSync(this.environmentsFolderPath)) {
|
|
32
|
+
this.environments = utils_1.fsUtil.readFile((0, node_path_1.join)(this.environmentsFolderPath, 'environments.json'), true);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.environmentsFolderPath}'`, 'error');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
39
|
+
this.envUidMapper = utils_1.fileHelper.fileExistsSync(this.envUidMapperPath)
|
|
40
|
+
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.envUidMapperPath), true)
|
|
41
|
+
: {};
|
|
42
|
+
await this.importEnvironments();
|
|
43
|
+
if ((_a = this.envSuccess) === null || _a === void 0 ? void 0 : _a.length) {
|
|
44
|
+
utils_1.fsUtil.writeFile(this.envSuccessPath, this.envSuccess);
|
|
45
|
+
}
|
|
46
|
+
if ((_b = this.envFailed) === null || _b === void 0 ? void 0 : _b.length) {
|
|
47
|
+
utils_1.fsUtil.writeFile(this.envFailsPath, this.envFailed);
|
|
48
|
+
}
|
|
49
|
+
(0, utils_1.log)(this.importConfig, 'Environments have been imported successfully!', 'success');
|
|
50
|
+
}
|
|
51
|
+
async importEnvironments() {
|
|
52
|
+
if (this.environments === undefined || (0, isEmpty_1.default)(this.environments)) {
|
|
53
|
+
(0, utils_1.log)(this.importConfig, 'No Environment Found', 'info');
|
|
54
|
+
return (0, node_path_1.resolve)();
|
|
55
|
+
}
|
|
56
|
+
const apiContent = (0, values_1.default)(this.environments);
|
|
57
|
+
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
58
|
+
this.envSuccess.push(response);
|
|
59
|
+
this.envUidMapper[uid] = response.uid;
|
|
60
|
+
(0, utils_1.log)(this.importConfig, `Environment '${name}' imported successfully`, 'success');
|
|
61
|
+
utils_1.fsUtil.writeFile(this.envUidMapperPath, this.envUidMapper);
|
|
62
|
+
};
|
|
63
|
+
const onReject = ({ error, apiData }) => {
|
|
64
|
+
var _a;
|
|
65
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
66
|
+
const { name } = apiData;
|
|
67
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
|
|
68
|
+
(0, utils_1.log)(this.importConfig, `Environment '${name}' already exists`, 'info');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.envFailed.push(apiData);
|
|
72
|
+
(0, utils_1.log)(this.importConfig, `Environment '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
|
|
73
|
+
(0, utils_1.log)(this.importConfig, error, 'error');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
await this.makeConcurrentCall({
|
|
77
|
+
apiContent,
|
|
78
|
+
processName: 'import environments',
|
|
79
|
+
apiParams: {
|
|
80
|
+
serializeData: this.serializeEnvironments.bind(this),
|
|
81
|
+
reject: onReject.bind(this),
|
|
82
|
+
resolve: onSuccess.bind(this),
|
|
83
|
+
entity: 'create-environments',
|
|
84
|
+
includeParamOnCompletion: true,
|
|
85
|
+
},
|
|
86
|
+
concurrencyLimit: config_1.default.fetchConcurrency || 2,
|
|
87
|
+
}, undefined, false);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* @method serializeEnvironments
|
|
91
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
92
|
+
* @returns {ApiOptions} ApiOptions
|
|
93
|
+
*/
|
|
94
|
+
serializeEnvironments(apiOptions) {
|
|
95
|
+
const { apiData: environment } = apiOptions;
|
|
96
|
+
if (this.envUidMapper.hasOwnProperty(environment.uid)) {
|
|
97
|
+
(0, utils_1.log)(this.importConfig, `Environment '${environment.name}' already exists. Skipping it to avoid duplicates!`, 'info');
|
|
98
|
+
apiOptions.entity = undefined;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
apiOptions.apiData = environment;
|
|
102
|
+
}
|
|
103
|
+
return apiOptions;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.default = ImportEnvironments;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import BaseClass, { ApiOptions } from './base-class';
|
|
2
|
+
import { ModuleClassParams } from '../../types';
|
|
3
|
+
export default class ImportExtensions extends BaseClass {
|
|
4
|
+
private mapperDirPath;
|
|
5
|
+
private extensionsFolderPath;
|
|
6
|
+
private extUidMapperPath;
|
|
7
|
+
private extSuccessPath;
|
|
8
|
+
private extFailsPath;
|
|
9
|
+
private extensionsConfig;
|
|
10
|
+
private extensions;
|
|
11
|
+
private extUidMapper;
|
|
12
|
+
private extSuccess;
|
|
13
|
+
private extFailed;
|
|
14
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
15
|
+
/**
|
|
16
|
+
* @method start
|
|
17
|
+
* @returns {Promise<void>} Promise<void>
|
|
18
|
+
*/
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
importExtensions(): Promise<any>;
|
|
21
|
+
/**
|
|
22
|
+
* @method serializeExtensions
|
|
23
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
24
|
+
* @returns {ApiOptions} ApiOptions
|
|
25
|
+
*/
|
|
26
|
+
serializeExtensions(apiOptions: ApiOptions): ApiOptions;
|
|
27
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
|
+
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
8
|
+
const utils_1 = require("../../utils");
|
|
9
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
|
+
class ImportExtensions extends base_class_1.default {
|
|
11
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
12
|
+
super({ importConfig, stackAPIClient });
|
|
13
|
+
this.extensionsConfig = config_1.default.modules.extensions;
|
|
14
|
+
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'extensions');
|
|
15
|
+
this.extensionsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.extensionsConfig.dirName);
|
|
16
|
+
this.extUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
17
|
+
this.extSuccessPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
|
|
18
|
+
this.extFailsPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
|
|
19
|
+
this.extFailed = [];
|
|
20
|
+
this.extSuccess = [];
|
|
21
|
+
this.extUidMapper = {};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @method start
|
|
25
|
+
* @returns {Promise<void>} Promise<void>
|
|
26
|
+
*/
|
|
27
|
+
async start() {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
(0, utils_1.log)(this.importConfig, 'Migrating extensions', 'info');
|
|
30
|
+
//Step1 check folder exists or not
|
|
31
|
+
if (utils_1.fileHelper.fileExistsSync(this.extensionsFolderPath)) {
|
|
32
|
+
this.extensions = utils_1.fsUtil.readFile((0, node_path_1.join)(this.extensionsFolderPath, 'extensions.json'), true);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.extensionsFolderPath}'`, 'error');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
39
|
+
this.extUidMapper = utils_1.fileHelper.fileExistsSync(this.extUidMapperPath)
|
|
40
|
+
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.extUidMapperPath), true)
|
|
41
|
+
: {};
|
|
42
|
+
await this.importExtensions();
|
|
43
|
+
if ((_a = this.extSuccess) === null || _a === void 0 ? void 0 : _a.length) {
|
|
44
|
+
utils_1.fsUtil.writeFile(this.extSuccessPath, this.extSuccess);
|
|
45
|
+
}
|
|
46
|
+
if ((_b = this.extFailed) === null || _b === void 0 ? void 0 : _b.length) {
|
|
47
|
+
utils_1.fsUtil.writeFile(this.extFailsPath, this.extFailed);
|
|
48
|
+
}
|
|
49
|
+
(0, utils_1.log)(this.importConfig, 'Extensions have been imported successfully!', 'success');
|
|
50
|
+
}
|
|
51
|
+
async importExtensions() {
|
|
52
|
+
if (this.extensions === undefined || (0, isEmpty_1.default)(this.extensions)) {
|
|
53
|
+
(0, utils_1.log)(this.importConfig, 'No Extensions Found', 'info');
|
|
54
|
+
return (0, node_path_1.resolve)();
|
|
55
|
+
}
|
|
56
|
+
const apiContent = (0, values_1.default)(this.extensions);
|
|
57
|
+
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
|
|
58
|
+
this.extSuccess.push(response);
|
|
59
|
+
this.extUidMapper[uid] = response.uid;
|
|
60
|
+
(0, utils_1.log)(this.importConfig, `Extension '${title}' imported successfully`, 'success');
|
|
61
|
+
utils_1.fsUtil.writeFile(this.extUidMapperPath, this.extUidMapper);
|
|
62
|
+
};
|
|
63
|
+
const onReject = ({ error, apiData }) => {
|
|
64
|
+
var _a;
|
|
65
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
66
|
+
const { title } = apiData;
|
|
67
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.title) {
|
|
68
|
+
(0, utils_1.log)(this.importConfig, `Extension '${title}' already exists`, 'info');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.extFailed.push(apiData);
|
|
72
|
+
(0, utils_1.log)(this.importConfig, `Extension '${title}' failed to be import ${(0, utils_1.formatError)(error)}`, 'error');
|
|
73
|
+
(0, utils_1.log)(this.importConfig, error, 'error');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
await this.makeConcurrentCall({
|
|
77
|
+
apiContent,
|
|
78
|
+
processName: 'import extensions',
|
|
79
|
+
apiParams: {
|
|
80
|
+
serializeData: this.serializeExtensions.bind(this),
|
|
81
|
+
reject: onReject.bind(this),
|
|
82
|
+
resolve: onSuccess.bind(this),
|
|
83
|
+
entity: 'create-extensions',
|
|
84
|
+
includeParamOnCompletion: true,
|
|
85
|
+
},
|
|
86
|
+
concurrencyLimit: config_1.default.concurrency || config_1.default.fetchConcurrency || 1,
|
|
87
|
+
}, undefined, false);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* @method serializeExtensions
|
|
91
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
92
|
+
* @returns {ApiOptions} ApiOptions
|
|
93
|
+
*/
|
|
94
|
+
serializeExtensions(apiOptions) {
|
|
95
|
+
const { apiData: extension } = apiOptions;
|
|
96
|
+
if (this.extUidMapper.hasOwnProperty(extension.uid)) {
|
|
97
|
+
(0, utils_1.log)(this.importConfig, `Extension '${extension.title}' already exists. Skipping it to avoid duplicates!`, 'info');
|
|
98
|
+
apiOptions.entity = undefined;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
apiOptions.apiData = extension;
|
|
102
|
+
}
|
|
103
|
+
return apiOptions;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.default = ImportExtensions;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Contentstack Import
|
|
3
|
+
* Copyright (c) 2019 Contentstack LLC
|
|
4
|
+
* MIT Licensed
|
|
5
|
+
*/
|
|
6
|
+
import { ModuleClassParams } from '../../types';
|
|
7
|
+
import BaseClass, { ApiOptions } from './base-class';
|
|
8
|
+
export default class ImportGlobalFields extends BaseClass {
|
|
9
|
+
private gFsMapperPath;
|
|
10
|
+
private gFsFolderPath;
|
|
11
|
+
private gFsFailsPath;
|
|
12
|
+
private gFsSuccessPath;
|
|
13
|
+
private gFsUidMapperPath;
|
|
14
|
+
private gFsPendingPath;
|
|
15
|
+
private pendingGFs;
|
|
16
|
+
private failedGFs;
|
|
17
|
+
private createdGFs;
|
|
18
|
+
private gFs;
|
|
19
|
+
private gFsUidMapper;
|
|
20
|
+
private config;
|
|
21
|
+
private stackAPIClient;
|
|
22
|
+
private marketplaceAppMapperPath;
|
|
23
|
+
private reqConcurrency;
|
|
24
|
+
private installedExtensions;
|
|
25
|
+
private gFsConfig;
|
|
26
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
27
|
+
start(): Promise<any>;
|
|
28
|
+
importGFs(): Promise<void>;
|
|
29
|
+
createGFs({ apiParams, element: globalField, isLastRequest, }: {
|
|
30
|
+
apiParams: ApiOptions;
|
|
31
|
+
element: Record<string, string>;
|
|
32
|
+
isLastRequest: boolean;
|
|
33
|
+
}): Promise<unknown>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-prototype-builtins */
|
|
3
|
+
/*!
|
|
4
|
+
* Contentstack Import
|
|
5
|
+
* Copyright (c) 2019 Contentstack LLC
|
|
6
|
+
* MIT Licensed
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const tslib_1 = require("tslib");
|
|
10
|
+
const path = tslib_1.__importStar(require("path"));
|
|
11
|
+
const lodash_1 = require("lodash");
|
|
12
|
+
const utils_1 = require("../../utils");
|
|
13
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
14
|
+
class ImportGlobalFields extends base_class_1.default {
|
|
15
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
16
|
+
super({ importConfig, stackAPIClient });
|
|
17
|
+
this.config = importConfig;
|
|
18
|
+
this.gFsConfig = importConfig.modules['global-fields'];
|
|
19
|
+
this.gFs = [];
|
|
20
|
+
this.gFsUidMapper = {};
|
|
21
|
+
this.createdGFs = [];
|
|
22
|
+
this.failedGFs = [];
|
|
23
|
+
this.pendingGFs = [];
|
|
24
|
+
this.reqConcurrency = this.gFsConfig.writeConcurrency || this.config.writeConcurrency;
|
|
25
|
+
this.gFsMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields');
|
|
26
|
+
this.gFsFolderPath = path.resolve(this.config.data, this.gFsConfig.dirName);
|
|
27
|
+
this.gFsFailsPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'fails.json');
|
|
28
|
+
this.gFsSuccessPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'success.json');
|
|
29
|
+
this.gFsUidMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'uid-mapping.json');
|
|
30
|
+
this.gFsPendingPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'pending_global_fields.js');
|
|
31
|
+
this.marketplaceAppMapperPath = path.join(this.config.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
32
|
+
}
|
|
33
|
+
async start() {
|
|
34
|
+
this.gFs = utils_1.fsUtil.readFile(path.join(this.gFsFolderPath, this.gFsConfig.fileName));
|
|
35
|
+
if (!this.gFs || (0, lodash_1.isEmpty)(this.gFs)) {
|
|
36
|
+
(0, utils_1.log)(this.config, 'No global fields found to import', 'info');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await utils_1.fsUtil.makeDirectory(this.gFsMapperPath);
|
|
40
|
+
if (utils_1.fileHelper.fileExistsSync(this.gFsUidMapperPath)) {
|
|
41
|
+
this.gFsUidMapper = (utils_1.fsUtil.readFile(this.gFsUidMapperPath) || {});
|
|
42
|
+
}
|
|
43
|
+
this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
|
|
44
|
+
await this.importGFs();
|
|
45
|
+
utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
|
|
46
|
+
(0, utils_1.log)(this.config, 'Global fields import has been completed!', 'info');
|
|
47
|
+
}
|
|
48
|
+
async importGFs() {
|
|
49
|
+
const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
|
|
50
|
+
this.createdGFs.push(globalField);
|
|
51
|
+
this.gFsUidMapper[uid] = globalField;
|
|
52
|
+
utils_1.fsUtil.writeFile(this.gFsUidMapperPath, this.gFsUidMapper);
|
|
53
|
+
(0, utils_1.log)(this.config, 'Global field ' + uid + ' created successfully', 'success');
|
|
54
|
+
};
|
|
55
|
+
const onReject = ({ error, apiData: { uid } = undefined }) => {
|
|
56
|
+
(0, utils_1.log)(this.importConfig, `Global fields '${uid}' failed to import`, 'error');
|
|
57
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
58
|
+
this.failedGFs.push({ uid });
|
|
59
|
+
};
|
|
60
|
+
return await this.makeConcurrentCall({
|
|
61
|
+
processName: 'Import global fields',
|
|
62
|
+
apiContent: this.gFs,
|
|
63
|
+
apiParams: {
|
|
64
|
+
reject: onReject.bind(this),
|
|
65
|
+
resolve: onSuccess.bind(this),
|
|
66
|
+
entity: 'create-gfs',
|
|
67
|
+
includeParamOnCompletion: true,
|
|
68
|
+
},
|
|
69
|
+
concurrencyLimit: this.reqConcurrency,
|
|
70
|
+
}, this.createGFs.bind(this));
|
|
71
|
+
}
|
|
72
|
+
async createGFs({ apiParams, element: globalField, isLastRequest, }) {
|
|
73
|
+
return new Promise(async (resolve, reject) => {
|
|
74
|
+
(0, utils_1.lookupExtension)(this.config, globalField.schema, this.config.preserveStackVersion, this.installedExtensions);
|
|
75
|
+
const isReferenceFieldRemoved = await (0, utils_1.removeReferenceFields)(globalField.schema, undefined, this.stackAPIClient);
|
|
76
|
+
if (isReferenceFieldRemoved) {
|
|
77
|
+
this.pendingGFs.push(globalField.uid);
|
|
78
|
+
}
|
|
79
|
+
return this.stack
|
|
80
|
+
.globalField()
|
|
81
|
+
.create({ global_field: globalField })
|
|
82
|
+
.then((response) => {
|
|
83
|
+
apiParams.resolve({
|
|
84
|
+
response,
|
|
85
|
+
apiData: globalField,
|
|
86
|
+
});
|
|
87
|
+
resolve(true);
|
|
88
|
+
})
|
|
89
|
+
.catch((error) => {
|
|
90
|
+
apiParams.reject({
|
|
91
|
+
error,
|
|
92
|
+
apiData: globalField,
|
|
93
|
+
});
|
|
94
|
+
reject(true);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.default = ImportGlobalFields;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import BaseClass, { ApiOptions } from './base-class';
|
|
2
|
+
import { ModuleClassParams } from '../../types';
|
|
3
|
+
export default class Importlabels extends BaseClass {
|
|
4
|
+
private mapperDirPath;
|
|
5
|
+
private labelsFolderPath;
|
|
6
|
+
private labelUidMapperPath;
|
|
7
|
+
private createdLabelPath;
|
|
8
|
+
private labelFailsPath;
|
|
9
|
+
private labelsConfig;
|
|
10
|
+
private labels;
|
|
11
|
+
private labelUidMapper;
|
|
12
|
+
private createdLabel;
|
|
13
|
+
private failedLabel;
|
|
14
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
15
|
+
/**
|
|
16
|
+
* @method start
|
|
17
|
+
* @returns {Promise<void>} Promise<void>
|
|
18
|
+
*/
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
importlabels(): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* @method serializelabels
|
|
23
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
24
|
+
* @returns {ApiOptions} ApiOptions
|
|
25
|
+
*/
|
|
26
|
+
serializelabels(apiOptions: ApiOptions): ApiOptions;
|
|
27
|
+
updateLabels(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* @method serializeUpdatelabels
|
|
30
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
31
|
+
* @returns {ApiOptions} ApiOptions
|
|
32
|
+
*/
|
|
33
|
+
serializeUpdatelabels(apiOptions: ApiOptions): ApiOptions;
|
|
34
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
5
|
+
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
6
|
+
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
11
|
+
class Importlabels extends base_class_1.default {
|
|
12
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
13
|
+
super({ importConfig, stackAPIClient });
|
|
14
|
+
this.labelsConfig = config_1.default.modules.labels;
|
|
15
|
+
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'labels');
|
|
16
|
+
this.labelsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.labelsConfig.dirName);
|
|
17
|
+
this.labelUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
18
|
+
this.createdLabelPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
|
|
19
|
+
this.labelFailsPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
|
|
20
|
+
this.labels = {};
|
|
21
|
+
this.failedLabel = [];
|
|
22
|
+
this.createdLabel = [];
|
|
23
|
+
this.labelUidMapper = {};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @method start
|
|
27
|
+
* @returns {Promise<void>} Promise<void>
|
|
28
|
+
*/
|
|
29
|
+
async start() {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
(0, utils_1.log)(this.importConfig, 'Migrating labels', 'info');
|
|
32
|
+
//Step1 check folder exists or not
|
|
33
|
+
if (utils_1.fileHelper.fileExistsSync(this.labelsFolderPath)) {
|
|
34
|
+
this.labels = utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelsFolderPath, 'labels.json'), true);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.labelsFolderPath}'`, 'error');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
//create labels in mapper directory
|
|
41
|
+
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
42
|
+
this.labelUidMapper = utils_1.fileHelper.fileExistsSync(this.labelUidMapperPath)
|
|
43
|
+
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelUidMapperPath), true)
|
|
44
|
+
: {};
|
|
45
|
+
await this.importlabels();
|
|
46
|
+
//update parent in created label
|
|
47
|
+
await this.updateLabels();
|
|
48
|
+
if ((_a = this.createdLabel) === null || _a === void 0 ? void 0 : _a.length) {
|
|
49
|
+
utils_1.fsUtil.writeFile(this.createdLabelPath, this.createdLabel);
|
|
50
|
+
}
|
|
51
|
+
if ((_b = this.failedLabel) === null || _b === void 0 ? void 0 : _b.length) {
|
|
52
|
+
utils_1.fsUtil.writeFile(this.labelFailsPath, this.failedLabel);
|
|
53
|
+
}
|
|
54
|
+
(0, utils_1.log)(this.importConfig, 'Labels have been imported successfully!', 'success');
|
|
55
|
+
}
|
|
56
|
+
async importlabels() {
|
|
57
|
+
if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
|
|
58
|
+
(0, utils_1.log)(this.importConfig, 'No Label Found', 'info');
|
|
59
|
+
return (0, node_path_1.resolve)();
|
|
60
|
+
}
|
|
61
|
+
const apiContent = (0, values_1.default)(this.labels);
|
|
62
|
+
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
63
|
+
this.labelUidMapper[uid] = response;
|
|
64
|
+
(0, utils_1.log)(this.importConfig, `Label '${name}' imported successfully`, 'success');
|
|
65
|
+
utils_1.fsUtil.writeFile(this.labelUidMapperPath, this.labelUidMapper);
|
|
66
|
+
};
|
|
67
|
+
const onReject = ({ error, apiData }) => {
|
|
68
|
+
var _a;
|
|
69
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
70
|
+
const { name } = apiData;
|
|
71
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
|
|
72
|
+
(0, utils_1.log)(this.importConfig, `Label '${name}' already exists`, 'info');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.failedLabel.push(apiData);
|
|
76
|
+
(0, utils_1.log)(this.importConfig, `Label '${name}' failed to be import. ${(0, utils_1.formatError)(error)}`, 'error');
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
await this.makeConcurrentCall({
|
|
80
|
+
apiContent,
|
|
81
|
+
processName: 'create labels',
|
|
82
|
+
apiParams: {
|
|
83
|
+
serializeData: this.serializelabels.bind(this),
|
|
84
|
+
reject: onReject.bind(this),
|
|
85
|
+
resolve: onSuccess.bind(this),
|
|
86
|
+
entity: 'create-labels',
|
|
87
|
+
includeParamOnCompletion: true,
|
|
88
|
+
},
|
|
89
|
+
concurrencyLimit: config_1.default.fetchConcurrency || 1,
|
|
90
|
+
}, undefined, false);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @method serializelabels
|
|
94
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
95
|
+
* @returns {ApiOptions} ApiOptions
|
|
96
|
+
*/
|
|
97
|
+
serializelabels(apiOptions) {
|
|
98
|
+
var _a;
|
|
99
|
+
const { apiData: label } = apiOptions;
|
|
100
|
+
if (this.labelUidMapper.hasOwnProperty(label.uid)) {
|
|
101
|
+
(0, utils_1.log)(this.importConfig, `Label '${label.name}' already exists. Skipping it to avoid duplicates!`, 'info');
|
|
102
|
+
apiOptions.entity = undefined;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
let labelReq = label;
|
|
106
|
+
if (((_a = label === null || label === void 0 ? void 0 : label.parent) === null || _a === void 0 ? void 0 : _a.length) != 0) {
|
|
107
|
+
labelReq = (0, omit_1.default)(label, ['parent']);
|
|
108
|
+
}
|
|
109
|
+
apiOptions.apiData = labelReq;
|
|
110
|
+
}
|
|
111
|
+
return apiOptions;
|
|
112
|
+
}
|
|
113
|
+
async updateLabels() {
|
|
114
|
+
if (!(0, isEmpty_1.default)(this.labels)) {
|
|
115
|
+
const apiContent = (0, values_1.default)(this.labels);
|
|
116
|
+
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
117
|
+
this.createdLabel.push(response);
|
|
118
|
+
(0, utils_1.log)(this.importConfig, `Label '${name}' updated successfully`, 'success');
|
|
119
|
+
};
|
|
120
|
+
const onReject = ({ error, apiData }) => {
|
|
121
|
+
(0, utils_1.log)(this.importConfig, `Failed to update label '${apiData === null || apiData === void 0 ? void 0 : apiData.name}'. ${(0, utils_1.formatError)(error)}`, 'error');
|
|
122
|
+
};
|
|
123
|
+
await this.makeConcurrentCall({
|
|
124
|
+
apiContent,
|
|
125
|
+
processName: 'update labels',
|
|
126
|
+
apiParams: {
|
|
127
|
+
serializeData: this.serializeUpdatelabels.bind(this),
|
|
128
|
+
reject: onReject.bind(this),
|
|
129
|
+
resolve: onSuccess.bind(this),
|
|
130
|
+
entity: 'update-labels',
|
|
131
|
+
includeParamOnCompletion: true,
|
|
132
|
+
},
|
|
133
|
+
concurrencyLimit: config_1.default.fetchConcurrency || 1,
|
|
134
|
+
}, undefined, false);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @method serializeUpdatelabels
|
|
139
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
140
|
+
* @returns {ApiOptions} ApiOptions
|
|
141
|
+
*/
|
|
142
|
+
serializeUpdatelabels(apiOptions) {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
const { apiData: label } = apiOptions;
|
|
145
|
+
const labelUid = label.uid;
|
|
146
|
+
if (this.labelUidMapper.hasOwnProperty(labelUid)) {
|
|
147
|
+
const newLabel = this.labelUidMapper[labelUid];
|
|
148
|
+
if (((_a = label === null || label === void 0 ? void 0 : label.parent) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
149
|
+
for (let i = 0; i < ((_b = label === null || label === void 0 ? void 0 : label.parent) === null || _b === void 0 ? void 0 : _b.length); i++) {
|
|
150
|
+
const parentUid = label.parent[i];
|
|
151
|
+
if (this.labelUidMapper.hasOwnProperty(parentUid)) {
|
|
152
|
+
const mappedLabel = this.labelUidMapper[parentUid];
|
|
153
|
+
label.parent[i] = mappedLabel.uid;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const createdLabelRes = this.labelUidMapper[labelUid];
|
|
157
|
+
createdLabelRes.parent = label.parent;
|
|
158
|
+
apiOptions.apiData = createdLabelRes;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
apiOptions.entity = undefined;
|
|
162
|
+
this.createdLabel.push(newLabel);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
apiOptions.entity = undefined;
|
|
167
|
+
}
|
|
168
|
+
return apiOptions;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.default = Importlabels;
|
|
@@ -32,14 +32,6 @@ class ImportLocales extends base_class_1.default {
|
|
|
32
32
|
this.langUidMapperPath = path.resolve(this.config.data, 'mapper', 'languages', 'uid-mapper.json');
|
|
33
33
|
}
|
|
34
34
|
async start() {
|
|
35
|
-
/**
|
|
36
|
-
* read locales
|
|
37
|
-
* create a mapper dir
|
|
38
|
-
* read / create a locale uid mapper
|
|
39
|
-
* update master language details if it same
|
|
40
|
-
* create locales
|
|
41
|
-
* update locales
|
|
42
|
-
*/
|
|
43
35
|
this.languages = utils_1.fsUtil.readFile(path.join(this.langFolderPath, this.localeConfig.fileName));
|
|
44
36
|
if (!this.languages || (0, lodash_1.isEmpty)(this.languages)) {
|
|
45
37
|
(0, utils_1.log)(this.config, 'No languages found to import', 'info');
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { NodeCrypto, ContentstackClient } from '@contentstack/cli-utilities';
|
|
2
|
+
import BaseClass from './base-class';
|
|
3
|
+
import { ModuleClassParams } from '../../types';
|
|
4
|
+
export default class ImportMarketplaceApps extends BaseClass {
|
|
5
|
+
private mapperDirPath;
|
|
6
|
+
private marketPlaceFolderPath;
|
|
7
|
+
private marketPlaceUidMapperPath;
|
|
8
|
+
private marketPlaceAppConfig;
|
|
9
|
+
private marketplaceApps;
|
|
10
|
+
private httpClient;
|
|
11
|
+
private appNameMapping;
|
|
12
|
+
private appUidMapping;
|
|
13
|
+
private installationUidMapping;
|
|
14
|
+
private installedApps;
|
|
15
|
+
private appOrginalName;
|
|
16
|
+
developerHubBaseUrl: string;
|
|
17
|
+
sdkClient: ContentstackClient;
|
|
18
|
+
nodeCrypto: NodeCrypto;
|
|
19
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
20
|
+
/**
|
|
21
|
+
* @method start
|
|
22
|
+
* @returns {Promise<void>} Promise<void>
|
|
23
|
+
*/
|
|
24
|
+
start(): Promise<void>;
|
|
25
|
+
setHttpClient(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* @method startInstallation
|
|
28
|
+
* @returns {Promise<void>}
|
|
29
|
+
*/
|
|
30
|
+
startInstallation(): Promise<void>;
|
|
31
|
+
generateUidMapper(): Promise<Record<string, unknown>>;
|
|
32
|
+
getAndValidateEncryptionKey(defaultValue: string, retry?: number): Promise<any>;
|
|
33
|
+
/**
|
|
34
|
+
* @method handleAllPrivateAppsCreationProcess
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
*/
|
|
37
|
+
handleAllPrivateAppsCreationProcess(): Promise<void>;
|
|
38
|
+
createPrivateApps(app: any, uidCleaned?: boolean, appSuffix?: number): Promise<any>;
|
|
39
|
+
updateManifestUILocations(locations: any, type?: string, appSuffix?: number): Promise<any[]>;
|
|
40
|
+
appCreationCallback(app: any, response: any, appSuffix: number): Promise<any>;
|
|
41
|
+
/**
|
|
42
|
+
* @method installApps
|
|
43
|
+
* @returns {Void}
|
|
44
|
+
*/
|
|
45
|
+
installApps(app: any): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* @method updateAppsConfig
|
|
48
|
+
* @returns {Promise<void>}
|
|
49
|
+
*/
|
|
50
|
+
updateAppsConfig(app: any): Promise<void>;
|
|
51
|
+
}
|