@contentstack/cli-cm-import 1.6.0 → 1.7.1

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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/lib/commands/cm/stacks/import.js +1 -1
  3. package/lib/config/index.js +24 -1
  4. package/lib/import/modules/base-class.d.ts +3 -2
  5. package/lib/import/modules/base-class.js +53 -0
  6. package/lib/import/modules/content-types.d.ts +56 -0
  7. package/lib/import/modules/content-types.js +186 -0
  8. package/lib/import/modules/custom-roles.d.ts +37 -0
  9. package/lib/import/modules/custom-roles.js +171 -0
  10. package/lib/import/modules/environments.d.ts +27 -0
  11. package/lib/import/modules/environments.js +106 -0
  12. package/lib/import/modules/extensions.d.ts +27 -0
  13. package/lib/import/modules/extensions.js +106 -0
  14. package/lib/import/modules/global-fields.d.ts +34 -0
  15. package/lib/import/modules/global-fields.js +99 -0
  16. package/lib/import/modules/labels.d.ts +34 -0
  17. package/lib/import/modules/labels.js +171 -0
  18. package/lib/import/modules/locales.js +0 -8
  19. package/lib/import/modules/marketplace-apps.d.ts +51 -0
  20. package/lib/import/modules/marketplace-apps.js +309 -0
  21. package/lib/import/modules/webhooks.d.ts +27 -0
  22. package/lib/import/modules/webhooks.js +110 -0
  23. package/lib/import/modules-js/custom-roles.js +2 -0
  24. package/lib/import/modules-js/entries.js +8 -2
  25. package/lib/import/modules-js/extensions.d.ts +1 -0
  26. package/lib/import/modules-js/marketplace-apps.js +11 -11
  27. package/lib/types/default-config.d.ts +13 -0
  28. package/lib/types/import-config.d.ts +1 -0
  29. package/lib/types/index.d.ts +33 -0
  30. package/lib/types/index.js +2 -0
  31. package/lib/utils/content-type-helper.d.ts +3 -1
  32. package/lib/utils/content-type-helper.js +3 -1
  33. package/lib/utils/extension-helper.d.ts +0 -5
  34. package/lib/utils/extension-helper.js +23 -11
  35. package/lib/utils/index.d.ts +1 -1
  36. package/lib/utils/index.js +11 -1
  37. package/lib/utils/interactive.d.ts +5 -0
  38. package/lib/utils/interactive.js +66 -1
  39. package/lib/utils/marketplace-app-helper.d.ts +13 -1
  40. package/lib/utils/marketplace-app-helper.js +127 -15
  41. package/oclif.manifest.json +1 -1
  42. 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
+ }