@contentstack/cli-cm-import 0.1.1-beta.1 → 0.1.1-beta.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.
@@ -51,7 +51,7 @@ importEnvironments.prototype = {
51
51
  mkdirp.sync(envMapperPath)
52
52
  return new Promise(function (resolve, reject) {
53
53
  if (self.environments === undefined) {
54
- addlogs(config, chalk.yellow('No Environment Found'), 'error')
54
+ addlogs(config, chalk.yellow('No Environment Found'), 'success')
55
55
  return resolve()
56
56
  }
57
57
 
@@ -50,6 +50,7 @@ importGlobalFields.prototype = {
50
50
  globalfieldsMapperPath = path.resolve(config.data, 'mapper', 'global_fields')
51
51
  globalfieldsUidMapperPath = path.resolve(config.data, 'mapper', 'global_fields', 'uid-mapping.json')
52
52
  globalfieldsSuccessPath = path.resolve(config.data, 'mapper', 'global_fields', 'success.json')
53
+ globalFieldsPending = path.resolve(config.data, 'mapper', 'global_fields', 'pending_global_fields.js')
53
54
  globalfieldsFailsPath = path.resolve(config.data, 'mapper', 'global_fields', 'fails.json')
54
55
  self.globalfields = helper.readFile(path.resolve(globalfieldsFolderPath, globalfieldsConfig.fileName))
55
56
  if (fs.existsSync(globalfieldsUidMapperPath)) {
@@ -64,6 +65,7 @@ importGlobalFields.prototype = {
64
65
  return new Promise(function (resolve, reject) {
65
66
  if (self.globalfields === undefined) {
66
67
  addlogs(config, chalk.white('No globalfields Found'), 'success')
68
+ helper.writeFile(globalFieldsPending, _globalField_pending)
67
69
  return resolve()
68
70
  }
69
71
  let snipUids = Object.keys(self.globalfields)
@@ -114,6 +116,7 @@ importGlobalFields.prototype = {
114
116
  }).then(function () {
115
117
  // globalfields have imported successfully
116
118
  helper.writeFile(globalfieldsSuccessPath, self.success)
119
+ helper.writeFile(globalFieldsPending, _globalField_pending)
117
120
  addlogs(config, chalk.green('globalfields have been imported successfully!'), 'success')
118
121
  return resolve()
119
122
  }).catch(function (err) {
@@ -12,7 +12,7 @@ const chalk = require('chalk');
12
12
  const _ = require('lodash')
13
13
 
14
14
  const helper = require('../util/fs');
15
- const {addlogs} = require('../util/log');
15
+ const { addlogs } = require('../util/log');
16
16
  let config = require('../../config/default')
17
17
  let stack = require('../util/contentstack-management-sdk')
18
18
 
@@ -26,7 +26,7 @@ let labelFailsPath
26
26
  let client
27
27
 
28
28
 
29
- function importLabels () {
29
+ function importLabels() {
30
30
  this.fails = [];
31
31
  this.success = [];
32
32
  this.labelUidMapper = {};
@@ -50,35 +50,39 @@ importLabels.prototype = {
50
50
  labelSuccessPath = path.resolve(config.data, 'labels', 'success.json');
51
51
  labelFailsPath = path.resolve(config.data, 'labels', 'fails.json');
52
52
  mkdirp.sync(labelMapperPath);
53
-
54
53
  return new Promise(function (resolve, reject) {
55
- if(self.labels == undefined) {
54
+ if (self.labels == undefined) {
56
55
  addlogs(config, chalk.white('No Label Found'), 'error');
57
56
  return resolve();
58
57
  }
59
58
  self.labelUids = Object.keys(self.labels);
60
59
  return Promise.map(self.labelUids, function (labelUid) {
61
60
  let label = self.labels[labelUid];
62
- if(label.parent.length != 0) {
61
+ if (label.parent.length != 0) {
63
62
  delete label['parent'];
64
- }
63
+ }
65
64
 
66
65
  if (!self.labelUidMapper.hasOwnProperty(labelUid)) {
67
66
  let requestOption = {
68
- label: label
67
+ label: label
69
68
  };
70
-
69
+
71
70
  // return self.createLabels(self.labels[labelUid]);
72
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).label().create(requestOption)
73
- .then(function (response) {
74
- self.labelUidMapper[labelUid] = response;
75
- helper.writeFile(labelUidMapperPath, self.labelUidMapper);
76
- return;
77
- }).catch(function (error) {
78
- self.fails.push(label);
79
- addlogs(config, chalk.red('Label: \'' + label.name + '\' failed to be imported\n' + JSON.stringify(error)), 'error');
80
- return;
81
- });
71
+ return client.stack({ api_key: config.target_stack, management_token: config.management_token }).label().create(requestOption)
72
+ .then(function (response) {
73
+ self.labelUidMapper[labelUid] = response;
74
+ helper.writeFile(labelUidMapperPath, self.labelUidMapper);
75
+ return;
76
+ }).catch(function (error) {
77
+ self.fails.push(label);
78
+ // addlogs(config, chalk.red('Label: \'' + label.name + '\' failed to be imported\n'), 'error');
79
+ if (error.errors.name) {
80
+ addlogs(config, chalk.red('Label: \'' + label.name + '\' already exist'), 'error');
81
+ } else {
82
+ addlogs(config, chalk.red('Label: \'' + label.name + '\' failed to be imported\n'), 'error');
83
+ }
84
+ return;
85
+ });
82
86
  } else {
83
87
  // the label has already been created
84
88
  addlogs(config, (chalk.white('The label: \'' + label.name +
@@ -97,7 +101,7 @@ importLabels.prototype = {
97
101
  }).catch(function (error) {
98
102
  // eslint-disable-next-line no-console
99
103
  return reject(error);
100
- });
104
+ });
101
105
  }).catch(function (error) {
102
106
  // error while importing labels
103
107
  helper.writeFile(labelFailsPath, self.fails);
@@ -107,34 +111,36 @@ importLabels.prototype = {
107
111
  });
108
112
  },
109
113
 
110
- updateLabels: function() {
111
- let self = this;
114
+ updateLabels: function () {
115
+ let self = this;
112
116
  return new Promise(function (resolve, reject) {
113
117
  let labelsObj = helper.readFile(path.resolve(labelsFolderPath, labelConfig.fileName));
114
118
  return Promise.map(self.labelUids, function (labelUid) {
115
119
  let label = labelsObj[labelUid];
116
- if(self.labelUidMapper.hasOwnProperty(labelUid)) {
120
+ if (self.labelUidMapper.hasOwnProperty(labelUid)) {
117
121
  let newLabelUid = self.labelUidMapper[labelUid];
118
- if(label.parent.length != 0) {
122
+ if (label.parent.length > 0) {
119
123
  let parentUids = label.parent;
120
- for(let i=0; i<parentUids.length; i++) {
121
- if(self.labelUidMapper.hasOwnProperty(parentUids[i])) {
122
- label.parent[i] = self.labelUidMapper[parentUids[i]];
124
+ for (let i = 0; i < parentUids.length; i++) {
125
+ if (self.labelUidMapper.hasOwnProperty(parentUids[i])) {
126
+ label.parent[i] = self.labelUidMapper[parentUids[i]].uid;
123
127
  }
124
128
  }
129
+ return client.stack({ api_key: config.target_stack, management_token: config.management_token }).label(newLabelUid.uid).fetch()
130
+ .then(function (response) {
131
+ //Object.assign(response, _.cloneDeep(label))
132
+ response.parent = label.parent
133
+ response.update().then((result) => {
134
+ self.success.push(result);
135
+ }).catch(error => {
136
+ return reject(error);
137
+ })
138
+ }).catch(function (error) {
139
+ return reject(error);
140
+ });
125
141
  }
126
142
 
127
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).label(newLabelUid.uid).fetch()
128
- .then(function (response) {
129
- Object.assign(response, _.cloneDeep(label))
130
- response.update().then((result) => {
131
- self.success.push(result);
132
- }).catch(error => {
133
- return reject(error);
134
- })
135
- }).catch(function (error) {
136
- return reject(error);
137
- });
143
+
138
144
  }
139
145
  }, {
140
146
  concurrency: reqConcurrency
@@ -16,6 +16,7 @@ let {addlogs} = require('../util/log')
16
16
  let util = require('../util')
17
17
  let stack = require('../util/contentstack-management-sdk')
18
18
  let config = require('../../config/default')
19
+ let _ = require('lodash')
19
20
  let reqConcurrency = config.concurrency
20
21
  let langConfig = config.modules.locales
21
22
  let langFolderPath
@@ -69,7 +70,6 @@ importLanguages.prototype = {
69
70
 
70
71
  return client.stack({api_key: config.target_stack, management_token: config.management_token}).locale().create(requestOption)
71
72
  .then(locale => {
72
- self.update_locales(lang)
73
73
  self.success.push(locale.items)
74
74
  self.langUidMapper[langUid] = locale.uid
75
75
  helper.writeFile(langUidMapperPath, self.langUidMapper)
@@ -92,9 +92,15 @@ importLanguages.prototype = {
92
92
  concurrency: reqConcurrency,
93
93
  }).then(function () {
94
94
  // languages have imported successfully
95
- helper.writeFile(langSuccessPath, self.success)
96
- addlogs(config, chalk.green('Languages have been imported successfully!'), 'success')
97
- return resolve()
95
+ self.update_locales(langUids)
96
+ .then(() => {
97
+ helper.writeFile(langSuccessPath, self.success)
98
+ addlogs(config, chalk.green('Languages have been imported successfully!'), 'success')
99
+ return resolve()
100
+ }).catch(function (error) {
101
+ return reject(error)
102
+ })
103
+
98
104
  }).catch(function (error) {
99
105
  // error while importing languages
100
106
  helper.writeFile(langFailsPath, self.fails)
@@ -103,25 +109,30 @@ importLanguages.prototype = {
103
109
  })
104
110
  })
105
111
  },
106
- update_locales: function (lang) {
112
+ update_locales: function (langUids) {
107
113
  let self = this
108
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).locale(lang.code).fetch()
109
- // return request(requestOption)
110
- .then(function (locale) {
111
- locale.code = lang.code
112
- locale.fallback_locale = lang.fallback_locale
113
- locale.name = lang.name
114
- return locale.update()
115
- }).catch(function (error) {
116
- // let error = JSON.parse(err.message)
117
- if (error.hasOwnProperty('errorCode') && error.errorCode === 247) {
118
- addlogs(config, error.errors.code[0], 'error')
119
- return
120
- }
121
- self.fails.push(lang)
122
- addlogs(config, 'Language: \'' + lang.code + '\' failed to update\n', 'error')
123
- return
114
+ return new Promise(function (resolve, reject) {
115
+ Promise.all(
116
+ langUids.map(async langUid => {
117
+ let lang = {}
118
+ let requireKeys = config.modules.locales.requiredKeys
119
+ let _lang = self.languages[langUid]
120
+ requireKeys.forEach(e => {
121
+ lang[e] = _lang[e]
122
+ })
123
+ let langobj = client.stack({api_key: config.target_stack, management_token: config.management_token}).locale(lang.code)
124
+ Object.assign(langobj, _.cloneDeep(lang))
125
+ langobj.update()
126
+ .then(()=>{
127
+ })
128
+ })
129
+ )
130
+ .then(()=>{
131
+ return resolve()
132
+ }).catch((error) => {
133
+ return reject(error)
124
134
  })
135
+ })
125
136
  },
126
137
  }
127
138
 
@@ -0,0 +1,118 @@
1
+ /*!
2
+ * Contentstack Import
3
+ * Copyright (c) 2019 Contentstack LLC
4
+ * MIT Licensed
5
+ */
6
+
7
+ const mkdirp = require('mkdirp');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const Promise = require('bluebird');
11
+ const chalk = require('chalk');
12
+ const _ = require('lodash')
13
+
14
+ const helper = require('../util/fs');
15
+ const { addlogs } = require('../util/log');
16
+ let config = require('../../config/default')
17
+ let stack = require('../util/contentstack-management-sdk');
18
+
19
+ let reqConcurrency = config.concurrency;
20
+ let workflowConfig = config.modules.workflows;
21
+ let workflowFolderPath
22
+ let workflowMapperPath
23
+ let workflowUidMapperPath
24
+ let workflowSuccessPath
25
+ let workflowFailsPath
26
+ let client
27
+
28
+
29
+ function importWorkflows() {
30
+ this.fails = [];
31
+ this.success = [];
32
+ this.workflowUidMapper = {};
33
+ this.labelUids = [];
34
+ if (fs.existsSync(workflowUidMapperPath)) {
35
+ this.workflowUidMapper = helper.readFile(workflowUidMapperPath);
36
+ this.workflowUidMapper = this.workflowUidMapper || {};
37
+ }
38
+ }
39
+
40
+ importWorkflows.prototype = {
41
+ start: function (credentialConfig) {
42
+ let self = this;
43
+ config = credentialConfig
44
+ client = stack.Client(config)
45
+ addlogs(config, chalk.white('Migrating workflows'), 'success')
46
+ workflowFolderPath = path.resolve(config.data, workflowConfig.dirName)
47
+ self.workflows = helper.readFile(path.resolve(workflowFolderPath, workflowConfig.fileName));
48
+ workflowMapperPath = path.resolve(config.data, 'mapper', 'workflows');
49
+ workflowUidMapperPath = path.resolve(config.data, 'mapper', 'workflows', 'uid-mapping.json');
50
+ workflowSuccessPath = path.resolve(config.data, 'workflows', 'success.json');
51
+ workflowFailsPath = path.resolve(config.data, 'workflows', 'fails.json');
52
+ mkdirp.sync(workflowMapperPath);
53
+ return new Promise(function (resolve, reject) {
54
+ if (self.workflows == undefined) {
55
+ addlogs(config, chalk.white('No workflow Found'), 'error');
56
+ return resolve();
57
+ }
58
+ self.workflowsUids = Object.keys(self.workflows);
59
+ return Promise.map(self.workflowsUids, function (workflowUid) {
60
+ let workflow = self.workflows[workflowUid];
61
+
62
+ if (!self.workflowUidMapper.hasOwnProperty(workflowUid)) {
63
+ for (let index = 0; index < workflow.workflow_stages.length; index++) {
64
+ if (workflow.workflow_stages[index].SYS_ACL.users.uids.length > 0 && workflow.workflow_stages[index].SYS_ACL.users.uids[0] !== "$all") {
65
+ workflow.workflow_stages[index].SYS_ACL.users.uids = ["$all"]
66
+ }
67
+
68
+ if (workflow.workflow_stages[index].SYS_ACL.roles.uids.length > 0) {
69
+ workflow.workflow_stages[index].SYS_ACL.roles.uids = []
70
+ }
71
+
72
+ if (workflow.workflow_stages[index].next_available_stages.length > 0) {
73
+ workflow.workflow_stages[index].next_available_stages = ["$all"]
74
+ }
75
+ }
76
+
77
+ let requestOption = {
78
+ workflow: workflow
79
+ };
80
+
81
+ return client.stack({ api_key: config.target_stack, management_token: config.management_token }).workflow().create(requestOption)
82
+ .then(function (response) {
83
+ self.workflowUidMapper[workflowUid] = response;
84
+ helper.writeFile(workflowUidMapperPath, self.workflowUidMapper);
85
+ return;
86
+ }).catch(function (error) {
87
+ self.fails.push(workflow);
88
+ if (error.errors.name) {
89
+ addlogs(config, chalk.red('workflow: \'' + workflow.name + '\' already exist'), 'error');
90
+ } else if (error.errors['workflow_stages.0.users']) {
91
+ addlogs(config, chalk.red("Failed to import Workflows as you've specified certain roles in the Stage transition and access rules section. We currently don't import roles to the stack."), 'error');
92
+ } else {
93
+ addlogs(config, chalk.red('workflow: \'' + workflow.name + '\' failed'), 'error');
94
+ }
95
+ return;
96
+ });
97
+ } else {
98
+ // the workflow has already been created
99
+ addlogs(config, (chalk.white('The Workflows: \'' + workflow.name +
100
+ '\' already exists. Skipping it to avoid duplicates!')), 'success');
101
+ return;
102
+ }
103
+ // import 1 workflows at a time
104
+ }, {
105
+ concurrency: reqConcurrency
106
+ }).then(function () {
107
+ helper.writeFile(workflowSuccessPath, self.success);
108
+ addlogs(config, (chalk.green('Workflows have been imported successfully!')), 'success');
109
+ return resolve();
110
+ }).catch(function (error) {
111
+ helper.writeFile(workflowFailsPath, self.fails);
112
+ addlogs(config, chalk.red('Workflows import failed'), 'error');
113
+ return reject(error);
114
+ });
115
+ });
116
+ }
117
+ }
118
+ module.exports = new importWorkflows();
@@ -1,16 +1,28 @@
1
- const contentstacksdk = require('@contentstack/management')
2
-
3
-
4
- exports.Client = function (config) {
1
+ const contentstacksdk = require("@contentstack/management");
5
2
 
3
+ exports.Client = function (config) {
6
4
  const option = {
7
5
  host: config.host,
8
6
  authtoken: config.auth_token,
7
+ management_token: config.management_token,
9
8
  api_key: config.target_stack,
10
9
  maxContentLength: 100000000,
11
10
  maxBodyLength: 1000000000,
12
- logHandler: (level, data) => {}
13
- }
14
- const client = contentstacksdk.client(option)
15
- return client
16
- }
11
+ logHandler: (level, data) => {},
12
+ retryCondition: (error) => {
13
+ // no async function should be used here
14
+ if (
15
+ error.response &&
16
+ (error.response.status === 429 || error.response.status === 408)
17
+ ) {
18
+ return true;
19
+ }
20
+ return false;
21
+ },
22
+ retryDelayOptions: {
23
+ base: 1000,
24
+ },
25
+ };
26
+ const client = contentstacksdk.client(option);
27
+ return client;
28
+ };
@@ -4,49 +4,47 @@
4
4
  * MIT Licensed
5
5
  */
6
6
 
7
+ // eslint-disable-next-line unicorn/filename-case
8
+ var path = require('path')
9
+ var helper = require('./fs')
10
+ var util = require('../util')
11
+ var config = util.getConfig()
12
+ var extensionPath = path.resolve(config.data, 'mapper/extensions', 'uid-mapping.json')
13
+ var globalfieldsPath = path.resolve(config.data, 'mapper/globalfields', 'uid-mapping.json')
7
14
 
8
- var path = require('path');
9
-
10
- var helper = require('./fs');
11
- var util = require('../util/');
12
- var config = util.getConfig();
13
- var extensionPath = path.resolve(config.data, 'mapper/extensions', 'uid-mapping.json');
14
- var globalfieldsPath = path.resolve(config.data, 'mapper/globalfields', 'uid-mapping.json');
15
-
16
-
15
+ // eslint-disable-next-line camelcase
17
16
  var extension_uid_Replace = module.exports = function (schema, preserveStackVersion) {
18
17
  for (var i in schema) {
19
18
  if (schema[i].data_type === 'group') {
20
- extension_uid_Replace(schema[i].schema, preserveStackVersion);
19
+ extension_uid_Replace(schema[i].schema, preserveStackVersion)
21
20
  } else if (schema[i].data_type === 'blocks') {
22
21
  for (var block in schema[i].blocks) {
23
- if(schema[i].blocks[block].hasOwnProperty('reference_to')) {
24
- delete schema[i].blocks[block].schema;
22
+ if (schema[i].blocks[block].hasOwnProperty('reference_to')) {
23
+ delete schema[i].blocks[block].schema
25
24
  } else {
26
- extension_uid_Replace(schema[i].blocks[block].schema, preserveStackVersion);
25
+ extension_uid_Replace(schema[i].blocks[block].schema, preserveStackVersion)
27
26
  }
28
27
  }
29
- } else if(schema[i].data_type === 'reference' && !schema[i].field_metadata.hasOwnProperty('ref_multiple_content_types')) {
28
+ } else if (schema[i].data_type === 'reference' && !schema[i].field_metadata.hasOwnProperty('ref_multiple_content_types')) {
30
29
  if (preserveStackVersion) {
31
30
  // do nothing
32
31
  } else {
33
- schema[i]['reference_to'] = [schema[i].reference_to];
34
- schema[i]['field_metadata']['ref_multiple_content_types'] = true;
32
+ schema[i].reference_to = [schema[i].reference_to]
33
+ schema[i].field_metadata.ref_multiple_content_types = true
35
34
  }
36
- } else if(schema[i].data_type === 'global_field') {
37
- var global_fields_key_value = schema[i]['reference_to'];
38
- var global_fields_data = helper.readFile(path.join(globalfieldsPath));
39
- if(global_fields_data && global_fields_data.hasOwnProperty(global_fields_key_value)) {
40
- schema[i]['reference_to'] = global_fields_data[global_fields_key_value];
35
+ } else if (schema[i].data_type === 'global_field') {
36
+ var global_fields_key_value = schema[i].reference_to
37
+ var global_fields_data = helper.readFile(path.join(globalfieldsPath))
38
+ if (global_fields_data && global_fields_data.hasOwnProperty(global_fields_key_value)) {
39
+ schema[i].reference_to = global_fields_data[global_fields_key_value]
41
40
  }
42
- } else {
43
- if(schema[i].hasOwnProperty('extension_uid')) {
44
- var extension_key_value = schema[i]['extension_uid'];
45
- var data = helper.readFile(path.join(extensionPath));
46
- if(data && data.hasOwnProperty(extension_key_value)) {
47
- schema[i]['extension_uid'] = data[extension_key_value];
48
- }
41
+ } else if (schema[i].hasOwnProperty('extension_uid')) {
42
+ var extension_key_value = schema[i].extension_uid
43
+ var data = helper.readFile(path.join(extensionPath))
44
+ if (data && data.hasOwnProperty(extension_key_value)) {
45
+ // eslint-disable-next-line camelcase
46
+ schema[i].extension_uid = data[extension_key_value]
49
47
  }
50
48
  }
51
49
  }
52
- };
50
+ }