@contentstack/cli-cm-import 1.0.1 → 1.2.0

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,53 +4,51 @@
4
4
  * MIT Licensed
5
5
  */
6
6
 
7
- const mkdirp = require('mkdirp');
8
7
  const fs = require('fs');
9
8
  const path = require('path');
9
+ const chalk = require('chalk');
10
+ const mkdirp = require('mkdirp');
10
11
  const Promise = require('bluebird');
11
12
  const { isEmpty } = require('lodash');
12
13
 
13
14
  const helper = require('../util/fs');
14
15
  let { addlogs } = require('../util/log');
15
- const chalk = require('chalk');
16
- let stack = require('../util/contentstack-management-sdk');
16
+ const { formatError } = require('../util');
17
+ const config = require('../../config/default');
18
+ const stack = require('../util/contentstack-management-sdk');
19
+
20
+ module.exports = class ImportEnvironments {
21
+ fails = [];
22
+ success = [];
23
+ envUidMapper = {};
24
+ fetchConcurrency = config.modules.environments.concurrency || config.fetchConcurrency || 2;
17
25
 
18
- let config = require('../../config/default');
19
- let environmentConfig = config.modules.environments;
20
- let environmentsFolderPath;
21
- let envMapperPath;
22
- let envUidMapperPath;
23
- let envSuccessPath;
24
- let envFailsPath;
25
- let client;
26
+ constructor(credentialConfig) {
27
+ this.config = credentialConfig;
28
+ }
26
29
 
27
- function importEnvironments() {
28
- this.fails = [];
29
- this.success = [];
30
- this.envUidMapper = {};
31
- }
30
+ start() {
31
+ addlogs(this.config, 'Migrating environment', 'success');
32
+
33
+ const self = this;
34
+ const client = stack.Client(this.config);
35
+ let environmentConfig = config.modules.environments;
36
+ let environmentsFolderPath = path.resolve(this.config.data, environmentConfig.dirName);
37
+ let envMapperPath = path.resolve(this.config.data, 'mapper', 'environments');
38
+ let envUidMapperPath = path.resolve(this.config.data, 'mapper', 'environments', 'uid-mapping.json');
39
+ let envSuccessPath = path.resolve(this.config.data, 'environments', 'success.json');
40
+ let envFailsPath = path.resolve(this.config.data, 'environments', 'fails.json');
41
+ self.environments = helper.readFileSync(path.resolve(environmentsFolderPath, environmentConfig.fileName));
32
42
 
33
- importEnvironments.prototype = {
34
- start: function (credentialConfig) {
35
- let self = this;
36
- config = credentialConfig;
37
- addlogs(config, 'Migrating environment', 'success');
38
- environmentsFolderPath = path.resolve(config.data, environmentConfig.dirName);
39
- envMapperPath = path.resolve(config.data, 'mapper', 'environments');
40
- envUidMapperPath = path.resolve(config.data, 'mapper', 'environments', 'uid-mapping.json');
41
- envSuccessPath = path.resolve(config.data, 'environments', 'success.json');
42
- envFailsPath = path.resolve(config.data, 'environments', 'fails.json');
43
- self.environments = helper.readFile(path.resolve(environmentsFolderPath, environmentConfig.fileName));
44
- client = stack.Client(config);
45
43
  if (fs.existsSync(envUidMapperPath)) {
46
- self.envUidMapper = helper.readFile(envUidMapperPath);
44
+ self.envUidMapper = helper.readFileSync(envUidMapperPath);
47
45
  self.envUidMapper = self.envUidMapper || {};
48
46
  }
49
47
 
50
48
  mkdirp.sync(envMapperPath);
51
49
  return new Promise(function (resolve, reject) {
52
50
  if (self.environments === undefined || isEmpty(self.environments)) {
53
- addlogs(config, chalk.yellow('No Environment Found'), 'success');
51
+ addlogs(self.config, chalk.yellow('No Environment Found'), 'success');
54
52
  return resolve({ empty: true });
55
53
  }
56
54
 
@@ -60,9 +58,7 @@ importEnvironments.prototype = {
60
58
  function (envUid) {
61
59
  let env = self.environments[envUid];
62
60
  if (!self.envUidMapper.hasOwnProperty(envUid)) {
63
- let requestOption = {
64
- environment: env,
65
- };
61
+ let requestOption = { environment: env };
66
62
 
67
63
  return client
68
64
  .stack({ api_key: config.target_stack, management_token: config.management_token })
@@ -71,12 +67,13 @@ importEnvironments.prototype = {
71
67
  .then((environment) => {
72
68
  self.success.push(environment.items);
73
69
  self.envUidMapper[envUid] = environment.uid;
74
- helper.writeFile(envUidMapperPath, self.envUidMapper);
70
+ helper.writeFileSync(envUidMapperPath, self.envUidMapper);
75
71
  })
76
72
  .catch(function (err) {
77
73
  let error = JSON.parse(err.message);
74
+
78
75
  if (error.errors.name) {
79
- addlogs(config, chalk.white("Environment: '" + env.name + "' already exists"), 'error');
76
+ addlogs(self.config, chalk.white("Environment: '" + env.name + "' already exists"), 'error');
80
77
  } else {
81
78
  addlogs(
82
79
  config,
@@ -95,26 +92,19 @@ importEnvironments.prototype = {
95
92
  'success',
96
93
  );
97
94
  }
98
- // import 2 environments at a time
99
- },
100
- {
101
- concurrency: 2,
102
95
  },
96
+ { concurrency: self.fetchConcurrency },
103
97
  )
104
98
  .then(function () {
105
- // environments have imported successfully
106
- helper.writeFile(envSuccessPath, self.success);
107
- addlogs(config, chalk.green('Environments have been imported successfully!'), 'success');
108
- return resolve();
99
+ helper.writeFileSync(envSuccessPath, self.success);
100
+ addlogs(self.config, chalk.green('Environments have been imported successfully!'), 'success');
101
+ resolve();
109
102
  })
110
103
  .catch(function (error) {
111
- // error while importing environments
112
- helper.writeFile(envFailsPath, self.fails);
113
- addlogs(config, chalk.red('Environment import failed'), 'error');
114
- return reject(error);
104
+ helper.writeFileSync(envFailsPath, self.fails);
105
+ addlogs(self.config, chalk.red(`Failed to import environment ${formatError(error)}`), 'error');
106
+ reject(error);
115
107
  });
116
108
  });
117
- },
109
+ }
118
110
  };
119
-
120
- module.exports = new importEnvironments();
@@ -9,44 +9,40 @@ const fs = require('fs');
9
9
  const path = require('path');
10
10
  const Promise = require('bluebird');
11
11
  const chalk = require('chalk');
12
- const {isEmpty} = require('lodash');
12
+ const { isEmpty } = require('lodash');
13
13
 
14
+ const util = require('../util');
14
15
  const helper = require('../util/fs');
15
16
  const { addlogs } = require('../util/log');
16
- const util = require('../util');
17
+ const { formatError } = require('../util');
17
18
 
18
19
  let config = util.getConfig();
19
- const reqConcurrency = config.concurrency;
20
- const extensionsConfig = config.modules.extensions;
21
20
  const stack = require('../util/contentstack-management-sdk');
22
- let extensionsFolderPath;
23
- let extMapperPath;
24
- let extUidMapperPath;
25
- let extSuccessPath;
26
- let extFailsPath;
27
- let client;
28
21
 
29
- function importExtensions() {
30
- this.fails = [];
31
- this.success = [];
32
- this.extUidMapper = {};
33
- }
22
+ module.exports = class ImportExtensions {
23
+ fails = [];
24
+ success = [];
25
+ extUidMapper = {};
26
+ extensionsConfig = config.modules.extensions;
27
+ reqConcurrency = config.concurrency || config.fetchConcurrency || 1;
34
28
 
35
- importExtensions.prototype = {
36
- start: function (credential) {
37
- addlogs(config, chalk.white('Migrating extensions'), 'success');
38
- let self = this;
39
- config = credential;
40
- client = stack.Client(config);
29
+ constructor(credential) {
30
+ this.config = credential;
31
+ }
41
32
 
42
- extensionsFolderPath = path.resolve(config.data, extensionsConfig.dirName);
43
- extMapperPath = path.resolve(config.data, 'mapper', 'extensions');
44
- extUidMapperPath = path.resolve(config.data, 'mapper/extensions', 'uid-mapping.json');
45
- extSuccessPath = path.resolve(config.data, 'extensions', 'success.json');
46
- extFailsPath = path.resolve(config.data, 'extensions', 'fails.json');
47
- self.extensions = helper.readFile(path.resolve(extensionsFolderPath, extensionsConfig.fileName));
33
+ start() {
34
+ addlogs(this.config, chalk.white('Migrating extensions'), 'success');
35
+
36
+ const self = this;
37
+ const client = stack.Client(this.config);
38
+ let extensionsFolderPath = path.resolve(this.config.data, this.extensionsConfig.dirName);
39
+ let extMapperPath = path.resolve(this.config.data, 'mapper', 'extensions');
40
+ let extUidMapperPath = path.resolve(this.config.data, 'mapper/extensions', 'uid-mapping.json');
41
+ let extSuccessPath = path.resolve(this.config.data, 'extensions', 'success.json');
42
+ let extFailsPath = path.resolve(this.config.data, 'extensions', 'fails.json');
43
+ this.extensions = helper.readFileSync(path.resolve(extensionsFolderPath, this.extensionsConfig.fileName));
48
44
  if (fs.existsSync(extUidMapperPath)) {
49
- self.extUidMapper = helper.readFile(extUidMapperPath);
45
+ self.extUidMapper = helper.readFileSync(extUidMapperPath);
50
46
  self.extUidMapper = self.extUidMapper || {};
51
47
  }
52
48
 
@@ -54,7 +50,7 @@ importExtensions.prototype = {
54
50
 
55
51
  return new Promise(function (resolve, reject) {
56
52
  if (self.extensions === undefined || isEmpty(self.extensions)) {
57
- addlogs(config, chalk.white('No Extensions Found'), 'success');
53
+ addlogs(self.config, chalk.white('No Extensions Found'), 'success');
58
54
  return resolve({ empty: true });
59
55
  }
60
56
  let extUids = Object.keys(self.extensions);
@@ -70,13 +66,13 @@ importExtensions.prototype = {
70
66
  .then((response) => {
71
67
  self.success.push(response);
72
68
  self.extUidMapper[extUid] = response.uid;
73
- helper.writeFile(extUidMapperPath, self.extUidMapper);
69
+ helper.writeFileSync(extUidMapperPath, self.extUidMapper);
74
70
  })
75
71
  .catch(function (err) {
76
72
  let error = JSON.parse(err.message);
77
73
  self.fails.push(ext);
78
74
  if (error.errors.title) {
79
- addlogs(config, chalk.white("Extension: '" + ext.title + "' already exists"), 'success');
75
+ addlogs(self.config, chalk.white("Extension: '" + ext.title + "' already exists"), 'success');
80
76
  } else {
81
77
  addlogs(
82
78
  config,
@@ -95,23 +91,21 @@ importExtensions.prototype = {
95
91
  // import 2 extensions at a time
96
92
  },
97
93
  {
98
- concurrency: reqConcurrency,
94
+ concurrency: self.reqConcurrency,
99
95
  },
100
96
  )
101
97
  .then(function () {
102
98
  // extensions have imported successfully
103
- helper.writeFile(extSuccessPath, self.success);
104
- addlogs(config, chalk.green('Extensions have been imported successfully!'), 'success');
105
- return resolve();
99
+ helper.writeFileSync(extSuccessPath, self.success);
100
+ addlogs(self.config, chalk.green('Extensions have been imported successfully!'), 'success');
101
+ resolve();
106
102
  })
107
103
  .catch(function (error) {
108
104
  // error while importing extensions
109
- helper.writeFile(extFailsPath, self.fails);
110
- addlogs(config, chalk.red('Extension import failed'), 'error');
111
- return reject(error);
105
+ helper.writeFileSync(extFailsPath, self.fails);
106
+ addlogs(self.config, chalk.red(`Extension import failed ${formatError(error)}`), 'error');
107
+ reject(error);
112
108
  });
113
109
  });
114
- },
110
+ }
115
111
  };
116
-
117
- module.exports = new importExtensions();
@@ -4,79 +4,80 @@
4
4
  * MIT Licensed
5
5
  */
6
6
 
7
- let mkdirp = require('mkdirp');
8
7
  let fs = require('fs');
9
8
  let path = require('path');
10
- let Promise = require('bluebird');
11
9
  let chalk = require('chalk');
12
- const {isEmpty} = require('lodash');
10
+ let mkdirp = require('mkdirp');
11
+ let Promise = require('bluebird');
12
+ const { isEmpty } = require('lodash');
13
13
 
14
14
  let helper = require('../util/fs');
15
15
  let { addlogs } = require('../util/log');
16
+ const { formatError } = require('../util');
17
+ let config = require('../../config/default');
18
+ const stack = require('../util/contentstack-management-sdk');
16
19
  let extension_supress = require('../util/extensionsUidReplace');
17
20
  let removeReferenceFields = require('../util/removeReferenceFields');
18
- const stack = require('../util/contentstack-management-sdk');
19
-
20
- let config = require('../../config/default');
21
- let reqConcurrency = config.concurrency;
22
- let globalfieldsConfig = config.modules.globalfields;
23
- let globalfieldsFolderPath;
24
- let globalfieldsMapperPath;
25
- let globalfieldsUidMapperPath;
26
- let globalfieldsSuccessPath;
27
- let globalfieldsFailsPath;
28
- let client;
29
- let globalFieldsPending;
21
+ const { getInstalledExtensions } = require('../util/marketplace-app-helper');
30
22
 
31
23
  global._globalField_pending = [];
32
24
 
33
- function importGlobalFields() {
34
- this.fails = [];
35
- this.success = [];
36
- this.snipUidMapper = {};
37
- this.requestOptions = {
38
- uri: config.host + config.apis.globalfields,
39
- headers: config.headers,
40
- method: 'POST',
41
- };
42
- }
25
+ module.exports = class ImportGlobalFields {
26
+ fails = [];
27
+ success = [];
28
+ snipUidMapper = {};
29
+ installedExtensions = [];
30
+ reqConcurrency = config.concurrency || config.fetchConcurrency || 1;
31
+
32
+ constructor(credential) {
33
+ this.config = credential;
34
+ }
35
+
36
+ async start() {
37
+ addlogs(this.config, chalk.white('Migrating global-fields'), 'success');
43
38
 
44
- importGlobalFields.prototype = {
45
- start: function (credential) {
46
- addlogs(config, chalk.white('Migrating global-fields'), 'success');
47
39
  let self = this;
48
- config = credential;
49
- globalfieldsFolderPath = path.resolve(config.data, globalfieldsConfig.dirName);
50
- globalfieldsMapperPath = path.resolve(config.data, 'mapper', 'global_fields');
51
- globalfieldsUidMapperPath = path.resolve(config.data, 'mapper', 'global_fields', 'uid-mapping.json');
52
- globalfieldsSuccessPath = path.resolve(config.data, 'mapper', 'global_fields', 'success.json');
53
- globalFieldsPending = path.resolve(config.data, 'mapper', 'global_fields', 'pending_global_fields.js');
54
- globalfieldsFailsPath = path.resolve(config.data, 'mapper', 'global_fields', 'fails.json');
55
- self.globalfields = helper.readFile(path.resolve(globalfieldsFolderPath, globalfieldsConfig.fileName));
40
+ let globalfieldsConfig = config.modules.globalfields;
41
+ let globalfieldsFolderPath = path.resolve(this.config.data, globalfieldsConfig.dirName);
42
+ let appMapperFolderPath = path.join(this.config.data, 'mapper', 'marketplace_apps');
43
+ let globalfieldsMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields');
44
+ let globalfieldsUidMapperPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'uid-mapping.json');
45
+ let globalfieldsSuccessPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'success.json');
46
+ let globalFieldsPending = path.resolve(this.config.data, 'mapper', 'global_fields', 'pending_global_fields.js');
47
+ let globalfieldsFailsPath = path.resolve(this.config.data, 'mapper', 'global_fields', 'fails.json');
48
+ self.globalfields = helper.readFileSync(path.resolve(globalfieldsFolderPath, globalfieldsConfig.fileName));
49
+
56
50
  if (fs.existsSync(globalfieldsUidMapperPath)) {
57
- self.snipUidMapper = helper.readFile(globalfieldsUidMapperPath);
58
- self.snipUidMapper = this.snipUidMapper || {};
51
+ self.snipUidMapper = helper.readFileSync(globalfieldsUidMapperPath);
52
+ self.snipUidMapper = self.snipUidMapper || {};
59
53
  }
60
54
 
61
55
  if (!fs.existsSync(globalfieldsMapperPath)) {
62
56
  mkdirp.sync(globalfieldsMapperPath);
63
57
  }
64
- client = stack.Client(config);
58
+
59
+ if (fs.existsSync(path.join(appMapperFolderPath, 'marketplace-apps.json'))) {
60
+ self.installedExtensions = helper.readFileSync(path.join(appMapperFolderPath, 'marketplace-apps.json')) || {};
61
+ }
62
+
63
+ if (isEmpty(self.installedExtensions)) {
64
+ self.installedExtensions = await getInstalledExtensions(self.config);
65
+ }
66
+
67
+ const client = stack.Client(self.config);
65
68
  return new Promise(function (resolve, reject) {
66
69
  if (self.globalfields === undefined || isEmpty(self.globalfields)) {
67
- addlogs(config, chalk.white('No globalfields Found'), 'success');
68
- helper.writeFile(globalFieldsPending, _globalField_pending);
70
+ addlogs(self.config, chalk.white('No globalfields Found'), 'success');
71
+ helper.writeFileSync(globalFieldsPending, _globalField_pending);
69
72
  return resolve({ empty: true });
70
73
  }
71
74
  let snipUids = Object.keys(self.globalfields);
72
75
  return Promise.map(
73
76
  snipUids,
74
77
  function (snipUid) {
75
- let flag = {
76
- supressed: false,
77
- };
78
+ let flag = { supressed: false };
78
79
  let snip = self.globalfields[snipUid];
79
- extension_supress(snip.schema);
80
+ extension_supress(snip.schema, self.config.preserveStackVersion, self.installedExtensions);
80
81
  removeReferenceFields(snip.schema, flag);
81
82
 
82
83
  if (flag.supressed) {
@@ -85,60 +86,60 @@ importGlobalFields.prototype = {
85
86
  }
86
87
 
87
88
  if (!self.snipUidMapper.hasOwnProperty(snipUid)) {
88
- let requestOption = {
89
- global_field: snip,
90
- };
89
+ let requestOption = { global_field: snip };
91
90
  return client
92
- .stack({ api_key: config.target_stack, management_token: config.management_token })
91
+ .stack({ api_key: self.config.target_stack, management_token: self.config.management_token })
93
92
  .globalField()
94
93
  .create(requestOption)
95
94
  .then((globalField) => {
96
95
  self.success.push(globalField.items);
97
96
  let global_field_uid = globalField.uid;
98
97
  self.snipUidMapper[snipUid] = globalField.items;
99
- helper.writeFile(globalfieldsUidMapperPath, self.snipUidMapper);
100
- addlogs(config, chalk.green('Global field ' + global_field_uid + ' created successfully'), 'success');
98
+ helper.writeFileSync(globalfieldsUidMapperPath, self.snipUidMapper);
99
+ addlogs(
100
+ self.config,
101
+ chalk.green('Global field ' + global_field_uid + ' created successfully'),
102
+ 'success',
103
+ );
101
104
  })
102
105
  .catch(function (err) {
103
106
  let error = JSON.parse(err.message);
104
107
  if (error.errors.title) {
105
108
  // eslint-disable-next-line no-undef
106
- addlogs(config, chalk.white(snip.uid + ' globalfield already exists'), 'error');
109
+ addlogs(self.config, chalk.white(snip.uid + ' globalfield already exists'), 'error');
107
110
  } else {
108
- addlogs(config, chalk.red('Globalfield failed to import ' + JSON.stringify(error.errors)), 'error');
111
+ addlogs(self.config, chalk.red(`Globalfield failed to import ${formatError(error)}`), 'error');
109
112
  }
113
+
110
114
  self.fails.push(snip);
111
115
  });
112
116
  } else {
113
117
  // globalfields has already been created
114
118
  addlogs(
115
- config,
119
+ self.config,
116
120
  chalk.white('The globalfields already exists. Skipping it to avoid duplicates!'),
117
121
  'success',
118
122
  );
119
123
  }
120
124
  // import 2 globalfields at a time
121
125
  },
122
- {
123
- concurrency: reqConcurrency,
124
- },
126
+ { concurrency: self.reqConcurrency },
125
127
  )
126
128
  .then(function () {
127
129
  // globalfields have imported successfully
128
- helper.writeFile(globalfieldsSuccessPath, self.success);
129
- helper.writeFile(globalFieldsPending, _globalField_pending);
130
- addlogs(config, chalk.green('globalfields have been imported successfully!'), 'success');
130
+ helper.writeFileSync(globalfieldsSuccessPath, self.success);
131
+ helper.writeFileSync(globalFieldsPending, _globalField_pending);
132
+ addlogs(self.config, chalk.green('globalfields have been imported successfully!'), 'success');
131
133
  return resolve();
132
134
  })
133
135
  .catch(function (err) {
134
136
  let error = JSON.parse(err);
135
137
  // error while importing globalfields
136
- helper.writeFile(globalfieldsFailsPath, self.fails);
137
- addlogs(config, chalk.red('globalfields import failed'), 'error');
138
+ addlogs(self.config, err, 'error');
139
+ helper.writeFileSync(globalfieldsFailsPath, self.fails);
140
+ addlogs(self.config, chalk.red('globalfields import failed'), 'error');
138
141
  return reject(error);
139
142
  });
140
143
  });
141
- },
144
+ }
142
145
  };
143
-
144
- module.exports = new importGlobalFields();