@contentstack/cli-cm-export 1.9.3 → 1.10.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.
- package/README.md +1 -1
- package/lib/config/index.js +12 -1
- package/lib/export/module-exporter.js +9 -5
- package/lib/export/modules/taxonomies.d.ts +45 -0
- package/lib/export/modules/taxonomies.js +159 -0
- package/lib/types/default-config.d.ts +13 -0
- package/lib/types/index.d.ts +15 -1
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
|
|
|
48
48
|
$ csdx COMMAND
|
|
49
49
|
running command...
|
|
50
50
|
$ csdx (--version)
|
|
51
|
-
@contentstack/cli-cm-export/1.
|
|
51
|
+
@contentstack/cli-cm-export/1.10.1 linux-x64 node-v18.18.2
|
|
52
52
|
$ csdx --help [COMMAND]
|
|
53
53
|
USAGE
|
|
54
54
|
$ csdx COMMAND
|
package/lib/config/index.js
CHANGED
|
@@ -10,7 +10,6 @@ const config = {
|
|
|
10
10
|
'https://eu-api.contentstack.com': 'https://eu-developerhub-api.contentstack.com',
|
|
11
11
|
'https://azure-na-api.contentstack.com': 'https://azure-na-developerhub-api.contentstack.com',
|
|
12
12
|
'https://azure-eu-api.contentstack.com': 'https://azure-eu-developerhub-api.contentstack.com',
|
|
13
|
-
'https://stag-api.csnonprod.com': 'https://stag-developerhub-api.csnonprod.com',
|
|
14
13
|
},
|
|
15
14
|
// use below hosts for eu region
|
|
16
15
|
// host:'https://eu-api.contentstack.com/v3',
|
|
@@ -26,6 +25,7 @@ const config = {
|
|
|
26
25
|
'environments',
|
|
27
26
|
'extensions',
|
|
28
27
|
'webhooks',
|
|
28
|
+
'taxonomies',
|
|
29
29
|
'global-fields',
|
|
30
30
|
'content-types',
|
|
31
31
|
'custom-roles',
|
|
@@ -159,6 +159,16 @@ const config = {
|
|
|
159
159
|
dirName: 'marketplace_apps',
|
|
160
160
|
fileName: 'marketplace_apps.json',
|
|
161
161
|
},
|
|
162
|
+
taxonomies: {
|
|
163
|
+
dirName: 'taxonomies',
|
|
164
|
+
fileName: 'taxonomies.json',
|
|
165
|
+
invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath'],
|
|
166
|
+
},
|
|
167
|
+
terms: {
|
|
168
|
+
dirName: 'terms',
|
|
169
|
+
fileName: 'terms.json',
|
|
170
|
+
invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath'],
|
|
171
|
+
},
|
|
162
172
|
},
|
|
163
173
|
languagesCode: [
|
|
164
174
|
'af-za',
|
|
@@ -389,5 +399,6 @@ const config = {
|
|
|
389
399
|
writeConcurrency: 5,
|
|
390
400
|
developerHubBaseUrl: '',
|
|
391
401
|
marketplaceAppEncryptionKey: 'nF2ejRQcTv',
|
|
402
|
+
onlyTSModules: ['taxonomies'],
|
|
392
403
|
};
|
|
393
404
|
exports.default = config;
|
|
@@ -30,6 +30,7 @@ class ModuleExporter {
|
|
|
30
30
|
for (const branch of this.exportConfig.branches) {
|
|
31
31
|
try {
|
|
32
32
|
this.exportConfig.branchName = branch.uid;
|
|
33
|
+
this.stackAPIClient.stackHeaders.branch = branch.uid;
|
|
33
34
|
this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid);
|
|
34
35
|
(0, utils_1.log)(this.exportConfig, `Exporting content from branch ${branch.uid}`, 'success');
|
|
35
36
|
(0, utils_1.writeExportMetaFile)(this.exportConfig, this.exportConfig.branchDir);
|
|
@@ -63,11 +64,14 @@ class ModuleExporter {
|
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
else {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
//NOTE - new modules support only ts
|
|
68
|
+
if (this.exportConfig.onlyTSModules.indexOf(moduleName) === -1) {
|
|
69
|
+
exportedModuleResponse = await (0, modules_js_1.default)({
|
|
70
|
+
stackAPIClient: this.stackAPIClient,
|
|
71
|
+
exportConfig: this.exportConfig,
|
|
72
|
+
moduleName,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
// set master locale to config
|
|
73
77
|
if (moduleName === 'stack' && (exportedModuleResponse === null || exportedModuleResponse === void 0 ? void 0 : exportedModuleResponse.code)) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import BaseClass from './base-class';
|
|
2
|
+
import { ModuleClassParams } from '../../types';
|
|
3
|
+
export default class ExportTaxonomies extends BaseClass {
|
|
4
|
+
private taxonomies;
|
|
5
|
+
private terms;
|
|
6
|
+
private taxonomiesConfig;
|
|
7
|
+
private termsConfig;
|
|
8
|
+
private qs;
|
|
9
|
+
taxonomiesFolderPath: string;
|
|
10
|
+
termsFolderPath: string;
|
|
11
|
+
constructor({ exportConfig, stackAPIClient }: ModuleClassParams);
|
|
12
|
+
start(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* fetch all taxonomies in the provided stack
|
|
15
|
+
* @param {number} skip
|
|
16
|
+
* @returns {Promise<any>}
|
|
17
|
+
*/
|
|
18
|
+
getAllTaxonomies(skip?: number): Promise<any>;
|
|
19
|
+
/**
|
|
20
|
+
* remove invalid keys and write data into taxonomies
|
|
21
|
+
* @function sanitizeTaxonomiesAttribs
|
|
22
|
+
* @param taxonomies
|
|
23
|
+
*/
|
|
24
|
+
sanitizeTaxonomiesAttribs(taxonomies: Record<string, string>[]): void;
|
|
25
|
+
/**
|
|
26
|
+
* fetch all terms of respective taxonomy and write it into <taxonomy-uid>-terms file
|
|
27
|
+
* @returns {Promise<void>}
|
|
28
|
+
*/
|
|
29
|
+
getAllTerms(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* fetch all terms of the provided taxonomy uid
|
|
32
|
+
* @async
|
|
33
|
+
* @param {string} taxonomyUID
|
|
34
|
+
* @param {number} skip
|
|
35
|
+
* @returns {Promise<any>}
|
|
36
|
+
*/
|
|
37
|
+
fetchTermsOfTaxonomy(taxonomyUID: string, skip?: number): Promise<any>;
|
|
38
|
+
/**
|
|
39
|
+
* remove invalid keys and write data into taxonomies
|
|
40
|
+
* @function sanitizeTaxonomiesAttribs
|
|
41
|
+
* @param terms
|
|
42
|
+
*/
|
|
43
|
+
sanitizeTermsAttribs(terms: Record<string, string>[]): void;
|
|
44
|
+
handleErrorMsg(err: any): void;
|
|
45
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
5
|
+
const keys_1 = tslib_1.__importDefault(require("lodash/keys"));
|
|
6
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
class ExportTaxonomies extends base_class_1.default {
|
|
11
|
+
constructor({ exportConfig, stackAPIClient }) {
|
|
12
|
+
super({ exportConfig, stackAPIClient });
|
|
13
|
+
this.taxonomies = {};
|
|
14
|
+
this.terms = [];
|
|
15
|
+
this.taxonomiesConfig = exportConfig.modules.taxonomies;
|
|
16
|
+
this.termsConfig = exportConfig.modules.terms;
|
|
17
|
+
this.qs = { include_count: true, skip: 0, asc: 'created_at' };
|
|
18
|
+
}
|
|
19
|
+
async start() {
|
|
20
|
+
(0, utils_1.log)(this.exportConfig, 'Starting taxonomies export', 'info');
|
|
21
|
+
//create taxonomies and terms folder in data directory path
|
|
22
|
+
this.taxonomiesFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.taxonomiesConfig.dirName);
|
|
23
|
+
await utils_1.fsUtil.makeDirectory(this.taxonomiesFolderPath);
|
|
24
|
+
this.termsFolderPath = (0, node_path_1.resolve)(this.taxonomiesFolderPath, this.termsConfig.dirName);
|
|
25
|
+
await utils_1.fsUtil.makeDirectory(this.termsFolderPath);
|
|
26
|
+
//fetch all taxonomies and write into taxonomies folder
|
|
27
|
+
await this.getAllTaxonomies();
|
|
28
|
+
if (this.taxonomies === undefined || (0, isEmpty_1.default)(this.taxonomies)) {
|
|
29
|
+
(0, utils_1.log)(this.exportConfig, 'No taxonomies found!', 'info');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
utils_1.fsUtil.writeFile((0, node_path_1.resolve)(this.taxonomiesFolderPath, this.taxonomiesConfig.fileName), this.taxonomies);
|
|
34
|
+
(0, utils_1.log)(this.exportConfig, 'All taxonomies exported successfully!', 'success');
|
|
35
|
+
}
|
|
36
|
+
//fetch all terms of respective and write into taxonomies/terms folder
|
|
37
|
+
await this.getAllTerms();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* fetch all taxonomies in the provided stack
|
|
41
|
+
* @param {number} skip
|
|
42
|
+
* @returns {Promise<any>}
|
|
43
|
+
*/
|
|
44
|
+
async getAllTaxonomies(skip = 0) {
|
|
45
|
+
if (skip) {
|
|
46
|
+
this.qs.skip = skip;
|
|
47
|
+
}
|
|
48
|
+
await this.stack
|
|
49
|
+
.taxonomy()
|
|
50
|
+
.query(this.qs)
|
|
51
|
+
.find()
|
|
52
|
+
.then(async (data) => {
|
|
53
|
+
const { items, count } = data;
|
|
54
|
+
const taxonomiesCount = count !== undefined ? count : items === null || items === void 0 ? void 0 : items.length;
|
|
55
|
+
if (items === null || items === void 0 ? void 0 : items.length) {
|
|
56
|
+
this.sanitizeTaxonomiesAttribs(items);
|
|
57
|
+
skip += this.taxonomiesConfig.limit || 100;
|
|
58
|
+
if (skip >= taxonomiesCount) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
return await this.getAllTaxonomies(skip);
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
this.handleErrorMsg(error);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* remove invalid keys and write data into taxonomies
|
|
70
|
+
* @function sanitizeTaxonomiesAttribs
|
|
71
|
+
* @param taxonomies
|
|
72
|
+
*/
|
|
73
|
+
sanitizeTaxonomiesAttribs(taxonomies) {
|
|
74
|
+
for (let index = 0; index < (taxonomies === null || taxonomies === void 0 ? void 0 : taxonomies.length); index++) {
|
|
75
|
+
const taxonomyUID = taxonomies[index].uid;
|
|
76
|
+
this.taxonomies[taxonomyUID] = (0, omit_1.default)(taxonomies[index], this.taxonomiesConfig.invalidKeys);
|
|
77
|
+
(0, utils_1.log)(this.exportConfig, `'${taxonomyUID}' taxonomy exported successfully!`, 'success');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* fetch all terms of respective taxonomy and write it into <taxonomy-uid>-terms file
|
|
82
|
+
* @returns {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
async getAllTerms() {
|
|
85
|
+
var _a;
|
|
86
|
+
const taxonomiesUID = (0, keys_1.default)(this.taxonomies) || [];
|
|
87
|
+
this.qs.depth = 0;
|
|
88
|
+
for (let index = 0; index < (taxonomiesUID === null || taxonomiesUID === void 0 ? void 0 : taxonomiesUID.length); index++) {
|
|
89
|
+
const taxonomyUID = taxonomiesUID[index];
|
|
90
|
+
this.terms = [];
|
|
91
|
+
await this.fetchTermsOfTaxonomy(taxonomyUID);
|
|
92
|
+
if (!((_a = this.terms) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
93
|
+
(0, utils_1.log)(this.exportConfig, `No terms found for taxonomy - '${taxonomyUID}'!`, 'info');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
utils_1.fsUtil.writeFile((0, node_path_1.resolve)(this.termsFolderPath, `${taxonomyUID}-${this.termsConfig.fileName}`), this.terms);
|
|
97
|
+
(0, utils_1.log)(this.exportConfig, `Terms from taxonomy '${taxonomyUID}' exported successfully!`, 'success');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
(0, utils_1.log)(this.exportConfig, `All the terms exported successfully!`, 'success');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* fetch all terms of the provided taxonomy uid
|
|
104
|
+
* @async
|
|
105
|
+
* @param {string} taxonomyUID
|
|
106
|
+
* @param {number} skip
|
|
107
|
+
* @returns {Promise<any>}
|
|
108
|
+
*/
|
|
109
|
+
async fetchTermsOfTaxonomy(taxonomyUID, skip = 0) {
|
|
110
|
+
if (skip) {
|
|
111
|
+
this.qs.skip = skip;
|
|
112
|
+
}
|
|
113
|
+
await this.stack
|
|
114
|
+
.taxonomy(taxonomyUID)
|
|
115
|
+
.terms()
|
|
116
|
+
.query(this.qs)
|
|
117
|
+
.find()
|
|
118
|
+
.then(async (data) => {
|
|
119
|
+
const { items, count } = data;
|
|
120
|
+
const termsCount = count !== undefined ? count : items === null || items === void 0 ? void 0 : items.length;
|
|
121
|
+
if (items === null || items === void 0 ? void 0 : items.length) {
|
|
122
|
+
this.sanitizeTermsAttribs(items);
|
|
123
|
+
skip += this.taxonomiesConfig.limit || 100;
|
|
124
|
+
if (skip >= termsCount) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
return await this.fetchTermsOfTaxonomy(taxonomyUID, skip);
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
.catch((error) => {
|
|
131
|
+
this.handleErrorMsg(error);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* remove invalid keys and write data into taxonomies
|
|
136
|
+
* @function sanitizeTaxonomiesAttribs
|
|
137
|
+
* @param terms
|
|
138
|
+
*/
|
|
139
|
+
sanitizeTermsAttribs(terms) {
|
|
140
|
+
for (let index = 0; index < (terms === null || terms === void 0 ? void 0 : terms.length); index++) {
|
|
141
|
+
const term = (0, omit_1.default)(terms[index], this.termsConfig.invalidKeys);
|
|
142
|
+
this.terms.push(term);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
handleErrorMsg(err) {
|
|
146
|
+
var _a, _b;
|
|
147
|
+
if (err === null || err === void 0 ? void 0 : err.errorMessage) {
|
|
148
|
+
(0, utils_1.log)(this.exportConfig, `Failed to export! ${err.errorMessage}`, 'error');
|
|
149
|
+
}
|
|
150
|
+
else if (err === null || err === void 0 ? void 0 : err.message) {
|
|
151
|
+
const errorMsg = ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.taxonomy) || ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b.term) || (err === null || err === void 0 ? void 0 : err.message);
|
|
152
|
+
(0, utils_1.log)(this.exportConfig, `Failed to export! ${errorMsg}`, 'error');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
(0, utils_1.log)(this.exportConfig, `Failed to export! ${err}`, 'error');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.default = ExportTaxonomies;
|
|
@@ -134,6 +134,18 @@ export default interface DefaultConfig {
|
|
|
134
134
|
fileName: string;
|
|
135
135
|
requiredKeys: string[];
|
|
136
136
|
};
|
|
137
|
+
taxonomies: {
|
|
138
|
+
dirName: string;
|
|
139
|
+
fileName: string;
|
|
140
|
+
invalidKeys: string[];
|
|
141
|
+
dependencies?: Modules[];
|
|
142
|
+
};
|
|
143
|
+
terms: {
|
|
144
|
+
dirName: string;
|
|
145
|
+
fileName: string;
|
|
146
|
+
invalidKeys: string[];
|
|
147
|
+
dependencies?: Modules[];
|
|
148
|
+
};
|
|
137
149
|
};
|
|
138
150
|
languagesCode: string[];
|
|
139
151
|
apis: {
|
|
@@ -155,4 +167,5 @@ export default interface DefaultConfig {
|
|
|
155
167
|
writeConcurrency: number;
|
|
156
168
|
developerHubBaseUrl: string;
|
|
157
169
|
marketplaceAppEncryptionKey: string;
|
|
170
|
+
onlyTSModules: string[];
|
|
158
171
|
}
|
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
|
exportConfig: ExportConfig;
|
|
@@ -90,5 +90,19 @@ export interface StackConfig {
|
|
|
90
90
|
dependencies?: Modules[];
|
|
91
91
|
limit?: number;
|
|
92
92
|
}
|
|
93
|
+
export interface TaxonomiesConfig {
|
|
94
|
+
dirName: string;
|
|
95
|
+
fileName: string;
|
|
96
|
+
invalidKeys: string[];
|
|
97
|
+
dependencies?: Modules[];
|
|
98
|
+
limit?: number;
|
|
99
|
+
}
|
|
100
|
+
export interface TermsConfig {
|
|
101
|
+
dirName: string;
|
|
102
|
+
fileName: string;
|
|
103
|
+
invalidKeys: string[];
|
|
104
|
+
dependencies?: Modules[];
|
|
105
|
+
limit?: number;
|
|
106
|
+
}
|
|
93
107
|
export { default as DefaultConfig } from './default-config';
|
|
94
108
|
export { default as ExportConfig } from './export-config';
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-export",
|
|
3
3
|
"description": "Contentstack CLI plugin to export content from stack",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.10.1",
|
|
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.
|
|
8
|
+
"@contentstack/cli-command": "~1.2.16",
|
|
9
|
+
"@contentstack/cli-utilities": "~1.5.7",
|
|
10
10
|
"@oclif/core": "^2.9.3",
|
|
11
11
|
"async": "^3.2.4",
|
|
12
12
|
"big-json": "^3.2.0",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"winston": "^3.7.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@contentstack/cli-auth": "~1.3.
|
|
28
|
-
"@contentstack/cli-config": "~1.4.
|
|
29
|
-
"@contentstack/cli-dev-dependencies": "~1.2.
|
|
27
|
+
"@contentstack/cli-auth": "~1.3.17",
|
|
28
|
+
"@contentstack/cli-config": "~1.4.15",
|
|
29
|
+
"@contentstack/cli-dev-dependencies": "~1.2.4",
|
|
30
30
|
"@oclif/plugin-help": "^5.1.19",
|
|
31
31
|
"@oclif/test": "^1.2.6",
|
|
32
32
|
"@types/big-json": "^3.2.0",
|