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