@contentstack/cli-cm-import 0.1.1-beta.9 → 1.0.1

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.
@@ -3,88 +3,94 @@
3
3
  * Copyright (c) 2019 Contentstack LLC
4
4
  * MIT Licensed
5
5
  */
6
- const Promise = require('bluebird')
7
- const fs = require('fs')
8
- const path = require('path')
9
- const _ = require('lodash')
10
- const mkdirp = require('mkdirp')
11
- const chalk = require('chalk')
12
-
13
- const helper = require('../util/fs')
14
- const {addlogs} = require('../util/log')
15
- const lookupReplaceAssets = require('../util/lookupReplaceAssets')
16
- const lookupReplaceEntries = require('../util/lookupReplaceEntries')
17
- const suppress = require('../util/supress-mandatory-fields')
18
- const extension_suppress = require('../util/extensionsUidReplace')
19
- const util = require('../util')
20
- let config = util.getConfig()
21
- const stack = require('../util/contentstack-management-sdk')
22
- let client
23
-
24
- let reqConcurrency = config.concurrency
25
- let eConfig = config.modules.entries
26
- let ePath = path.resolve(config.data, eConfig.dirName)
27
- let ctPath = path.resolve(config.data, config.modules.content_types.dirName)
28
- let lPath = path.resolve(config.data, config.modules.locales.dirName, config.modules.locales.fileName)
29
-
30
- let mappedAssetUidPath
31
- let mappedAssetUrlPath
32
- let entryMapperPath
33
- let environmentPath
34
- let entryUidMapperPath
35
- let uniqueUidMapperPath
36
- let modifiedSchemaPath
37
- let createdEntriesWOUidPath
38
- let failedWOPath
39
- let masterLanguage
40
-
41
- let skipFiles = ['__master.json', '__priority.json', 'schema.json']
42
- let entryBatchLimit = config.rateLimit || 10
6
+ const Promise = require('bluebird');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const _ = require('lodash');
10
+ const mkdirp = require('mkdirp');
11
+ const chalk = require('chalk');
12
+
13
+ const helper = require('../util/fs');
14
+ const { addlogs } = require('../util/log');
15
+ const lookupReplaceAssets = require('../util/lookupReplaceAssets');
16
+ const lookupReplaceEntries = require('../util/lookupReplaceEntries');
17
+ const suppress = require('../util/supress-mandatory-fields');
18
+ const extension_suppress = require('../util/extensionsUidReplace');
19
+ const util = require('../util');
20
+ let config = util.getConfig();
21
+ const stack = require('../util/contentstack-management-sdk');
22
+ let client;
23
+
24
+ let reqConcurrency = config.concurrency;
25
+ let eConfig = config.modules.entries;
26
+ let ePath = path.resolve(config.data, eConfig.dirName);
27
+ let ctPath = path.resolve(config.data, config.modules.content_types.dirName);
28
+ let lPath = path.resolve(config.data, config.modules.locales.dirName, config.modules.locales.fileName);
29
+
30
+ let mappedAssetUidPath;
31
+ let mappedAssetUrlPath;
32
+ let entryMapperPath;
33
+ let environmentPath;
34
+ let entryUidMapperPath;
35
+ let uniqueUidMapperPath;
36
+ let modifiedSchemaPath;
37
+ let createdEntriesWOUidPath;
38
+ let failedWOPath;
39
+ let masterLanguage;
40
+
41
+ let skipFiles = ['__master.json', '__priority.json', 'schema.json'];
42
+ let entryBatchLimit = config.rateLimit || 10;
43
43
 
44
44
  function importEntries() {
45
- let self = this
46
- mappedAssetUidPath = path.resolve(config.data, 'mapper', 'assets', 'uid-mapping.json')
47
- mappedAssetUrlPath = path.resolve(config.data, 'mapper', 'assets', 'url-mapping.json')
45
+ let self = this;
46
+ mappedAssetUidPath = path.resolve(config.data, 'mapper', 'assets', 'uid-mapping.json');
47
+ mappedAssetUrlPath = path.resolve(config.data, 'mapper', 'assets', 'url-mapping.json');
48
48
 
49
- entryMapperPath = path.resolve(config.data, 'mapper', 'entries')
50
- environmentPath = path.resolve(config.data, 'environments', 'environments.json')
51
- mkdirp.sync(entryMapperPath)
49
+ entryMapperPath = path.resolve(config.data, 'mapper', 'entries');
50
+ environmentPath = path.resolve(config.data, 'environments', 'environments.json');
51
+ mkdirp.sync(entryMapperPath);
52
52
 
53
- entryUidMapperPath = path.join(entryMapperPath, 'uid-mapping.json')
54
- uniqueUidMapperPath = path.join(entryMapperPath, 'unique-mapping.json')
55
- modifiedSchemaPath = path.join(entryMapperPath, 'modified-schemas.json')
53
+ entryUidMapperPath = path.join(entryMapperPath, 'uid-mapping.json');
54
+ uniqueUidMapperPath = path.join(entryMapperPath, 'unique-mapping.json');
55
+ modifiedSchemaPath = path.join(entryMapperPath, 'modified-schemas.json');
56
56
 
57
- createdEntriesWOUidPath = path.join(entryMapperPath, 'created-entries-wo-uid.json')
58
- failedWOPath = path.join(entryMapperPath, 'failedWO.json')
57
+ createdEntriesWOUidPath = path.join(entryMapperPath, 'created-entries-wo-uid.json');
58
+ failedWOPath = path.join(entryMapperPath, 'failedWO.json');
59
59
  // Object of Schemas, referred to by their content type uid
60
- this.ctSchemas = {}
60
+ this.ctSchemas = {};
61
61
  // Array of content type uids, that have reference fields
62
- this.refSchemas = []
62
+ this.refSchemas = [];
63
+ // map of content types uids and their json-rte fields
64
+ this.ctJsonRte = [];
65
+ // map of content types uids and their json-rte fields
66
+ this.ctJsonRteWithEntryRefs = [];
67
+ // Entry refs that are held back to resolve after all entries have been created
68
+ this.jsonRteEntryRefs = {};
63
69
  // Collection of entries, that were not created, as they already exist on Stack
64
- this.createdEntriesWOUid = []
70
+ this.createdEntriesWOUid = [];
65
71
  // Collection of entry uids, mapped to the language they exist in
66
- this.uniqueUids = {}
72
+ this.uniqueUids = {};
67
73
  // Map of old entry uid to new
68
- this.mappedUids = {}
74
+ this.mappedUids = {};
69
75
  // Entries that were created successfully
70
- this.success = []
76
+ this.success = [];
71
77
  // Entries that failed to get created OR updated
72
- this.fails = []
78
+ this.fails = [];
73
79
 
74
- let files = fs.readdirSync(ctPath)
75
- this.environment = helper.readFile(environmentPath)
80
+ let files = fs.readdirSync(ctPath);
81
+ this.environment = helper.readFile(environmentPath);
76
82
  for (let index in files) {
77
83
  if (index) {
78
84
  try {
79
85
  if (skipFiles.indexOf(files[index]) === -1) {
80
86
  if (files[index] != 'field_rules_uid.json') {
81
- let schema = require(path.resolve(path.join(ctPath, files[index])))
82
- self.ctSchemas[schema.uid] = schema
87
+ let schema = require(path.resolve(path.join(ctPath, files[index])));
88
+ self.ctSchemas[schema.uid] = schema;
83
89
  }
84
90
  }
85
91
  } catch (error) {
86
- console.error(error)
87
- process.exit(0)
92
+ console.error(error);
93
+ process.exit(0);
88
94
  }
89
95
  }
90
96
  }
@@ -92,500 +98,703 @@ function importEntries() {
92
98
 
93
99
  importEntries.prototype = {
94
100
  /**
95
- * Start point for entry import
96
- * @return promise
97
- */
101
+ * Start point for entry import
102
+ * @return promise
103
+ */
98
104
  start: async function (credentialConfig) {
99
- let self = this
100
- config = credentialConfig
101
- client = stack.Client(config)
102
- masterLanguage = config.master_locale
103
- addlogs(config, 'Migrating entries', 'success')
104
- let languages = helper.readFile(lPath)
105
+ let self = this;
106
+ config = credentialConfig;
107
+ client = stack.Client(config);
108
+ masterLanguage = config.master_locale;
109
+ addlogs(config, 'Migrating entries', 'success');
110
+ let languages = helper.readFile(lPath);
105
111
  return new Promise(function (resolve, reject) {
106
- let langs = [masterLanguage.code]
112
+ let langs = [masterLanguage.code];
107
113
  for (let i in languages) {
108
114
  if (i) {
109
- langs.push(languages[i].code)
115
+ langs.push(languages[i].code);
110
116
  }
111
117
  }
112
118
 
113
- // Step 1: Removes filed rules from content type
119
+ // Step 1: Removes field rules from content type
114
120
  // This allows to handle cases like self references and circular reference
115
121
  // if mandatory reference fields are not filed in entries then avoids the error
116
122
  // Also remove field visibility rules
117
- return self.supressFields().then(async function () {
118
- let mappedAssetUids = helper.readFile(mappedAssetUidPath) || {}
119
- let mappedAssetUrls = helper.readFile(mappedAssetUrlPath) || {}
120
-
121
- // Step 2: Iterate over available languages to create entries in each.
122
- let counter = 0
123
- return Promise.map(langs, async function () {
124
- let lang = langs[counter]
125
- if ((config.hasOwnProperty('onlylocales') && config.onlylocales.indexOf(lang) !== -1) || !config.hasOwnProperty('onlylocales')) {
126
- await self.createEntries(lang, mappedAssetUids, mappedAssetUrls)
127
- await self.getCreatedEntriesWOUid()
128
- await self.repostEntries(lang)
129
- addlogs(config, 'Successfully imported \'' + lang + '\' entries!', 'success')
130
- counter++
131
- } else {
132
- addlogs(config, lang + ' has not been configured for import, thus skipping it', 'success')
133
- counter++
134
- }
135
- }, {
136
- concurrency: 1,
137
- }).then(async function () {
138
- // Step 3: Revert all the changes done in content type in step 1
139
- await self.unSuppressFields()
140
- await self.removeBuggedEntries()
141
- let ct_field_visibility_uid = helper.readFile(path.join(ctPath + '/field_rules_uid.json'))
142
- let ct_files = fs.readdirSync(ctPath)
143
- if (ct_field_visibility_uid && ct_field_visibility_uid != 'undefined') {
144
- for (let index = 0; index < ct_field_visibility_uid.length; index++) {
145
- if (ct_files.indexOf(ct_field_visibility_uid[index] + '.json') > -1) {
146
- let schema = require(path.resolve(ctPath, ct_field_visibility_uid[index]))
147
- await self.field_rules_update(schema)
123
+ return self
124
+ .supressFields()
125
+ .then(async function () {
126
+ let mappedAssetUids = helper.readFile(mappedAssetUidPath) || {};
127
+ let mappedAssetUrls = helper.readFile(mappedAssetUrlPath) || {};
128
+
129
+ // Step 2: Iterate over available languages to create entries in each.
130
+ let counter = 0;
131
+ return Promise.map(
132
+ langs,
133
+ async function () {
134
+ let lang = langs[counter];
135
+ if (
136
+ (config.hasOwnProperty('onlylocales') && config.onlylocales.indexOf(lang) !== -1) ||
137
+ !config.hasOwnProperty('onlylocales')
138
+ ) {
139
+ await self.createEntries(lang, mappedAssetUids, mappedAssetUrls);
140
+ await self.getCreatedEntriesWOUid();
141
+ await self.repostEntries(lang);
142
+ addlogs(config, "Successfully imported '" + lang + "' entries!", 'success');
143
+ counter++;
144
+ } else {
145
+ addlogs(config, lang + ' has not been configured for import, thus skipping it', 'success');
146
+ counter++;
147
+ }
148
+ },
149
+ {
150
+ concurrency: 1,
151
+ },
152
+ ).then(async function () {
153
+ // Step 3: Revert all the changes done in content type in step 1
154
+ await self.unSuppressFields();
155
+ await self.removeBuggedEntries();
156
+ let ct_field_visibility_uid = helper.readFile(path.join(ctPath + '/field_rules_uid.json'));
157
+ let ct_files = fs.readdirSync(ctPath);
158
+ if (ct_field_visibility_uid && ct_field_visibility_uid != 'undefined') {
159
+ for (const element of ct_field_visibility_uid) {
160
+ if (ct_files.indexOf(element + '.json') > -1) {
161
+ let schema = require(path.resolve(ctPath, element));
162
+ await self.field_rules_update(schema);
163
+ }
148
164
  }
149
165
  }
150
- }
151
- addlogs(config, chalk.green('Entries have been imported successfully!'), 'success')
152
- if (config.entriesPublish) {
153
- return self.publish(langs).then(function () {
154
- addlogs(config, chalk.green('All the entries have been published successfully'), 'success')
155
- return resolve()
156
- }).catch(errors => {
157
- addlogs(config, chalk.error('Some entries might have failed to publish.'), 'error')
158
- return reject(errors)
159
- })
160
- }
161
- return resolve()
166
+ addlogs(config, chalk.green('Entries have been imported successfully!'), 'success');
167
+ if (config.entriesPublish) {
168
+ return self
169
+ .publish(langs)
170
+ .then(function () {
171
+ addlogs(config, chalk.green('All the entries have been published successfully'), 'success');
172
+ return resolve();
173
+ })
174
+ .catch((errors) => {
175
+ addlogs(config, chalk.error('Some entries might have failed to publish.'), 'error');
176
+ return reject(errors);
177
+ });
178
+ }
179
+ return resolve();
180
+ });
162
181
  })
163
- }).catch(function (error) {
164
- return reject(error)
165
- })
166
- })
182
+ .catch(function (error) {
183
+ return reject(error);
184
+ });
185
+ });
167
186
  },
168
187
 
169
188
  createEntries: function (lang, mappedAssetUids, mappedAssetUrls) {
170
- let self = this
189
+ let self = this;
171
190
  return new Promise(function (resolve, reject) {
172
- let contentTypeUids = Object.keys(self.ctSchemas)
191
+ let contentTypeUids = Object.keys(self.ctSchemas);
173
192
  if (fs.existsSync(entryUidMapperPath)) {
174
- self.mappedUids = helper.readFile(entryUidMapperPath)
193
+ self.mappedUids = helper.readFile(entryUidMapperPath);
175
194
  }
176
- self.mappedUids = self.mappedUids || {}
177
- return Promise.map(contentTypeUids, function (ctUid) {
178
- let eLangFolderPath = path.join(entryMapperPath, lang)
179
- let eLogFolderPath = path.join(entryMapperPath, lang, ctUid)
180
- mkdirp.sync(eLogFolderPath)
181
- // entry file path
182
- let eFilePath = path.resolve(ePath, ctUid, lang + '.json')
183
-
184
- // log created/updated entries
185
- let successEntryLogPath = path.join(eLogFolderPath, 'success.json')
186
- let failedEntryLogPath = path.join(eLogFolderPath, 'fails.json')
187
- let createdEntriesPath = path.join(eLogFolderPath, 'created-entries.json')
188
- let createdEntries = {}
189
- let stack = client.stack({api_key: config.target_stack, management_token: config.management_token})
190
-
191
- if (fs.existsSync(createdEntriesPath)) {
192
- createdEntries = helper.readFile(createdEntriesPath)
193
- createdEntries = createdEntries || {}
194
- }
195
- if (fs.existsSync(eFilePath)) {
196
- let entries = helper.readFile(eFilePath)
197
- if (!_.isPlainObject(entries) || _.isEmpty(entries)) {
198
- addlogs(config, chalk.white('No entries were found for Content type:\'' + ctUid + '\' in \'' + lang +
199
- '\' language!'), 'success')
200
- } else {
201
- addlogs(config, `Creating entries for content type ${ctUid} in language ${lang} ...`, 'success')
202
- for (let eUid in entries) {
203
- if (eUid) {
204
- // will replace all old asset uid/urls with new ones
205
- entries[eUid] = lookupReplaceAssets({
206
- content_type: self.ctSchemas[ctUid],
207
- entry: entries[eUid],
208
- }, mappedAssetUids, mappedAssetUrls, eLangFolderPath)
209
- }
210
- }
211
- let eUids = Object.keys(entries)
212
- let batches = []
195
+ self.mappedUids = self.mappedUids || {};
196
+ return Promise.map(
197
+ contentTypeUids,
198
+ function (ctUid) {
199
+ let eLangFolderPath = path.join(entryMapperPath, lang);
200
+ let eLogFolderPath = path.join(entryMapperPath, lang, ctUid);
201
+ mkdirp.sync(eLogFolderPath);
202
+ // entry file path
203
+ let eFilePath = path.resolve(ePath, ctUid, lang + '.json');
213
204
 
214
- // Run entry creation in batches of ~16~ entries
215
- for (let i = 0; i < eUids.length; i += Math.round(entryBatchLimit / 3)) {
216
- batches.push(eUids.slice(i, i + Math.round(entryBatchLimit / 3)))
217
- }
218
- return Promise.map(batches, async function (batch) {
219
- return Promise.map(batch, async function (eUid) {
220
- // if entry is already created
221
- if (createdEntries.hasOwnProperty(eUid)) {
222
- addlogs(config, ('Skipping ' + JSON.stringify({
223
- content_type: ctUid,
224
- locale: lang,
225
- oldEntryUid: eUid,
226
- newEntryUid: createdEntries[eUid],
227
- }) + ' as it is already created'), 'success')
228
- self.success[ctUid] = createdEntries[eUid]
229
- // if its a non-master language, i.e. the entry isn't present in the master language
230
- if (lang !== masterLanguage) {
231
- self.uniqueUids[eUid] = self.uniqueUids[eUid] || {}
232
- if (self.uniqueUids[eUid].locales) {
233
- self.uniqueUids[eUid].locales.push(lang)
234
- } else {
235
- self.uniqueUids[eUid].locales = [lang]
236
- }
237
- self.uniqueUids[eUid].content_type = ctUid
205
+ // log created/updated entries
206
+ let successEntryLogPath = path.join(eLogFolderPath, 'success.json');
207
+ let failedEntryLogPath = path.join(eLogFolderPath, 'fails.json');
208
+ let createdEntriesPath = path.join(eLogFolderPath, 'created-entries.json');
209
+ let createdEntries = {};
210
+ let stackForEntries = client.stack({
211
+ api_key: config.target_stack,
212
+ management_token: config.management_token,
213
+ });
214
+
215
+ if (fs.existsSync(createdEntriesPath)) {
216
+ createdEntries = helper.readFile(createdEntriesPath);
217
+ createdEntries = createdEntries || {};
218
+ }
219
+ if (fs.existsSync(eFilePath)) {
220
+ let entries = helper.readFile(eFilePath);
221
+ if (!_.isPlainObject(entries) || _.isEmpty(entries)) {
222
+ addlogs(
223
+ config,
224
+ chalk.white("No entries were found for Content type:'" + ctUid + "' in '" + lang + "' language!"),
225
+ 'success',
226
+ );
227
+ } else {
228
+ addlogs(config, `Creating entries for content type ${ctUid} in language ${lang} ...`, 'success');
229
+ for (let eUid in entries) {
230
+ if (eUid) {
231
+ // check ctUid in self.ctJsonRte array, if ct exists there... only then remove entry references for json rte
232
+ // also with json rte, api creates the json-rte field with the same uid as passed in the payload.
233
+
234
+ if (self.ctJsonRte.indexOf(ctUid) > -1) {
235
+ entries[eUid] = self.removeUidsFromJsonRteFields(entries[eUid], self.ctSchemas[ctUid].schema);
238
236
  }
239
- return
240
- }
241
- let requestObject = {
242
- qs: {
243
- locale: lang,
244
- },
245
- json: {
246
- entry: entries[eUid],
247
- },
237
+
238
+ // remove entry references from json-rte fields
239
+ if (self.ctJsonRteWithEntryRefs.indexOf(ctUid) > -1) {
240
+ entries[eUid] = self.removeEntryRefsFromJSONRTE(entries[eUid], self.ctSchemas[ctUid].schema);
241
+ }
242
+ // will replace all old asset uid/urls with new ones
243
+ entries[eUid] = lookupReplaceAssets(
244
+ {
245
+ content_type: self.ctSchemas[ctUid],
246
+ entry: entries[eUid],
247
+ },
248
+ mappedAssetUids,
249
+ mappedAssetUrls,
250
+ eLangFolderPath,
251
+ );
248
252
  }
249
- if (self.mappedUids.hasOwnProperty(eUid)) {
250
- let entryToUpdate = stack.contentType(ctUid).entry(self.mappedUids[eUid])
251
- Object.assign(entryToUpdate, _.cloneDeep(entries[eUid]))
252
- return entryToUpdate.update({locale: entryToUpdate.locale}).then(async entryResponse => {
253
- self.success[ctUid] = self.success[ctUid] || []
254
- self.success[ctUid].push(entries[eUid])
255
- if (!self.mappedUids.hasOwnProperty(eUid)) {
256
- self.mappedUids[eUid] = entryResponse.uid
257
- createdEntries = entryResponse
258
- // if its a non-master language, i.e. the entry isn't present in the master language
259
- if (lang !== masterLanguage) {
260
- self.uniqueUids[eUid] = self.uniqueUids[eUid] || {}
261
- if (self.uniqueUids[eUid].locales) {
262
- self.uniqueUids[eUid].locales.push(lang)
263
- } else {
264
- self.uniqueUids[eUid].locales = [lang]
253
+ }
254
+ let eUids = Object.keys(entries);
255
+ let batches = [];
256
+
257
+ // Run entry creation in batches of ~16~ entries
258
+ for (let i = 0; i < eUids.length; i += Math.round(entryBatchLimit / 3)) {
259
+ batches.push(eUids.slice(i, i + Math.round(entryBatchLimit / 3)));
260
+ }
261
+ return Promise.map(
262
+ batches,
263
+ async function (batch) {
264
+ return Promise.map(
265
+ batch,
266
+ async function (eUid) {
267
+ // if entry is already created
268
+ if (createdEntries.hasOwnProperty(eUid)) {
269
+ addlogs(
270
+ config,
271
+ 'Skipping ' +
272
+ JSON.stringify({
273
+ content_type: ctUid,
274
+ locale: lang,
275
+ oldEntryUid: eUid,
276
+ newEntryUid: createdEntries[eUid],
277
+ }) +
278
+ ' as it is already created',
279
+ 'success',
280
+ );
281
+ self.success[ctUid] = createdEntries[eUid];
282
+ // if its a non-master language, i.e. the entry isn't present in the master language
283
+ if (lang !== masterLanguage.code) {
284
+ self.uniqueUids[eUid] = self.uniqueUids[eUid] || {};
285
+ if (self.uniqueUids[eUid].locales) {
286
+ self.uniqueUids[eUid].locales.push(lang);
287
+ } else {
288
+ self.uniqueUids[eUid].locales = [lang];
289
+ }
290
+ self.uniqueUids[eUid].content_type = ctUid;
265
291
  }
266
- self.uniqueUids[eUid].content_type = ctUid
292
+ return;
267
293
  }
268
- }
269
- }).catch(function (err) {
270
- let error = JSON.parse(err.message)
271
- addlogs(config, chalk.red('Error updating entry', JSON.stringify(error)), 'error')
272
- self.fails.push({
273
- content_type: ctUid,
274
- locale: lang,
275
- entry: entries[eUid],
276
- error: error,
277
- })
278
- return err
279
- })
280
- }
281
- delete requestObject.json.entry.publish_details
282
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(ctUid).entry().create(requestObject.json)
283
- .then(async entryResponse => {
284
- self.success[ctUid] = self.success[ctUid] || []
285
- self.success[ctUid].push(entries[eUid])
286
- if (!self.mappedUids.hasOwnProperty(eUid)) {
287
- self.mappedUids[eUid] = entryResponse.uid
288
- createdEntries = entryResponse
289
- // if its a non-master language, i.e. the entry isn't present in the master language
290
- if (lang !== masterLanguage) {
291
- self.uniqueUids[eUid] = self.uniqueUids[eUid] || {}
292
- if (self.uniqueUids[eUid].locales) {
293
- self.uniqueUids[eUid].locales.push(lang)
294
- } else {
295
- self.uniqueUids[eUid].locales = [lang]
294
+ let requestObject = {
295
+ qs: {
296
+ locale: lang,
297
+ },
298
+ json: {
299
+ entry: entries[eUid],
300
+ },
301
+ };
302
+ if (self.mappedUids.hasOwnProperty(eUid)) {
303
+ let entryToUpdate = stackForEntries.contentType(ctUid).entry(self.mappedUids[eUid]);
304
+ Object.assign(entryToUpdate, _.cloneDeep(entries[eUid]));
305
+ return entryToUpdate
306
+ .update({ locale: entryToUpdate.locale })
307
+ .then(async (entryResponse) => {
308
+ self.success[ctUid] = self.success[ctUid] || [];
309
+ self.success[ctUid].push(entries[eUid]);
310
+ if (!self.mappedUids.hasOwnProperty(eUid)) {
311
+ self.mappedUids[eUid] = entryResponse.uid;
312
+ createdEntries = entryResponse;
313
+ // if its a non-master language, i.e. the entry isn't present in the master language
314
+ if (lang !== masterLanguage.code) {
315
+ self.uniqueUids[eUid] = self.uniqueUids[eUid] || {};
316
+ if (self.uniqueUids[eUid].locales) {
317
+ self.uniqueUids[eUid].locales.push(lang);
318
+ } else {
319
+ self.uniqueUids[eUid].locales = [lang];
320
+ }
321
+ self.uniqueUids[eUid].content_type = ctUid;
322
+ }
323
+ }
324
+ })
325
+ .catch(function (err) {
326
+ let error = JSON.parse(err.message);
327
+ addlogs(config, chalk.red('Error updating entry', JSON.stringify(error)), 'error');
328
+ self.fails.push({
329
+ content_type: ctUid,
330
+ locale: lang,
331
+ entry: entries[eUid],
332
+ error: error,
333
+ });
334
+ return err;
335
+ });
296
336
  }
297
- self.uniqueUids[eUid].content_type = ctUid
298
- }
299
- }
300
- }).catch(function (error) {
301
- if (error.hasOwnProperty('error_code') && error.error_code === 119) {
302
- if (error.errors.title) {
303
- addlogs(config, 'Entry ' + eUid + ' already exist, skip to avoid creating a duplicate entry', 'error')
304
- } else {
305
- addlogs(config, chalk.red('Error creating entry due to: ' + JSON.stringify(error)), 'error')
306
- }
307
- self.createdEntriesWOUid.push({
308
- content_type: ctUid,
309
- locale: lang,
310
- entry: entries[eUid],
311
- error: error,
312
- })
313
- helper.writeFile(createdEntriesWOUidPath, self.createdEntriesWOUid)
314
- return
315
- }
316
- // TODO: if status code: 422, check the reason
317
- // 429 for rate limit
318
- addlogs(config, chalk.red('Error creating entry', JSON.stringify(error)), 'error')
319
- self.fails.push({
320
- content_type: ctUid,
321
- locale: lang,
322
- entry: entries[eUid],
323
- error: error,
324
- })
325
- })
326
-
327
- // create/update 5 entries at a time
328
- }, {
329
- concurrency: 1,
330
- }).then(function () {
331
- helper.writeFile(successEntryLogPath, self.success[ctUid])
332
- helper.writeFile(failedEntryLogPath, self.fails[ctUid])
333
- helper.writeFile(entryUidMapperPath, self.mappedUids)
334
- helper.writeFile(uniqueUidMapperPath, self.uniqueUids)
335
- helper.writeFile(createdEntriesPath, createdEntries)
336
- })
337
- // process one batch at a time
338
- }, {
339
- concurrency: 1,
340
- }).then(function () {
341
- if (self.success && self.success[ctUid] && self.success[ctUid].length > 0)
342
- addlogs(config, self.success[ctUid].length + ' entries created successfully in ' + ctUid + ' content type in ' + lang +
343
- ' locale!', 'success')
344
- if (self.fails && self.fails[ctUid] && self.fails[ctUid].length > 0)
345
- addlogs(config, self.fails[ctUid].length + ' entries failed to create in ' + ctUid + ' content type in ' + lang +
346
- ' locale!', 'error')
347
- self.success[ctUid] = []
348
- self.fails[ctUid] = []
349
- })
337
+ delete requestObject.json.entry.publish_details;
338
+ return client
339
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
340
+ .contentType(ctUid)
341
+ .entry()
342
+ .create(requestObject.json, { locale: lang })
343
+ .then(async (entryResponse) => {
344
+ self.success[ctUid] = self.success[ctUid] || [];
345
+ self.success[ctUid].push(entries[eUid]);
346
+ if (!self.mappedUids.hasOwnProperty(eUid)) {
347
+ self.mappedUids[eUid] = entryResponse.uid;
348
+ createdEntries = entryResponse;
349
+ // if its a non-master language, i.e. the entry isn't present in the master language
350
+ if (lang !== masterLanguage.code) {
351
+ self.uniqueUids[eUid] = self.uniqueUids[eUid] || {};
352
+ if (self.uniqueUids[eUid].locales) {
353
+ self.uniqueUids[eUid].locales.push(lang);
354
+ } else {
355
+ self.uniqueUids[eUid].locales = [lang];
356
+ }
357
+ self.uniqueUids[eUid].content_type = ctUid;
358
+ }
359
+ }
360
+ })
361
+ .catch(function (error) {
362
+ if (error.hasOwnProperty('error_code') && error.error_code === 119) {
363
+ if (error.errors.title) {
364
+ addlogs(
365
+ config,
366
+ 'Entry ' + eUid + ' already exist, skip to avoid creating a duplicate entry',
367
+ 'error',
368
+ );
369
+ } else {
370
+ addlogs(
371
+ config,
372
+ chalk.red('Error creating entry due to: ' + JSON.stringify(error)),
373
+ 'error',
374
+ );
375
+ }
376
+ self.createdEntriesWOUid.push({
377
+ content_type: ctUid,
378
+ locale: lang,
379
+ entry: entries[eUid],
380
+ error: error,
381
+ });
382
+ helper.writeFile(createdEntriesWOUidPath, self.createdEntriesWOUid);
383
+ return;
384
+ }
385
+ // TODO: if status code: 422, check the reason
386
+ // 429 for rate limit
387
+ addlogs(config, chalk.red('Error creating entry', JSON.stringify(error)), 'error');
388
+ self.fails.push({
389
+ content_type: ctUid,
390
+ locale: lang,
391
+ entry: entries[eUid],
392
+ error: error,
393
+ });
394
+ });
395
+ // create/update 5 entries at a time
396
+ },
397
+ {
398
+ concurrency: 1,
399
+ },
400
+ ).then(function () {
401
+ helper.writeFile(successEntryLogPath, self.success[ctUid]);
402
+ helper.writeFile(failedEntryLogPath, self.fails[ctUid]);
403
+ helper.writeFile(entryUidMapperPath, self.mappedUids);
404
+ helper.writeFile(uniqueUidMapperPath, self.uniqueUids);
405
+ helper.writeFile(createdEntriesPath, createdEntries);
406
+ });
407
+ // process one batch at a time
408
+ },
409
+ {
410
+ concurrency: 1,
411
+ },
412
+ ).then(function () {
413
+ if (self.success && self.success[ctUid] && self.success[ctUid].length > 0)
414
+ addlogs(
415
+ config,
416
+ self.success[ctUid].length +
417
+ ' entries created successfully in ' +
418
+ ctUid +
419
+ ' content type in ' +
420
+ lang +
421
+ ' locale!',
422
+ 'success',
423
+ );
424
+ if (self.fails && self.fails[ctUid] && self.fails[ctUid].length > 0)
425
+ addlogs(
426
+ config,
427
+ self.fails[ctUid].length +
428
+ ' entries failed to create in ' +
429
+ ctUid +
430
+ ' content type in ' +
431
+ lang +
432
+ ' locale!',
433
+ 'error',
434
+ );
435
+ self.success[ctUid] = [];
436
+ self.fails[ctUid] = [];
437
+ });
438
+ }
439
+ } else {
440
+ addlogs(
441
+ config,
442
+ chalk.white(
443
+ 'Unable to find entry file path for ' +
444
+ ctUid +
445
+ " content type!\nThe file '" +
446
+ eFilePath +
447
+ "' does not exist!",
448
+ ),
449
+ 'error',
450
+ );
350
451
  }
351
- } else {
352
- addlogs(config, chalk.white('Unable to find entry file path for ' + ctUid + ' content type!\nThe file \'' +
353
- eFilePath + '\' does not exist!'), 'error')
354
- }
355
- }, {
356
- concurrency: reqConcurrency,
357
- }).then(function () {
358
- addlogs(config, chalk.green('Entries created successfully in \'' + lang + '\' language'), 'success')
359
- return resolve()
360
- }).catch(function (error) {
361
- addlogs(config, chalk.red('Failed to create entries in \'' + lang + '\' language'), 'error')
362
- return reject(error)
363
- })
364
- })
452
+ },
453
+ {
454
+ concurrency: reqConcurrency,
455
+ },
456
+ )
457
+ .then(function () {
458
+ addlogs(config, chalk.green("Entries created successfully in '" + lang + "' language"), 'success');
459
+ return resolve();
460
+ })
461
+ .catch(function (error) {
462
+ addlogs(config, chalk.red("Failed to create entries in '" + lang + "' language"), 'error');
463
+ return reject(error);
464
+ });
465
+ });
365
466
  },
366
467
  getCreatedEntriesWOUid: function () {
367
- let self = this
468
+ let self = this;
368
469
  return new Promise(function (resolve) {
369
- self.createdEntriesWOUid = helper.readFile(createdEntriesWOUidPath)
370
- self.failedWO = []
470
+ self.createdEntriesWOUid = helper.readFile(createdEntriesWOUidPath);
471
+ self.failedWO = [];
371
472
  if (_.isArray(self.createdEntriesWOUid) && self.createdEntriesWOUid.length > 0) {
372
- return Promise.map(self.createdEntriesWOUid, function (entry) {
373
- return self.fetchEntry(entry)
374
- }, {
375
- concurrency: reqConcurrency,
376
- }).then(function () {
377
- helper.writeFile(failedWOPath, self.failedWO)
378
- addlogs(config, 'Mapped entries without mapped uid successfully!', 'success')
379
- return resolve()
380
- })
473
+ return Promise.map(
474
+ self.createdEntriesWOUid,
475
+ function (entry) {
476
+ return self.fetchEntry(entry);
477
+ },
478
+ {
479
+ concurrency: reqConcurrency,
480
+ },
481
+ ).then(function () {
482
+ helper.writeFile(failedWOPath, self.failedWO);
483
+ addlogs(config, 'Mapped entries without mapped uid successfully!', 'success');
484
+ return resolve();
485
+ });
381
486
  }
382
- addlogs(config, 'No entries without mapped uid found!', 'success')
383
- return resolve()
384
- })
487
+ addlogs(config, 'No entries without mapped uid found!', 'success');
488
+ return resolve();
489
+ });
385
490
  },
386
491
  repostEntries: function (lang) {
387
- let self = this
492
+ let self = this;
388
493
  return new Promise(function (resolve, reject) {
389
- let _mapped_ = helper.readFile(path.join(entryMapperPath, 'uid-mapping.json'))
494
+ let _mapped_ = helper.readFile(path.join(entryMapperPath, 'uid-mapping.json'));
390
495
  if (_.isPlainObject(_mapped_)) {
391
- self.mappedUids = _.merge(_mapped_, self.mappedUids)
496
+ self.mappedUids = _.merge(_mapped_, self.mappedUids);
392
497
  }
393
- return Promise.map(self.refSchemas, function (ctUid) {
394
- let eFolderPath = path.join(entryMapperPath, lang, ctUid)
395
- let eSuccessFilePath = path.join(eFolderPath, 'success.json')
396
-
397
- if (!fs.existsSync(eSuccessFilePath)) {
398
- addlogs(config, 'Success file was not found at: ' + eSuccessFilePath, 'success')
399
- return
400
- }
498
+ return Promise.map(
499
+ self.refSchemas,
500
+ function (ctUid) {
501
+ let eFolderPath = path.join(entryMapperPath, lang, ctUid);
502
+ let eSuccessFilePath = path.join(eFolderPath, 'success.json');
503
+ let eFilePath = path.resolve(ePath, ctUid, lang + '.json');
504
+ let sourceStackEntries = helper.readFile(eFilePath);
401
505
 
402
- let entries = helper.readFile(eSuccessFilePath)
403
- entries = entries || []
404
- if (entries.length === 0) {
405
- addlogs(config, 'No entries were created to be updated in \'' + lang + '\' language!', 'success')
406
- return
407
- }
506
+ if (!fs.existsSync(eSuccessFilePath)) {
507
+ addlogs(config, 'Success file was not found at: ' + eSuccessFilePath, 'success');
508
+ return;
509
+ }
408
510
 
409
- // Keep track of entries that have their references updated
410
- let refsUpdatedUids = helper.readFile(path.join(eFolderPath, 'refsUpdatedUids.json'))
411
- let refsUpdateFailed = helper.readFile(path.join(eFolderPath, 'refsUpdateFailed.json'))
412
- let schema = self.ctSchemas[ctUid]
413
-
414
- let batches = []
415
- refsUpdatedUids = refsUpdatedUids || []
416
- refsUpdateFailed = refsUpdateFailed || []
417
-
418
- // map reference uids @mapper/language/mapped-uids.json
419
- // map failed reference uids @mapper/language/unmapped-uids.json
420
- let refUidMapperPath = path.join(entryMapperPath, lang)
421
-
422
- entries = _.map(entries, function (entry) {
423
- try {
424
- let uid = entry.uid
425
- let _entry = lookupReplaceEntries({
426
- content_type: schema,
427
- entry: entry,
428
- }, _.clone(self.mappedUids), refUidMapperPath)
429
- // if there's self references, the uid gets replaced
430
- _entry.uid = uid
431
- return _entry
432
- } catch (error) {
433
- console.error(error)
434
- return error
511
+ let entries = helper.readFile(eSuccessFilePath);
512
+ entries = entries || [];
513
+ if (entries.length === 0) {
514
+ addlogs(config, "No entries were created to be updated in '" + lang + "' language!", 'success');
515
+ return;
435
516
  }
436
- })
437
517
 
438
- // Run entry creation in batches of ~16~ entries
439
- for (let i = 0; i < entries.length; i += Math.round(entryBatchLimit / 3)) {
440
- batches.push(entries.slice(i, i + Math.round(entryBatchLimit / 3)))
441
- }
442
- return Promise.map(batches, async function (batch, index) {
443
- return Promise.map(batch, async function (entry) {
444
- entry.uid = self.mappedUids[entry.uid]
445
- if (refsUpdatedUids.indexOf(entry.uid) !== -1) {
446
- addlogs(config, 'Entry: ' + entry.uid + ' in Content Type: ' + ctUid + ' in lang: ' +
447
- lang + ' references fields are already updated.', 'success')
448
- return
449
- }
518
+ // Keep track of entries that have their references updated
519
+ let refsUpdatedUids = helper.readFile(path.join(eFolderPath, 'refsUpdatedUids.json'));
520
+ let refsUpdateFailed = helper.readFile(path.join(eFolderPath, 'refsUpdateFailed.json'));
521
+ let schema = self.ctSchemas[ctUid];
522
+
523
+ let batches = [];
524
+ refsUpdatedUids = refsUpdatedUids || [];
525
+ refsUpdateFailed = refsUpdateFailed || [];
526
+
527
+ // map reference uids @mapper/language/mapped-uids.json
528
+ // map failed reference uids @mapper/language/unmapped-uids.json
529
+ let refUidMapperPath = path.join(entryMapperPath, lang);
530
+
531
+ entries = _.map(entries, function (entry) {
532
+ try {
533
+ let uid = entry.uid;
534
+ let updatedEntry;
535
+
536
+ // restores json rte entry refs if they exist
537
+ if (self.ctJsonRte.indexOf(ctUid) > -1) {
538
+ // the entries stored in eSuccessFilePath, have the same uids as the entries from source data
539
+ updatedEntry = self.restoreJsonRteEntryRefs(entry, sourceStackEntries[entry.uid], schema.schema);
540
+ } else {
541
+ updatedEntry = entry;
542
+ }
450
543
 
451
- let requestObject = {
452
- qs: {
453
- locale: lang,
454
- },
455
- json: {
456
- entry: entry,
457
- },
544
+ let _entry = lookupReplaceEntries(
545
+ {
546
+ content_type: schema,
547
+ entry: updatedEntry,
548
+ },
549
+ _.clone(self.mappedUids),
550
+ refUidMapperPath,
551
+ );
552
+ // if there's self references, the uid gets replaced
553
+ _entry.uid = uid;
554
+ return _entry;
555
+ } catch (error) {
556
+ console.error(error);
557
+ return error;
458
558
  }
459
- let promiseResult = new Promise((resolve, reject) => {
460
- let entryResponse = client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(ctUid).entry(entry.uid)
461
- Object.assign(entryResponse, entry)
462
- delete entryResponse.publish_details
463
- return entryResponse.update({locale: lang})
464
- .then(response => {
465
- for (let j = 0; j < entries.length; j++) {
466
- if (entries[j].uid === response.uid) {
467
- entries[j] = response
468
- break
559
+ });
560
+
561
+ // Run entry creation in batches of ~16~ entries
562
+ for (let i = 0; i < entries.length; i += Math.round(entryBatchLimit / 3)) {
563
+ batches.push(entries.slice(i, i + Math.round(entryBatchLimit / 3)));
564
+ }
565
+ return Promise.map(
566
+ batches,
567
+ async function (batch, index) {
568
+ return Promise.map(
569
+ batch,
570
+ async function (entry) {
571
+ entry.uid = self.mappedUids[entry.uid];
572
+ if (refsUpdatedUids.indexOf(entry.uid) !== -1) {
573
+ addlogs(
574
+ config,
575
+ 'Entry: ' +
576
+ entry.uid +
577
+ ' in Content Type: ' +
578
+ ctUid +
579
+ ' in lang: ' +
580
+ lang +
581
+ ' references fields are already updated.',
582
+ 'success',
583
+ );
584
+ return;
469
585
  }
470
- }
471
- refsUpdatedUids.push(response.uid)
472
- return resolve()
473
- })
474
- .catch(function (error) {
475
- addlogs(config, chalk.red('Entry Uid: ' + entry.uid + ' of Content Type: ' + ctUid +
476
- ' failed to update in locale: ' + lang), 'error')
477
-
478
- addlogs(config, error, 'error')
479
- refsUpdateFailed.push({
480
- content_type: ctUid,
481
- entry: entry,
482
- locale: lang,
483
- error: error,
586
+
587
+ let promiseResult = new Promise((resolveUpdatedUids, rejectUpdatedUids) => {
588
+ let entryResponse = client
589
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
590
+ .contentType(ctUid)
591
+ .entry(entry.uid);
592
+ Object.assign(entryResponse, entry);
593
+ delete entryResponse.publish_details;
594
+ return entryResponse
595
+ .update({ locale: lang })
596
+ .then((response) => {
597
+ for (let j = 0; j < entries.length; j++) {
598
+ if (entries[j].uid === response.uid) {
599
+ entries[j] = response;
600
+ break;
601
+ }
602
+ }
603
+ refsUpdatedUids.push(response.uid);
604
+ return resolveUpdatedUids();
605
+ })
606
+ .catch(function (error) {
607
+ addlogs(
608
+ config,
609
+ chalk.red(
610
+ 'Entry Uid: ' +
611
+ entry.uid +
612
+ ' of Content Type: ' +
613
+ ctUid +
614
+ ' failed to update in locale: ' +
615
+ lang,
616
+ ),
617
+ 'error',
618
+ );
619
+
620
+ addlogs(config, error, 'error');
621
+ refsUpdateFailed.push({
622
+ content_type: ctUid,
623
+ entry: entry,
624
+ locale: lang,
625
+ error: error,
626
+ });
627
+ return rejectUpdatedUids(error);
628
+ });
629
+ });
630
+ await promiseResult;
631
+ },
632
+ {
633
+ concurrency: reqConcurrency,
634
+ },
635
+ )
636
+ .then(function () {
637
+ // batch completed successfully
638
+ helper.writeFile(path.join(eFolderPath, 'success.json'), entries);
639
+ helper.writeFile(path.join(eFolderPath, 'refsUpdatedUids.json'), refsUpdatedUids);
640
+ helper.writeFile(path.join(eFolderPath, 'refsUpdateFailed.json'), refsUpdateFailed);
641
+ addlogs(config, 'Completed re-post entries batch no: ' + (index + 1) + ' successfully!', 'success');
484
642
  })
485
- return reject()
486
- })
643
+ .catch(function (error) {
644
+ // error while executing entry in batch
645
+ addlogs(config, chalk.red('Failed re-post entries at batch no: ' + (index + 1)), 'error');
646
+ throw error;
647
+ });
648
+ },
649
+ {
650
+ concurrency: reqConcurrency,
651
+ },
652
+ )
653
+ .then(function () {
654
+ // finished updating entries with references
655
+ addlogs(
656
+ config,
657
+ "Imported entries of Content Type: '" + ctUid + "' in language: '" + lang + "' successfully!",
658
+ 'success',
659
+ );
487
660
  })
488
- await promiseResult
489
- }, {
490
- concurrency: reqConcurrency,
491
- }).then(function () {
492
- // batch completed successfully
493
- helper.writeFile(path.join(eFolderPath, 'success.json'), entries)
494
- helper.writeFile(path.join(eFolderPath, 'refsUpdatedUids.json'), refsUpdatedUids)
495
- helper.writeFile(path.join(eFolderPath, 'refsUpdateFailed.json'), refsUpdateFailed)
496
- addlogs(config, 'Completed re-post entries batch no: ' + (index + 1) + ' successfully!', 'success')
497
- }).catch(function (error) {
498
- // error while executing entry in batch
499
- addlogs(config, chalk.red('Failed re-post entries at batch no: ' + (index + 1)), 'error')
500
- throw error
501
- })
502
- }, {
661
+ .catch(function (error) {
662
+ // error while updating entries with references
663
+ addlogs(
664
+ config,
665
+ chalk.red(
666
+ "Failed while importing entries of Content Type: '" +
667
+ ctUid +
668
+ "' in language: '" +
669
+ lang +
670
+ "' successfully!",
671
+ ),
672
+ 'error',
673
+ );
674
+ throw error;
675
+ });
676
+ },
677
+ {
503
678
  concurrency: reqConcurrency,
504
- }).then(function () {
505
- // finished updating entries with references
506
- addlogs(config, 'Imported entries of Content Type: \'' + ctUid + '\' in language: \'' + lang +
507
- '\' successfully!', 'success')
508
- }).catch(function (error) {
509
- // error while updating entries with references
510
- addlogs(config, chalk.red('Failed while importing entries of Content Type: \'' + ctUid + '\' in language: \'' +
511
- lang + '\' successfully!'), 'error')
512
- throw error
679
+ },
680
+ )
681
+ .then(function () {
682
+ // completed updating entry references
683
+ addlogs(config, chalk.green("Imported entries in '" + lang + "' language successfully!"), 'success');
684
+ return resolve();
513
685
  })
514
- }, {
515
- concurrency: reqConcurrency,
516
- }).then(function () {
517
- // completed updating entry references
518
- addlogs(config, chalk.green('Imported entries in \'' + lang + '\' language successfully!'), 'success')
519
- return resolve()
520
- }).catch(function (error) {
521
- // error while updating entry references
522
- addlogs(config, chalk.red('Failed to re post entries in ' + lang + ' language'), 'error')
523
- return reject(error)
524
- })
525
- })
686
+ .catch(function (error) {
687
+ // error while updating entry references
688
+ addlogs(config, chalk.red('Failed to re post entries in ' + lang + ' language'), 'error');
689
+ return reject(error);
690
+ });
691
+ });
526
692
  },
527
693
  supressFields: async function () {
528
- addlogs(config, chalk.white('Suppressing content type fields...'), 'success')
529
- let self = this
694
+ // it should be spelled as suppressFields
695
+ addlogs(config, chalk.white('Suppressing content type fields...'), 'success');
696
+ let self = this;
530
697
  return new Promise(function (resolve, reject) {
531
- let modifiedSchemas = []
532
- let suppressedSchemas = []
698
+ let modifiedSchemas = [];
699
+ let suppressedSchemas = [];
533
700
 
534
701
  for (let uid in self.ctSchemas) {
535
702
  if (uid) {
536
- let contentTypeSchema = _.cloneDeep(self.ctSchemas[uid])
703
+ let contentTypeSchema = _.cloneDeep(self.ctSchemas[uid]);
537
704
  let flag = {
538
705
  suppressed: false,
539
706
  references: false,
540
- }
707
+ jsonRte: false,
708
+ jsonRteEmbeddedEntries: false,
709
+ };
541
710
  if (contentTypeSchema.field_rules) {
542
- delete contentTypeSchema.field_rules
711
+ delete contentTypeSchema.field_rules;
543
712
  }
544
713
 
545
714
  // Set mandatory or unique flag to false
546
- suppress(contentTypeSchema.schema, flag)
715
+ suppress(contentTypeSchema.schema, flag);
547
716
  // Check if suppress modified flag
548
717
  if (flag.suppressed) {
549
- suppressedSchemas.push(contentTypeSchema)
550
- modifiedSchemas.push(self.ctSchemas[uid])
718
+ suppressedSchemas.push(contentTypeSchema);
719
+ modifiedSchemas.push(self.ctSchemas[uid]);
551
720
  }
552
721
 
553
722
  if (flag.references) {
554
- self.refSchemas.push(uid)
723
+ self.refSchemas.push(uid);
724
+ }
725
+
726
+ if (flag.jsonRte) {
727
+ self.ctJsonRte.push(uid);
728
+ if (flag.jsonRteEmbeddedEntries) {
729
+ self.ctJsonRteWithEntryRefs.push(uid);
730
+ // pushing ct uid to refSchemas, because
731
+ // repostEntries uses refSchemas content types for
732
+ // reposting entries
733
+ if (self.refSchemas.indexOf(uid) === -1) {
734
+ self.refSchemas.push(uid);
735
+ }
736
+ }
737
+ }
738
+
739
+ if (flag.jsonRte) {
740
+ self.ctJsonRte.push(uid);
741
+ if (flag.jsonRteEmbeddedEntries) {
742
+ self.ctJsonRteWithEntryRefs.push(uid);
743
+ // pushing ct uid to refSchemas, because
744
+ // repostEntries uses refSchemas content types for
745
+ // reposting entries
746
+ if (self.refSchemas.indexOf(uid) === -1) {
747
+ self.refSchemas.push(uid);
748
+ }
749
+ }
555
750
  }
556
751
 
557
752
  // Replace extensions with new UID
558
- extension_suppress(contentTypeSchema.schema, config.preserveStackVersion)
753
+ extension_suppress(contentTypeSchema.schema, config.preserveStackVersion);
559
754
  }
560
755
  }
561
756
 
562
757
  // write modified schema in backup file
563
- helper.writeFile(modifiedSchemaPath, modifiedSchemas)
564
-
565
- return Promise.map(suppressedSchemas, async function (schema) {
566
- let contentTypeResponse = client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(schema.uid)
567
- Object.assign(contentTypeResponse, _.cloneDeep(schema))
568
- return contentTypeResponse.update()
569
- .then(UpdatedcontentType => {
758
+ helper.writeFile(modifiedSchemaPath, modifiedSchemas);
570
759
 
571
- }).catch(function (error) {
572
- addlogs(config, chalk.red('Failed to modify mandatory field of \'' + schema.uid + '\' content type'), 'error')
760
+ return Promise.map(
761
+ suppressedSchemas,
762
+ async function (schema) {
763
+ let contentTypeResponse = client
764
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
765
+ .contentType(schema.uid);
766
+ Object.assign(contentTypeResponse, _.cloneDeep(schema));
767
+ return contentTypeResponse
768
+ .update()
769
+ .then((_updatedcontentType) => {
770
+ // empty function
771
+ })
772
+ .catch(function (_error) {
773
+ addlogs(
774
+ config,
775
+ chalk.red("Failed to modify mandatory field of '" + schema.uid + "' content type"),
776
+ 'error',
777
+ );
778
+ });
779
+ // update 5 content types at a time
780
+ },
781
+ {
782
+ // update reqConcurrency content types at a time
783
+ concurrency: reqConcurrency,
784
+ },
785
+ )
786
+ .then(function () {
787
+ return resolve();
573
788
  })
574
- // update 5 content types at a time
575
- }, {
576
- // update reqConcurrency content types at a time
577
- concurrency: reqConcurrency,
578
- }).then(function () {
579
- return resolve()
580
- }).catch(function (error) {
581
- addlogs(config, chalk.red('Error while suppressing mandatory field schemas'), 'error')
582
- return reject(error)
583
- })
584
- })
789
+ .catch(function (error) {
790
+ addlogs(config, chalk.red('Error while suppressing mandatory field schemas'), 'error');
791
+ return reject(error);
792
+ });
793
+ });
585
794
  },
586
795
  fetchEntry: function (query) {
587
- let self = this
588
- return new Promise(function (resolve, reject) {
796
+ let self = this;
797
+ return new Promise(function (resolve, _reject) {
589
798
  let requestObject = {
590
799
  qs: {
591
800
  query: {
@@ -593,271 +802,652 @@ importEntries.prototype = {
593
802
  },
594
803
  locale: query.locale,
595
804
  },
596
- }
805
+ };
597
806
 
598
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(query.content_type).entry().query(requestObject.qs).find()
599
- .then(function (response) {
600
- if (response.body.entries.length <= 0) {
601
- addlogs(config, 'Unable to map entry WO uid: ' + query.entry.uid, 'error')
602
- self.failedWO.push(query)
603
- return resolve()
604
- }
605
- self.mappedUids[query.entry.uid] = response.body.entries[0].uid
606
- let _ePath = path.join(entryMapperPath, query.locale, query.content_type, 'success.json')
607
- let entries = helper.readFile(_ePath)
608
- entries.push(query.entry)
609
- helper.writeFile(_ePath, entries)
610
- addlogs(config, 'Completed mapping entry wo uid: ' + query.entry.uid + ': ' + response.body.entries[0].uid, 'clientsuccess')
611
- return resolve()
612
- }).catch(function (error) {
613
- return resolve()
614
- })
615
- })
807
+ return client
808
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
809
+ .contentType(query.content_type)
810
+ .entry()
811
+ .query(requestObject.qs)
812
+ .find()
813
+ .then(function (response) {
814
+ if (response.body.entries.length <= 0) {
815
+ addlogs(config, 'Unable to map entry WO uid: ' + query.entry.uid, 'error');
816
+ self.failedWO.push(query);
817
+ return resolve();
818
+ }
819
+ self.mappedUids[query.entry.uid] = response.body.entries[0].uid;
820
+ let _ePath = path.join(entryMapperPath, query.locale, query.content_type, 'success.json');
821
+ let entries = helper.readFile(_ePath);
822
+ entries.push(query.entry);
823
+ helper.writeFile(_ePath, entries);
824
+ addlogs(
825
+ config,
826
+ 'Completed mapping entry wo uid: ' + query.entry.uid + ': ' + response.body.entries[0].uid,
827
+ 'clientsuccess',
828
+ );
829
+ return resolve();
830
+ })
831
+ .catch(function (_error) {
832
+ return resolve();
833
+ });
834
+ });
616
835
  },
617
836
  unSuppressFields: function () {
618
- let self = this
619
837
  return new Promise(function (resolve, reject) {
620
- let modifiedSchemas = helper.readFile(modifiedSchemaPath)
621
- let modifiedSchemasUids = []
622
- let updatedExtensionUidsSchemas = []
838
+ let modifiedSchemas = helper.readFile(modifiedSchemaPath);
839
+ let modifiedSchemasUids = [];
840
+ let updatedExtensionUidsSchemas = [];
623
841
  for (let uid in modifiedSchemas) {
624
842
  if (uid) {
625
- let _contentTypeSchema = _.cloneDeep(modifiedSchemas[uid])
843
+ let _contentTypeSchema = _.cloneDeep(modifiedSchemas[uid]);
626
844
  if (_contentTypeSchema.field_rules) {
627
- delete _contentTypeSchema.field_rules
845
+ delete _contentTypeSchema.field_rules;
628
846
  }
629
- extension_suppress(_contentTypeSchema.schema, config.preserveStackVersion)
630
- updatedExtensionUidsSchemas.push(_contentTypeSchema)
847
+ extension_suppress(_contentTypeSchema.schema, config.preserveStackVersion);
848
+ updatedExtensionUidsSchemas.push(_contentTypeSchema);
631
849
  }
632
850
  }
633
851
 
634
- return Promise.map(updatedExtensionUidsSchemas, async function (schema) {
635
- let promise = new Promise((resolve, reject) => {
636
- client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(schema.uid).fetch()
637
- .then(contentTypeResponse => {
638
- contentTypeResponse.schema = schema.schema
639
- contentTypeResponse.update()
640
- .then(UpdatedcontentType => {
641
- modifiedSchemasUids.push(schema.uid)
642
- addlogs(config, (chalk.white('Content type: \'' + schema.uid + '\' has been restored to its previous glory!')))
643
- return resolve()
644
- }).catch(function (error) {
645
- addlogs(config, chalk.red('Failed to re-update ' + schema.uid), 'error')
646
- addlogs(config, error, 'error')
647
- return reject(error)
648
- })
649
- }).catch(function (error) {
650
- addlogs(config, error, 'error')
651
- return reject(error)
652
- })
653
- })
654
- await promise
655
- }, {
656
- concurrency: reqConcurrency,
657
- }).then(function () {
658
- for (let i = 0; i < modifiedSchemas.length; i++) {
659
- if (modifiedSchemasUids.indexOf(modifiedSchemas[i].uid) !== -1) {
660
- modifiedSchemas.splice(i, 1)
661
- i--
852
+ return Promise.map(
853
+ updatedExtensionUidsSchemas,
854
+ async function (schema) {
855
+ let promise = new Promise((resolveContentType, rejectContentType) => {
856
+ client
857
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
858
+ .contentType(schema.uid)
859
+ .fetch()
860
+ .then((contentTypeResponse) => {
861
+ contentTypeResponse.schema = schema.schema;
862
+ contentTypeResponse
863
+ .update()
864
+ .then((_updatedcontentType) => {
865
+ modifiedSchemasUids.push(schema.uid);
866
+ addlogs(
867
+ config,
868
+ chalk.white("Content type: '" + schema.uid + "' has been restored to its previous glory!"),
869
+ );
870
+ return resolveContentType();
871
+ })
872
+ .catch(function (error) {
873
+ addlogs(config, chalk.red('Failed to re-update ' + schema.uid), 'error');
874
+ addlogs(config, error, 'error');
875
+ return rejectContentType(error);
876
+ });
877
+ })
878
+ .catch(function (error) {
879
+ addlogs(config, error, 'error');
880
+ return rejectContentType(error);
881
+ });
882
+ });
883
+ await promise;
884
+ },
885
+ {
886
+ concurrency: reqConcurrency,
887
+ },
888
+ )
889
+ .then(function () {
890
+ for (let i = 0; i < modifiedSchemas.length; i++) {
891
+ if (modifiedSchemasUids.indexOf(modifiedSchemas[i].uid) !== -1) {
892
+ modifiedSchemas.splice(i, 1);
893
+ i--;
894
+ }
662
895
  }
663
- }
664
- // re-write, in case some schemas failed to update
665
- helper.writeFile(modifiedSchemaPath, _.compact(modifiedSchemas))
666
- addlogs(config, 'Re-modified content type schemas to their original form!', 'success')
667
- return resolve()
668
- }).catch(function (error) {
669
- // failed to update modified schemas back to their original form
670
- return reject(error)
671
- })
672
- })
896
+ // re-write, in case some schemas failed to update
897
+ helper.writeFile(modifiedSchemaPath, _.compact(modifiedSchemas));
898
+ addlogs(config, 'Re-modified content type schemas to their original form!', 'success');
899
+ return resolve();
900
+ })
901
+ .catch(function (error) {
902
+ // failed to update modified schemas back to their original form
903
+ return reject(error);
904
+ });
905
+ });
673
906
  },
674
907
  removeBuggedEntries: function () {
675
- let self = this
908
+ let self = this;
676
909
  return new Promise(function (resolve, reject) {
677
- let entries = helper.readFile(uniqueUidMapperPath)
678
- let bugged = []
679
- let removed = []
910
+ let entries = helper.readFile(uniqueUidMapperPath);
911
+ let bugged = [];
912
+ let removed = [];
680
913
  for (let uid in entries) {
681
914
  if (entries[uid].locales.indexOf(masterLanguage.code) === -1) {
682
915
  bugged.push({
683
916
  content_type: entries[uid].content_type,
684
917
  uid: uid,
685
- })
918
+ });
686
919
  }
687
920
  }
688
921
 
689
- return Promise.map(bugged, function (entry) {
690
- return client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(entry.content_type).entry(self.mappedUids[entry.uid]).delete({locale: masterLanguage.code})
922
+ return Promise.map(
923
+ bugged,
924
+ function (entry) {
925
+ return client
926
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
927
+ .contentType(entry.content_type)
928
+ .entry(self.mappedUids[entry.uid])
929
+ .delete({ locale: masterLanguage.code })
930
+ .then(function () {
931
+ removed.push(self.mappedUids[entry.uid]);
932
+ addlogs(config, 'Removed bugged entry from master ' + JSON.stringify(entry), 'success');
933
+ })
934
+ .catch(function (error) {
935
+ addlogs(config, chalk.red('Failed to remove bugged entry from master language'), 'error');
936
+ addlogs(config, error, 'error');
937
+ addlogs(config, JSON.stringify(entry), 'error');
938
+ });
939
+ },
940
+ {
941
+ concurrency: reqConcurrency,
942
+ },
943
+ )
691
944
  .then(function () {
692
- removed.push(self.mappedUids[entry.uid])
693
- addlogs(config, 'Removed bugged entry from master ' + JSON.stringify(entry), 'success')
694
- })
695
- .catch(function (error) {
696
- addlogs(config, chalk.red('Failed to remove bugged entry from master language'), 'error')
697
- addlogs(config, error, 'error')
698
- addlogs(config, JSON.stringify(entry), 'error')
699
- })
700
- }, {
701
- concurrency: reqConcurrency,
702
- }).then(function () {
703
- for (let i = 0; i < bugged.length; i++) {
704
- if (removed.indexOf(bugged[i].uid) !== -1) {
705
- bugged.splice(i, 1)
706
- i--
945
+ for (let i = 0; i < bugged.length; i++) {
946
+ if (removed.indexOf(bugged[i].uid) !== -1) {
947
+ bugged.splice(i, 1);
948
+ i--;
949
+ }
707
950
  }
708
- }
709
951
 
710
- helper.writeFile(path.join(entryMapperPath, 'removed-uids.json'), removed)
711
- helper.writeFile(path.join(entryMapperPath, 'pending-uids.json'), bugged)
952
+ helper.writeFile(path.join(entryMapperPath, 'removed-uids.json'), removed);
953
+ helper.writeFile(path.join(entryMapperPath, 'pending-uids.json'), bugged);
712
954
 
713
- addlogs(config, chalk.green('The stack has been eradicated from bugged entries!'), 'success')
714
- return resolve()
715
- }).catch(function (error) {
716
- // error while removing bugged entries from stack
717
- return reject(error)
718
- })
719
- })
955
+ addlogs(config, chalk.green('The stack has been eradicated from bugged entries!'), 'success');
956
+ return resolve();
957
+ })
958
+ .catch(function (error) {
959
+ // error while removing bugged entries from stack
960
+ return reject(error);
961
+ });
962
+ });
720
963
  },
721
964
  field_rules_update: function (schema) {
722
- let self = this
723
965
  return new Promise(function (resolve, reject) {
724
966
  if (schema.field_rules) {
725
- let fieldRuleLength = schema.field_rules.length
967
+ let fieldRuleLength = schema.field_rules.length;
726
968
  for (let k = 0; k < fieldRuleLength; k++) {
727
- let fieldRuleConditionLength = schema.field_rules[k].conditions.length
969
+ let fieldRuleConditionLength = schema.field_rules[k].conditions.length;
728
970
  for (let i = 0; i < fieldRuleConditionLength; i++) {
729
971
  if (schema.field_rules[k].conditions[i].operand_field === 'reference') {
730
- let fieldRulesValue = schema.field_rules[k].conditions[i].value
731
- let fieldRulesArray = fieldRulesValue.split('.')
732
- let updatedValue = []
733
- for (let j = 0; j < fieldRulesArray.length; j++) {
734
- let splitedFieldRulesValue = fieldRulesArray[j]
735
- let oldUid = helper.readFile(path.join(entryUidMapperPath))
972
+ let fieldRulesValue = schema.field_rules[k].conditions[i].value;
973
+ let fieldRulesArray = fieldRulesValue.split('.');
974
+ let updatedValue = [];
975
+ for (const element of fieldRulesArray) {
976
+ let splitedFieldRulesValue = element;
977
+ let oldUid = helper.readFile(path.join(entryUidMapperPath));
736
978
  if (oldUid.hasOwnProperty(splitedFieldRulesValue)) {
737
- updatedValue.push(oldUid[splitedFieldRulesValue])
979
+ updatedValue.push(oldUid[splitedFieldRulesValue]);
738
980
  } else {
739
- updatedValue.push(fieldRulesArray[j])
981
+ updatedValue.push(element);
740
982
  }
741
983
  }
742
- schema.field_rules[k].conditions[i].value = updatedValue.join('.')
984
+ schema.field_rules[k].conditions[i].value = updatedValue.join('.');
743
985
  }
744
986
  }
745
987
  }
746
988
  } else {
747
- addlogs(config, 'field_rules is not available...', 'error')
989
+ addlogs(config, 'field_rules is not available...', 'error');
748
990
  }
749
991
 
750
- let ctObj = client.stack({ api_key: config.target_stack, management_token: config.management_token }).contentType(schema.uid)
751
- Object.assign(ctObj, _.cloneDeep(schema))
752
- ctObj.update()
992
+ client
993
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
994
+ .contentType(schema.uid)
995
+ .fetch()
996
+ .then((contentTypeResponse) => {
997
+ // Object.assign(ctObj, _.cloneDeep(schema))
998
+ contentTypeResponse.field_rules = schema.field_rules;
999
+ contentTypeResponse.update();
1000
+ })
753
1001
  .then(() => {
754
- return resolve()
755
- }).catch(function (error) {
756
- return reject(error)
1002
+ return resolve();
757
1003
  })
758
- })
1004
+ .catch(function (error) {
1005
+ return reject(error);
1006
+ });
1007
+ });
759
1008
  },
760
1009
  publish: function (langs) {
761
- let self = this
1010
+ let self = this;
762
1011
  let requestObject = {
763
1012
  entry: {},
764
- }
1013
+ };
765
1014
 
766
- let contentTypeUids = Object.keys(self.ctSchemas)
767
- let entryMapper = helper.readFile(entryUidMapperPath)
1015
+ let contentTypeUids = Object.keys(self.ctSchemas);
1016
+ let entryMapper = helper.readFile(entryUidMapperPath);
768
1017
 
769
1018
  return new Promise(function (resolve, reject) {
770
- return Promise.map(langs, function (_lang, counter) {
771
- let lang = langs[counter]
772
- return Promise.map(contentTypeUids, function (ctUid) {
773
- let eFilePath = path.resolve(ePath, ctUid, lang + '.json')
774
- let entries = helper.readFile(eFilePath)
775
-
776
- let eUids = Object.keys(entries)
777
- let batches = []
778
-
779
- if (eUids.length > 0) {
780
- for (let i = 0; i < eUids.length; i += entryBatchLimit) {
781
- batches.push(eUids.slice(i, i + entryBatchLimit))
782
- }
783
- } else {
784
- return
785
- }
1019
+ return Promise.map(
1020
+ langs,
1021
+ function (_lang, counter) {
1022
+ let lang = langs[counter];
1023
+ return Promise.map(
1024
+ contentTypeUids,
1025
+ function (ctUid) {
1026
+ let eFilePath = path.resolve(ePath, ctUid, lang + '.json');
1027
+ let entries = helper.readFile(eFilePath);
786
1028
 
787
- return Promise.map(batches, async function (batch) {
788
- return Promise.map(batch, async function (eUid) {
789
- let entry = entries[eUid]
790
- let envId = []
791
- let locales = []
792
- if (entry.publish_details && entry.publish_details.length > 0) {
793
- _.forEach(entries[eUid].publish_details, function (pubObject) {
794
- if (self.environment.hasOwnProperty(pubObject.environment) && _.indexOf(envId, self.environment[pubObject.environment].name) === -1) {
795
- envId.push(self.environment[pubObject.environment].name)
796
- }
797
- if (pubObject.locale) {
798
- let idx = _.indexOf(locales, pubObject.locale)
799
- if (idx === -1) {
800
- locales.push(pubObject.locale)
801
- }
802
- }
803
- })
1029
+ let eUids = Object.keys(entries);
1030
+ let batches = [];
804
1031
 
805
- let entryUid = entryMapper[eUid]
806
- if (entryUid) {
807
- requestObject.entry.environments = envId
808
- requestObject.entry.locales = locales
809
- let publishPromiseResult = new Promise((resolve, reject) => {
810
- client.stack({api_key: config.target_stack, management_token: config.management_token}).contentType(ctUid).entry(entryUid).publish({publishDetails: requestObject.entry, locale: lang})
811
- // eslint-disable-next-line max-nested-callbacks
812
- .then(result => {
813
- // addlogs(config, 'Entry ' + eUid + ' published successfully in ' + ctUid + ' content type', 'success')
814
- console.log('Entry ' + eUid + ' published successfully in ' + ctUid + ' content type');
815
- return resolve(result)
816
- // eslint-disable-next-line max-nested-callbacks
817
- }).catch(function (err) {
818
- // addlogs(config, 'Entry ' + eUid + ' not published successfully in ' + ctUid + ' content type', 'error')
819
- console.log('Entry ' + eUid + ' not published successfully in ' + ctUid + ' content type')
820
- return reject(err.errorMessage)
821
- })
822
- })
823
- return publishPromiseResult
1032
+ if (eUids.length > 0) {
1033
+ for (let i = 0; i < eUids.length; i += entryBatchLimit) {
1034
+ batches.push(eUids.slice(i, i + entryBatchLimit));
824
1035
  }
825
1036
  } else {
826
- return {}
1037
+ return;
827
1038
  }
828
- }, {
829
- concurrency: reqConcurrency,
830
- }).then(function () {
831
- }).catch(function (error) {
832
- // error while executing entry in batch
833
- addlogs(config, error, 'error')
834
- return error
1039
+
1040
+ return Promise.map(
1041
+ batches,
1042
+ async function (batch) {
1043
+ return Promise.map(
1044
+ batch,
1045
+ async function (eUid) {
1046
+ let entry = entries[eUid];
1047
+ let envId = [];
1048
+ let locales = [];
1049
+ if (entry.publish_details && entry.publish_details.length > 0) {
1050
+ _.forEach(entries[eUid].publish_details, function (pubObject) {
1051
+ if (
1052
+ self.environment.hasOwnProperty(pubObject.environment) &&
1053
+ _.indexOf(envId, self.environment[pubObject.environment].name) === -1
1054
+ ) {
1055
+ envId.push(self.environment[pubObject.environment].name);
1056
+ }
1057
+ if (pubObject.locale) {
1058
+ let idx = _.indexOf(locales, pubObject.locale);
1059
+ if (idx === -1) {
1060
+ locales.push(pubObject.locale);
1061
+ }
1062
+ }
1063
+ });
1064
+
1065
+ let entryUid = entryMapper[eUid];
1066
+ if (entryUid) {
1067
+ requestObject.entry.environments = envId;
1068
+ requestObject.entry.locales = locales;
1069
+ return new Promise((resolveEntryPublished, rejectEntryPublished) => {
1070
+ client
1071
+ .stack({ api_key: config.target_stack, management_token: config.management_token })
1072
+ .contentType(ctUid)
1073
+ .entry(entryUid)
1074
+ .publish({ publishDetails: requestObject.entry, locale: lang })
1075
+ // eslint-disable-next-line max-nested-callbacks
1076
+ .then((result) => {
1077
+ // addlogs(config, 'Entry ' + eUid + ' published successfully in ' + ctUid + ' content type', 'success')
1078
+ console.log('Entry ' + eUid + ' published successfully in ' + ctUid + ' content type');
1079
+ return resolveEntryPublished(result);
1080
+ // eslint-disable-next-line max-nested-callbacks
1081
+ })
1082
+ .catch(function (err) {
1083
+ // addlogs(config, 'Entry ' + eUid + ' not published successfully in ' + ctUid + ' content type', 'error')
1084
+ console.log(
1085
+ 'Entry ' + eUid + ' not published successfully in ' + ctUid + ' content type',
1086
+ );
1087
+ return rejectEntryPublished(err.errorMessage);
1088
+ });
1089
+ });
1090
+ }
1091
+ } else {
1092
+ return {};
1093
+ }
1094
+ },
1095
+ {
1096
+ concurrency: reqConcurrency,
1097
+ },
1098
+ )
1099
+ .then(function () {
1100
+ // empty function
1101
+ })
1102
+ .catch(function (error) {
1103
+ // error while executing entry in batch
1104
+ addlogs(config, error, 'error');
1105
+ return error;
1106
+ });
1107
+ },
1108
+ {
1109
+ concurrency: 1,
1110
+ },
1111
+ )
1112
+ .then(function () {
1113
+ // addlogs(config, 'Entries published successfully in ' + ctUid + ' content type', 'success')
1114
+ console.log('Entries published successfully in ' + ctUid + ' content type');
1115
+ })
1116
+ .catch(function (error) {
1117
+ addlogs(
1118
+ config,
1119
+ 'Failed some of the Entry publishing in ' + ctUid + ' content type, go through logs for details.',
1120
+ 'error',
1121
+ );
1122
+ return error;
1123
+ });
1124
+ },
1125
+ {
1126
+ concurrency: 1,
1127
+ },
1128
+ )
1129
+ .then(function () {
1130
+ // empty function
835
1131
  })
836
- }, {
837
- concurrency: 1,
838
- }).then(function () {
839
- // addlogs(config, 'Entries published successfully in ' + ctUid + ' content type', 'success')
840
- console.log('Entries published successfully in ' + ctUid + ' content type')
841
- }).catch(function (error) {
842
- addlogs(config, 'Failed some of the Entry publishing in ' + ctUid + ' content type, go through logs for details.', 'error')
843
- return error
844
- })
845
- }, {
1132
+ .catch(function (error) {
1133
+ return error;
1134
+ });
1135
+ },
1136
+ {
846
1137
  concurrency: 1,
847
- }).then(function () {
848
-
849
- }).catch(function (error) {
850
- return error
1138
+ },
1139
+ )
1140
+ .then(function () {
1141
+ return resolve();
851
1142
  })
852
- }, {
853
- concurrency: 1,
854
- }).then(function () {
855
- return resolve()
856
- }).catch(error => {
857
- return reject(error)
858
- })
859
- })
1143
+ .catch((error) => {
1144
+ return reject(error);
1145
+ });
1146
+ });
860
1147
  },
861
- }
1148
+ removeEntryRefsFromJSONRTE: function (entry, ctSchema) {
1149
+ for (const element of ctSchema) {
1150
+ switch (element.data_type) {
1151
+ case 'blocks': {
1152
+ if (entry[element.uid]) {
1153
+ if (element.multiple) {
1154
+ entry[element.uid] = entry[element.uid].map((e) => {
1155
+ let key = Object.keys(e).pop();
1156
+ let subBlock = element.blocks.filter((block) => block.uid === key).pop();
1157
+ e[key] = this.removeEntryRefsFromJSONRTE(e[key], subBlock.schema);
1158
+ return e;
1159
+ });
1160
+ }
1161
+ }
1162
+ break;
1163
+ }
1164
+ case 'global_field':
1165
+ case 'group': {
1166
+ if (entry[element.uid]) {
1167
+ if (element.multiple) {
1168
+ entry[element.uid] = entry[element.uid].map((e) => {
1169
+ e = this.removeEntryRefsFromJSONRTE(e, element.schema);
1170
+ return e;
1171
+ });
1172
+ } else {
1173
+ entry[element.uid] = this.removeEntryRefsFromJSONRTE(entry[element.uid], element.schema);
1174
+ }
1175
+ }
1176
+ break;
1177
+ }
1178
+ case 'json': {
1179
+ if (entry[element.uid] && element.field_metadata.rich_text_type) {
1180
+ if (element.multiple) {
1181
+ entry[element.uid] = entry[element.uid].map((jsonRteData) => {
1182
+ // repeated code from else block, will abstract later
1183
+ let entryReferences = jsonRteData.children.filter((e) => this.doEntryReferencesExist(e));
1184
+ if (entryReferences.length > 0) {
1185
+ jsonRteData.children = jsonRteData.children.filter((e) => !this.doEntryReferencesExist(e));
1186
+ return jsonRteData; // return jsonRteData without entry references
1187
+ } else {
1188
+ return jsonRteData; // return jsonRteData as it is, because there are no entry references
1189
+ }
1190
+ });
1191
+ } else {
1192
+ let entryReferences = entry[element.uid].children.filter((e) => this.doEntryReferencesExist(e));
1193
+ if (entryReferences.length > 0) {
1194
+ entry[element.uid].children = entry[element.uid].children.filter(
1195
+ (e) => !this.doEntryReferencesExist(e),
1196
+ );
1197
+ }
1198
+ }
1199
+ }
1200
+ break;
1201
+ }
1202
+ }
1203
+ }
1204
+ return entry;
1205
+ },
1206
+ doEntryReferencesExist: function (element) {
1207
+ // checks if the children of p element contain any references
1208
+ // only checking one level deep, not recursive
1209
+
1210
+ if (element.length) {
1211
+ for (const item of element) {
1212
+ if (
1213
+ (item.type === 'p' || item.type === 'a') &&
1214
+ item.children &&
1215
+ item.children.length > 0
1216
+ ) {
1217
+ return this.doEntryReferencesExist(item.children);
1218
+ } else if (this.isEntryRef(item)) {
1219
+ return true;
1220
+ }
1221
+ }
1222
+ } else {
1223
+ if (this.isEntryRef(element)) {
1224
+ return true;
1225
+ }
1226
+
1227
+ if ((element.type === 'p' || element.type === 'a') && element.children && element.children.length > 0) {
1228
+ return this.doEntryReferencesExist(element.children);
1229
+ }
1230
+ }
1231
+ return false;
1232
+ },
1233
+ restoreJsonRteEntryRefs: function (entry, sourceStackEntry, ctSchema) {
1234
+ let mappedAssetUids = helper.readFile(mappedAssetUidPath) || {};
1235
+ let mappedAssetUrls = helper.readFile(mappedAssetUrlPath) || {};
1236
+ for (const element of ctSchema) {
1237
+ switch (element.data_type) {
1238
+ case 'blocks': {
1239
+ if (entry[element.uid]) {
1240
+ if (element.multiple) {
1241
+ entry[element.uid] = entry[element.uid].map((e, eIndex) => {
1242
+ let key = Object.keys(e).pop();
1243
+ let subBlock = element.blocks.filter((block) => block.uid === key).pop();
1244
+ let sourceStackElement = sourceStackEntry[element.uid][eIndex][key];
1245
+ e[key] = this.restoreJsonRteEntryRefs(e[key], sourceStackElement, subBlock.schema);
1246
+ return e;
1247
+ });
1248
+ }
1249
+ }
1250
+ break;
1251
+ }
1252
+ case 'global_field':
1253
+ case 'group': {
1254
+ if (entry[element.uid]) {
1255
+ if (element.multiple) {
1256
+ entry[element.uid] = entry[element.uid].map((e, eIndex) => {
1257
+ let sourceStackElement = sourceStackEntry[element.uid][eIndex];
1258
+ e = this.restoreJsonRteEntryRefs(e, sourceStackElement, element.schema);
1259
+ return e;
1260
+ });
1261
+ } else {
1262
+ let sourceStackElement = sourceStackEntry[element.uid];
1263
+ entry[element.uid] = this.restoreJsonRteEntryRefs(entry[element.uid], sourceStackElement, element.schema);
1264
+ }
1265
+ }
1266
+ break;
1267
+ }
1268
+ case 'json': {
1269
+ if (entry[element.uid] && element.field_metadata.rich_text_type) {
1270
+ if (element.multiple) {
1271
+ entry[element.uid] = entry[element.uid].map((field, index) => {
1272
+ // i am facing a Maximum call stack exceeded issue,
1273
+ // probably because of this loop operation
1274
+
1275
+ let entryRefs = sourceStackEntry[element.uid][index].children
1276
+ .map((e, i) => {
1277
+ return { index: i, value: e };
1278
+ })
1279
+ .filter((e) => this.doEntryReferencesExist(e.value))
1280
+ .map((e) => {
1281
+ // commenting the line below resolved the maximum call stack exceeded issue
1282
+ // e.value = this.setDirtyTrue(e.value)
1283
+ this.setDirtyTrue(e.value);
1284
+ return e;
1285
+ })
1286
+ .map((e) => {
1287
+ // commenting the line below resolved the maximum call stack exceeded issue
1288
+ // e.value = this.resolveAssetRefsInEntryRefsForJsonRte(e, mappedAssetUids, mappedAssetUrls)
1289
+ this.resolveAssetRefsInEntryRefsForJsonRte(e.value, mappedAssetUids, mappedAssetUrls);
1290
+ return e;
1291
+ });
1292
+
1293
+ if (entryRefs.length > 0) {
1294
+ entryRefs.forEach((entryRef) => {
1295
+ field.children.splice(entryRef.index, 0, entryRef.value);
1296
+ });
1297
+ }
1298
+ return field;
1299
+ });
1300
+ } else {
1301
+ let entryRefs = sourceStackEntry[element.uid].children
1302
+ .map((e, index) => {
1303
+ return { index: index, value: e };
1304
+ })
1305
+ .filter((e) => this.doEntryReferencesExist(e.value))
1306
+ .map((e) => {
1307
+ this.setDirtyTrue(e.value);
1308
+ return e;
1309
+ })
1310
+ .map((e) => {
1311
+ this.resolveAssetRefsInEntryRefsForJsonRte(e.value, mappedAssetUids, mappedAssetUrls);
1312
+ return e;
1313
+ });
1314
+
1315
+ if (entryRefs.length > 0) {
1316
+ entryRefs.forEach((entryRef) => {
1317
+ entry[entryRef.uid].children.splice(entryRef.index, 0, entryRef.value);
1318
+ });
1319
+ }
1320
+ }
1321
+ }
1322
+ break;
1323
+ }
1324
+ }
1325
+ }
1326
+ return entry;
1327
+ },
1328
+ isEntryRef: function (element) {
1329
+ return element.type === 'reference' && element.attrs.type === 'entry';
1330
+ },
1331
+ removeUidsFromJsonRteFields: function (entry, ctSchema) {
1332
+ for (const element of ctSchema) {
1333
+ switch (element.data_type) {
1334
+ case 'blocks': {
1335
+ if (entry[element.uid]) {
1336
+ if (element.multiple) {
1337
+ entry[element.uid] = entry[element.uid].map((e) => {
1338
+ let key = Object.keys(e).pop();
1339
+ let subBlock = element.blocks.filter((block) => block.uid === key).pop();
1340
+ e[key] = this.removeUidsFromJsonRteFields(e[key], subBlock.schema);
1341
+ return e;
1342
+ });
1343
+ }
1344
+ }
1345
+ break;
1346
+ }
1347
+ case 'global_field':
1348
+ case 'group': {
1349
+ if (entry[element.uid]) {
1350
+ if (element.multiple) {
1351
+ entry[element.uid] = entry[element.uid].map((e) => {
1352
+ e = this.removeUidsFromJsonRteFields(e, element.schema);
1353
+ return e;
1354
+ });
1355
+ } else {
1356
+ entry[element.uid] = this.removeUidsFromJsonRteFields(entry[element.uid], element.schema);
1357
+ }
1358
+ }
1359
+ break;
1360
+ }
1361
+ case 'json': {
1362
+ if (entry[element.uid] && element.field_metadata.rich_text_type) {
1363
+ if (element.multiple) {
1364
+ entry[element.uid] = entry[element.uid].map((jsonRteData) => {
1365
+ delete jsonRteData.uid; // remove uid
1366
+ jsonRteData.attrs.dirty = true;
1367
+ jsonRteData.children = jsonRteData.children.map((child) => this.removeUidsFromChildren(child));
1368
+ return jsonRteData;
1369
+ });
1370
+ } else {
1371
+ delete entry[element.uid].uid; // remove uid
1372
+ entry[element.uid].attrs.dirty = true;
1373
+ entry[element.uid].children = entry[element.uid].children.map((child) =>
1374
+ this.removeUidsFromChildren(child),
1375
+ );
1376
+ }
1377
+ }
1378
+ break;
1379
+ }
1380
+ }
1381
+ }
1382
+ return entry;
1383
+ },
1384
+ removeUidsFromChildren: function (children) {
1385
+ if (children.length && children.length > 0) {
1386
+ return children.map((child) => {
1387
+ if (child.type && child.type.length > 0) {
1388
+ delete child.uid; // remove uid
1389
+ child.attrs.dirty = true;
1390
+ }
1391
+ if (child.children && child.children.length > 0) {
1392
+ child.children = this.removeUidsFromChildren(child.children);
1393
+ }
1394
+ return child;
1395
+ });
1396
+ } else {
1397
+ if (children.type && children.type.length > 0) {
1398
+ delete children.uid; // remove uid
1399
+ children.attrs.dirty = true;
1400
+ }
1401
+ if (children.children && children.children.length > 0) {
1402
+ children.children = this.removeUidsFromChildren(children.children);
1403
+ }
1404
+ return children;
1405
+ }
1406
+ },
1407
+ setDirtyTrue: function (jsonRteChild) {
1408
+ // also removing uids in this function
1409
+ if (jsonRteChild.type) {
1410
+ jsonRteChild.attrs['dirty'] = true;
1411
+ delete jsonRteChild.uid;
1412
+
1413
+ if (jsonRteChild.children && jsonRteChild.children.length > 0) {
1414
+ jsonRteChild.children = jsonRteChild.children.map((subElement) => this.setDirtyTrue(subElement));
1415
+ }
1416
+ }
1417
+ return jsonRteChild;
1418
+ },
1419
+ resolveAssetRefsInEntryRefsForJsonRte: function (jsonRteChild, mappedAssetUids, mappedAssetUrls) {
1420
+ if (jsonRteChild.type) {
1421
+ if (jsonRteChild.attrs.type === 'asset') {
1422
+ let assetUrl;
1423
+ if (mappedAssetUids[jsonRteChild.attrs['asset-uid']]) {
1424
+ jsonRteChild.attrs['asset-uid'] = mappedAssetUids[jsonRteChild.attrs['asset-uid']];
1425
+ }
1426
+
1427
+ if (jsonRteChild.attrs['display-type'] !== 'link') {
1428
+ assetUrl = jsonRteChild.attrs['asset-link'];
1429
+ } else {
1430
+ assetUrl = jsonRteChild.attrs['href'];
1431
+ }
1432
+
1433
+ if (mappedAssetUrls[assetUrl]) {
1434
+ if (jsonRteChild.attrs['display-type'] !== 'link') {
1435
+ jsonRteChild.attrs['asset-link'] = mappedAssetUrls[assetUrl];
1436
+ } else {
1437
+ jsonRteChild.attrs['href'] = mappedAssetUrls[assetUrl];
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ if (jsonRteChild.children && jsonRteChild.children.length > 0) {
1443
+ jsonRteChild.children = jsonRteChild.children.map((subElement) =>
1444
+ this.resolveAssetRefsInEntryRefsForJsonRte(subElement, mappedAssetUids, mappedAssetUrls),
1445
+ );
1446
+ }
1447
+ }
1448
+
1449
+ return jsonRteChild;
1450
+ },
1451
+ };
862
1452
 
863
- module.exports = new importEntries()
1453
+ module.exports = new importEntries();