@contentstack/cli-cm-export-to-csv 1.3.8 → 1.3.10

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.8",
2
+ "version": "1.3.10",
3
3
  "commands": {
4
4
  "cm:export-to-csv": {
5
5
  "id": "cm:export-to-csv",
@@ -15,8 +15,8 @@
15
15
  "Exporting entries to csv",
16
16
  "csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type>",
17
17
  "",
18
- "Exporting entries to csv with stack name provided",
19
- "csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type> --stack-name <stack-name>",
18
+ "Exporting entries to csv with stack name provided and branch name provided",
19
+ "csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type> --stack-name <stack-name> --branch <branch-name>",
20
20
  "",
21
21
  "Exporting organization users to csv",
22
22
  "csdx cm:export-to-csv --action <users> --org <org-uid>",
@@ -58,6 +58,14 @@
58
58
  "required": false,
59
59
  "multiple": false
60
60
  },
61
+ "stack-api-key": {
62
+ "name": "stack-api-key",
63
+ "type": "option",
64
+ "char": "k",
65
+ "description": "API key of the source stack",
66
+ "required": false,
67
+ "multiple": false
68
+ },
61
69
  "org-name": {
62
70
  "name": "org-name",
63
71
  "type": "option",
@@ -78,6 +86,13 @@
78
86
  "description": "Content type for which entries needs to be exported",
79
87
  "required": false,
80
88
  "multiple": false
89
+ },
90
+ "branch": {
91
+ "name": "branch",
92
+ "type": "option",
93
+ "description": "Branch from which entries need to be exported",
94
+ "required": false,
95
+ "multiple": false
81
96
  }
82
97
  },
83
98
  "args": {}
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.3.8",
4
+ "version": "1.3.10",
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.8",
9
- "@contentstack/cli-utilities": "^1.4.4",
8
+ "@contentstack/cli-command": "^1.2.9",
9
+ "@contentstack/cli-utilities": "^1.4.5",
10
10
  "chalk": "^4.1.0",
11
11
  "fast-csv": "^4.3.6",
12
12
  "inquirer": "8.2.4",
@@ -44,6 +44,7 @@
44
44
  "postpack": "rm -f oclif.manifest.json",
45
45
  "prepack": "oclif manifest && oclif readme",
46
46
  "test": "nyc mocha --forbid-only \"test/**/*.test.js\"",
47
+ "test:unit": "nyc mocha --timeout 10000 --forbid-only \"test/unit/**/*.test.js\"",
47
48
  "version": "oclif readme && git add README.md",
48
49
  "clean": "rm -rf ./node_modules tsconfig.build.tsbuildinfo"
49
50
  },
@@ -1,5 +1,12 @@
1
1
  const { Command } = require('@contentstack/cli-command');
2
- const { configHandler, managementSDKClient, flags, isAuthenticated } = require('@contentstack/cli-utilities');
2
+ const {
3
+ configHandler,
4
+ managementSDKClient,
5
+ flags,
6
+ isAuthenticated,
7
+ cliux,
8
+ doesBranchExist,
9
+ } = require('@contentstack/cli-utilities');
3
10
  const util = require('../../util');
4
11
  const config = require('../../util/config');
5
12
 
@@ -26,6 +33,12 @@ class ExportToCsvCommand extends Command {
26
33
  required: false,
27
34
  description: 'Name of the stack that needs to be created as csv filename.',
28
35
  }),
36
+ 'stack-api-key': flags.string({
37
+ char: 'k',
38
+ multiple: false,
39
+ required: false,
40
+ description: 'API key of the source stack',
41
+ }),
29
42
  'org-name': flags.string({
30
43
  multiple: false,
31
44
  required: false,
@@ -41,6 +54,11 @@ class ExportToCsvCommand extends Command {
41
54
  required: false,
42
55
  multiple: false,
43
56
  }),
57
+ branch: flags.string({
58
+ description: 'Branch from which entries need to be exported',
59
+ multiple: false,
60
+ required: false,
61
+ }),
44
62
  };
45
63
 
46
64
  async run() {
@@ -52,9 +70,11 @@ class ExportToCsvCommand extends Command {
52
70
  action: actionFlag,
53
71
  'org-name': orgName,
54
72
  'stack-name': stackName,
73
+ 'stack-api-key': stackAPIKey,
55
74
  locale: locale,
56
75
  'content-type': contentTypesFlag,
57
76
  alias: managementTokenAlias,
77
+ branch: branchUid,
58
78
  },
59
79
  } = await this.parse(ExportToCsvCommand);
60
80
 
@@ -76,6 +96,7 @@ class ExportToCsvCommand extends Command {
76
96
  let stackAPIClient;
77
97
  let language;
78
98
  let contentTypes = [];
99
+ let stackBranches;
79
100
  const listOfTokens = configHandler.get('tokens');
80
101
 
81
102
  if (managementTokenAlias && listOfTokens[managementTokenAlias]) {
@@ -105,16 +126,59 @@ class ExportToCsvCommand extends Command {
105
126
  } else {
106
127
  organization = await util.chooseOrganization(managementAPIClient); // prompt for organization
107
128
  }
108
-
109
- stack = await util.chooseStack(managementAPIClient, organization.uid); // prompt for stack
129
+ if (!stackAPIKey) {
130
+ stack = await util.chooseStack(managementAPIClient, organization.uid); // prompt for stack
131
+ } else {
132
+ stack = await util.chooseStack(managementAPIClient, organization.uid, stackAPIKey);
133
+ }
110
134
  }
111
135
 
112
136
  stackAPIClient = this.getStackClient(managementAPIClient, stack);
137
+
138
+ if (branchUid) {
139
+ try {
140
+ const branchExists = await doesBranchExist(stackAPIClient, branchUid);
141
+ if (branchExists?.errorCode) {
142
+ throw new Error(branchExists.errorMessage);
143
+ }
144
+ stack.branch_uid = branchUid;
145
+ stackAPIClient = this.getStackClient(managementAPIClient, stack);
146
+ } catch (error) {
147
+ if (error.message || error.errorMessage) {
148
+ cliux.error(util.formatError(error));
149
+ this.exit();
150
+ }
151
+ }
152
+ } else {
153
+ stackBranches = await this.getStackBranches(stackAPIClient);
154
+ if (stackBranches === undefined) {
155
+ stackAPIClient = this.getStackClient(managementAPIClient, stack);
156
+ } else {
157
+ const { branch } = await util.chooseBranch(stackBranches);
158
+ stack.branch_uid = branch;
159
+ stackAPIClient = this.getStackClient(managementAPIClient, stack);
160
+ }
161
+ }
162
+
113
163
  const contentTypeCount = await util.getContentTypeCount(stackAPIClient);
164
+
114
165
  const environments = await util.getEnvironments(stackAPIClient); // fetch environments, because in publish details only env uid are available and we need env names
115
166
 
116
167
  if (contentTypesFlag) {
117
168
  contentTypes = contentTypesFlag.split(',').map(this.snakeCase);
169
+ const contentTypesArray = await stackAPIClient
170
+ .contentType()
171
+ .query()
172
+ .find()
173
+ .then((res) => res.items.map((contentType) => contentType.uid));
174
+
175
+ const doesContentTypeExist = contentTypesArray.includes(contentTypesFlag);
176
+
177
+ if (!doesContentTypeExist) {
178
+ throw new Error(
179
+ `The Content Type ${contentTypesFlag} was not found. Please try again. Content Type is not valid.`,
180
+ );
181
+ }
118
182
  } else {
119
183
  for (let index = 0; index <= contentTypeCount / 100; index++) {
120
184
  const contentTypesMap = await util.getContentTypes(stackAPIClient, index);
@@ -152,12 +216,11 @@ class ExportToCsvCommand extends Command {
152
216
  );
153
217
  flatEntries = flatEntries.concat(flatEntriesResult);
154
218
  }
155
- let fileName = `${stack.name}_${contentType}_${language.code}_entries_export.csv`;
156
-
219
+ let fileName = `${stackName ? stackName : stack.name}_${contentType}_${language.code}_entries_export.csv`;
157
220
  util.write(this, flatEntries, fileName, 'entries'); // write to file
158
221
  }
159
222
  } catch (error) {
160
- this.log(util.formatError(error));
223
+ cliux.error(util.formatError(error));
161
224
  }
162
225
  break;
163
226
  }
@@ -184,21 +247,21 @@ class ExportToCsvCommand extends Command {
184
247
  const mappedRoles = util.getMappedRoles(orgRoles);
185
248
  const listOfUsers = util.cleanOrgUsers(orgUsers, mappedUsers, mappedRoles);
186
249
  const fileName = `${util.kebabize(
187
- organization.name.replace(config.organizationNameRegex, ''),
250
+ (orgName ? orgName : organization.name).replace(config.organizationNameRegex, ''),
188
251
  )}_users_export.csv`;
189
252
 
190
253
  util.write(this, listOfUsers, fileName, 'organization details');
191
254
  } catch (error) {
192
- if (error.message) {
193
- this.log(util.formatError(error));
255
+ if (error.message || error.errorMessage) {
256
+ cliux.error(util.formatError(error));
194
257
  }
195
258
  }
196
259
  break;
197
260
  }
198
261
  }
199
262
  } catch (error) {
200
- if (error.message) {
201
- this.log(util.formatError(error));
263
+ if (error.message || error.errorMessage) {
264
+ cliux.error(util.formatError(error));
202
265
  }
203
266
  }
204
267
  }
@@ -208,13 +271,26 @@ class ExportToCsvCommand extends Command {
208
271
  }
209
272
 
210
273
  getStackClient(managementAPIClient, stack) {
274
+ const stackInit = {
275
+ api_key: stack.apiKey,
276
+ branch_uid: stack.branch_uid,
277
+ };
211
278
  if (stack.token) {
212
279
  return managementAPIClient.stack({
213
- api_key: stack.apiKey,
280
+ ...stackInit,
214
281
  management_token: stack.token,
215
282
  });
216
283
  }
217
- return managementAPIClient.stack({ api_key: stack.apiKey });
284
+ return managementAPIClient.stack(stackInit);
285
+ }
286
+
287
+ getStackBranches(stackAPIClient) {
288
+ return stackAPIClient
289
+ .branch()
290
+ .query()
291
+ .find()
292
+ .then(({ items }) => (items !== undefined ? items : []))
293
+ .catch((_err) => {});
218
294
  }
219
295
  }
220
296
 
@@ -226,8 +302,8 @@ ExportToCsvCommand.examples = [
226
302
  'Exporting entries to csv',
227
303
  'csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type>',
228
304
  '',
229
- 'Exporting entries to csv with stack name provided',
230
- 'csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type> --stack-name <stack-name>',
305
+ 'Exporting entries to csv with stack name provided and branch name provided',
306
+ 'csdx cm:export-to-csv --action <entries> --locale <locale> --alias <management-token-alias> --content-type <content-type> --stack-name <stack-name> --branch <branch-name>',
231
307
  '',
232
308
  'Exporting organization users to csv',
233
309
  'csdx cm:export-to-csv --action <users> --org <org-uid>',
package/src/util/index.js CHANGED
@@ -8,6 +8,7 @@ const debug = require('debug')('export-to-csv');
8
8
  const checkboxPlus = require('inquirer-checkbox-plus-prompt');
9
9
 
10
10
  const config = require('./config.js');
11
+ const { cliux } = require('@contentstack/cli-utilities');
11
12
 
12
13
  const directory = './data';
13
14
  const delimeter = os.platform() === 'win32' ? '\\' : '/';
@@ -97,13 +98,24 @@ function getOrganizationsWhereUserIsAdmin(managementAPIClient) {
97
98
  });
98
99
  }
99
100
 
100
- function chooseStack(managementAPIClient, orgUid) {
101
+ function chooseStack(managementAPIClient, orgUid, stackApiKey) {
101
102
  return new Promise(async (resolve, reject) => {
102
103
  try {
103
104
  let stacks = await getStacks(managementAPIClient, orgUid);
105
+
106
+ if (stackApiKey) {
107
+ const stackName = Object.keys(stacks).find((key) => stacks[key] === stackApiKey);
108
+
109
+ if (stackName) {
110
+ resolve({ name: stackName, apiKey: stackApiKey });
111
+ } else {
112
+ throw new Error('Could not find stack');
113
+ }
114
+ return;
115
+ }
116
+
104
117
  let stackList = Object.keys(stacks);
105
118
  stackList.push(config.cancelString);
106
-
107
119
  let _chooseStack = [
108
120
  {
109
121
  type: 'list',
@@ -126,6 +138,26 @@ function chooseStack(managementAPIClient, orgUid) {
126
138
  });
127
139
  }
128
140
 
141
+ async function chooseBranch(branchList) {
142
+ try {
143
+ const branches = await branchList;
144
+
145
+ const branchesArray = branches.map((branch) => branch.uid);
146
+
147
+ let _chooseBranch = [
148
+ {
149
+ type: 'list',
150
+ name: 'branch',
151
+ message: 'Choose a Branch',
152
+ choices: branchesArray,
153
+ },
154
+ ];
155
+ return await inquirer.prompt(_chooseBranch);
156
+ } catch (err) {
157
+ cliux.error(err);
158
+ }
159
+ }
160
+
129
161
  function getStacks(managementAPIClient, orgUid) {
130
162
  return new Promise((resolve, reject) => {
131
163
  let result = {};
@@ -167,7 +199,7 @@ function chooseContentType(stackAPIClient, skip) {
167
199
  }
168
200
 
169
201
  function chooseInMemContentTypes(contentTypesList) {
170
- return new Promise(async (resolve, reject) => {
202
+ return new Promise((resolve, reject) => {
171
203
  let _chooseContentType = [
172
204
  {
173
205
  type: 'checkbox-plus',
@@ -213,7 +245,7 @@ function getContentTypes(stackAPIClient, skip) {
213
245
  let result = {};
214
246
  stackAPIClient
215
247
  .contentType()
216
- .query({ skip: skip * 100 })
248
+ .query({ skip: skip * 100, include_branch: true })
217
249
  .find()
218
250
  .then((contentTypes) => {
219
251
  contentTypes.items.forEach((contentType) => {
@@ -221,7 +253,9 @@ function getContentTypes(stackAPIClient, skip) {
221
253
  });
222
254
  resolve(result);
223
255
  })
224
- .catch((error) => reject(error));
256
+ .catch((error) => {
257
+ reject(error);
258
+ });
225
259
  });
226
260
  }
227
261
 
@@ -376,7 +410,7 @@ function write(command, entries, fileName, message) {
376
410
  process.chdir(directory);
377
411
  }
378
412
  // eslint-disable-next-line no-undef
379
- command.log(`Writing ${message} to file: ${process.cwd()}${delimeter}${fileName}`);
413
+ cliux.print(`Writing ${message} to file: ${process.cwd()}${delimeter}${fileName}`);
380
414
  fastcsv.writeToPath(fileName, entries, { headers: true });
381
415
  }
382
416
 
@@ -400,7 +434,7 @@ function startupQuestions() {
400
434
  });
401
435
  }
402
436
 
403
- function getOrgUsers(managementAPIClient, orgUid, ecsv) {
437
+ function getOrgUsers(managementAPIClient, orgUid) {
404
438
  return new Promise((resolve, reject) => {
405
439
  managementAPIClient
406
440
  .getUser({ include_orgs_roles: true })
@@ -442,10 +476,7 @@ async function getUsers(managementAPIClient, organization, params, result = [])
442
476
  await wait(200);
443
477
  return getUsers(managementAPIClient, organization, params, result);
444
478
  }
445
- } catch (error) {
446
- console.error(error);
447
- throw error;
448
- }
479
+ } catch (error) {}
449
480
  }
450
481
 
451
482
  function getMappedUsers(users) {
@@ -612,6 +643,7 @@ function wait(time) {
612
643
  module.exports = {
613
644
  chooseOrganization: chooseOrganization,
614
645
  chooseStack: chooseStack,
646
+ chooseBranch: chooseBranch,
615
647
  chooseContentType: chooseContentType,
616
648
  chooseLanguage: chooseLanguage,
617
649
  getEntries: getEntries,