@contentstack/cli-cm-import 1.10.0 → 1.11.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 +2 -0
- package/lib/config/index.js +10 -1
- package/lib/import/module-importer.js +14 -7
- package/lib/import/modules/base-class.d.ts +1 -1
- package/lib/import/modules/base-class.js +11 -0
- package/lib/import/modules/content-types.d.ts +2 -0
- package/lib/import/modules/content-types.js +5 -1
- package/lib/import/modules/entries.d.ts +2 -0
- package/lib/import/modules/entries.js +4 -0
- package/lib/import/modules/marketplace-apps.js +8 -2
- package/lib/import/modules/taxonomies.d.ts +63 -0
- package/lib/import/modules/taxonomies.js +217 -0
- package/lib/import/modules-js/marketplace-apps.js +11 -3
- package/lib/types/default-config.d.ts +11 -0
- package/lib/types/index.d.ts +11 -1
- package/lib/utils/backup-handler.d.ts +1 -1
- package/lib/utils/backup-handler.js +32 -31
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +5 -1
- package/lib/utils/log.d.ts +10 -0
- package/lib/utils/log.js +30 -0
- package/lib/utils/logger.js +9 -7
- package/lib/utils/marketplace-app-helper.js +14 -4
- package/lib/utils/taxonomies-helper.d.ts +16 -0
- package/lib/utils/taxonomies-helper.js +96 -0
- package/oclif.manifest.json +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
|
|
|
47
47
|
$ csdx COMMAND
|
|
48
48
|
running command...
|
|
49
49
|
$ csdx (--version)
|
|
50
|
-
@contentstack/cli-cm-import/1.
|
|
50
|
+
@contentstack/cli-cm-import/1.11.0 linux-x64 node-v18.18.2
|
|
51
51
|
$ csdx --help [COMMAND]
|
|
52
52
|
USAGE
|
|
53
53
|
$ csdx COMMAND
|
|
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
5
5
|
const cli_command_1 = require("@contentstack/cli-command");
|
|
6
6
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
7
|
+
const log_1 = require("../../../utils/log");
|
|
7
8
|
const import_1 = require("../../../import");
|
|
8
9
|
const utils_1 = require("../../../utils");
|
|
9
10
|
class ImportCommand extends cli_command_1.Command {
|
|
@@ -25,6 +26,7 @@ class ImportCommand extends cli_command_1.Command {
|
|
|
25
26
|
(0, utils_1.log)(importConfig, `The log has been stored at '${node_path_1.default.join(importConfig.backupDir, 'logs', 'import')}'`, 'success');
|
|
26
27
|
}
|
|
27
28
|
catch (error) {
|
|
29
|
+
(0, log_1.trace)(error, 'error', true);
|
|
28
30
|
(0, utils_1.log)({ data: backupDir }, `Failed to import stack content - ${(0, utils_1.formatError)(error)}`, 'error');
|
|
29
31
|
(0, utils_1.log)({ data: backupDir }, `The log has been stored at ${{ data: backupDir } ? node_path_1.default.join(backupDir || __dirname, 'logs', 'import') : node_path_1.default.join(__dirname, 'logs')}`, 'info');
|
|
30
32
|
}
|
package/lib/config/index.js
CHANGED
|
@@ -18,7 +18,6 @@ const config = {
|
|
|
18
18
|
'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com',
|
|
19
19
|
'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com',
|
|
20
20
|
'https://azure-eu-api.contentstack.com': 'https://azure-eu-developerhub-api.contentstack.com',
|
|
21
|
-
'https://stag-api.csnonprod.com': 'https://stag-developerhub-api.csnonprod.com',
|
|
22
21
|
},
|
|
23
22
|
modules: {
|
|
24
23
|
apiConcurrency: 5,
|
|
@@ -26,6 +25,7 @@ const config = {
|
|
|
26
25
|
'locales',
|
|
27
26
|
'environments',
|
|
28
27
|
'assets',
|
|
28
|
+
'taxonomies',
|
|
29
29
|
'extensions',
|
|
30
30
|
'marketplace-apps',
|
|
31
31
|
'global-fields',
|
|
@@ -142,6 +142,14 @@ const config = {
|
|
|
142
142
|
dirName: 'marketplace_apps',
|
|
143
143
|
fileName: 'marketplace_apps.json',
|
|
144
144
|
},
|
|
145
|
+
taxonomies: {
|
|
146
|
+
dirName: 'taxonomies',
|
|
147
|
+
fileName: 'taxonomies.json',
|
|
148
|
+
},
|
|
149
|
+
terms: {
|
|
150
|
+
dirName: 'terms',
|
|
151
|
+
fileName: 'terms.json',
|
|
152
|
+
},
|
|
145
153
|
},
|
|
146
154
|
languagesCode: [
|
|
147
155
|
'af-za',
|
|
@@ -380,5 +388,6 @@ const config = {
|
|
|
380
388
|
getEncryptionKeyMaxRetry: 3,
|
|
381
389
|
// useBackedupDir: '',
|
|
382
390
|
// backupConcurrency: 10,
|
|
391
|
+
onlyTSModules: ['taxonomies'],
|
|
383
392
|
};
|
|
384
393
|
exports.default = config;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
5
|
const modules_1 = tslib_1.__importDefault(require("./modules"));
|
|
7
6
|
const modules_js_1 = tslib_1.__importDefault(require("./modules-js"));
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
8
|
class ModuleImporter {
|
|
9
9
|
constructor(managementAPIClient, importConfig) {
|
|
10
10
|
this.managementAPIClient = managementAPIClient;
|
|
@@ -43,6 +43,8 @@ class ModuleImporter {
|
|
|
43
43
|
// To support the old config
|
|
44
44
|
this.importConfig.data = backupDir;
|
|
45
45
|
}
|
|
46
|
+
// NOTE init log
|
|
47
|
+
(0, utils_1.initLogger)(this.importConfig);
|
|
46
48
|
await (0, utils_1.sanitizeStack)(this.stackAPIClient);
|
|
47
49
|
return this.import();
|
|
48
50
|
}
|
|
@@ -58,7 +60,7 @@ class ModuleImporter {
|
|
|
58
60
|
(0, utils_1.log)(this.importConfig, `Starting import of ${moduleName} module`, 'info');
|
|
59
61
|
// import the modules by name
|
|
60
62
|
// calls the module runner which inturn calls the module itself
|
|
61
|
-
//
|
|
63
|
+
// NOTE: Implement a mechanism to determine whether module is new or old
|
|
62
64
|
if (this.importConfig.contentVersion === 2) {
|
|
63
65
|
return (0, modules_1.default)({
|
|
64
66
|
stackAPIClient: this.stackAPIClient,
|
|
@@ -66,11 +68,16 @@ class ModuleImporter {
|
|
|
66
68
|
moduleName,
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
else {
|
|
72
|
+
//NOTE - new modules support only ts
|
|
73
|
+
if (this.importConfig.onlyTSModules.indexOf(moduleName) === -1) {
|
|
74
|
+
return (0, modules_js_1.default)({
|
|
75
|
+
stackAPIClient: this.stackAPIClient,
|
|
76
|
+
importConfig: this.importConfig,
|
|
77
|
+
moduleName,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
74
81
|
}
|
|
75
82
|
async importAllModules() {
|
|
76
83
|
// use the algorithm to determine the parallel and sequential execution of modules
|
|
@@ -3,7 +3,7 @@ import { ImportConfig, ModuleClassParams } from '../../types';
|
|
|
3
3
|
export type AdditionalKeys = {
|
|
4
4
|
backupDir: string;
|
|
5
5
|
};
|
|
6
|
-
export type ApiModuleType = 'create-assets' | 'replace-assets' | 'publish-assets' | 'create-assets-folder' | 'create-extensions' | 'update-extensions' | 'create-locale' | 'update-locale' | 'create-gfs' | 'create-cts' | 'update-cts' | 'update-gfs' | 'create-environments' | 'create-labels' | 'update-labels' | 'create-webhooks' | 'create-workflows' | 'create-custom-role' | 'create-entries' | 'update-entries' | 'publish-entries' | 'delete-entries';
|
|
6
|
+
export type ApiModuleType = 'create-assets' | 'replace-assets' | 'publish-assets' | 'create-assets-folder' | 'create-extensions' | 'update-extensions' | 'create-locale' | 'update-locale' | 'create-gfs' | 'create-cts' | 'update-cts' | 'update-gfs' | 'create-environments' | 'create-labels' | 'update-labels' | 'create-webhooks' | 'create-workflows' | 'create-custom-role' | 'create-entries' | 'update-entries' | 'publish-entries' | 'delete-entries' | 'create-taxonomies' | 'create-terms';
|
|
7
7
|
export type ApiOptions = {
|
|
8
8
|
uid?: string;
|
|
9
9
|
url?: string;
|
|
@@ -255,6 +255,17 @@ class BaseClass {
|
|
|
255
255
|
.delete({ locale: additionalInfo.locale })
|
|
256
256
|
.then(onSuccess)
|
|
257
257
|
.catch(onReject);
|
|
258
|
+
case 'create-taxonomies':
|
|
259
|
+
return this.stack.taxonomy().create({ taxonomy: apiData }).then(onSuccess).catch(onReject);
|
|
260
|
+
case 'create-terms':
|
|
261
|
+
if (apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy_uid) {
|
|
262
|
+
return this.stack
|
|
263
|
+
.taxonomy(apiData.taxonomy_uid)
|
|
264
|
+
.terms()
|
|
265
|
+
.create({ term: apiData })
|
|
266
|
+
.then(onSuccess)
|
|
267
|
+
.catch(onReject);
|
|
268
|
+
}
|
|
258
269
|
default:
|
|
259
270
|
return Promise.resolve();
|
|
260
271
|
}
|
|
@@ -30,6 +30,8 @@ export default class ContentTypesImport extends BaseClass {
|
|
|
30
30
|
private installedExtensions;
|
|
31
31
|
private cTsConfig;
|
|
32
32
|
private gFsConfig;
|
|
33
|
+
private taxonomiesPath;
|
|
34
|
+
taxonomies: Record<string, unknown>;
|
|
33
35
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
34
36
|
start(): Promise<any>;
|
|
35
37
|
seedCTs(): Promise<any>;
|
|
@@ -38,6 +38,7 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
38
38
|
this.gFs = [];
|
|
39
39
|
this.createdGFs = [];
|
|
40
40
|
this.pendingGFs = [];
|
|
41
|
+
this.taxonomiesPath = path.join(importConfig.data, 'mapper/taxonomies', 'success.json');
|
|
41
42
|
}
|
|
42
43
|
async start() {
|
|
43
44
|
/**
|
|
@@ -54,6 +55,7 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
54
55
|
}
|
|
55
56
|
await utils_1.fsUtil.makeDirectory(this.cTsMapperPath);
|
|
56
57
|
this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
|
|
58
|
+
this.taxonomies = utils_1.fsUtil.readFile(this.taxonomiesPath);
|
|
57
59
|
await this.seedCTs();
|
|
58
60
|
(0, utils_1.log)(this.importConfig, 'Created content types', 'success');
|
|
59
61
|
await this.updateCTs();
|
|
@@ -108,7 +110,7 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
108
110
|
}
|
|
109
111
|
async updateCTs() {
|
|
110
112
|
const onSuccess = ({ response: contentType, apiData: { uid } }) => {
|
|
111
|
-
(0, utils_1.log)(this.importConfig,
|
|
113
|
+
(0, utils_1.log)(this.importConfig, `'${uid}' updated with references`, 'success');
|
|
112
114
|
};
|
|
113
115
|
const onReject = ({ error, apiData: { uid } }) => {
|
|
114
116
|
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
@@ -141,6 +143,8 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
141
143
|
}
|
|
142
144
|
this.fieldRules.push(contentType.uid);
|
|
143
145
|
}
|
|
146
|
+
//will remove taxonomy if taxonomy doesn't exists in stack
|
|
147
|
+
(0, utils_1.lookUpTaxonomy)(this.importConfig, contentType.schema, this.taxonomies);
|
|
144
148
|
(0, utils_1.lookupExtension)(this.importConfig, contentType.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
|
|
145
149
|
const contentTypePayload = this.stack.contentType(contentType.uid);
|
|
146
150
|
Object.assign(contentTypePayload, (0, lodash_1.cloneDeep)(contentType));
|
|
@@ -34,6 +34,8 @@ export default class EntriesImport extends BaseClass {
|
|
|
34
34
|
private entriesUidMapper;
|
|
35
35
|
private envs;
|
|
36
36
|
private autoCreatedEntries;
|
|
37
|
+
private taxonomiesPath;
|
|
38
|
+
taxonomies: Record<string, unknown>;
|
|
37
39
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
38
40
|
start(): Promise<any>;
|
|
39
41
|
disableMandatoryCTReferences(): Promise<void>;
|
|
@@ -23,6 +23,7 @@ class EntriesImport extends base_class_1.default {
|
|
|
23
23
|
this.uniqueUidMapperPath = path.join(this.entriesMapperPath, 'unique-mapping.json');
|
|
24
24
|
this.modifiedCTsPath = path.join(this.entriesMapperPath, 'modified-schemas.json');
|
|
25
25
|
this.marketplaceAppMapperPath = path.join(this.importConfig.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
26
|
+
this.taxonomiesPath = path.join(this.importConfig.data, 'mapper', 'taxonomies', 'terms', 'success.json');
|
|
26
27
|
this.entriesConfig = importConfig.modules.entries;
|
|
27
28
|
this.entriesPath = path.resolve(importConfig.data, this.entriesConfig.dirName);
|
|
28
29
|
this.cTsPath = path.resolve(importConfig.data, importConfig.modules['content-types'].dirName);
|
|
@@ -47,6 +48,7 @@ class EntriesImport extends base_class_1.default {
|
|
|
47
48
|
this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
|
|
48
49
|
this.assetUidMapper = utils_1.fsUtil.readFile(this.assetUidMapperPath) || {};
|
|
49
50
|
this.assetUrlMapper = utils_1.fsUtil.readFile(this.assetUrlMapperPath) || {};
|
|
51
|
+
this.taxonomies = utils_1.fsUtil.readFile(this.taxonomiesPath);
|
|
50
52
|
utils_1.fsUtil.makeDirectory(this.entriesMapperPath);
|
|
51
53
|
await this.disableMandatoryCTReferences();
|
|
52
54
|
this.locales = (0, lodash_1.values)(utils_1.fsUtil.readFile(this.localesPath));
|
|
@@ -316,6 +318,8 @@ class EntriesImport extends base_class_1.default {
|
|
|
316
318
|
if (this.jsonRteCTsWithRef.indexOf(cTUid) > -1) {
|
|
317
319
|
entry = (0, utils_1.removeEntryRefsFromJSONRTE)(entry, contentType.schema);
|
|
318
320
|
}
|
|
321
|
+
//will remove term if term doesn't exists in taxonomy
|
|
322
|
+
(0, utils_1.lookUpTerms)(contentType === null || contentType === void 0 ? void 0 : contentType.schema, entry, this.taxonomies, this.importConfig);
|
|
319
323
|
// will replace all old asset uid/urls with new ones
|
|
320
324
|
entry = (0, utils_1.lookupAssets)({
|
|
321
325
|
content_type: contentType,
|
|
@@ -14,6 +14,7 @@ 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
16
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
17
|
+
const log_1 = require("../../utils/log");
|
|
17
18
|
const interactive_1 = require("../../utils/interactive");
|
|
18
19
|
const utils_1 = require("../../utils");
|
|
19
20
|
class ImportMarketplaceApps extends base_class_1.default {
|
|
@@ -54,7 +55,7 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
54
55
|
this.developerHubBaseUrl = this.importConfig.developerHubBaseUrl || (await (0, utils_1.getDeveloperHubUrl)(this.importConfig));
|
|
55
56
|
this.sdkClient = await (0, cli_utilities_1.managementSDKClient)({ endpoint: this.developerHubBaseUrl });
|
|
56
57
|
this.appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
|
|
57
|
-
host: this.developerHubBaseUrl.split('://').pop()
|
|
58
|
+
host: this.developerHubBaseUrl.split('://').pop(),
|
|
58
59
|
});
|
|
59
60
|
this.importConfig.org_uid = await (0, utils_1.getOrgUid)(this.importConfig);
|
|
60
61
|
await this.setHttpClient();
|
|
@@ -223,6 +224,7 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
223
224
|
return this.createPrivateApps(updatedApp, true, appSuffix + 1);
|
|
224
225
|
}
|
|
225
226
|
else {
|
|
227
|
+
(0, log_1.trace)(response, 'error', true);
|
|
226
228
|
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(message), 'error');
|
|
227
229
|
if (this.importConfig.forceStopMarketplaceAppsPrompt)
|
|
228
230
|
return Promise.resolve();
|
|
@@ -308,13 +310,17 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
308
310
|
})
|
|
309
311
|
.then(({ data }) => {
|
|
310
312
|
if (data === null || data === void 0 ? void 0 : data.message) {
|
|
313
|
+
(0, log_1.trace)(data, 'error', true);
|
|
311
314
|
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(data.message), 'success');
|
|
312
315
|
}
|
|
313
316
|
else {
|
|
314
317
|
(0, utils_1.log)(this.importConfig, `${app.manifest.name} app config updated successfully.!`, 'success');
|
|
315
318
|
}
|
|
316
319
|
})
|
|
317
|
-
.catch((error) =>
|
|
320
|
+
.catch((error) => {
|
|
321
|
+
(0, log_1.trace)(error, 'error', true);
|
|
322
|
+
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
323
|
+
});
|
|
318
324
|
}
|
|
319
325
|
}
|
|
320
326
|
exports.default = ImportMarketplaceApps;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import BaseClass, { ApiOptions } from './base-class';
|
|
2
|
+
import { ModuleClassParams } from '../../types';
|
|
3
|
+
export default class ImportTaxonomies extends BaseClass {
|
|
4
|
+
private taxonomiesMapperDirPath;
|
|
5
|
+
private taxonomiesFolderPath;
|
|
6
|
+
private taxSuccessPath;
|
|
7
|
+
private taxFailsPath;
|
|
8
|
+
private taxonomiesConfig;
|
|
9
|
+
private taxonomies;
|
|
10
|
+
private termsFolderPath;
|
|
11
|
+
private termsMapperDirPath;
|
|
12
|
+
private termsConfig;
|
|
13
|
+
private termsSuccessPath;
|
|
14
|
+
private termsFailsPath;
|
|
15
|
+
taxonomiesSuccess: Record<string, unknown>;
|
|
16
|
+
taxonomiesFailed: Record<string, unknown>;
|
|
17
|
+
termsSuccess: Record<string, Record<string, unknown>>;
|
|
18
|
+
termsFailed: Record<string, Record<string, unknown>>;
|
|
19
|
+
terms: Record<string, any>;
|
|
20
|
+
taxonomyUIDs: string[];
|
|
21
|
+
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
22
|
+
/**
|
|
23
|
+
* @method start
|
|
24
|
+
* @returns {Promise<void>} Promise<void>
|
|
25
|
+
*/
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* create taxonomy and enter success & failure related data into taxonomies mapper file
|
|
29
|
+
* @method importTaxonomies
|
|
30
|
+
* @async
|
|
31
|
+
* @returns {Promise<any>} Promise<any>
|
|
32
|
+
*/
|
|
33
|
+
importTaxonomies(): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* @method serializeTaxonomy
|
|
36
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
37
|
+
* @returns {ApiOptions} ApiOptions
|
|
38
|
+
*/
|
|
39
|
+
serializeTaxonomy(apiOptions: ApiOptions): ApiOptions;
|
|
40
|
+
/**
|
|
41
|
+
* create taxonomies success and fail in (mapper/taxonomies)
|
|
42
|
+
* @method createTaxonomySuccessAndFailedFile
|
|
43
|
+
*/
|
|
44
|
+
createTaxonomySuccessAndFailedFile(): void;
|
|
45
|
+
/**
|
|
46
|
+
* create terms and enter success & failure related data into terms mapper file
|
|
47
|
+
* @method importTerms
|
|
48
|
+
* @async
|
|
49
|
+
* @returns {Promise<any>} Promise<any>
|
|
50
|
+
*/
|
|
51
|
+
importTerms(): Promise<any>;
|
|
52
|
+
/**
|
|
53
|
+
* @method serializeTerms
|
|
54
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
55
|
+
* @returns {ApiOptions} ApiOptions
|
|
56
|
+
*/
|
|
57
|
+
serializeTerms(apiOptions: ApiOptions): ApiOptions;
|
|
58
|
+
/**
|
|
59
|
+
* create terms success and fail in (mapper/taxonomies/terms)
|
|
60
|
+
* @method createTermSuccessAndFailedFile
|
|
61
|
+
*/
|
|
62
|
+
createTermSuccessAndFailedFile(): void;
|
|
63
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const keys_1 = tslib_1.__importDefault(require("lodash/keys"));
|
|
5
|
+
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
8
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
9
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
|
+
const utils_1 = require("../../utils");
|
|
11
|
+
class ImportTaxonomies extends base_class_1.default {
|
|
12
|
+
constructor({ importConfig, stackAPIClient }) {
|
|
13
|
+
super({ importConfig, stackAPIClient });
|
|
14
|
+
this.taxonomiesSuccess = {};
|
|
15
|
+
this.taxonomiesFailed = {};
|
|
16
|
+
this.termsSuccess = {};
|
|
17
|
+
this.termsFailed = {};
|
|
18
|
+
this.terms = [];
|
|
19
|
+
this.taxonomyUIDs = [];
|
|
20
|
+
this.taxonomiesConfig = importConfig.modules.taxonomies;
|
|
21
|
+
this.termsConfig = importConfig.modules.terms;
|
|
22
|
+
this.taxonomiesMapperDirPath = (0, node_path_1.join)(importConfig.backupDir, 'mapper', 'taxonomies');
|
|
23
|
+
this.termsMapperDirPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'terms');
|
|
24
|
+
this.taxonomiesFolderPath = (0, node_path_1.join)(importConfig.backupDir, this.taxonomiesConfig.dirName);
|
|
25
|
+
this.termsFolderPath = (0, node_path_1.join)(this.taxonomiesFolderPath, this.termsConfig.dirName);
|
|
26
|
+
this.taxSuccessPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'success.json');
|
|
27
|
+
this.taxFailsPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'fails.json');
|
|
28
|
+
this.termsSuccessPath = (0, node_path_1.join)(this.termsMapperDirPath, 'success.json');
|
|
29
|
+
this.termsFailsPath = (0, node_path_1.join)(this.termsMapperDirPath, 'fails.json');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @method start
|
|
33
|
+
* @returns {Promise<void>} Promise<void>
|
|
34
|
+
*/
|
|
35
|
+
async start() {
|
|
36
|
+
(0, utils_1.log)(this.importConfig, 'Migrating taxonomies...', 'info');
|
|
37
|
+
//Step1 check folder exists or not
|
|
38
|
+
if (utils_1.fileHelper.fileExistsSync(this.taxonomiesFolderPath)) {
|
|
39
|
+
this.taxonomies = utils_1.fsUtil.readFile((0, node_path_1.join)(this.taxonomiesFolderPath, 'taxonomies.json'), true);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.taxonomiesFolderPath}'`, 'error');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
//Step 2 create taxonomies & terms mapper directory
|
|
46
|
+
await utils_1.fsUtil.makeDirectory(this.taxonomiesMapperDirPath);
|
|
47
|
+
await utils_1.fsUtil.makeDirectory(this.termsMapperDirPath);
|
|
48
|
+
//Step 3 import taxonomy and create success & failure file
|
|
49
|
+
await this.importTaxonomies();
|
|
50
|
+
this.createTaxonomySuccessAndFailedFile();
|
|
51
|
+
if (!utils_1.fileHelper.fileExistsSync(this.termsFolderPath)) {
|
|
52
|
+
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.termsFolderPath}'`, 'error');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
//Step 4 import terms and create success & failure file
|
|
56
|
+
await this.importTerms();
|
|
57
|
+
this.createTermSuccessAndFailedFile();
|
|
58
|
+
(0, utils_1.log)(this.importConfig, 'Taxonomies imported successfully!', 'success');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* create taxonomy and enter success & failure related data into taxonomies mapper file
|
|
62
|
+
* @method importTaxonomies
|
|
63
|
+
* @async
|
|
64
|
+
* @returns {Promise<any>} Promise<any>
|
|
65
|
+
*/
|
|
66
|
+
async importTaxonomies() {
|
|
67
|
+
if (this.taxonomies === undefined || (0, isEmpty_1.default)(this.taxonomies)) {
|
|
68
|
+
(0, utils_1.log)(this.importConfig, 'No Taxonomies Found!', 'info');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const apiContent = (0, values_1.default)(this.taxonomies);
|
|
72
|
+
this.taxonomyUIDs = (0, keys_1.default)(this.taxonomies);
|
|
73
|
+
const onSuccess = ({ response }) => {
|
|
74
|
+
const { uid } = response;
|
|
75
|
+
this.taxonomiesSuccess[uid] = (0, pick_1.default)(response, ['name', 'description']);
|
|
76
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${uid}' imported successfully!`, 'success');
|
|
77
|
+
};
|
|
78
|
+
const onReject = ({ error, apiData }) => {
|
|
79
|
+
var _a;
|
|
80
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
81
|
+
const { uid } = apiData;
|
|
82
|
+
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.taxonomy) {
|
|
83
|
+
this.taxonomiesFailed[uid] = apiData;
|
|
84
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${uid}' failed to be import! ${err.errors.taxonomy}`, 'error');
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.taxonomiesFailed[apiData.uid] = apiData;
|
|
88
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${uid}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
await this.makeConcurrentCall({
|
|
92
|
+
apiContent,
|
|
93
|
+
processName: 'import taxonomies',
|
|
94
|
+
apiParams: {
|
|
95
|
+
serializeData: this.serializeTaxonomy.bind(this),
|
|
96
|
+
reject: onReject,
|
|
97
|
+
resolve: onSuccess,
|
|
98
|
+
entity: 'create-taxonomies',
|
|
99
|
+
includeParamOnCompletion: true,
|
|
100
|
+
},
|
|
101
|
+
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
102
|
+
}, undefined, false);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* @method serializeTaxonomy
|
|
106
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
107
|
+
* @returns {ApiOptions} ApiOptions
|
|
108
|
+
*/
|
|
109
|
+
serializeTaxonomy(apiOptions) {
|
|
110
|
+
const { apiData: taxonomy } = apiOptions;
|
|
111
|
+
apiOptions.apiData = taxonomy;
|
|
112
|
+
return apiOptions;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* create taxonomies success and fail in (mapper/taxonomies)
|
|
116
|
+
* @method createTaxonomySuccessAndFailedFile
|
|
117
|
+
*/
|
|
118
|
+
createTaxonomySuccessAndFailedFile() {
|
|
119
|
+
if (this.taxonomiesSuccess !== undefined && !(0, isEmpty_1.default)(this.taxonomiesSuccess)) {
|
|
120
|
+
utils_1.fsUtil.writeFile(this.taxSuccessPath, this.taxonomiesSuccess);
|
|
121
|
+
}
|
|
122
|
+
if (this.taxonomiesFailed !== undefined && !(0, isEmpty_1.default)(this.taxonomiesFailed)) {
|
|
123
|
+
utils_1.fsUtil.writeFile(this.taxFailsPath, this.taxonomiesFailed);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* create terms and enter success & failure related data into terms mapper file
|
|
128
|
+
* @method importTerms
|
|
129
|
+
* @async
|
|
130
|
+
* @returns {Promise<any>} Promise<any>
|
|
131
|
+
*/
|
|
132
|
+
async importTerms() {
|
|
133
|
+
var _a, _b;
|
|
134
|
+
if (!((_a = this.taxonomyUIDs) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const onSuccess = ({ response, apiData: { taxonomy_uid } = { taxonomy_uid: null } }) => {
|
|
138
|
+
var _a;
|
|
139
|
+
const { uid } = response;
|
|
140
|
+
if (!((_a = this.termsSuccess) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]))
|
|
141
|
+
this.termsSuccess[taxonomy_uid] = {};
|
|
142
|
+
this.termsSuccess[taxonomy_uid][uid] = (0, pick_1.default)(response, ['name']);
|
|
143
|
+
(0, utils_1.log)(this.importConfig, `Term '${uid}' imported successfully!`, 'success');
|
|
144
|
+
};
|
|
145
|
+
const onReject = ({ error, apiData }) => {
|
|
146
|
+
var _a, _b;
|
|
147
|
+
const { taxonomy_uid, uid } = apiData;
|
|
148
|
+
if (!((_a = this.termsFailed) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]))
|
|
149
|
+
this.termsFailed[taxonomy_uid] = {};
|
|
150
|
+
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
151
|
+
if ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b.term) {
|
|
152
|
+
this.termsFailed[taxonomy_uid][uid] = apiData;
|
|
153
|
+
(0, utils_1.log)(this.importConfig, `Term '${uid}' failed to be import! ${err.errors.term}`, 'error');
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
this.termsFailed[taxonomy_uid][uid] = apiData;
|
|
157
|
+
(0, utils_1.log)(this.importConfig, `Term '${uid}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
for (const taxUID of this.taxonomyUIDs) {
|
|
161
|
+
//read terms from respective taxonomy
|
|
162
|
+
this.terms = utils_1.fsUtil.readFile((0, node_path_1.join)(this.termsFolderPath, `${taxUID}-${this.termsConfig.fileName}`), true);
|
|
163
|
+
if ((_b = this.terms) === null || _b === void 0 ? void 0 : _b.length) {
|
|
164
|
+
const apiContent = this.terms;
|
|
165
|
+
await this.makeConcurrentCall({
|
|
166
|
+
apiContent,
|
|
167
|
+
processName: 'import terms',
|
|
168
|
+
apiParams: {
|
|
169
|
+
serializeData: this.serializeTerms.bind(this),
|
|
170
|
+
reject: onReject,
|
|
171
|
+
resolve: onSuccess,
|
|
172
|
+
entity: 'create-terms',
|
|
173
|
+
includeParamOnCompletion: true,
|
|
174
|
+
},
|
|
175
|
+
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
176
|
+
}, undefined, false);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* @method serializeTerms
|
|
182
|
+
* @param {ApiOptions} apiOptions ApiOptions
|
|
183
|
+
* @returns {ApiOptions} ApiOptions
|
|
184
|
+
*/
|
|
185
|
+
serializeTerms(apiOptions) {
|
|
186
|
+
var _a, _b;
|
|
187
|
+
const { apiData: term } = apiOptions;
|
|
188
|
+
const { parent_uid, taxonomy_uid } = term;
|
|
189
|
+
//check whether parent term exists or not in taxonomy
|
|
190
|
+
if (parent_uid !== null) {
|
|
191
|
+
if (!((_b = (_a = this.termsSuccess) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]) === null || _b === void 0 ? void 0 : _b[parent_uid])) {
|
|
192
|
+
(0, utils_1.log)(this.importConfig, `Parent term '${term === null || term === void 0 ? void 0 : term.parent_uid}' does not exist! Skipping '${term.uid}' creation to avoid further issues.`, 'info');
|
|
193
|
+
apiOptions.apiData = undefined;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
apiOptions.apiData = term;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
apiOptions.apiData = term;
|
|
201
|
+
}
|
|
202
|
+
return apiOptions;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* create terms success and fail in (mapper/taxonomies/terms)
|
|
206
|
+
* @method createTermSuccessAndFailedFile
|
|
207
|
+
*/
|
|
208
|
+
createTermSuccessAndFailedFile() {
|
|
209
|
+
if (this.termsSuccess !== undefined && !(0, isEmpty_1.default)(this.termsSuccess)) {
|
|
210
|
+
utils_1.fsUtil.writeFile(this.termsSuccessPath, this.termsSuccess);
|
|
211
|
+
}
|
|
212
|
+
if (this.termsFailed !== undefined && !(0, isEmpty_1.default)(this.termsFailed)) {
|
|
213
|
+
utils_1.fsUtil.writeFile(this.termsFailsPath, this.termsFailed);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.default = ImportTaxonomies;
|
|
@@ -9,8 +9,9 @@ const path = require('path');
|
|
|
9
9
|
const chalk = require('chalk');
|
|
10
10
|
const mkdirp = require('mkdirp');
|
|
11
11
|
const { cliux, HttpClient, NodeCrypto, managementSDKClient, isAuthenticated, HttpClientDecorator, OauthDecorator, } = require('@contentstack/cli-utilities');
|
|
12
|
-
const { log, fileHelper: { readFileSync, writeFile },
|
|
13
|
-
|
|
12
|
+
const { log, formatError, fileHelper: { readFileSync, writeFile }, } = require('../../utils');
|
|
13
|
+
const { trace } = require('../../utils/log');
|
|
14
|
+
const { default: config } = require('../../config');
|
|
14
15
|
const { getDeveloperHubUrl, getAllStackSpecificApps } = require('../../utils/marketplace-app-helper');
|
|
15
16
|
module.exports = class ImportMarketplaceApps {
|
|
16
17
|
constructor(importConfig, stackAPIClient) {
|
|
@@ -306,6 +307,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
306
307
|
updateParam = Object.assign(Object.assign({ manifest: app.manifest }, installation), { configuration, server_configuration });
|
|
307
308
|
}
|
|
308
309
|
else if (installation.message) {
|
|
310
|
+
trace(installation, 'error', true);
|
|
309
311
|
log(this.config, formatError(installation.message), 'success');
|
|
310
312
|
await this.confirmToCloseProcess(installation);
|
|
311
313
|
}
|
|
@@ -329,6 +331,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
329
331
|
.get(response.redirect_url)
|
|
330
332
|
.then(async ({ response }) => {
|
|
331
333
|
if (_.includes([501, 403], response.status)) {
|
|
334
|
+
trace(response, 'error', true); // NOTE Log complete stack and hide on UI
|
|
332
335
|
log(this.config, `${appName} - ${response.statusText}, OAuth api call failed.!`, 'error');
|
|
333
336
|
log(this.config, formatError(response), 'error');
|
|
334
337
|
await this.confirmToCloseProcess({ message: response.data });
|
|
@@ -338,6 +341,7 @@ module.exports = class ImportMarketplaceApps {
|
|
|
338
341
|
}
|
|
339
342
|
})
|
|
340
343
|
.catch((error) => {
|
|
344
|
+
trace(error, 'error', true);
|
|
341
345
|
if (_.includes([501, 403], error.status)) {
|
|
342
346
|
log(this.config, formatError(error), 'error');
|
|
343
347
|
}
|
|
@@ -403,13 +407,17 @@ module.exports = class ImportMarketplaceApps {
|
|
|
403
407
|
})
|
|
404
408
|
.then(({ data }) => {
|
|
405
409
|
if (data.message) {
|
|
410
|
+
trace(data, 'error', true);
|
|
406
411
|
log(this.config, formatError(data.message), 'success');
|
|
407
412
|
}
|
|
408
413
|
else {
|
|
409
414
|
log(this.config, `${app.manifest.name} app config updated successfully.!`, 'success');
|
|
410
415
|
}
|
|
411
416
|
})
|
|
412
|
-
.catch((error) =>
|
|
417
|
+
.catch((error) => {
|
|
418
|
+
trace(data, 'error', true);
|
|
419
|
+
log(this.config, formatError(error), 'error');
|
|
420
|
+
});
|
|
413
421
|
}
|
|
414
422
|
validateAppName(name) {
|
|
415
423
|
if (name.length < 3 || name.length > 20) {
|
|
@@ -112,6 +112,16 @@ export default interface DefaultConfig {
|
|
|
112
112
|
fileName: string;
|
|
113
113
|
requiredKeys: string[];
|
|
114
114
|
};
|
|
115
|
+
taxonomies: {
|
|
116
|
+
dirName: string;
|
|
117
|
+
fileName: string;
|
|
118
|
+
dependencies?: Modules[];
|
|
119
|
+
};
|
|
120
|
+
terms: {
|
|
121
|
+
dirName: string;
|
|
122
|
+
fileName: string;
|
|
123
|
+
dependencies?: Modules[];
|
|
124
|
+
};
|
|
115
125
|
};
|
|
116
126
|
languagesCode: string[];
|
|
117
127
|
apis: {
|
|
@@ -140,4 +150,5 @@ export default interface DefaultConfig {
|
|
|
140
150
|
getEncryptionKeyMaxRetry: number;
|
|
141
151
|
createBackupDir?: string;
|
|
142
152
|
overwriteSupportedModules: string[];
|
|
153
|
+
onlyTSModules: string[];
|
|
143
154
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface User {
|
|
|
20
20
|
email: string;
|
|
21
21
|
authtoken: string;
|
|
22
22
|
}
|
|
23
|
-
export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps';
|
|
23
|
+
export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies';
|
|
24
24
|
export type ModuleClassParams = {
|
|
25
25
|
stackAPIClient: ReturnType<ContentstackClient['stack']>;
|
|
26
26
|
importConfig: ImportConfig;
|
|
@@ -60,5 +60,15 @@ export interface CustomRoleConfig {
|
|
|
60
60
|
fileName: string;
|
|
61
61
|
customRolesLocalesFileName: string;
|
|
62
62
|
}
|
|
63
|
+
export interface TaxonomiesConfig {
|
|
64
|
+
dirName: string;
|
|
65
|
+
fileName: string;
|
|
66
|
+
dependencies?: Modules[];
|
|
67
|
+
}
|
|
68
|
+
export interface TermsConfig {
|
|
69
|
+
dirName: string;
|
|
70
|
+
fileName: string;
|
|
71
|
+
dependencies?: Modules[];
|
|
72
|
+
}
|
|
63
73
|
export { default as DefaultConfig } from './default-config';
|
|
64
74
|
export { default as ImportConfig } from './import-config';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ImportConfig } from '../types';
|
|
2
|
-
export default function
|
|
2
|
+
export default function backupHandler(importConfig: ImportConfig): Promise<string>;
|
|
@@ -5,44 +5,45 @@ const path = tslib_1.__importStar(require("path"));
|
|
|
5
5
|
const fs_extra_1 = require("fs-extra");
|
|
6
6
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
7
7
|
const index_1 = require("./index");
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
}
|
|
8
|
+
async function backupHandler(importConfig) {
|
|
9
|
+
if (importConfig.hasOwnProperty('useBackedupDir')) {
|
|
10
|
+
return importConfig.useBackedupDir;
|
|
11
|
+
}
|
|
12
|
+
let backupDirPath;
|
|
13
|
+
const subDir = isSubDirectory(importConfig);
|
|
14
|
+
if (subDir) {
|
|
15
|
+
backupDirPath = path.resolve(importConfig.contentDir, '..', '_backup_' + Math.floor(Math.random() * 1000));
|
|
16
|
+
if (importConfig.createBackupDir) {
|
|
17
|
+
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}`, {
|
|
18
|
+
color: 'yellow',
|
|
19
|
+
});
|
|
22
20
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
index_1.fileHelper.makeDirectory(importConfig.createBackupDir);
|
|
31
|
-
backupDirPath = importConfig.createBackupDir;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// NOTE: If the backup folder's directory is provided, create it at that location; otherwise, the default path (working directory).
|
|
24
|
+
backupDirPath = path.join(process.cwd(), '_backup_' + Math.floor(Math.random() * 1000));
|
|
25
|
+
if (importConfig.createBackupDir) {
|
|
26
|
+
if (index_1.fileHelper.fileExistsSync(importConfig.createBackupDir)) {
|
|
27
|
+
index_1.fileHelper.removeDirSync(importConfig.createBackupDir);
|
|
32
28
|
}
|
|
29
|
+
index_1.fileHelper.makeDirectory(importConfig.createBackupDir);
|
|
30
|
+
backupDirPath = importConfig.createBackupDir;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
}
|
|
33
|
+
if (backupDirPath) {
|
|
34
|
+
cli_utilities_1.cliux.print('Copying content to the backup directory...');
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
36
|
return (0, fs_extra_1.copy)(importConfig.contentDir, backupDirPath, (error) => {
|
|
37
37
|
if (error) {
|
|
38
|
+
(0, index_1.trace)(error, 'error', true);
|
|
38
39
|
return reject(error);
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
resolve(backupDirPath);
|
|
41
42
|
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
44
45
|
}
|
|
45
|
-
exports.default =
|
|
46
|
+
exports.default = backupHandler;
|
|
46
47
|
/**
|
|
47
48
|
* Check whether provided backup directory path is sub directory or not
|
|
48
49
|
* @param importConfig
|
|
@@ -53,8 +54,8 @@ function isSubDirectory(importConfig) {
|
|
|
53
54
|
const child = importConfig.createBackupDir ? importConfig.createBackupDir : process.cwd();
|
|
54
55
|
const relative = path.relative(parent, child);
|
|
55
56
|
if (relative) {
|
|
56
|
-
return
|
|
57
|
+
return !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
57
58
|
}
|
|
58
|
-
//true if both parent and child have same path
|
|
59
|
+
// true if both parent and child have same path
|
|
59
60
|
return true;
|
|
60
61
|
}
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -10,3 +10,5 @@ export { schemaTemplate, suppressSchemaReference, removeReferenceFields } from '
|
|
|
10
10
|
export { lookupExtension } from './extension-helper';
|
|
11
11
|
export { lookupEntries, removeUidsFromJsonRteFields, removeEntryRefsFromJSONRTE, restoreJsonRteEntryRefs, } from './entries-helper';
|
|
12
12
|
export * from './common-helper';
|
|
13
|
+
export * from './log';
|
|
14
|
+
export { lookUpTaxonomy, lookUpTerms } from './taxonomies-helper';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.updateAppConfig = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.installApp = exports.handleNameConflict = exports.createPrivateApp = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = void 0;
|
|
3
|
+
exports.lookUpTerms = exports.lookUpTaxonomy = exports.restoreJsonRteEntryRefs = exports.removeEntryRefsFromJSONRTE = exports.removeUidsFromJsonRteFields = exports.lookupEntries = exports.lookupExtension = exports.removeReferenceFields = exports.suppressSchemaReference = exports.schemaTemplate = exports.updateAppConfig = exports.ifAppAlreadyExist = exports.getAllStackSpecificApps = exports.confirmToCloseProcess = exports.makeRedirectUrlCall = exports.installApp = exports.handleNameConflict = exports.createPrivateApp = exports.getConfirmationToCreateApps = exports.getOrgUid = exports.getDeveloperHubUrl = exports.lookupAssets = exports.uploadAssetHelper = exports.unlinkFileLogger = exports.log = exports.backupHandler = exports.fsUtil = exports.fileHelper = exports.setupImportConfig = exports.interactive = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
exports.interactive = tslib_1.__importStar(require("./interactive"));
|
|
6
6
|
var import_config_handler_1 = require("./import-config-handler");
|
|
@@ -40,3 +40,7 @@ Object.defineProperty(exports, "removeUidsFromJsonRteFields", { enumerable: true
|
|
|
40
40
|
Object.defineProperty(exports, "removeEntryRefsFromJSONRTE", { enumerable: true, get: function () { return entries_helper_1.removeEntryRefsFromJSONRTE; } });
|
|
41
41
|
Object.defineProperty(exports, "restoreJsonRteEntryRefs", { enumerable: true, get: function () { return entries_helper_1.restoreJsonRteEntryRefs; } });
|
|
42
42
|
tslib_1.__exportStar(require("./common-helper"), exports);
|
|
43
|
+
tslib_1.__exportStar(require("./log"), exports);
|
|
44
|
+
var taxonomies_helper_1 = require("./taxonomies-helper");
|
|
45
|
+
Object.defineProperty(exports, "lookUpTaxonomy", { enumerable: true, get: function () { return taxonomies_helper_1.lookUpTaxonomy; } });
|
|
46
|
+
Object.defineProperty(exports, "lookUpTerms", { enumerable: true, get: function () { return taxonomies_helper_1.lookUpTerms; } });
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LogEntry } from 'winston/index';
|
|
2
|
+
import { Logger } from '@contentstack/cli-utilities';
|
|
3
|
+
import { LogsType, MessageType } from '@contentstack/cli-utilities/lib/logger';
|
|
4
|
+
import { ImportConfig } from '../types';
|
|
5
|
+
export declare function isImportConfig(config: ImportConfig | MessageType): config is ImportConfig;
|
|
6
|
+
export declare function log(entry: LogEntry): void;
|
|
7
|
+
export declare function log(error: MessageType, logType: LogsType): void;
|
|
8
|
+
export declare function log(error: MessageType, logType: 'error', hidden: boolean): void;
|
|
9
|
+
export declare function initLogger(config?: ImportConfig | undefined): Logger;
|
|
10
|
+
export declare const trace: typeof log;
|
package/lib/utils/log.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.trace = exports.initLogger = exports.log = exports.isImportConfig = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
|
+
let logger;
|
|
7
|
+
function isImportConfig(config) {
|
|
8
|
+
return config.data !== undefined && (config === null || config === void 0 ? void 0 : config.contentVersion) !== undefined;
|
|
9
|
+
}
|
|
10
|
+
exports.isImportConfig = isImportConfig;
|
|
11
|
+
function log(entryOrMessage, logType, hidden) {
|
|
12
|
+
logger = initLogger();
|
|
13
|
+
if (logType === 'error') {
|
|
14
|
+
logger.log(entryOrMessage, logType, hidden);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
logger.log(entryOrMessage, logType);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.log = log;
|
|
21
|
+
function initLogger(config) {
|
|
22
|
+
var _a;
|
|
23
|
+
if (!logger) {
|
|
24
|
+
const basePath = (0, path_1.join)((_a = config === null || config === void 0 ? void 0 : config.data) !== null && _a !== void 0 ? _a : process.cwd(), 'logs', 'import');
|
|
25
|
+
logger = new cli_utilities_1.Logger(Object.assign(config !== null && config !== void 0 ? config : {}, { basePath }));
|
|
26
|
+
}
|
|
27
|
+
return logger;
|
|
28
|
+
}
|
|
29
|
+
exports.initLogger = initLogger;
|
|
30
|
+
exports.trace = log;
|
package/lib/utils/logger.js
CHANGED
|
@@ -9,7 +9,6 @@ exports.unlinkFileLogger = exports.log = void 0;
|
|
|
9
9
|
const tslib_1 = require("tslib");
|
|
10
10
|
const winston = tslib_1.__importStar(require("winston"));
|
|
11
11
|
const path = tslib_1.__importStar(require("path"));
|
|
12
|
-
const mkdirp_1 = tslib_1.__importDefault(require("mkdirp"));
|
|
13
12
|
const slice = Array.prototype.slice;
|
|
14
13
|
const ansiRegexPattern = [
|
|
15
14
|
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
|
@@ -55,9 +54,7 @@ let successTransport;
|
|
|
55
54
|
let errorTransport;
|
|
56
55
|
function init(_logPath) {
|
|
57
56
|
if (!logger || !errorLogger) {
|
|
58
|
-
|
|
59
|
-
// Create dir if doesn't already exist
|
|
60
|
-
mkdirp_1.default.sync(logsDir);
|
|
57
|
+
const logsDir = path.resolve(_logPath, 'logs', 'import');
|
|
61
58
|
successTransport = {
|
|
62
59
|
filename: path.join(logsDir, 'success.log'),
|
|
63
60
|
maxFiles: 20,
|
|
@@ -75,7 +72,9 @@ function init(_logPath) {
|
|
|
75
72
|
logger = winston.createLogger({
|
|
76
73
|
transports: [
|
|
77
74
|
new winston.transports.File(successTransport),
|
|
78
|
-
new winston.transports.Console({
|
|
75
|
+
new winston.transports.Console({
|
|
76
|
+
format: winston.format.combine(winston.format.simple(), winston.format.colorize({ all: true, colors: { warn: 'yellow', info: 'white' } })),
|
|
77
|
+
}),
|
|
79
78
|
],
|
|
80
79
|
levels: myCustomLevels.levels,
|
|
81
80
|
});
|
|
@@ -98,7 +97,7 @@ function init(_logPath) {
|
|
|
98
97
|
logger.log('info', logString);
|
|
99
98
|
}
|
|
100
99
|
},
|
|
101
|
-
warn: function () {
|
|
100
|
+
warn: function (message) {
|
|
102
101
|
let args = slice.call(arguments);
|
|
103
102
|
let logString = returnString(args);
|
|
104
103
|
if (logString) {
|
|
@@ -126,7 +125,10 @@ const log = async (config, message, type) => {
|
|
|
126
125
|
// ignoring the type argument, as we are not using it to create a logfile anymore
|
|
127
126
|
if (type !== 'error') {
|
|
128
127
|
// removed type argument from init method
|
|
129
|
-
|
|
128
|
+
if (type === 'warn')
|
|
129
|
+
init(config.data).warn(message); //logged warning message in log file
|
|
130
|
+
else
|
|
131
|
+
init(config.data).log(message);
|
|
130
132
|
}
|
|
131
133
|
else {
|
|
132
134
|
init(config.data).error(message);
|
|
@@ -9,12 +9,13 @@ const includes_1 = tslib_1.__importDefault(require("lodash/includes"));
|
|
|
9
9
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
10
10
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
11
11
|
const logger_1 = require("./logger");
|
|
12
|
-
const
|
|
12
|
+
const log_1 = require("../utils/log");
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
|
+
const interactive_1 = require("./interactive");
|
|
14
15
|
const interactive_2 = require("../utils/interactive");
|
|
15
16
|
const getAllStackSpecificApps = async (developerHubBaseUrl, httpClient, config) => {
|
|
16
17
|
const appSdkAxiosInstance = await (0, cli_utilities_1.managementSDKClient)({
|
|
17
|
-
host: developerHubBaseUrl.split('://').pop()
|
|
18
|
+
host: developerHubBaseUrl.split('://').pop(),
|
|
18
19
|
});
|
|
19
20
|
return await appSdkAxiosInstance.axiosInstance
|
|
20
21
|
.get(`${developerHubBaseUrl}/installations?target_uids=${config.target_stack}`, {
|
|
@@ -23,7 +24,10 @@ const getAllStackSpecificApps = async (developerHubBaseUrl, httpClient, config)
|
|
|
23
24
|
},
|
|
24
25
|
})
|
|
25
26
|
.then(({ data }) => data.data)
|
|
26
|
-
.catch((error) =>
|
|
27
|
+
.catch((error) => {
|
|
28
|
+
(0, log_1.trace)(error, 'error', true);
|
|
29
|
+
(0, logger_1.log)(config, `Failed to export marketplace-apps ${(0, utils_1.formatError)(error)}`, 'error');
|
|
30
|
+
});
|
|
27
31
|
};
|
|
28
32
|
exports.getAllStackSpecificApps = getAllStackSpecificApps;
|
|
29
33
|
const getDeveloperHubUrl = async (config) => {
|
|
@@ -41,6 +45,7 @@ const getOrgUid = async (config) => {
|
|
|
41
45
|
.stack({ api_key: config.target_stack })
|
|
42
46
|
.fetch()
|
|
43
47
|
.catch((error) => {
|
|
48
|
+
(0, log_1.trace)(error, 'error', true);
|
|
44
49
|
(0, logger_1.log)(config, (0, utils_1.formatError)(error), 'error');
|
|
45
50
|
});
|
|
46
51
|
return (tempStackData === null || tempStackData === void 0 ? void 0 : tempStackData.org_uid) || '';
|
|
@@ -92,6 +97,7 @@ const makeRedirectUrlCall = async (response, appName, config) => {
|
|
|
92
97
|
.get(response.redirect_url)
|
|
93
98
|
.then(async ({ response }) => {
|
|
94
99
|
if ((0, includes_1.default)([501, 403], response.status)) {
|
|
100
|
+
(0, log_1.trace)(response, 'error', true);
|
|
95
101
|
(0, logger_1.log)(config, `${appName} - ${response.statusText}, OAuth api call failed.!`, 'error');
|
|
96
102
|
(0, logger_1.log)(config, (0, utils_1.formatError)(response), 'error');
|
|
97
103
|
await (0, exports.confirmToCloseProcess)(response.data, config);
|
|
@@ -101,6 +107,7 @@ const makeRedirectUrlCall = async (response, appName, config) => {
|
|
|
101
107
|
}
|
|
102
108
|
})
|
|
103
109
|
.catch((error) => {
|
|
110
|
+
(0, log_1.trace)(error, 'error', true);
|
|
104
111
|
if ((0, includes_1.default)([501, 403], error.status)) {
|
|
105
112
|
(0, logger_1.log)(config, (0, utils_1.formatError)(error), 'error');
|
|
106
113
|
}
|
|
@@ -145,6 +152,9 @@ const updateAppConfig = async (client, config, app, payload) => {
|
|
|
145
152
|
var _a;
|
|
146
153
|
(0, logger_1.log)(config, `${(_a = app === null || app === void 0 ? void 0 : app.manifest) === null || _a === void 0 ? void 0 : _a.name} app config updated successfully.!`, 'success');
|
|
147
154
|
})
|
|
148
|
-
.catch((error) =>
|
|
155
|
+
.catch((error) => {
|
|
156
|
+
(0, log_1.trace)(error, 'error', true);
|
|
157
|
+
(0, logger_1.log)(config, `Failed to update app config.${(0, utils_1.formatError)(error)}`, 'error');
|
|
158
|
+
});
|
|
149
159
|
};
|
|
150
160
|
exports.updateAppConfig = updateAppConfig;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ImportConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* check and remove if referenced taxonomy doesn't exists in stack
|
|
4
|
+
* @param {any} schema content type schema
|
|
5
|
+
* @param {Record<string, unknown>} taxonomies created taxonomies
|
|
6
|
+
* @param {ImportConfig} importConfig
|
|
7
|
+
*/
|
|
8
|
+
export declare const lookUpTaxonomy: (importConfig: ImportConfig, schema: any, taxonomies: Record<string, unknown>) => void;
|
|
9
|
+
/**
|
|
10
|
+
* check and remove if referenced terms doesn't exists in taxonomy
|
|
11
|
+
* @param {Record<string, any>[]} ctSchema content type schema
|
|
12
|
+
* @param {any} entry
|
|
13
|
+
* @param {Record<string, any>} taxonomiesAndTermData created taxonomies and terms
|
|
14
|
+
* @param {ImportConfig} importConfig
|
|
15
|
+
*/
|
|
16
|
+
export declare const lookUpTerms: (ctSchema: Record<string, any>[], entry: any, taxonomiesAndTermData: Record<string, any>, importConfig: ImportConfig) => void;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lookUpTerms = exports.lookUpTaxonomy = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* taxonomy lookup
|
|
6
|
+
*/
|
|
7
|
+
const _1 = require("./");
|
|
8
|
+
/**
|
|
9
|
+
* check and remove if referenced taxonomy doesn't exists in stack
|
|
10
|
+
* @param {any} schema content type schema
|
|
11
|
+
* @param {Record<string, unknown>} taxonomies created taxonomies
|
|
12
|
+
* @param {ImportConfig} importConfig
|
|
13
|
+
*/
|
|
14
|
+
const lookUpTaxonomy = function (importConfig, schema, taxonomies) {
|
|
15
|
+
for (let i in schema) {
|
|
16
|
+
if (schema[i].data_type === 'taxonomy') {
|
|
17
|
+
const taxonomyFieldData = schema[i].taxonomies;
|
|
18
|
+
const { updatedTaxonomyData, isTaxonomyFieldRemoved } = verifyAndRemoveTaxonomy(taxonomyFieldData, taxonomies, importConfig);
|
|
19
|
+
//Handle API error -> The 'taxonomies' property must have atleast one taxonomy object. Remove taxonomy field from schema.
|
|
20
|
+
if (isTaxonomyFieldRemoved) {
|
|
21
|
+
schema.splice(i, 1);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
schema[i].taxonomies = updatedTaxonomyData;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.lookUpTaxonomy = lookUpTaxonomy;
|
|
30
|
+
/**
|
|
31
|
+
* verify and remove referenced taxonomy with warning from respective content type
|
|
32
|
+
* @param {Record<string, any>[]} taxonomyFieldData
|
|
33
|
+
* @param {Record<string, unknown>} taxonomies created taxonomies
|
|
34
|
+
* @param {ImportConfig} importConfig
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
const verifyAndRemoveTaxonomy = function (taxonomyFieldData, taxonomies, importConfig) {
|
|
38
|
+
let isTaxonomyFieldRemoved = false;
|
|
39
|
+
for (let index = 0; index < (taxonomyFieldData === null || taxonomyFieldData === void 0 ? void 0 : taxonomyFieldData.length); index++) {
|
|
40
|
+
const taxonomyData = taxonomyFieldData[index];
|
|
41
|
+
if (taxonomies === undefined || !taxonomies.hasOwnProperty(taxonomyData === null || taxonomyData === void 0 ? void 0 : taxonomyData.taxonomy_uid)) {
|
|
42
|
+
// remove taxonomy from taxonomies field data with warning if respective taxonomy doesn't exists
|
|
43
|
+
(0, _1.log)(importConfig, `Taxonomy '${taxonomyData === null || taxonomyData === void 0 ? void 0 : taxonomyData.taxonomy_uid}' does not exist. Removing the data from the taxonomies field`, 'warn');
|
|
44
|
+
taxonomyFieldData.splice(index, 1);
|
|
45
|
+
--index;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (!(taxonomyFieldData === null || taxonomyFieldData === void 0 ? void 0 : taxonomyFieldData.length)) {
|
|
49
|
+
(0, _1.log)(importConfig, 'Taxonomy does not exist. Removing the field from content type', 'warn');
|
|
50
|
+
isTaxonomyFieldRemoved = true;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
updatedTaxonomyData: taxonomyFieldData,
|
|
54
|
+
isTaxonomyFieldRemoved,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* check and remove if referenced terms doesn't exists in taxonomy
|
|
59
|
+
* @param {Record<string, any>[]} ctSchema content type schema
|
|
60
|
+
* @param {any} entry
|
|
61
|
+
* @param {Record<string, any>} taxonomiesAndTermData created taxonomies and terms
|
|
62
|
+
* @param {ImportConfig} importConfig
|
|
63
|
+
*/
|
|
64
|
+
const lookUpTerms = function (ctSchema, entry, taxonomiesAndTermData, importConfig) {
|
|
65
|
+
for (let index = 0; index < (ctSchema === null || ctSchema === void 0 ? void 0 : ctSchema.length); index++) {
|
|
66
|
+
if (ctSchema[index].data_type === 'taxonomy') {
|
|
67
|
+
const taxonomyFieldData = entry[ctSchema[index].uid];
|
|
68
|
+
const updatedTaxonomyData = verifyAndRemoveTerms(taxonomyFieldData, taxonomiesAndTermData, importConfig);
|
|
69
|
+
entry[ctSchema[index].uid] = updatedTaxonomyData;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
exports.lookUpTerms = lookUpTerms;
|
|
74
|
+
/**
|
|
75
|
+
* verify and remove referenced term with warning from respective entry
|
|
76
|
+
* @param {Record<string, any>[]} taxonomyFieldData entry taxonomies data
|
|
77
|
+
* @param {Record<string, any>} taxonomiesAndTermData created taxonomies and terms
|
|
78
|
+
* @param {ImportConfig} importConfig
|
|
79
|
+
* @returns { Record<string, any>[]}
|
|
80
|
+
*/
|
|
81
|
+
const verifyAndRemoveTerms = function (taxonomyFieldData, taxonomiesAndTermData, importConfig) {
|
|
82
|
+
for (let index = 0; index < (taxonomyFieldData === null || taxonomyFieldData === void 0 ? void 0 : taxonomyFieldData.length); index++) {
|
|
83
|
+
const taxonomyData = taxonomyFieldData[index];
|
|
84
|
+
const taxUID = taxonomyData === null || taxonomyData === void 0 ? void 0 : taxonomyData.taxonomy_uid;
|
|
85
|
+
const termUID = taxonomyData === null || taxonomyData === void 0 ? void 0 : taxonomyData.term_uid;
|
|
86
|
+
if (taxonomiesAndTermData === undefined ||
|
|
87
|
+
!taxonomiesAndTermData.hasOwnProperty(taxUID) ||
|
|
88
|
+
(taxonomiesAndTermData.hasOwnProperty(taxUID) && !taxonomiesAndTermData[taxUID].hasOwnProperty(termUID))) {
|
|
89
|
+
// remove term from taxonomies field data with warning if respective term doesn't exists
|
|
90
|
+
(0, _1.log)(importConfig, `Term '${termUID}' does not exist. Removing it from taxonomy - '${taxUID}'`, 'warn');
|
|
91
|
+
taxonomyFieldData.splice(index, 1);
|
|
92
|
+
--index;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return taxonomyFieldData;
|
|
96
|
+
};
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
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.11.0",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-command": "~1.2.
|
|
9
|
-
"@contentstack/cli-utilities": "~1.5.
|
|
10
|
-
"@contentstack/management": "~1.
|
|
8
|
+
"@contentstack/cli-command": "~1.2.15",
|
|
9
|
+
"@contentstack/cli-utilities": "~1.5.5",
|
|
10
|
+
"@contentstack/management": "~1.12.0",
|
|
11
11
|
"@oclif/core": "^2.9.3",
|
|
12
|
+
"axios": "^1.6.0",
|
|
12
13
|
"big-json": "^3.2.0",
|
|
13
14
|
"bluebird": "^3.7.2",
|
|
14
15
|
"chalk": "^4.1.2",
|
|
@@ -96,4 +97,4 @@
|
|
|
96
97
|
}
|
|
97
98
|
},
|
|
98
99
|
"repository": "https://github.com/contentstack/cli"
|
|
99
|
-
}
|
|
100
|
+
}
|