@contentstack/cli-utilities 1.0.1 → 1.0.3

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.
@@ -4,10 +4,10 @@ const tslib_1 = require("tslib");
4
4
  const conf_1 = tslib_1.__importDefault(require("conf"));
5
5
  const uuid_1 = require("uuid");
6
6
  const fs_1 = require("fs");
7
- const ENC_KEY = 'encryptionKey';
8
- const ENCRYPT_CONF = true;
9
- const CONFIG_NAME = 'contentstack_cli';
10
- const ENC_CONFIG_NAME = 'contentstack_cli_obfuscate';
7
+ const ENC_KEY = process.env.ENC_KEY || 'encryptionKey';
8
+ const ENCRYPT_CONF = process.env.ENCRYPT_CONF === 'true' || false;
9
+ const CONFIG_NAME = process.env.CONFIG_NAME || 'contentstack_cli';
10
+ const ENC_CONFIG_NAME = process.env.ENC_CONFIG_NAME || 'contentstack_cli_obfuscate';
11
11
  const OLD_CONFIG_BACKUP_FLAG = 'isOldConfigBackup';
12
12
  const xdgBasedir = require('xdg-basedir');
13
13
  const path = require('path');
@@ -105,10 +105,10 @@ class Config {
105
105
  // NOTE reading old code base encrypted file if exist
106
106
  try {
107
107
  const config = this.fallbackInit();
108
- const configData = this.getConfigDataAndUnlinkConfigFile(config);
109
- this.getEncryptedConfig(configData, true);
108
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config);
109
+ this.getEncryptedConfig(oldConfigData, true);
110
110
  }
111
- catch (error) {
111
+ catch (_error) {
112
112
  // console.trace(error.message)
113
113
  }
114
114
  }
@@ -116,8 +116,8 @@ class Config {
116
116
  try {
117
117
  if (skip === false) {
118
118
  const config = new conf_1.default({ configName: CONFIG_NAME });
119
- const configData = this.getConfigDataAndUnlinkConfigFile(config);
120
- this.getEncryptedConfig(configData, true);
119
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config);
120
+ this.getEncryptedConfig(oldConfigData, true);
121
121
  }
122
122
  else {
123
123
  getEncryptedDataElseFallBack();
@@ -143,17 +143,17 @@ class Config {
143
143
  try {
144
144
  const encryptionKey = this.getObfuscationKey();
145
145
  let config = new conf_1.default({ configName: CONFIG_NAME, encryptionKey });
146
- const configData = this.getConfigDataAndUnlinkConfigFile(config);
147
- this.getDecryptedConfig(configData); // NOTE NOTE reinitialize the config with old data and new decrypted file
146
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config);
147
+ this.getDecryptedConfig(oldConfigData); // NOTE NOTE reinitialize the config with old data and new decrypted file
148
148
  }
149
- catch (error) {
149
+ catch (_error) {
150
150
  // console.trace(error.message)
151
151
  try {
152
152
  const config = this.fallbackInit();
153
- const configData = this.getConfigDataAndUnlinkConfigFile(config);
154
- this.getDecryptedConfig(configData); // NOTE reinitialize the config with old data and new decrypted file
153
+ const _configData = this.getConfigDataAndUnlinkConfigFile(config);
154
+ this.getDecryptedConfig(_configData); // NOTE reinitialize the config with old data and new decrypted file
155
155
  }
156
- catch (error) {
156
+ catch (__error) {
157
157
  // console.trace(error.message)
158
158
  }
159
159
  }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const crypto_1 = tslib_1.__importDefault(require("crypto"));
5
+ const defaultValues = {
6
+ typeIdentifier: '◈',
7
+ algorithm: 'aes-192-cbc',
8
+ // file deepcode ignore HardcodedNonCryptoSecret: <This is a ToDo>
9
+ encryptionKey: 'nF2ejRQcTv',
10
+ };
11
+ class NodeCrypto {
12
+ constructor(config = defaultValues) {
13
+ const { algorithm, encryptionKey, typeIdentifier } = config;
14
+ this.algorithm = algorithm;
15
+ this.typeIdentifier = typeIdentifier;
16
+ this.key = crypto_1.default.scryptSync(encryptionKey, 'salt', 24);
17
+ }
18
+ encrypt(plainData) {
19
+ const iv = crypto_1.default.randomBytes(16);
20
+ const cipher = crypto_1.default.createCipheriv(this.algorithm, this.key, iv);
21
+ let data = plainData;
22
+ switch (typeof plainData) {
23
+ case 'number':
24
+ data = `${String(plainData)}${this.typeIdentifier}number`;
25
+ break;
26
+ case 'object':
27
+ data = `${JSON.stringify(plainData)}${this.typeIdentifier}object`;
28
+ break;
29
+ }
30
+ const encrypted = cipher.update(data, 'utf8', 'hex');
31
+ return [encrypted + cipher.final('hex'), Buffer.from(iv).toString('hex')].join('|');
32
+ }
33
+ decrypt(encryptedData) {
34
+ const [encrypted, iv] = encryptedData.split('|');
35
+ if (!iv)
36
+ throw new Error('IV not found');
37
+ const decipher = crypto_1.default.createDecipheriv(this.algorithm, this.key, Buffer.from(iv, 'hex'));
38
+ const result = decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8');
39
+ const [data, type] = result.split(this.typeIdentifier);
40
+ switch (type) {
41
+ case 'number':
42
+ return Number(data);
43
+ case 'object':
44
+ return JSON.parse(data);
45
+ }
46
+ return data;
47
+ }
48
+ }
49
+ exports.default = NodeCrypto;
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.printFlagDeprecation = exports.configHandler = exports.messageHandler = exports.CLIError = exports.cliux = exports.logger = void 0;
3
+ exports.NodeCrypto = exports.printFlagDeprecation = exports.configHandler = exports.messageHandler = exports.CLIError = exports.cliux = exports.logger = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  var logger_1 = require("./logger");
6
6
  Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return tslib_1.__importDefault(logger_1).default; } });
@@ -15,3 +15,5 @@ Object.defineProperty(exports, "configHandler", { enumerable: true, get: functio
15
15
  var flag_deprecation_check_1 = require("./flag-deprecation-check");
16
16
  Object.defineProperty(exports, "printFlagDeprecation", { enumerable: true, get: function () { return tslib_1.__importDefault(flag_deprecation_check_1).default; } });
17
17
  tslib_1.__exportStar(require("./http-client"), exports);
18
+ var encrypter_1 = require("./encrypter");
19
+ Object.defineProperty(exports, "NodeCrypto", { enumerable: true, get: function () { return tslib_1.__importDefault(encrypter_1).default; } });
@@ -3,12 +3,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.chooseDeliveryTokenAlias = exports.chooseTokenAlias = exports.chooseLocale = exports.chooseLocales = exports.chooseEnvironment = exports.chooseEnvironments = exports.chooseContentTypes = exports.chooseEntry = exports.chooseContentType = exports.chooseStack = exports.chooseOrganization = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const ora_1 = tslib_1.__importDefault(require("ora"));
6
+ const cli_error_1 = tslib_1.__importDefault(require("../cli-error"));
6
7
  const config_handler_1 = tslib_1.__importDefault(require("../config-handler"));
7
8
  const validations_1 = require("./validations");
9
+ const management_1 = tslib_1.__importDefault(require("@contentstack/management"));
8
10
  const inquirer = require('inquirer');
9
11
  inquirer.registerPrompt('search-list', require('inquirer-search-list'));
10
12
  inquirer.registerPrompt('search-checkbox', require('inquirer-search-checkbox'));
11
- const { Command } = require('@contentstack/cli-command');
13
+ let _region;
14
+ let _authToken;
15
+ let _managementAPIClient;
16
+ const region = () => {
17
+ if (!_region) {
18
+ _region = config_handler_1.default.get('region');
19
+ }
20
+ return _region;
21
+ };
22
+ const cmaHost = () => {
23
+ let cma = region().cma;
24
+ if (cma.startsWith('http')) {
25
+ const u = new URL(cma);
26
+ if (u.host)
27
+ return u.host;
28
+ }
29
+ return cma;
30
+ };
31
+ const managementAPIClient = (params) => {
32
+ if (params) {
33
+ _managementAPIClient = management_1.default.client(params);
34
+ }
35
+ else if (!_managementAPIClient) {
36
+ _managementAPIClient = management_1.default.client({ host: cmaHost() });
37
+ }
38
+ return _managementAPIClient;
39
+ };
40
+ const authToken = () => {
41
+ if (!_authToken) {
42
+ _authToken = config_handler_1.default.get('authtoken');
43
+ }
44
+ if (!_authToken) {
45
+ throw new cli_error_1.default('You are not logged in. Please login with command $ csdx auth:login');
46
+ }
47
+ return _authToken;
48
+ };
12
49
  function chooseOrganization(client, displayMessage, region, orgUid) {
13
50
  return new Promise(async (resolve, reject) => {
14
51
  try {
@@ -81,9 +118,7 @@ function chooseStack(client, organizationId, displayMessage, region) {
81
118
  exports.chooseStack = chooseStack;
82
119
  function chooseContentType(stackApiKey, displayMessage, region) {
83
120
  return new Promise(async (resolve, reject) => {
84
- const command = new Command();
85
- command.managementAPIClient = { host: command.cmaHost, authtoken: command.authToken };
86
- const client = command.managementAPIClient;
121
+ const client = managementAPIClient({ host: cmaHost(), authtoken: authToken() });
87
122
  try {
88
123
  const spinner = (0, ora_1.default)('Loading Content Types').start();
89
124
  // let {items: contentTypes} = await client.stack({api_key: stackApiKey}).contentType().query({include_count: true}).find()
@@ -113,9 +148,7 @@ function chooseContentType(stackApiKey, displayMessage, region) {
113
148
  exports.chooseContentType = chooseContentType;
114
149
  function chooseEntry(contentTypeUid, stackApiKey, displayMessage, region) {
115
150
  return new Promise(async (resolve, reject) => {
116
- const command = new Command();
117
- command.managementAPIClient = { host: command.cmaHost, authtoken: command.authToken };
118
- const client = command.managementAPIClient;
151
+ const client = managementAPIClient({ host: cmaHost(), authtoken: authToken() });
119
152
  try {
120
153
  const spinner = (0, ora_1.default)('Loading Entries').start();
121
154
  let entries = await getAll(client.stack({ api_key: stackApiKey }).contentType(contentTypeUid).entry());
@@ -274,7 +307,7 @@ function chooseLocales(stack, displayMessage) {
274
307
  });
275
308
  }
276
309
  exports.chooseLocales = chooseLocales;
277
- function chooseLocale(stack, displayMessage) {
310
+ function chooseLocale(stack, displayMessage, defaultLocale) {
278
311
  return new Promise(async (resolve, reject) => {
279
312
  try {
280
313
  const spinner = (0, ora_1.default)('Loading Locales').start();
@@ -290,6 +323,7 @@ function chooseLocale(stack, displayMessage) {
290
323
  type: 'search-list',
291
324
  name: 'chosenLocale',
292
325
  choices: localeList,
326
+ default: defaultLocale,
293
327
  message: displayMessage || 'Choose locale',
294
328
  loop: false,
295
329
  validate: validations_1.shouldNotBeEmpty
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstack/cli-utilities",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Utilities for contentstack projects",
5
5
  "main": "lib/index.js",
6
6
  "types": "./types/index.d.ts",
@@ -32,39 +32,38 @@
32
32
  "chalk": "^4.0.0",
33
33
  "conf": "^10.1.2",
34
34
  "debug": "^4.1.1",
35
- "inquirer": "^8.0.0",
35
+ "inquirer": "^8.2.4",
36
+ "inquirer-search-checkbox": "^1.0.0",
37
+ "inquirer-search-list": "^1.2.6",
36
38
  "ora": "^5.4.0",
37
39
  "unique-string": "^2.0.0",
38
40
  "winston": "^3.7.2",
39
- "xdg-basedir": "^4.0.0"
41
+ "xdg-basedir": "^4.0.0",
42
+ "uuid": "^8.3.2"
40
43
  },
41
44
  "devDependencies": {
42
45
  "@oclif/plugin-help": "^5.1.12",
43
46
  "@oclif/test": "^1.2.8",
44
- "@types/axios": "^0.14.0",
45
47
  "@types/chai": "^4.2.18",
46
- "@types/conf": "^3.0.0",
47
- "@types/dot-prop": "^5.0.1",
48
48
  "@types/inquirer": "^7.3.1",
49
49
  "@types/mkdirp": "^1.0.1",
50
50
  "@types/mocha": "^8.2.2",
51
- "@types/nock": "^11.1.0",
52
51
  "@types/node": "^14.14.32",
53
52
  "@types/sinon": "^10.0.2",
54
53
  "@types/tar": "^4.0.3",
55
- "@types/winston": "^2.4.4",
56
54
  "chai": "^4.3.4",
57
55
  "eslint": "^8.18.0",
58
56
  "eslint-config-oclif": "^3.1.0",
59
- "eslint-config-oclif-typescript": "^0.1.0",
57
+ "eslint-config-oclif-typescript": "^0.2.0",
58
+ "fancy-test": "^2.0.0",
60
59
  "globby": "^10.0.2",
61
- "mocha": "^9.2.2",
60
+ "mocha": "^10.0.0",
62
61
  "nock": "^13.1.0",
63
62
  "nyc": "^15.1.0",
64
63
  "rimraf": "^2.7.1",
65
64
  "sinon": "^11.1.1",
66
65
  "tmp": "^0.2.1",
67
- "ts-node": "^8.10.2",
66
+ "ts-node": "^10.9.1",
68
67
  "typescript": "^4.7.4"
69
68
  }
70
- }
69
+ }
@@ -2,10 +2,10 @@ import Conf from 'conf';
2
2
  import { v4 as uuid } from 'uuid';
3
3
  import { existsSync, unlinkSync, readFileSync } from 'fs';
4
4
 
5
- const ENC_KEY = 'encryptionKey';
6
- const ENCRYPT_CONF: boolean = true
7
- const CONFIG_NAME = 'contentstack_cli';
8
- const ENC_CONFIG_NAME = 'contentstack_cli_obfuscate';
5
+ const ENC_KEY = process.env.ENC_KEY || 'encryptionKey';
6
+ const ENCRYPT_CONF: boolean = process.env.ENCRYPT_CONF === 'true' || false;
7
+ const CONFIG_NAME = process.env.CONFIG_NAME || 'contentstack_cli';
8
+ const ENC_CONFIG_NAME = process.env.ENC_CONFIG_NAME || 'contentstack_cli_obfuscate';
9
9
  const OLD_CONFIG_BACKUP_FLAG = 'isOldConfigBackup'
10
10
 
11
11
  const xdgBasedir = require('xdg-basedir');
@@ -41,8 +41,8 @@ class Config {
41
41
  }
42
42
  } catch (error) {
43
43
  console.log("No data to be imported from Old config file");
44
-
45
44
  }
45
+
46
46
  this.set(OLD_CONFIG_BACKUP_FLAG, true)
47
47
  }
48
48
  }
@@ -52,10 +52,10 @@ class Config {
52
52
  for (const key in data) {
53
53
  const value = data[key];
54
54
  const setPath = _path ? _path + '.' + key : key
55
+
55
56
  if (typeof (value) == "object") {
56
57
  this.setOldConfigStoreData(value, setPath)
57
- }
58
- else {
58
+ } else {
59
59
  this.set(setPath, value)
60
60
  }
61
61
  }
@@ -119,9 +119,9 @@ class Config {
119
119
  // NOTE reading old code base encrypted file if exist
120
120
  try {
121
121
  const config = this.fallbackInit()
122
- const configData = this.getConfigDataAndUnlinkConfigFile(config)
123
- this.getEncryptedConfig(configData, true)
124
- } catch (error) {
122
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config)
123
+ this.getEncryptedConfig(oldConfigData, true)
124
+ } catch (_error) {
125
125
  // console.trace(error.message)
126
126
  }
127
127
  }
@@ -130,8 +130,8 @@ class Config {
130
130
  try {
131
131
  if (skip === false) {
132
132
  const config = new Conf({ configName: CONFIG_NAME })
133
- const configData = this.getConfigDataAndUnlinkConfigFile(config)
134
- this.getEncryptedConfig(configData, true)
133
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config)
134
+ this.getEncryptedConfig(oldConfigData, true)
135
135
  } else {
136
136
  getEncryptedDataElseFallBack()
137
137
  }
@@ -157,16 +157,16 @@ class Config {
157
157
  try {
158
158
  const encryptionKey: any = this.getObfuscationKey()
159
159
  let config = new Conf({ configName: CONFIG_NAME, encryptionKey })
160
- const configData = this.getConfigDataAndUnlinkConfigFile(config)
161
- this.getDecryptedConfig(configData) // NOTE NOTE reinitialize the config with old data and new decrypted file
162
- } catch (error) {
160
+ const oldConfigData = this.getConfigDataAndUnlinkConfigFile(config)
161
+ this.getDecryptedConfig(oldConfigData) // NOTE NOTE reinitialize the config with old data and new decrypted file
162
+ } catch (_error) {
163
163
  // console.trace(error.message)
164
164
 
165
165
  try {
166
166
  const config = this.fallbackInit()
167
- const configData = this.getConfigDataAndUnlinkConfigFile(config)
168
- this.getDecryptedConfig(configData) // NOTE reinitialize the config with old data and new decrypted file
169
- } catch (error) {
167
+ const _configData = this.getConfigDataAndUnlinkConfigFile(config)
168
+ this.getDecryptedConfig(_configData) // NOTE reinitialize the config with old data and new decrypted file
169
+ } catch (__error) {
170
170
  // console.trace(error.message)
171
171
  }
172
172
  }
@@ -0,0 +1,63 @@
1
+ import crypto from 'crypto';
2
+
3
+ type CryptoConfig = {
4
+ algorithm?: string;
5
+ encryptionKey?: string;
6
+ typeIdentifier?: string;
7
+ };
8
+
9
+ const defaultValues: CryptoConfig = {
10
+ typeIdentifier: '◈',
11
+ algorithm: 'aes-192-cbc',
12
+ // file deepcode ignore HardcodedNonCryptoSecret: <This is a ToDo>
13
+ encryptionKey: 'nF2ejRQcTv',
14
+ };
15
+
16
+ export default class NodeCrypto {
17
+ private readonly key: Buffer;
18
+ private readonly algorithm: string;
19
+ private readonly typeIdentifier: string;
20
+
21
+ constructor(config: CryptoConfig = defaultValues) {
22
+ const { algorithm, encryptionKey, typeIdentifier } = config;
23
+ this.algorithm = algorithm;
24
+ this.typeIdentifier = typeIdentifier;
25
+ this.key = crypto.scryptSync(encryptionKey, 'salt', 24);
26
+ }
27
+
28
+ encrypt(plainData) {
29
+ const iv = crypto.randomBytes(16);
30
+ const cipher = crypto.createCipheriv(this.algorithm, this.key, iv);
31
+ let data = plainData;
32
+
33
+ switch (typeof plainData) {
34
+ case 'number':
35
+ data = `${String(plainData)}${this.typeIdentifier}number`;
36
+ break;
37
+ case 'object':
38
+ data = `${JSON.stringify(plainData)}${this.typeIdentifier}object`;
39
+ break;
40
+ }
41
+
42
+ const encrypted = cipher.update(data, 'utf8', 'hex');
43
+
44
+ return [encrypted + cipher.final('hex'), Buffer.from(iv).toString('hex')].join('|');
45
+ }
46
+
47
+ decrypt(encryptedData) {
48
+ const [encrypted, iv] = encryptedData.split('|');
49
+ if (!iv) throw new Error('IV not found');
50
+ const decipher = crypto.createDecipheriv(this.algorithm, this.key, Buffer.from(iv, 'hex'));
51
+ const result = decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8');
52
+ const [data, type] = result.split(this.typeIdentifier);
53
+
54
+ switch (type) {
55
+ case 'number':
56
+ return Number(data);
57
+ case 'object':
58
+ return JSON.parse(data);
59
+ }
60
+
61
+ return data;
62
+ }
63
+ }
package/src/index.ts CHANGED
@@ -5,3 +5,4 @@ export { default as messageHandler } from './message-handler';
5
5
  export { default as configHandler } from './config-handler';
6
6
  export { default as printFlagDeprecation } from './flag-deprecation-check';
7
7
  export * from './http-client';
8
+ export { default as NodeCrypto } from './encrypter'
@@ -1,4 +1,5 @@
1
1
  import ora from 'ora'
2
+ import { default as CLIError } from '../cli-error';
2
3
  import { default as config } from '../config-handler';
3
4
  import {
4
5
  Token,
@@ -10,18 +11,66 @@ import {
10
11
  Entry,
11
12
  Locale
12
13
  } from './interfaces'
13
- import { shouldNotBeEmpty } from './validations';
14
+ import { shouldNotBeEmpty } from './validations';
15
+ import ContentstackManagementSDK from '@contentstack/management';
14
16
 
15
17
  const inquirer = require('inquirer')
16
18
  inquirer.registerPrompt('search-list', require('inquirer-search-list'))
17
19
  inquirer.registerPrompt('search-checkbox', require('inquirer-search-checkbox'))
18
- const {Command} = require('@contentstack/cli-command')
20
+
21
+ interface Region {
22
+ name: string;
23
+ cma: string;
24
+ cda: string;
25
+ }
26
+
27
+ let _region: Region;
28
+ let _authToken: string;
29
+ let _managementAPIClient: ContentstackManagementSDK.ContentstackClient;
30
+
31
+ const region = (): Region => {
32
+ if (!_region) {
33
+ _region = config.get('region');
34
+ }
35
+
36
+ return _region;
37
+ }
38
+
39
+ const cmaHost = () => {
40
+ let cma = region().cma;
41
+ if (cma.startsWith('http')) {
42
+ const u = new URL(cma);
43
+ if (u.host) return u.host;
44
+ }
45
+ return cma;
46
+ }
47
+
48
+ const managementAPIClient = (params) => {
49
+ if (params) {
50
+ _managementAPIClient = ContentstackManagementSDK.client(params)
51
+ } else if (!_managementAPIClient) {
52
+ _managementAPIClient = ContentstackManagementSDK.client({ host: cmaHost() });
53
+ }
54
+
55
+ return _managementAPIClient;
56
+ }
57
+
58
+ const authToken = () => {
59
+ if (!_authToken) {
60
+ _authToken = config.get('authtoken');
61
+ }
62
+ if (!_authToken) {
63
+ throw new CLIError('You are not logged in. Please login with command $ csdx auth:login');
64
+ }
65
+
66
+ return _authToken;
67
+ }
19
68
 
20
69
  export function chooseOrganization(client: any, displayMessage?: string, region?: string, orgUid?: string): Promise<selectedOrganization> {
21
70
  return new Promise(async (resolve, reject) => {
22
71
  try {
23
72
  const spinner = ora('Loading Organizations').start()
24
- let {items: organizations} = await client.organization().fetchAll()
73
+ let { items: organizations } = await client.organization().fetchAll()
25
74
  spinner.stop()
26
75
  let orgMap: any = {}
27
76
  if (orgUid) {
@@ -29,7 +78,7 @@ export function chooseOrganization(client: any, displayMessage?: string, region?
29
78
  orgMap[org.uid] = org.name
30
79
  })
31
80
  if (orgMap[orgUid]) {
32
- resolve({orgUid: orgUid, orgName: orgMap[orgUid]})
81
+ resolve({ orgUid: orgUid, orgName: orgMap[orgUid] })
33
82
  } else {
34
83
  return reject(new Error('The given orgUid doesn\'t exist or you might not have access to it.'))
35
84
  }
@@ -46,8 +95,8 @@ export function chooseOrganization(client: any, displayMessage?: string, region?
46
95
  loop: false,
47
96
  validate: shouldNotBeEmpty
48
97
  }
49
- inquirer.prompt(inquirerConfig).then(({chosenOrganization}: {chosenOrganization: string}) => {
50
- resolve({orgUid: orgMap[chosenOrganization], orgName: chosenOrganization})
98
+ inquirer.prompt(inquirerConfig).then(({ chosenOrganization }: { chosenOrganization: string }) => {
99
+ resolve({ orgUid: orgMap[chosenOrganization], orgName: chosenOrganization })
51
100
  })
52
101
  }
53
102
  } catch (error) {
@@ -56,11 +105,11 @@ export function chooseOrganization(client: any, displayMessage?: string, region?
56
105
  })
57
106
  }
58
107
 
59
- export function chooseStack(client: any, organizationId: string, displayMessage?: string, region?: string) : Promise<Stack> {
108
+ export function chooseStack(client: any, organizationId: string, displayMessage?: string, region?: string): Promise<Stack> {
60
109
  return new Promise(async (resolve, reject) => {
61
110
  try {
62
111
  const spinner = ora('Loading Stacks').start()
63
- let {items: stacks} = await client.stack({organization_uid: organizationId}).query({query: {}}).find()
112
+ let { items: stacks } = await client.stack({ organization_uid: organizationId }).query({ query: {} }).find()
64
113
  spinner.stop()
65
114
  let stackMap: any = {}
66
115
  stacks.forEach((stack: Stack) => {
@@ -74,8 +123,8 @@ export function chooseStack(client: any, organizationId: string, displayMessage?
74
123
  message: displayMessage || 'Choose a stack',
75
124
  loop: false,
76
125
  }
77
- inquirer.prompt(inquirerConfig).then(({chosenStack}: {chosenStack: string}) => {
78
- resolve({api_key: stackMap[chosenStack], name: chosenStack})
126
+ inquirer.prompt(inquirerConfig).then(({ chosenStack }: { chosenStack: string }) => {
127
+ resolve({ api_key: stackMap[chosenStack], name: chosenStack })
79
128
  })
80
129
  } catch (error) {
81
130
  console.error(error.message)
@@ -85,13 +134,12 @@ export function chooseStack(client: any, organizationId: string, displayMessage?
85
134
 
86
135
  export function chooseContentType(stackApiKey: string, displayMessage?: string, region?: string): Promise<ContentType> {
87
136
  return new Promise(async (resolve, reject) => {
88
- const command = new Command()
89
- command.managementAPIClient = {host: command.cmaHost, authtoken: command.authToken}
90
- const client = command.managementAPIClient
137
+ const client = managementAPIClient({ host: cmaHost(), authtoken: authToken() })
138
+
91
139
  try {
92
140
  const spinner = ora('Loading Content Types').start()
93
141
  // let {items: contentTypes} = await client.stack({api_key: stackApiKey}).contentType().query({include_count: true}).find()
94
- let contentTypes = await getAll(client.stack({api_key: stackApiKey}).contentType())
142
+ let contentTypes = await getAll(client.stack({ api_key: stackApiKey }).contentType())
95
143
  spinner.stop()
96
144
  let contentTypeMap: any = {}
97
145
  contentTypes.forEach((contentType: ContentType) => {
@@ -105,23 +153,22 @@ export function chooseContentType(stackApiKey: string, displayMessage?: string,
105
153
  message: displayMessage || 'Choose a content type',
106
154
  loop: false,
107
155
  }
108
- inquirer.prompt(inquirerConfig).then(({chosenContentType}: {chosenContentType: string}) => {
109
- resolve({uid: contentTypeMap[chosenContentType], title: chosenContentType})
156
+ inquirer.prompt(inquirerConfig).then(({ chosenContentType }: { chosenContentType: string }) => {
157
+ resolve({ uid: contentTypeMap[chosenContentType], title: chosenContentType })
110
158
  })
111
159
  } catch (error) {
112
160
  console.error(error.message)
113
161
  }
114
- })
162
+ })
115
163
  }
116
164
 
117
165
  export function chooseEntry(contentTypeUid: string, stackApiKey: string, displayMessage?: string, region?: string): Promise<Entry> {
118
166
  return new Promise(async (resolve, reject) => {
119
- const command = new Command()
120
- command.managementAPIClient = {host: command.cmaHost, authtoken: command.authToken}
121
- const client = command.managementAPIClient
167
+ const client = managementAPIClient({ host: cmaHost(), authtoken: authToken() })
168
+
122
169
  try {
123
170
  const spinner = ora('Loading Entries').start()
124
- let entries = await getAll(client.stack({api_key: stackApiKey}).contentType(contentTypeUid).entry())
171
+ let entries = await getAll(client.stack({ api_key: stackApiKey }).contentType(contentTypeUid).entry())
125
172
  spinner.stop()
126
173
  let entryMap: any = {}
127
174
  entries.forEach((entry: Entry) => {
@@ -135,13 +182,13 @@ export function chooseEntry(contentTypeUid: string, stackApiKey: string, display
135
182
  message: displayMessage || 'Choose an entry',
136
183
  loop: false
137
184
  }
138
- inquirer.prompt(inquirerConfig).then(({chosenEntry}: {chosenEntry: string}) => {
139
- resolve({uid: entryMap[chosenEntry], title: chosenEntry})
185
+ inquirer.prompt(inquirerConfig).then(({ chosenEntry }: { chosenEntry: string }) => {
186
+ resolve({ uid: entryMap[chosenEntry], title: chosenEntry })
140
187
  })
141
188
  } catch (error) {
142
189
  console.error(error.message)
143
190
  }
144
- })
191
+ })
145
192
  }
146
193
 
147
194
  export function chooseContentTypes(stack: any, displayMessage?: string): Promise<ContentType[]> {
@@ -163,7 +210,7 @@ export function chooseContentTypes(stack: any, displayMessage?: string): Promise
163
210
  message: displayMessage || 'Choose a content type',
164
211
  loop: false,
165
212
  }
166
- inquirer.prompt(inquirerConfig).then(({ chosenContentTypes }: { chosenContentTypes: string[]}) => {
213
+ inquirer.prompt(inquirerConfig).then(({ chosenContentTypes }: { chosenContentTypes: string[] }) => {
167
214
  let result: ContentType[] = chosenContentTypes.map(ct => {
168
215
  let foo: ContentType = { uid: contentTypeMap[ct], title: ct }
169
216
  return foo
@@ -173,7 +220,7 @@ export function chooseContentTypes(stack: any, displayMessage?: string): Promise
173
220
  } catch (error) {
174
221
  console.error(error.message)
175
222
  }
176
- })
223
+ })
177
224
  }
178
225
 
179
226
  export function chooseEnvironments(stack: any, displayMessage?: string): Promise<Environment[]> {
@@ -272,7 +319,7 @@ export function chooseLocales(stack: any, displayMessage?: string): Promise<Loca
272
319
  })
273
320
  }
274
321
 
275
- export function chooseLocale(stack: any, displayMessage?: string): Promise<Locale> {
322
+ export function chooseLocale(stack: any, displayMessage?: string, defaultLocale?: Locale): Promise<Locale> {
276
323
  return new Promise(async (resolve, reject) => {
277
324
  try {
278
325
  const spinner = ora('Loading Locales').start()
@@ -288,6 +335,7 @@ export function chooseLocale(stack: any, displayMessage?: string): Promise<Local
288
335
  type: 'search-list',
289
336
  name: 'chosenLocale',
290
337
  choices: localeList,
338
+ default: defaultLocale,
291
339
  message: displayMessage || 'Choose locale',
292
340
  loop: false,
293
341
  validate: shouldNotBeEmpty
@@ -338,7 +386,7 @@ export function chooseDeliveryTokenAlias(): Promise<Token> {
338
386
  })
339
387
  }
340
388
 
341
- async function getAll (element: any, skip: number=0): Promise<any> {
389
+ async function getAll(element: any, skip: number = 0): Promise<any> {
342
390
  return new Promise(async resolve => {
343
391
  let result: any[] = []
344
392
  result = await fetch(element, skip, result)
@@ -348,8 +396,8 @@ async function getAll (element: any, skip: number=0): Promise<any> {
348
396
 
349
397
  async function fetch(element: any, skip: number, accumulator: any[]): Promise<any[]> {
350
398
  return new Promise(async resolve => {
351
- let queryParams = {include_count: true, skip: skip}
352
- let {items: result, count: count} = await element.query(queryParams).find()
399
+ let queryParams = { include_count: true, skip: skip }
400
+ let { items: result, count: count } = await element.query(queryParams).find()
353
401
  accumulator = accumulator.concat(result)
354
402
  skip += result.length
355
403
  if (skip < count)
@@ -0,0 +1,14 @@
1
+ declare type CryptoConfig = {
2
+ algorithm?: string;
3
+ encryptionKey?: string;
4
+ typeIdentifier?: string;
5
+ };
6
+ export default class NodeCrypto {
7
+ private readonly key;
8
+ private readonly algorithm;
9
+ private readonly typeIdentifier;
10
+ constructor(config?: CryptoConfig);
11
+ encrypt(plainData: any): string;
12
+ decrypt(encryptedData: any): any;
13
+ }
14
+ export {};
@@ -0,0 +1,230 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+ import { HttpResponse } from './http-response';
3
+ export declare class HttpClient {
4
+ /**
5
+ * The request configuration.
6
+ */
7
+ private request;
8
+ /**
9
+ * The request configuration.
10
+ */
11
+ private readonly axiosInstance;
12
+ /**
13
+ * The payload format for a JSON or form-url-encoded request.
14
+ */
15
+ private bodyFormat;
16
+ /**
17
+ * Createa new pending HTTP request instance.
18
+ */
19
+ constructor();
20
+ /**
21
+ * Create a reusable HttpClient instance.
22
+ *
23
+ * @returns {HttpClient}
24
+ */
25
+ static create(): HttpClient;
26
+ /**
27
+ * Returns the Axios request config.
28
+ *
29
+ * @returns {AxiosRequestConfig}
30
+ */
31
+ requestConfig(): AxiosRequestConfig;
32
+ /**
33
+ * Resets the request config.
34
+ *
35
+ * @returns {AxiosRequestConfig}
36
+ */
37
+ resetConfig(): HttpClient;
38
+ /**
39
+ * Use the given `baseUrl` for all requests.
40
+ *
41
+ * @param {String} baseUrl
42
+ *
43
+ * @returns {HttpClient}
44
+ */
45
+ baseUrl(baseUrl: string): HttpClient;
46
+ /**
47
+ * Add request headers.
48
+ * @returns {HttpClient}
49
+ */
50
+ headers(headers: any): HttpClient;
51
+ /**
52
+ * Add query parameters to the request.
53
+ *
54
+ * @param {Object} queryParams
55
+ *
56
+ * @returns {HttpClient}
57
+ */
58
+ queryParams(queryParams: object): HttpClient;
59
+ /**
60
+ * Add basic authentication via `username` and `password` to the request.
61
+ *
62
+ * @param {String} username
63
+ * @param {String} password
64
+ *
65
+ * @returns {HttpClient}
66
+ */
67
+ basicAuth(username: string, password: string): HttpClient;
68
+ /**
69
+ * Add an authorization `token` to the request.
70
+ *
71
+ * @param {String} token
72
+ * @param {String} type
73
+ *
74
+ * @returns {HttpClient}
75
+ */
76
+ token(token: string, type?: string): HttpClient;
77
+ /**
78
+ * Merge your own custom Axios options into the request.
79
+ *
80
+ * @param {Object} options
81
+ *
82
+ * @returns {HttpClient}
83
+ */
84
+ options(options?: AxiosRequestConfig): HttpClient;
85
+ /**
86
+ * Add a request payload.
87
+ *
88
+ * @param {*} data
89
+ *
90
+ * @returns {HttpClient}
91
+ */
92
+ payload(data: any): HttpClient;
93
+ /**
94
+ * Define the request `timeout` in milliseconds.
95
+ *
96
+ * @param {Number} timeout
97
+ *
98
+ * @returns {HttpClient}
99
+ */
100
+ timeout(timeout: number): HttpClient;
101
+ /**
102
+ * Tell HttpClient to send the request as JSON payload.
103
+ *
104
+ * @returns {HttpClient}
105
+ */
106
+ asJson(): HttpClient;
107
+ /**
108
+ * Tell HttpClient to send the request as form parameters,
109
+ * encoded as URL query parameters.
110
+ *
111
+ * @returns {HttpClient}
112
+ */
113
+ asFormParams(): HttpClient;
114
+ /**
115
+ * Set the request payload format.
116
+ *
117
+ * @param {String} format
118
+ *
119
+ * @returns {HttpClient}
120
+ */
121
+ payloadFormat(format: BodyFormat): HttpClient;
122
+ /**
123
+ * Set the `Accept` request header. This indicates what
124
+ * content type the server should return.
125
+ *
126
+ * @param {String} accept
127
+ *
128
+ * @returns {HttpClient}
129
+ */
130
+ accept(accept: string): HttpClient;
131
+ /**
132
+ * Set the `Accept` request header to JSON. This indicates
133
+ * that the server should return JSON data.
134
+ *
135
+ * @param {String} accept
136
+ *
137
+ * @returns {HttpClient}
138
+ */
139
+ acceptJson(): HttpClient;
140
+ /**
141
+ * Set the `Content-Type` request header.
142
+ *
143
+ * @param {String} contentType
144
+ *
145
+ * @returns {HttpClient}
146
+ */
147
+ contentType(contentType: string): HttpClient;
148
+ /**
149
+ * Send an HTTP GET request, optionally with the given `queryParams`.
150
+ *
151
+ * @param {String} url
152
+ * @param {Object} queryParams
153
+ *
154
+ * @returns {HttpResponse}
155
+ *
156
+ * @throws
157
+ */
158
+ get<R>(url: string, queryParams?: object): Promise<HttpResponse<R>>;
159
+ /**
160
+ * Send an HTTP POST request, optionally with the given `payload`.
161
+ *
162
+ * @param {String} url
163
+ * @param {Object} payload
164
+ *
165
+ * @returns {HttpResponse}
166
+ *
167
+ * @throws
168
+ */
169
+ post<R>(url: string, payload?: any): Promise<HttpResponse<R>>;
170
+ /**
171
+ * Send an HTTP PUT request, optionally with the given `payload`.
172
+ *
173
+ * @param {String} url
174
+ * @param {Object} payload
175
+ *
176
+ * @returns {HttpResponse}
177
+ *
178
+ * @throws
179
+ */
180
+ put<R>(url: string, payload?: any): Promise<HttpResponse<R>>;
181
+ /**
182
+ * Send an HTTP PATCH request, optionally with the given `payload`.
183
+ *
184
+ * @param {String} url
185
+ * @param {Object} payload
186
+ *
187
+ * @returns {HttpResponse}
188
+ *
189
+ * @throws
190
+ */
191
+ patch<R>(url: string, payload?: any): Promise<HttpResponse<R>>;
192
+ /**
193
+ * Send an HTTP DELETE request, optionally with the given `queryParams`.
194
+ *
195
+ * @param {String} url
196
+ * @param {Object} queryParams
197
+ *
198
+ * @returns {HttpResponse}
199
+ *
200
+ * @throws
201
+ */
202
+ delete<R>(url: string, queryParams?: object): Promise<HttpResponse<R>>;
203
+ /**
204
+ * Send the HTTP request.
205
+ *
206
+ * @param {String} method
207
+ * @param {String} url
208
+ *
209
+ * @returns {HttpResponse}
210
+ *
211
+ * @throws
212
+ */
213
+ send<R>(method: HttpMethod, url: string): Promise<HttpResponse<R>>;
214
+ /**
215
+ * Create and send the HTTP request.
216
+ *
217
+ * @param {String} method
218
+ * @param {String} url
219
+ *
220
+ * @returns {Request}
221
+ */
222
+ createAndSendRequest(method: HttpMethod, url: string): Promise<AxiosResponse>;
223
+ /**
224
+ * Returns the request payload depending on the selected request payload format.
225
+ */
226
+ prepareRequestPayload(): any;
227
+ }
228
+ declare type BodyFormat = 'json' | 'formParams';
229
+ declare type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS';
230
+ export {};
@@ -0,0 +1,37 @@
1
+ import { AxiosResponse } from 'axios';
2
+ export declare class HttpResponse<ResponseType = any> {
3
+ /**
4
+ * The Axios response object.
5
+ */
6
+ private readonly response;
7
+ /**
8
+ * Wrap the given Axios `response` into a new response instance.
9
+ *
10
+ * @param {AxiosResponse} response
11
+ */
12
+ constructor(response: AxiosResponse);
13
+ /**
14
+ * Returns the response status.
15
+ *
16
+ * @returns {Number}
17
+ */
18
+ get status(): number;
19
+ /**
20
+ * Returns the response payload. This method is an alias for `response.payload()`.
21
+ *
22
+ * @returns {*}
23
+ */
24
+ get data(): any;
25
+ /**
26
+ * Returns the response payload.
27
+ *
28
+ * @returns {*}
29
+ */
30
+ get payload(): any;
31
+ /**
32
+ * Returns the response headers.
33
+ *
34
+ * @returns {Object}
35
+ */
36
+ get headers(): import("axios").AxiosResponseHeaders;
37
+ }
@@ -0,0 +1,4 @@
1
+ import { HttpClient } from './client';
2
+ export default HttpClient;
3
+ export * from './client';
4
+ export * from './http-response';
package/types/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export { default as messageHandler } from './message-handler';
5
5
  export { default as configHandler } from './config-handler';
6
6
  export { default as printFlagDeprecation } from './flag-deprecation-check';
7
7
  export * from './http-client';
8
+ export { default as NodeCrypto } from './encrypter';
@@ -7,6 +7,6 @@ export declare function chooseContentTypes(stack: any, displayMessage?: string):
7
7
  export declare function chooseEnvironments(stack: any, displayMessage?: string): Promise<Environment[]>;
8
8
  export declare function chooseEnvironment(stack: any, displayMessage?: string): Promise<Environment>;
9
9
  export declare function chooseLocales(stack: any, displayMessage?: string): Promise<Locale[]>;
10
- export declare function chooseLocale(stack: any, displayMessage?: string): Promise<Locale>;
10
+ export declare function chooseLocale(stack: any, displayMessage?: string, defaultLocale?: Locale): Promise<Locale>;
11
11
  export declare function chooseTokenAlias(): Promise<Token>;
12
12
  export declare function chooseDeliveryTokenAlias(): Promise<Token>;