@contentstack/cli-cm-import 0.1.1-beta.7 → 1.0.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,217 +4,248 @@
4
4
  * Copyright (c) 2019 Contentstack LLC
5
5
  * MIT Licensed
6
6
  */
7
- let mkdirp = require('mkdirp')
8
- let fs = require('fs')
9
- let path = require('path')
10
- let _ = require('lodash')
11
- let Promise = require('bluebird')
12
- let chalk = require('chalk')
7
+ let mkdirp = require('mkdirp');
8
+ let fs = require('fs');
9
+ let fsPromises = require('fs').promises;
10
+ let path = require('path');
11
+ let _ = require('lodash');
12
+ let Promise = require('bluebird');
13
+ let chalk = require('chalk');
13
14
 
14
- let helper = require('../util/fs')
15
- let util = require('../util')
16
- let {addlogs} = require('../util/log')
17
- let supress = require('../util/extensionsUidReplace')
18
- let sdkInstance = require('../util/contentstack-management-sdk')
15
+ let helper = require('../util/fs');
16
+ let { addlogs } = require('../util/log');
17
+ let supress = require('../util/extensionsUidReplace');
18
+ let sdkInstance = require('../util/contentstack-management-sdk');
19
19
 
20
- let config = require('../../config/default')
21
- let reqConcurrency = config.concurrency
22
- let requestLimit = config.rateLimit
23
- let contentTypeConfig = config.modules.content_types
24
- let globalFieldConfig = config.modules.globalfields
25
- let globalFieldsFolderPath
26
- let contentTypesFolderPath
27
- let mapperFolderPath
28
- let globalFieldMapperFolderPath
29
- let globalFieldUpdateFile
30
- let globalFieldPendingPath
31
- let skipFiles = ['__master.json', '__priority.json', 'schema.json', '.DS_Store']
32
- let fileNames
33
- let field_rules_ct = []
34
- let client
35
- let stack = {}
20
+ let config = require('../../config/default');
21
+ let reqConcurrency = config.concurrency;
22
+ let requestLimit = config.rateLimit;
23
+ let contentTypeConfig = config.modules.content_types;
24
+ let globalFieldConfig = config.modules.globalfields;
25
+ let globalFieldsFolderPath;
26
+ let contentTypesFolderPath;
27
+ let mapperFolderPath;
28
+ let globalFieldMapperFolderPath;
29
+ let globalFieldUpdateFile;
30
+ let globalFieldPendingPath;
31
+ let skipFiles = ['__master.json', '__priority.json', 'schema.json', '.DS_Store'];
32
+ let fileNames;
33
+ let field_rules_ct = [];
34
+ let client;
35
+ let stack = {};
36
36
 
37
37
  function importContentTypes() {
38
- let self = this
39
- this.contentTypes = []
40
- this.schemaTemplate = require('../util/schemaTemplate')
38
+ this.contentTypes = [];
39
+ this.schemaTemplate = require('../util/schemaTemplate');
41
40
  this.requestOptions = {
42
41
  json: {},
43
- }
42
+ };
44
43
  }
45
44
 
46
45
  importContentTypes.prototype = {
47
46
  start: function (credentialConfig) {
48
- addlogs(config, 'Migrating contenttypes', 'success')
49
- let self = this
50
- config = credentialConfig
51
- client = sdkInstance.Client(config)
52
- stack = client.stack({api_key: config.target_stack, management_token: config.management_token})
53
- globalFieldsFolderPath = path.resolve(config.data, globalFieldConfig.dirName)
54
- contentTypesFolderPath = path.resolve(config.data, contentTypeConfig.dirName)
55
- mapperFolderPath = path.join(config.data, 'mapper', 'content_types')
56
- globalFieldMapperFolderPath = helper.readFile(path.join(config.data, 'mapper', 'global_fields', 'success.json'))
57
- globalFieldPendingPath = helper.readFile(path.join(config.data, 'mapper', 'global_fields', 'pending_global_fields.js'))
58
- globalFieldUpdateFile = path.join(config.data, 'mapper', 'global_fields', 'success.json')
59
- fileNames = fs.readdirSync(path.join(contentTypesFolderPath))
60
- self.globalfields = helper.readFile(path.resolve(globalFieldsFolderPath, globalFieldConfig.fileName))
47
+ addlogs(config, 'Migrating contenttypes', 'success');
48
+ let self = this;
49
+ config = credentialConfig;
50
+ client = sdkInstance.Client(config);
51
+ stack = client.stack({ api_key: config.target_stack, management_token: config.management_token });
52
+ globalFieldsFolderPath = path.resolve(config.data, globalFieldConfig.dirName);
53
+ contentTypesFolderPath = path.resolve(config.data, contentTypeConfig.dirName);
54
+ mapperFolderPath = path.join(config.data, 'mapper', 'content_types');
55
+ globalFieldMapperFolderPath = helper.readFile(path.join(config.data, 'mapper', 'global_fields', 'success.json'));
56
+ globalFieldPendingPath = helper.readFile(
57
+ path.join(config.data, 'mapper', 'global_fields', 'pending_global_fields.js'),
58
+ );
59
+ globalFieldUpdateFile = path.join(config.data, 'mapper', 'global_fields', 'success.json');
60
+ fileNames = fs.readdirSync(path.join(contentTypesFolderPath));
61
+ self.globalfields = helper.readFile(path.resolve(globalFieldsFolderPath, globalFieldConfig.fileName));
61
62
  for (let index in fileNames) {
62
63
  if (skipFiles.indexOf(fileNames[index]) === -1) {
63
- self.contentTypes.push(helper.readFile(path.join(contentTypesFolderPath, fileNames[index])))
64
+ self.contentTypes.push(helper.readFile(path.join(contentTypesFolderPath, fileNames[index])));
64
65
  }
65
66
  }
66
67
 
67
- self.contentTypeUids = _.map(self.contentTypes, 'uid')
68
- self.createdContentTypeUids = []
68
+ self.contentTypeUids = _.map(self.contentTypes, 'uid').filter(val => val);
69
+ self.createdContentTypeUids = [];
69
70
  if (!fs.existsSync(mapperFolderPath)) {
70
- mkdirp.sync(mapperFolderPath)
71
+ mkdirp.sync(mapperFolderPath);
71
72
  }
72
73
  // avoid re-creating content types that already exists in the stack
73
74
  if (fs.existsSync(path.join(mapperFolderPath, 'success.json'))) {
74
- self.createdContentTypeUids = helper.readFile(path.join(mapperFolderPath, 'success.json')) || []
75
+ self.createdContentTypeUids = helper.readFile(path.join(mapperFolderPath, 'success.json')) || [];
75
76
  }
76
- self.contentTypeUids = _.difference(self.contentTypeUids, self.createdContentTypeUids)
77
- // remove contet types, already created
77
+ self.contentTypeUids = _.difference(self.contentTypeUids, self.createdContentTypeUids);
78
+ self.uidToTitleMap = self.mapUidToTitle(self.contentTypes);
79
+ // remove content types, already created
78
80
  _.remove(this.contentTypes, function (contentType) {
79
- return self.contentTypeUids.indexOf(contentType.uid) === -1
80
- })
81
- return new Promise(function (resolve, reject) {
82
- return Promise.map(self.contentTypeUids, function (contentTypeUid) {
83
- return self.seedContentTypes(contentTypeUid).then(function () {
84
-
85
- }).catch(function (error) {
86
- return reject(error)
87
- })
88
- }, {
89
- // seed 3 content types at a time
90
- concurrency: reqConcurrency,
91
- }).then(function () {
92
- let batches = []
93
- let lenObj = self.contentTypes
94
- // var a = Math.round(2.60);
95
- for (let i = 0; i < lenObj.length; i += Math.round(requestLimit / 3)) {
96
- batches.push(lenObj.slice(i, i + Math.round(requestLimit / 3)))
97
- }
81
+ return self.contentTypeUids.indexOf(contentType.uid) === -1;
82
+ });
98
83
 
99
- return Promise.map(batches, async function (batch) {
100
- return Promise.map(batch, async function (contentType) {
101
- await self.updateContentTypes(contentType)
102
- addlogs(config, contentType.uid + ' was updated successfully!', 'success')
103
- },
104
- {
105
- concurrency: reqConcurrency,
106
- }).then(function () {
107
- }).catch(e => {
108
- console.log('Something went wrong while migrating content type batch', e)
109
- })
110
- }, {
84
+ return new Promise(function (resolve, reject) {
85
+ if (self.contentTypes === undefined || _.isEmpty(self.contentTypes)) {
86
+ addlogs(config, chalk.yellow('No Content types found'), 'success');
87
+ return resolve({ empty: true })
88
+ }
89
+ return Promise.map(
90
+ self.contentTypeUids,
91
+ function (contentTypeUid) {
92
+ return self
93
+ .seedContentTypes(contentTypeUid, self.uidToTitleMap[contentTypeUid])
94
+ .catch(reject);
95
+ },
96
+ {
97
+ // seed 3 content types at a time
111
98
  concurrency: reqConcurrency,
112
- }).then(function () {
113
- // eslint-disable-next-line quotes
114
- if (field_rules_ct.length > 0) {
115
- fs.writeFile(contentTypesFolderPath + '/field_rules_uid.json', JSON.stringify(field_rules_ct), function (err) {
116
- if (err) throw err
117
- })
99
+ },
100
+ )
101
+ .then(function () {
102
+ let batches = [];
103
+ let lenObj = self.contentTypes;
104
+ for (let i = 0; i < lenObj.length; i += Math.round(requestLimit / 3)) {
105
+ batches.push(lenObj.slice(i, i + Math.round(requestLimit / 3)));
118
106
  }
119
-
120
- if(globalFieldPendingPath && globalFieldPendingPath.length !== 0) {
121
- return self.updateGlobalfields().then(function () {
122
- addlogs(config, chalk.green('Content types have been imported successfully!'), 'success')
123
- return resolve()
107
+
108
+ return Promise.map(
109
+ batches,
110
+ async function (batch) {
111
+ return Promise.map(
112
+ batch,
113
+ async function (contentType) {
114
+ await self.updateContentTypes(contentType)
115
+ addlogs(config, contentType.uid + ' was updated successfully!', 'success');
116
+ },
117
+ {
118
+ concurrency: reqConcurrency,
119
+ },
120
+ ).catch((e) => {
121
+ console.log('Something went wrong while migrating content type batch', e);
122
+ });
123
+ },
124
+ {
125
+ concurrency: reqConcurrency
126
+ }
127
+ ).then(async function () {
128
+ // eslint-disable-next-line quotes
129
+ if (field_rules_ct.length > 0) {
130
+ await fsPromises.writeFile(
131
+ contentTypesFolderPath + '/field_rules_uid.json',
132
+ JSON.stringify(field_rules_ct),
133
+ );
134
+ }
135
+
136
+ if (globalFieldPendingPath && globalFieldPendingPath.length !== 0) {
137
+ return self
138
+ .updateGlobalfields()
139
+ .then(function () {
140
+ addlogs(config, chalk.green('Content types have been imported successfully!'), 'success');
141
+ return resolve();
142
+ })
143
+ .catch((_error) => {
144
+ addlogs(config, chalk.green('Error in GlobalFields'), 'success');
145
+ return reject();
146
+ });
147
+ }
148
+ addlogs(config, chalk.green('Content types have been imported successfully!'), 'success');
149
+ return resolve();
124
150
  }).catch((error) => {
125
- addlogs(config, chalk.green('Error in GlobalFields'), 'success')
126
- return reject()
127
- })
128
- } else {
129
- addlogs(config, chalk.green('Content types have been imported successfully!'), 'success')
130
- return resolve()
131
- }
132
- }).catch(error => {
133
- return reject(error)
134
- })
135
- }).catch(error => {
136
- return reject(error)
137
- })
138
- })
151
+ return reject(error);
152
+ });
153
+ })
154
+ .catch((error) => {
155
+ return reject(error);
156
+ });
157
+ });
139
158
  },
140
- seedContentTypes: function (uid) {
141
- let self = this
159
+ seedContentTypes: function (uid, title) {
160
+ let self = this;
142
161
  return new Promise(function (resolve, reject) {
143
- let body = _.cloneDeep(self.schemaTemplate)
144
- body.content_type.uid = uid
145
- body.content_type.title = uid
146
- let requestObject = _.cloneDeep(self.requestOptions)
147
- requestObject.json = body
148
- return stack.contentType().create(requestObject.json)
149
- .then(() => {
150
- return resolve()
151
- })
152
- .catch(function (err) {
153
- let error = JSON.parse(err.message)
154
- if (error.error_code === 115 && (error.errors.uid || error.errors.title)) {
155
- // content type uid already exists
156
- return resolve()
157
- }
158
- return reject(error)
159
- })
160
- })
162
+ let body = _.cloneDeep(self.schemaTemplate);
163
+ body.content_type.uid = uid;
164
+ body.content_type.title = title;
165
+ let requestObject = _.cloneDeep(self.requestOptions);
166
+ requestObject.json = body;
167
+
168
+ return stack
169
+ .contentType()
170
+ .create(requestObject.json)
171
+ .then(resolve)
172
+ .catch(function (err) {
173
+ let error = JSON.parse(err.message);
174
+ if (error.error_code === 115 && (error.errors.uid || error.errors.title)) {
175
+ // content type uid already exists
176
+ return resolve();
177
+ }
178
+ return reject(error);
179
+ });
180
+ });
161
181
  },
162
182
  updateContentTypes: function (contentType) {
163
- let self = this
183
+ let self = this;
164
184
  return new Promise(function (resolve, reject) {
165
185
  setTimeout(function () {
166
- let requestObject = _.cloneDeep(self.requestOptions)
186
+ let requestObject = _.cloneDeep(self.requestOptions);
167
187
  if (contentType.field_rules) {
168
- field_rules_ct.push(contentType.uid)
169
- delete contentType.field_rules
188
+ field_rules_ct.push(contentType.uid);
189
+ delete contentType.field_rules;
170
190
  }
171
- supress(contentType.schema)
172
- requestObject.json.content_type = contentType
173
- let contentTypeResponse = stack.contentType(contentType.uid)
174
- Object.assign(contentTypeResponse, _.cloneDeep(contentType))
175
- contentTypeResponse.update()
176
- .then(UpdatedcontentType => {
177
- return resolve()
178
- }).catch(err => {
179
- addlogs(config, err, 'error')
180
- return reject()
181
- })
182
- }, 1000)
183
- })
191
+ supress(contentType.schema);
192
+ requestObject.json.content_type = contentType;
193
+ let contentTypeResponse = stack.contentType(contentType.uid);
194
+ Object.assign(contentTypeResponse, _.cloneDeep(contentType));
195
+ contentTypeResponse
196
+ .update()
197
+ .then((_updatedcontentType) => {
198
+ return resolve();
199
+ })
200
+ .catch((err) => {
201
+ addlogs(config, err, 'error');
202
+ return reject(err);
203
+ });
204
+ }, 1000);
205
+ });
184
206
  },
185
207
 
186
208
  updateGlobalfields: function () {
187
- let self = this
209
+ let self = this;
188
210
  return new Promise(function (resolve, reject) {
189
211
  // eslint-disable-next-line no-undef
190
212
  return Promise.map(globalFieldPendingPath, function (globalfield) {
191
- let lenGlobalField = (self.globalfields).length
192
- let Obj = _.find(self.globalfields, {uid: globalfield})
193
- let globalFieldObj = stack.globalField(globalfield)
194
- Object.assign(globalFieldObj, _.cloneDeep(Obj))
195
- return globalFieldObj.update()
196
- .then(globalFieldResponse => {
197
- let updateObjpos = _.findIndex(globalFieldMapperFolderPath, function (successobj) {
198
- let global_field_uid = globalFieldResponse.uid
199
- return global_field_uid === successobj
213
+ let Obj = _.find(self.globalfields, { uid: globalfield });
214
+ supress(Obj.schema);
215
+ let globalFieldObj = stack.globalField(globalfield);
216
+ Object.assign(globalFieldObj, _.cloneDeep(Obj));
217
+ return globalFieldObj
218
+ .update()
219
+ .then((globalFieldResponse) => {
220
+ let updateObjpos = _.findIndex(globalFieldMapperFolderPath, function (successobj) {
221
+ let global_field_uid = globalFieldResponse.uid;
222
+ return global_field_uid === successobj;
223
+ });
224
+ globalFieldMapperFolderPath.splice(updateObjpos, 1, Obj);
225
+ helper.writeFile(globalFieldUpdateFile, globalFieldMapperFolderPath);
226
+
227
+ resolve(globalFieldResponse)
200
228
  })
201
- globalFieldMapperFolderPath.splice(updateObjpos, 1, Obj)
202
- helper.writeFile(globalFieldUpdateFile, globalFieldMapperFolderPath)
203
- }).catch(function (err) {
204
- let error = JSON.parse(err.message)
205
- // eslint-disable-next-line no-console
206
- addlogs(config, chalk.red('Global Field failed to update ' + JSON.stringify(error.errors)), 'error')
207
- })
208
- }, {
209
- concurrency: reqConcurrency,
210
- }).then(function () {
211
- return resolve()
212
- }).catch(function (error) {
213
- // failed to update modified schemas back to their original form
214
- return reject(error)
215
- })
216
- })
229
+ .catch(function (err) {
230
+ let error = JSON.parse(err.message);
231
+ // eslint-disable-next-line no-console
232
+ addlogs(config, chalk.red('Global Field failed to update ' + JSON.stringify(error.errors)), 'error');
233
+ })
234
+ .catch(function (error) {
235
+ // failed to update modified schemas back to their original form
236
+ return reject(error);
237
+ });
238
+ });
239
+ });
217
240
  },
218
- }
219
241
 
220
- module.exports = new importContentTypes()
242
+ mapUidToTitle: function (contentTypes) {
243
+ let result = {};
244
+ contentTypes.forEach((ct) => {
245
+ result[ct.uid] = ct.title;
246
+ });
247
+ return result;
248
+ },
249
+ };
250
+
251
+ module.exports = new importContentTypes();