@contentstack/cli-cm-export-to-csv 1.6.2 → 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.
- package/LICENSE +1 -1
- package/package.json +4 -4
- package/src/util/index.js +82 -86
package/LICENSE
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-export-to-csv",
|
|
3
3
|
"description": "Export entities to csv",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.1",
|
|
5
5
|
"author": "Abhinav Gupta @abhinav-from-contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-command": "~1.2.
|
|
9
|
-
"@contentstack/cli-utilities": "~1.
|
|
8
|
+
"@contentstack/cli-command": "~1.2.18",
|
|
9
|
+
"@contentstack/cli-utilities": "~1.6.1",
|
|
10
10
|
"chalk": "^4.1.0",
|
|
11
11
|
"fast-csv": "^4.3.6",
|
|
12
12
|
"inquirer": "8.2.4",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"mkdirp": "^3.0.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@oclif/test": "^2.
|
|
17
|
+
"@oclif/test": "^2.5.6",
|
|
18
18
|
"@types/chai": "^4.3.6",
|
|
19
19
|
"@types/mocha": "^10.0.1",
|
|
20
20
|
"chai": "^4.3.8",
|
package/src/util/index.js
CHANGED
|
@@ -62,7 +62,6 @@ async function getOrganizations(managementAPIClient) {
|
|
|
62
62
|
try {
|
|
63
63
|
return await getOrganizationList(managementAPIClient, { skip: 0, page: 1, limit: 100 }, []);
|
|
64
64
|
} catch (error) {
|
|
65
|
-
console.log(error);
|
|
66
65
|
throw error;
|
|
67
66
|
}
|
|
68
67
|
}
|
|
@@ -461,7 +460,7 @@ function write(command, entries, fileName, message, delimiter, headers) {
|
|
|
461
460
|
process.chdir(directory);
|
|
462
461
|
}
|
|
463
462
|
// eslint-disable-next-line no-undef
|
|
464
|
-
cliux.print(`Writing ${message} to file: ${process.cwd()}${delimeter}${fileName}`);
|
|
463
|
+
cliux.print(`Writing ${message} to file: "${process.cwd()}${delimeter}${fileName}"`);
|
|
465
464
|
if (headers?.length) fastcsv.writeToPath(fileName, entries, { headers, delimiter });
|
|
466
465
|
else fastcsv.writeToPath(fileName, entries, { headers: true, delimiter });
|
|
467
466
|
}
|
|
@@ -701,10 +700,10 @@ function handleErrorMsg(err) {
|
|
|
701
700
|
|
|
702
701
|
/**
|
|
703
702
|
* This function does the sdk calls to get all the teams in org
|
|
704
|
-
* @param {object} managementAPIClient
|
|
705
|
-
* @param {object} org
|
|
706
|
-
* @param {object} queryParam
|
|
707
|
-
* @returns
|
|
703
|
+
* @param {object} managementAPIClient
|
|
704
|
+
* @param {object} org
|
|
705
|
+
* @param {object} queryParam
|
|
706
|
+
* @returns
|
|
708
707
|
*/
|
|
709
708
|
async function getAllTeams(managementAPIClient, org, queryParam = {}) {
|
|
710
709
|
try {
|
|
@@ -716,8 +715,8 @@ async function getAllTeams(managementAPIClient, org, queryParam = {}) {
|
|
|
716
715
|
|
|
717
716
|
/**
|
|
718
717
|
* This function is used to handle the pagination and call the sdk
|
|
719
|
-
* @param {object} managementAPIClient
|
|
720
|
-
* @param {object} org
|
|
718
|
+
* @param {object} managementAPIClient
|
|
719
|
+
* @param {object} org
|
|
721
720
|
*/
|
|
722
721
|
async function exportOrgTeams(managementAPIClient, org) {
|
|
723
722
|
let allTeamsInOrg = [];
|
|
@@ -738,9 +737,9 @@ async function exportOrgTeams(managementAPIClient, org) {
|
|
|
738
737
|
}
|
|
739
738
|
|
|
740
739
|
/**
|
|
741
|
-
* This function will get all the org level roles
|
|
742
|
-
* @param {object} managementAPIClient
|
|
743
|
-
* @param {object} org
|
|
740
|
+
* This function will get all the org level roles
|
|
741
|
+
* @param {object} managementAPIClient
|
|
742
|
+
* @param {object} org
|
|
744
743
|
*/
|
|
745
744
|
async function getOrgRolesForTeams(managementAPIClient, org) {
|
|
746
745
|
let roleMap = {}; // for org level there are two roles only admin and member
|
|
@@ -764,9 +763,9 @@ async function getOrgRolesForTeams(managementAPIClient, org) {
|
|
|
764
763
|
|
|
765
764
|
/**
|
|
766
765
|
* Removes the unnecessary fields from the objects in the data and assign org level roles to the team based on role uid
|
|
767
|
-
* @param {array} data
|
|
768
|
-
* @param {object} managementAPIClient
|
|
769
|
-
* @param {object} org
|
|
766
|
+
* @param {array} data
|
|
767
|
+
* @param {object} managementAPIClient
|
|
768
|
+
* @param {object} org
|
|
770
769
|
*/
|
|
771
770
|
async function cleanTeamsData(data, managementAPIClient, org) {
|
|
772
771
|
const roleMap = await getOrgRolesForTeams(managementAPIClient, org);
|
|
@@ -785,7 +784,7 @@ async function cleanTeamsData(data, managementAPIClient, org) {
|
|
|
785
784
|
'delete',
|
|
786
785
|
'fetch',
|
|
787
786
|
'stackRoleMappings',
|
|
788
|
-
'teamUsers'
|
|
787
|
+
'teamUsers',
|
|
789
788
|
];
|
|
790
789
|
if (data?.length) {
|
|
791
790
|
return data.map((team) => {
|
|
@@ -807,10 +806,10 @@ async function cleanTeamsData(data, managementAPIClient, org) {
|
|
|
807
806
|
|
|
808
807
|
/**
|
|
809
808
|
* This function is used to call all the other teams function to export the required files
|
|
810
|
-
* @param {object} managementAPIClient
|
|
811
|
-
* @param {object} organization
|
|
812
|
-
* @param {string} teamUid
|
|
813
|
-
* @param {character} delimiter
|
|
809
|
+
* @param {object} managementAPIClient
|
|
810
|
+
* @param {object} organization
|
|
811
|
+
* @param {string} teamUid
|
|
812
|
+
* @param {character} delimiter
|
|
814
813
|
*/
|
|
815
814
|
async function exportTeams(managementAPIClient, organization, teamUid, delimiter) {
|
|
816
815
|
cliux.print(
|
|
@@ -853,10 +852,10 @@ async function exportTeams(managementAPIClient, organization, teamUid, delimiter
|
|
|
853
852
|
|
|
854
853
|
/**
|
|
855
854
|
* This function is used to get individual team user details and write to file
|
|
856
|
-
* @param {array} allTeamsData
|
|
857
|
-
* @param {object} organization
|
|
855
|
+
* @param {array} allTeamsData
|
|
856
|
+
* @param {object} organization
|
|
858
857
|
* @param {string} teamUid optional
|
|
859
|
-
* @param {character} delimiter
|
|
858
|
+
* @param {character} delimiter
|
|
860
859
|
*/
|
|
861
860
|
async function getTeamsDetail(allTeamsData, organization, teamUid, delimiter) {
|
|
862
861
|
if (!teamUid) {
|
|
@@ -884,10 +883,10 @@ async function getTeamsDetail(allTeamsData, organization, teamUid, delimiter) {
|
|
|
884
883
|
|
|
885
884
|
/**
|
|
886
885
|
* This will export the role mappings of the team, for which stack the team has which role
|
|
887
|
-
* @param {object} managementAPIClient
|
|
888
|
-
* @param {array} allTeamsData Data for all the teams in the stack
|
|
886
|
+
* @param {object} managementAPIClient
|
|
887
|
+
* @param {array} allTeamsData Data for all the teams in the stack
|
|
889
888
|
* @param {string} teamUid for a particular team who's data we want
|
|
890
|
-
* @param {character} delimiter
|
|
889
|
+
* @param {character} delimiter
|
|
891
890
|
*/
|
|
892
891
|
async function exportRoleMappings(managementAPIClient, allTeamsData, teamUid, delimiter) {
|
|
893
892
|
let stackRoleWithTeamData = [];
|
|
@@ -936,7 +935,7 @@ async function exportRoleMappings(managementAPIClient, allTeamsData, teamUid, de
|
|
|
936
935
|
];
|
|
937
936
|
try {
|
|
938
937
|
const exportStackRole = await inquirer.prompt(export_stack_role);
|
|
939
|
-
if(exportStackRole.chooseExport==='no') {
|
|
938
|
+
if (exportStackRole.chooseExport === 'no') {
|
|
940
939
|
process.exit(1);
|
|
941
940
|
}
|
|
942
941
|
} catch (error) {
|
|
@@ -954,10 +953,10 @@ async function exportRoleMappings(managementAPIClient, allTeamsData, teamUid, de
|
|
|
954
953
|
|
|
955
954
|
/**
|
|
956
955
|
* Mapping the team stacks with the stack role and returning and array of object
|
|
957
|
-
* @param {object} managementAPIClient
|
|
958
|
-
* @param {array} stackRoleMapping
|
|
959
|
-
* @param {string} teamName
|
|
960
|
-
* @param {string} teamUid
|
|
956
|
+
* @param {object} managementAPIClient
|
|
957
|
+
* @param {array} stackRoleMapping
|
|
958
|
+
* @param {string} teamName
|
|
959
|
+
* @param {string} teamUid
|
|
961
960
|
*/
|
|
962
961
|
async function mapRoleWithTeams(managementAPIClient, stackRoleMapping, teamName, teamUid) {
|
|
963
962
|
const roles = await getRoleData(managementAPIClient, stackRoleMapping.stackApiKey);
|
|
@@ -983,8 +982,8 @@ async function mapRoleWithTeams(managementAPIClient, stackRoleMapping, teamName,
|
|
|
983
982
|
|
|
984
983
|
/**
|
|
985
984
|
* Making sdk call to get all the roles in the given stack
|
|
986
|
-
* @param {object} managementAPIClient
|
|
987
|
-
* @param {string} stackApiKey
|
|
985
|
+
* @param {object} managementAPIClient
|
|
986
|
+
* @param {string} stackApiKey
|
|
988
987
|
*/
|
|
989
988
|
async function getRoleData(managementAPIClient, stackApiKey) {
|
|
990
989
|
try {
|
|
@@ -996,7 +995,7 @@ async function getRoleData(managementAPIClient, stackApiKey) {
|
|
|
996
995
|
|
|
997
996
|
/**
|
|
998
997
|
* Here in the users array we are adding the team-name and team-uid to individual users and returning an array of object of user details only
|
|
999
|
-
* @param {array} teams
|
|
998
|
+
* @param {array} teams
|
|
1000
999
|
*/
|
|
1001
1000
|
async function getTeamsUserDetails(teams) {
|
|
1002
1001
|
const allTeamUsers = [];
|
|
@@ -1081,7 +1080,7 @@ async function getTaxonomy(payload) {
|
|
|
1081
1080
|
* @returns {*} Promise<any>
|
|
1082
1081
|
*/
|
|
1083
1082
|
async function taxonomySDKHandler(payload, skip) {
|
|
1084
|
-
const { stackAPIClient, taxonomyUID, type } = payload;
|
|
1083
|
+
const { stackAPIClient, taxonomyUID, type, format } = payload;
|
|
1085
1084
|
|
|
1086
1085
|
const queryParams = { include_count: true, limit: payload.limit };
|
|
1087
1086
|
if (skip >= 0) queryParams['skip'] = skip || 0;
|
|
@@ -1093,13 +1092,13 @@ async function taxonomySDKHandler(payload, skip) {
|
|
|
1093
1092
|
.query(queryParams)
|
|
1094
1093
|
.find()
|
|
1095
1094
|
.then((data) => data)
|
|
1096
|
-
.catch((err) =>
|
|
1095
|
+
.catch((err) => handleTaxonomyErrorMsg(err));
|
|
1097
1096
|
case 'taxonomy':
|
|
1098
1097
|
return await stackAPIClient
|
|
1099
1098
|
.taxonomy(taxonomyUID)
|
|
1100
1099
|
.fetch()
|
|
1101
1100
|
.then((data) => data)
|
|
1102
|
-
.catch((err) =>
|
|
1101
|
+
.catch((err) => handleTaxonomyErrorMsg(err));
|
|
1103
1102
|
case 'terms':
|
|
1104
1103
|
queryParams['depth'] = 0;
|
|
1105
1104
|
return await stackAPIClient
|
|
@@ -1108,9 +1107,15 @@ async function taxonomySDKHandler(payload, skip) {
|
|
|
1108
1107
|
.query(queryParams)
|
|
1109
1108
|
.find()
|
|
1110
1109
|
.then((data) => data)
|
|
1111
|
-
.catch((err) =>
|
|
1110
|
+
.catch((err) => handleTaxonomyErrorMsg(err));
|
|
1111
|
+
case 'export-taxonomies':
|
|
1112
|
+
return await stackAPIClient
|
|
1113
|
+
.taxonomy(taxonomyUID)
|
|
1114
|
+
.export({ format })
|
|
1115
|
+
.then((data) => data)
|
|
1116
|
+
.catch((err) => handleTaxonomyErrorMsg(err));
|
|
1112
1117
|
default:
|
|
1113
|
-
|
|
1118
|
+
handleTaxonomyErrorMsg({ errorMessage: 'Invalid module!' });
|
|
1114
1119
|
}
|
|
1115
1120
|
}
|
|
1116
1121
|
|
|
@@ -1153,11 +1158,9 @@ function formatTermsOfTaxonomyData(terms, taxonomyUID) {
|
|
|
1153
1158
|
}
|
|
1154
1159
|
}
|
|
1155
1160
|
|
|
1156
|
-
function
|
|
1157
|
-
if (err?.errorMessage) {
|
|
1158
|
-
|
|
1159
|
-
} else if (err?.message) {
|
|
1160
|
-
const errorMsg = err?.errors?.taxonomy || err?.errors?.term || err?.message;
|
|
1161
|
+
function handleTaxonomyErrorMsg(err) {
|
|
1162
|
+
if (err?.errorMessage || err?.message) {
|
|
1163
|
+
const errorMsg = err?.errorMessage || err?.errors?.taxonomy || err?.errors?.term || err?.message;
|
|
1161
1164
|
cliux.print(`Error: ${errorMsg}`, { color: 'red' });
|
|
1162
1165
|
} else {
|
|
1163
1166
|
console.log(err);
|
|
@@ -1167,60 +1170,53 @@ function handleErrorMsg(err) {
|
|
|
1167
1170
|
}
|
|
1168
1171
|
|
|
1169
1172
|
/**
|
|
1170
|
-
*
|
|
1173
|
+
* Generate a CSV file that can be imported for use with the migration script.
|
|
1171
1174
|
* @param {*} payload api request payload
|
|
1172
1175
|
* @param {*} taxonomies taxonomies data
|
|
1173
1176
|
* @returns
|
|
1174
1177
|
*/
|
|
1175
1178
|
async function createImportableCSV(payload, taxonomies) {
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
}
|
|
1187
|
-
taxonomiesData.push(sanitizedTaxonomy);
|
|
1188
|
-
payload['taxonomyUID'] = taxonomyUID;
|
|
1189
|
-
const terms = await getAllTermsOfTaxonomy(payload);
|
|
1190
|
-
//fetch all parent terms
|
|
1191
|
-
const parentTerms = terms.filter((term) => term?.parent_uid === null);
|
|
1192
|
-
const termsData = getParentAndChildTerms(parentTerms, terms, headers);
|
|
1193
|
-
taxonomiesData.push(...termsData);
|
|
1179
|
+
let taxonomiesData = [];
|
|
1180
|
+
let headers = [];
|
|
1181
|
+
payload['type'] = 'export-taxonomies';
|
|
1182
|
+
payload['format'] = 'csv';
|
|
1183
|
+
for (const taxonomy of taxonomies) {
|
|
1184
|
+
if (taxonomy?.uid) {
|
|
1185
|
+
payload['taxonomyUID'] = taxonomy?.uid;
|
|
1186
|
+
const data = await taxonomySDKHandler(payload);
|
|
1187
|
+
const taxonomies = await csvParse(data, headers);
|
|
1188
|
+
taxonomiesData.push(...taxonomies);
|
|
1189
|
+
}
|
|
1194
1190
|
}
|
|
1195
|
-
}
|
|
1196
1191
|
|
|
1197
|
-
|
|
1192
|
+
return { taxonomiesData, headers };
|
|
1198
1193
|
}
|
|
1199
1194
|
|
|
1200
1195
|
/**
|
|
1201
|
-
*
|
|
1202
|
-
* @param {*}
|
|
1203
|
-
* @param {*}
|
|
1204
|
-
* @
|
|
1205
|
-
* @param {*} termsData parent and child terms
|
|
1196
|
+
* Parse the CSV data and segregate the headers from the actual data.
|
|
1197
|
+
* @param {*} data taxonomy csv data with headers
|
|
1198
|
+
* @param {*} headers list of csv headers
|
|
1199
|
+
* @returns taxonomy data without headers
|
|
1206
1200
|
*/
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
const
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
}
|
|
1201
|
+
const csvParse = (data, headers) => {
|
|
1202
|
+
return new Promise((resolve, reject) => {
|
|
1203
|
+
const taxonomies = [];
|
|
1204
|
+
const stream = fastcsv.parseStream(fastcsv.parse());
|
|
1205
|
+
stream.write(data);
|
|
1206
|
+
stream.end();
|
|
1207
|
+
stream
|
|
1208
|
+
.on('data', (data) => {
|
|
1209
|
+
taxonomies.push(data);
|
|
1210
|
+
})
|
|
1211
|
+
.on('error', (err) => reject(err))
|
|
1212
|
+
.on('end', () => {
|
|
1213
|
+
taxonomies[0]?.forEach((header) => {
|
|
1214
|
+
if (!headers.includes(header)) headers.push(header);
|
|
1215
|
+
});
|
|
1216
|
+
resolve(taxonomies.splice(1));
|
|
1217
|
+
});
|
|
1218
|
+
});
|
|
1219
|
+
};
|
|
1224
1220
|
|
|
1225
1221
|
module.exports = {
|
|
1226
1222
|
chooseOrganization: chooseOrganization,
|