@contentstack/cli-cm-export 0.1.1-beta.1 → 0.1.1-beta.12

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.
@@ -5,6 +5,13 @@ exports.Client = function (config) {
5
5
  host: config.host,
6
6
  authtoken: config.auth_token,
7
7
  api_key: config.source_stack,
8
+ logHandler: (level, data) => {},
9
+ }
10
+
11
+ if (typeof config.branchName === 'string') {
12
+ option.headers = {
13
+ branch: config.branchName,
14
+ }
8
15
  }
9
16
 
10
17
  const client = contentstacksdk.client(option)
@@ -6,89 +6,153 @@
6
6
  let defaultConfig = require('../../config/default')
7
7
  let message = require('../../../messages/index.json')
8
8
  let {initial} = require('../../app')
9
+ let path = require('path')
10
+ const helper = require('../util/helper');
9
11
  let _ = require('lodash')
10
12
  const {cli} = require('cli-ux')
11
13
 
12
- exports.configWithMToken = function (config, managementTokens, host) {
14
+ exports.configWithMToken = function (config, managementTokens, host, contentTypes, branchName, securedAssets) {
13
15
  let externalConfig = require(config)
16
+ defaultConfig.securedAssets = securedAssets
14
17
  defaultConfig.management_token = managementTokens.token
15
18
  defaultConfig.host = host.cma
16
19
  defaultConfig.cdn = host.cda
20
+ defaultConfig.branchName = branchName
21
+ if (moduleName) {
22
+ defaultConfig.moduleName = moduleName
23
+ // Specfic content type setting is only for entries module
24
+ if (
25
+ moduleName === 'entries' &&
26
+ Array.isArray(contentTypes) &&
27
+ contentTypes.length > 0
28
+ ) {
29
+ defaultConfig.contentTypes = contentTypes
30
+ }
31
+ }
17
32
  defaultConfig = _.merge(defaultConfig, externalConfig)
18
33
  initial(defaultConfig)
19
34
  }
20
35
 
21
- exports.parameterWithMToken = function (masterLang, managementTokens, sourceStack, data, moduleName, host) {
22
- let masterloc = {master_locale: {code: masterLang}}
36
+ exports.parameterWithMToken = function (managementTokens, data, moduleName, host, _authToken, contentTypes, branchName, securedAssets) {
23
37
  defaultConfig.management_token = managementTokens.token
38
+ defaultConfig.auth_token = _authToken
24
39
  defaultConfig.host = host.cma
25
40
  defaultConfig.cdn = host.cda
26
- if (moduleName && moduleName !== undefined) {
41
+ defaultConfig.branchName = branchName
42
+ defaultConfig.securedAssets = securedAssets
43
+ if (moduleName) {
27
44
  defaultConfig.moduleName = moduleName
45
+ // Specfic content type setting is only for entries module
46
+ if (
47
+ moduleName === 'entries' &&
48
+ Array.isArray(contentTypes) &&
49
+ contentTypes.length > 0
50
+ ) {
51
+ defaultConfig.contentTypes = contentTypes
52
+ }
28
53
  }
29
- defaultConfig.source_stack = sourceStack
54
+ defaultConfig.source_stack = managementTokens.apiKey
30
55
  defaultConfig.data = data
31
- defaultConfig = _.merge(defaultConfig, masterloc)
32
56
  initial(defaultConfig)
33
57
  }
34
58
 
35
59
  // using ManagementToken
36
- exports.withoutParameterMToken = async (managementTokens, moduleName, host) => {
37
- const masterLocale = await cli.prompt(message.promptMessageList.promptMasterLocale)
60
+ exports.withoutParameterMToken = async (managementTokens, moduleName, host, _authToken, contentTypes, branchName, securedAssets) => {
38
61
  const stackUid = managementTokens.apiKey
39
62
  const pathOfExport = await cli.prompt(message.promptMessageList.promptPathStoredData)
40
- let masterloc = {master_locale: {code: masterLocale}}
41
63
  defaultConfig.management_token = managementTokens.token
42
64
  defaultConfig.host = host.cma
43
65
  defaultConfig.cdn = host.cda
44
- if (moduleName && moduleName !== undefined) {
66
+ defaultConfig.branchName = branchName
67
+ defaultConfig.auth_token = _authToken
68
+ defaultConfig.securedAssets = securedAssets
69
+ if (moduleName) {
45
70
  defaultConfig.moduleName = moduleName
71
+ // Specfic content type setting is only for entries module
72
+ if (
73
+ moduleName === 'entries' &&
74
+ Array.isArray(contentTypes) &&
75
+ contentTypes.length > 0
76
+ ) {
77
+ defaultConfig.contentTypes = contentTypes
78
+ }
46
79
  }
47
80
  defaultConfig.source_stack = stackUid
48
81
  defaultConfig.data = pathOfExport
49
- defaultConfig = _.merge(defaultConfig, masterloc)
50
82
  initial(defaultConfig)
51
83
  }
52
84
 
53
- exports.configWithAuthToken = function (config, _authToken, moduleName, host) {
54
- let externalConfig = require(config)
85
+ exports.configWithAuthToken = function (config, _authToken, moduleName, host, contentTypes, branchName, securedAssets) {
86
+ let externalConfig = helper.readFile(path.resolve(config))
55
87
  defaultConfig.auth_token = _authToken
56
88
  defaultConfig.host = host.cma
57
89
  defaultConfig.cdn = host.cda
58
- if (moduleName && moduleName !== undefined) {
90
+ defaultConfig.branchName = branchName
91
+ defaultConfig.securedAssets = securedAssets
92
+ if (moduleName) {
59
93
  defaultConfig.moduleName = moduleName
94
+ // Specfic content type setting is only for entries module
95
+ if (
96
+ moduleName === 'entries' &&
97
+ Array.isArray(contentTypes) &&
98
+ contentTypes.length > 0
99
+ ) {
100
+ defaultConfig.contentTypes = contentTypes
101
+ }
60
102
  }
61
103
  defaultConfig = _.merge(defaultConfig, externalConfig)
62
104
  initial(defaultConfig)
63
105
  }
64
106
 
65
- exports.parametersWithAuthToken = function (masterLang, _authToken, sourceStack, data, moduleName, host) {
66
- let masterloc = {master_locale: {code: masterLang}}
67
- defaultConfig.auth_token = _authToken
68
- defaultConfig.source_stack = sourceStack
69
- if (moduleName && moduleName !== undefined) {
70
- defaultConfig.moduleName = moduleName
71
- }
72
- defaultConfig.host = host.cma
73
- defaultConfig.cdn = host.cda
74
- defaultConfig.data = data
75
- defaultConfig = _.merge(defaultConfig, masterloc)
76
- initial(defaultConfig)
107
+ exports.parametersWithAuthToken = function (_authToken, sourceStack, data, moduleName, host, contentTypes, branchName, securedAssets) {
108
+ return new Promise(async(resolve, reject) => {
109
+ defaultConfig.auth_token = _authToken
110
+ defaultConfig.source_stack = sourceStack
111
+ if (moduleName) {
112
+ defaultConfig.moduleName = moduleName
113
+ // Specfic content type setting is only for entries module
114
+ if (
115
+ moduleName === 'entries' &&
116
+ Array.isArray(contentTypes) &&
117
+ contentTypes.length > 0
118
+ ) {
119
+ defaultConfig.contentTypes = contentTypes
120
+ }
121
+ }
122
+ defaultConfig.branchName = branchName
123
+ defaultConfig.host = host.cma
124
+ defaultConfig.cdn = host.cda
125
+ defaultConfig.data = data
126
+ defaultConfig.securedAssets = securedAssets
127
+ var exportStart = initial(defaultConfig)
128
+ exportStart.then(() => {
129
+ return resolve()
130
+ }).catch((error) => {
131
+ return reject(error)
132
+ })
133
+ })
77
134
  }
78
135
 
79
- exports.withoutParametersWithAuthToken = async (_authToken, moduleName, host) => {
80
- const masterLocale = await cli.prompt(message.promptMessageList.promptMasterLocale)
136
+ exports.withoutParametersWithAuthToken = async (_authToken, moduleName, host, contentTypes, branchName, securedAssets) => {
81
137
  const stackUid = await cli.prompt(message.promptMessageList.promptSourceStack)
82
138
  const pathOfExport = await cli.prompt(message.promptMessageList.promptPathStoredData)
83
- let masterloc = {master_locale: {code: masterLocale}}
84
139
  defaultConfig.auth_token = _authToken
85
140
  defaultConfig.source_stack = stackUid
86
- if (moduleName && moduleName !== undefined) {
141
+ defaultConfig.securedAssets = securedAssets
142
+ if (moduleName) {
87
143
  defaultConfig.moduleName = moduleName
144
+ // Specfic content type setting is only for entries module
145
+ if (
146
+ moduleName === 'entries' &&
147
+ Array.isArray(contentTypes) &&
148
+ contentTypes.length > 0
149
+ ) {
150
+ defaultConfig.contentTypes = contentTypes
151
+ }
88
152
  }
153
+ defaultConfig.branchName = branchName
89
154
  defaultConfig.data = pathOfExport
90
155
  defaultConfig.host = host.cma
91
156
  defaultConfig.cdn = host.cda
92
- defaultConfig = _.merge(defaultConfig, masterloc)
93
157
  initial(defaultConfig)
94
158
  }
@@ -23,14 +23,10 @@ exports.validateConfig = function (config) {
23
23
  } else if (!config.email && !config.password && config.preserveStackVersion) {
24
24
  throw new Error('Kindly provide Email and password for stack details')
25
25
  }
26
-
27
- if(!config.languagesCode.includes(config.master_locale.code)) {
28
- addlogs(config, chalk.red('Kindly provide valid master_locale code'), 'error')
29
- process.exit()
30
- }
31
26
  }
32
27
 
33
28
  exports.buildAppConfig = function (config) {
34
29
  config = _.merge(defaultConfig, config)
35
30
  return config
36
31
  }
32
+
@@ -24,12 +24,11 @@ function returnString(args) {
24
24
 
25
25
  var myCustomLevels = {
26
26
  levels: {
27
- error: 0,
28
27
  warn: 1,
29
28
  info: 2,
30
29
  debug: 3,
31
30
  },
32
- colors: {
31
+ colors: { //colors aren't being used anywhere as of now, we're using chalk to add colors while logging
33
32
  info: 'blue',
34
33
  debug: 'green',
35
34
  warn: 'yellow',
@@ -37,26 +36,52 @@ var myCustomLevels = {
37
36
  },
38
37
  }
39
38
 
40
- function init (_logPath, logfileName) {
41
- var logsDir = path.resolve(_logPath, 'logs', 'export')
42
- // Create dir if doesn't already exist
43
- mkdirp.sync(logsDir)
44
- var logPath = path.join(logsDir, logfileName + '.log')
39
+ let logger
40
+ let errorLogger
45
41
 
46
- var transports = [new (winston.transports.File)({
47
- filename: logPath,
48
- maxFiles: 20,
49
- maxsize: 1000000,
50
- tailable: true,
51
- json: true,
52
- })]
42
+ let successTransport
43
+ let errorTransport
53
44
 
54
- transports.push(new (winston.transports.Console)())
45
+ function init(_logPath) {
46
+ if (!logger || !errorLogger) {
47
+ var logsDir = path.resolve(_logPath, 'logs', 'export')
48
+ // Create dir if doesn't already exist
49
+ mkdirp.sync(logsDir)
55
50
 
56
- var logger = new(winston.Logger)({
57
- transports: transports,
58
- levels: myCustomLevels.levels
59
- })
51
+ successTransport = {
52
+ filename: path.join(logsDir, 'success.log'),
53
+ maxFiles: 20,
54
+ maxsize: 1000000,
55
+ tailable: true,
56
+ json: true,
57
+ level: 'info',
58
+ }
59
+
60
+ errorTransport = {
61
+ filename: path.join(logsDir, 'error.log'),
62
+ maxFiles: 20,
63
+ maxsize: 1000000,
64
+ tailable: true,
65
+ json: true,
66
+ level: 'error',
67
+ }
68
+
69
+ logger = new (winston.Logger)({
70
+ transports: [
71
+ new (winston.transports.File)(successTransport),
72
+ new (winston.transports.Console)()
73
+ ],
74
+ levels: myCustomLevels.levels
75
+ });
76
+
77
+ errorLogger = new (winston.Logger)({
78
+ transports: [
79
+ new (winston.transports.File)(errorTransport),
80
+ new (winston.transports.Console)({ level: 'error' })
81
+ ],
82
+ levels: { error: 0 }
83
+ })
84
+ }
60
85
 
61
86
  return {
62
87
  log: function () {
@@ -77,7 +102,7 @@ function init (_logPath, logfileName) {
77
102
  var args = slice.call(arguments)
78
103
  var logString = returnString(args)
79
104
  if (logString) {
80
- logger.log('error', logString)
105
+ errorLogger.log('error', logString)
81
106
  }
82
107
  },
83
108
  debug: function () {
@@ -91,10 +116,23 @@ function init (_logPath, logfileName) {
91
116
  }
92
117
 
93
118
  exports.addlogs = async (config, message, type) => {
94
- // console.log("datattaat", data)
119
+ // ignoring the type argument, as we are not using it to create a logfile anymore
95
120
  if (type !== 'error') {
96
- init(config.data, type).log(message)
121
+ // removed type argument from init method
122
+ init(config.data).log(message)
97
123
  } else {
98
- init(config.data, type).error(message)
124
+ init(config.data).error(message)
99
125
  }
100
126
  }
127
+
128
+ exports.unlinkFileLogger = () => {
129
+ if (logger) {
130
+ const fileLogger = logger.transports.file
131
+ logger.remove(fileLogger)
132
+ }
133
+
134
+ if (errorLogger) {
135
+ const fileLogger = errorLogger.transports.file
136
+ errorLogger.remove(fileLogger)
137
+ }
138
+ }
@@ -18,7 +18,7 @@ module.exports.login = config => {
18
18
  if (config.email && config.password) {
19
19
  // eslint-disable-next-line no-console
20
20
  console.log('Logging into Contentstack')
21
- return client.login({email: config.email, password: config.password})
21
+ client.login({email: config.email, password: config.password})
22
22
  .then(function (response) {
23
23
  // eslint-disable-next-line no-console
24
24
  console.log(chalk.green('Contentstack account authenticated successfully!'))
@@ -29,11 +29,11 @@ module.exports.login = config => {
29
29
  authtoken: config.authtoken,
30
30
  'X-User-Agent': 'contentstack-export/v',
31
31
  }
32
- return resolve(config)
32
+ resolve(config)
33
33
  }).catch(function (error) {
34
- return reject(error)
34
+ reject(error)
35
35
  })
36
- } if (!config.email && !config.password && config.source_stack && config.access_token) {
36
+ } else if (!config.email && !config.password && config.source_stack && config.access_token) {
37
37
  addlogs(config, chalk.yellow('Content types, entries, assets, labels, global fields, extensions modules will be exported'), 'success')
38
38
  addlogs(config, chalk.yellow('Email, password, or management token is not set in the config, cannot export Webhook and label modules'), 'success')
39
39
  config.headers = {
@@ -41,22 +41,21 @@ module.exports.login = config => {
41
41
  access_token: config.access_token,
42
42
  'X-User-Agent': 'contentstack-export/v',
43
43
  }
44
- return resolve(config)
44
+ resolve(config)
45
45
  // eslint-disable-next-line no-else-return
46
- } else if (config.auth_token) {
46
+ } else if (config.auth_token && !config.management_token) {
47
47
  client.stack({api_key: config.source_stack, management_token: config.management_token}).users()
48
48
  .then(function () {
49
- return resolve()
50
- })
51
- .catch(error => {
49
+ resolve()
50
+ }).catch(error => {
52
51
  if (error.errors.api_key) {
53
52
  return reject(error)
54
53
  }
55
54
  addlogs(config, error.errorMessage, 'error')
56
- return reject()
55
+ reject(error)
57
56
  })
58
57
  } else if (config.management_token) {
59
- return resolve()
58
+ resolve()
60
59
  }
61
60
  })
62
61
  }
@@ -8,7 +8,6 @@
8
8
 
9
9
  var Bluebird = require('bluebird');
10
10
  var request = Bluebird.promisify(require('request'));
11
- var debug = require('debug')('util:requests');
12
11
  //var pkg = require('../../package');
13
12
  var app = require('../../app');
14
13
 
@@ -22,14 +21,12 @@ function validate(req) {
22
21
  throw new Error(`Missing uri in request!\n${JSON.stringify(req)}`);
23
22
  }
24
23
  if (typeof req.method === 'undefined') {
25
- debug(`${req.uri || req.url} had no method, setting it as 'GET'`);
26
24
  req.method = 'GET';
27
25
  }
28
26
  if (typeof req.json === 'undefined') {
29
27
  req.json = true;
30
28
  }
31
29
  if (typeof req.headers === 'undefined') {
32
- debug(`${req.uri || req.url} had no headers`);
33
30
  var config = app.getConfig();
34
31
  req.headers = config.headers;
35
32
  }
@@ -44,25 +41,25 @@ var makeCall = module.exports = function(req, RETRY) {
44
41
  } else if (RETRY > MAX_RETRY_LIMIT) {
45
42
  return reject(new Error('Max retry limit exceeded!'));
46
43
  }
47
- debug(`${req.method.toUpperCase()}: ${req.uri || req.url}`);
44
+ // console.log(`${req.method.toUpperCase()}: ${req.uri || req.url}`);
48
45
  return request(req).then(function (response) {
49
46
  var timeDelay;
50
47
  if (response.statusCode >= 200 && response.statusCode <= 399) {
51
48
  return resolve(response);
52
49
  } else if (response.statusCode === 429) {
53
50
  timeDelay = Math.pow(Math.SQRT2, RETRY) * 100;
54
- debug(`API rate limit exceeded.\nReceived ${response.statusCode} status\nBody ${JSON.stringify(response)}`);
55
- debug(`Retrying ${req.uri || req.url} with ${timeDelay} sec delay`);
56
- return setTimeout(function (req, RETRY) {
57
- return makeCall(req, RETRY)
51
+ // console.log(`API rate limit exceeded.\nReceived ${response.statusCode} status\nBody ${JSON.stringify(response)}`);
52
+ console.log(`Retrying ${req.uri || req.url} with ${timeDelay} sec delay`);
53
+ return setTimeout(function (reqObj, retry) {
54
+ return makeCall(reqObj, retry)
58
55
  .then(resolve)
59
56
  .catch(reject);
60
57
  }, timeDelay, req, RETRY);
61
58
  } else if (response.statusCode >= 500) {
62
59
  // retry, with delay
63
60
  timeDelay = Math.pow(Math.SQRT2, RETRY) * 100;
64
- debug(`Recevied ${response.statusCode} status\nBody ${JSON.stringify(response)}`);
65
- debug(`Retrying ${req.uri || req.url} with ${timeDelay} sec delay`);
61
+ // console.log(`Recevied ${response.statusCode} status\nBody ${JSON.stringify(response)}`);
62
+ console.log(`Retrying ${req.uri || req.url} with ${timeDelay} sec delay`);
66
63
  RETRY++;
67
64
  return setTimeout(function (req, RETRY) {
68
65
  return makeCall(req, RETRY)
@@ -70,13 +67,11 @@ var makeCall = module.exports = function(req, RETRY) {
70
67
  .catch(reject);
71
68
  }, timeDelay, req, RETRY);
72
69
  } else {
73
- debug(`Request failed\n${JSON.stringify(req)}`);
74
- debug(`Response received\n${JSON.stringify(response)}`);
75
70
  return reject(response);
76
71
  }
77
72
  }).catch(reject);
78
73
  } catch (error) {
79
- debug(error);
74
+ console.log(error);
80
75
  return reject(error);
81
76
  }
82
77
  });
@@ -0,0 +1,62 @@
1
+ const mkdirp = require("mkdirp");
2
+ const path = require("path");
3
+ const request = require("./request");
4
+ const helper = require("./helper");
5
+
6
+ const setupBranches = async (config, branch) => {
7
+ if (typeof config !== "object") {
8
+ throw new Error("Invalid config to setup the branch");
9
+ }
10
+ let branches = [];
11
+
12
+ if (typeof branch === "string") {
13
+ //check branch exists
14
+ const result = await request({
15
+ url: `https://${config.host}/v3/stacks/branches/${branch}`,
16
+ headers: {
17
+ api_key: config.source_stack,
18
+ authtoken: config.auth_token,
19
+ },
20
+ });
21
+ if (
22
+ result &&
23
+ typeof result.body === "object" &&
24
+ typeof result.body.branch === "object"
25
+ ) {
26
+ branches.push(result.body.branch);
27
+ } else {
28
+ throw new Error("No branch found with the name " + branch);
29
+ }
30
+ } else {
31
+ try {
32
+ const result = await request({
33
+ url: `https://${config.host}/v3/stacks/branches`,
34
+ headers: {
35
+ api_key: config.source_stack,
36
+ authtoken: config.auth_token,
37
+ },
38
+ });
39
+
40
+ if (
41
+ result &&
42
+ result.body &&
43
+ Array.isArray(result.body.branches) &&
44
+ result.body.branches.length > 0
45
+ ) {
46
+ branches = result.body.branches;
47
+ } else {
48
+ branches.push("main");
49
+ }
50
+ } catch (error) {
51
+ return;
52
+ }
53
+ }
54
+
55
+ mkdirp.sync(config.data);
56
+ // create branch info file
57
+ helper.writeFile(path.join(config.data, "branches.json"), branches);
58
+ // add branches list in the
59
+ config.branches = branches;
60
+ };
61
+
62
+ module.exports = setupBranches;