@contentstack/cli-cm-import 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,536 @@
1
+ "use strict";
2
+ /* eslint-disable no-prototype-builtins */
3
+ /*!
4
+ * Contentstack Import
5
+ * Copyright (c) 2019 Contentstack LLC
6
+ * MIT Licensed
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const tslib_1 = require("tslib");
10
+ const path = tslib_1.__importStar(require("path"));
11
+ const lodash_1 = require("lodash");
12
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
13
+ const utils_1 = require("../../utils");
14
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
15
+ class EntriesImport extends base_class_1.default {
16
+ constructor({ importConfig, stackAPIClient }) {
17
+ super({ importConfig, stackAPIClient });
18
+ this.assetUidMapperPath = path.resolve(importConfig.data, 'mapper', 'assets', 'uid-mapping.json');
19
+ this.assetUrlMapperPath = path.resolve(importConfig.data, 'mapper', 'assets', 'url-mapping.json');
20
+ this.entriesMapperPath = path.resolve(importConfig.data, 'mapper', 'entries');
21
+ this.envPath = path.resolve(importConfig.data, 'environments', 'environments.json');
22
+ this.entriesUIDMapperPath = path.join(this.entriesMapperPath, 'uid-mapping.json');
23
+ this.uniqueUidMapperPath = path.join(this.entriesMapperPath, 'unique-mapping.json');
24
+ this.modifiedCTsPath = path.join(this.entriesMapperPath, 'modified-schemas.json');
25
+ this.marketplaceAppMapperPath = path.join(this.importConfig.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
26
+ this.entriesConfig = importConfig.modules.entries;
27
+ this.entriesPath = path.resolve(importConfig.data, this.entriesConfig.dirName);
28
+ this.cTsPath = path.resolve(importConfig.data, importConfig.modules['content-types'].dirName);
29
+ this.localesPath = path.resolve(importConfig.data, importConfig.modules.locales.dirName, importConfig.modules.locales.fileName);
30
+ this.importConcurrency = this.entriesConfig.importConcurrency || importConfig.importConcurrency;
31
+ this.entriesUidMapper = {};
32
+ this.modifiedCTs = [];
33
+ this.refCTs = [];
34
+ this.jsonRteCTs = [];
35
+ this.jsonRteCTsWithRef = [];
36
+ this.envs = {};
37
+ this.autoCreatedEntries = [];
38
+ }
39
+ async start() {
40
+ try {
41
+ this.cTs = utils_1.fsUtil.readFile(path.join(this.cTsPath, 'schema.json'));
42
+ if (!this.cTs || (0, lodash_1.isEmpty)(this.cTs)) {
43
+ (0, utils_1.log)(this.importConfig, 'No content type found', 'info');
44
+ return;
45
+ }
46
+ this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
47
+ this.assetUidMapper = utils_1.fsUtil.readFile(this.assetUidMapperPath) || {};
48
+ this.assetUrlMapper = utils_1.fsUtil.readFile(this.assetUrlMapperPath) || {};
49
+ utils_1.fsUtil.makeDirectory(this.entriesMapperPath);
50
+ await this.disableMandatoryCTReferences();
51
+ this.locales = (0, lodash_1.values)(utils_1.fsUtil.readFile(this.localesPath));
52
+ this.locales.unshift(this.importConfig.master_locale); // adds master locale to the list
53
+ //Create Entries
54
+ const entryRequestOptions = this.populateEntryCreatePayload();
55
+ for (let entryRequestOption of entryRequestOptions) {
56
+ await this.createEntries(entryRequestOption);
57
+ }
58
+ await utils_1.fileHelper.writeLargeFile(path.join(this.entriesMapperPath, 'uid-mapping.json'), this.entriesUidMapper); // TBD: manages mapper in one file, should find an alternative
59
+ utils_1.fsUtil.writeFile(path.join(this.entriesMapperPath, 'failed-entries.json'), this.failedEntries);
60
+ // Update entries with references
61
+ const entryUpdateRequestOptions = this.populateEntryUpdatePayload();
62
+ for (let entryUpdateRequestOption of entryUpdateRequestOptions) {
63
+ await this.updateEntriesWithReferences(entryUpdateRequestOption).catch((error) => {
64
+ (0, utils_1.log)(this.importConfig, `Error while updating entries references of ${entryUpdateRequestOption.cTUid} in locale ${entryUpdateRequestOption.locale}`, 'error');
65
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
66
+ });
67
+ }
68
+ utils_1.fsUtil.writeFile(path.join(this.entriesMapperPath, 'failed-entries.json'), this.failedEntries);
69
+ (0, utils_1.log)(this.importConfig, 'Restoring content type changes', 'info');
70
+ await this.enableMandatoryCTReferences().catch((error) => {
71
+ (0, utils_1.log)(this.importConfig, `Error while updating content type references ${(0, utils_1.formatError)(error)}`, 'error');
72
+ });
73
+ if (this.autoCreatedEntries.length > 0) {
74
+ (0, utils_1.log)(this.importConfig, 'Removing entries from master language which got created by default', 'info');
75
+ await this.removeAutoCreatedEntries().catch((error) => {
76
+ (0, utils_1.log)(this.importConfig, `Error while removing auto created entries in master locale ${(0, utils_1.formatError)(error)}`, 'error');
77
+ });
78
+ }
79
+ // Update field rule of content types which are got removed earlier
80
+ (0, utils_1.log)(this.importConfig, 'Updating the field rules of content type', 'info');
81
+ await this.updateFieldRules().catch((error) => {
82
+ (0, utils_1.log)(this.importConfig, `Error while updating field rules of content type ${(0, utils_1.formatError)(error)}`, 'error');
83
+ });
84
+ (0, utils_1.log)(this.importConfig, 'Entries imported successfully', 'success');
85
+ // Publishing entries
86
+ if (this.importConfig.entriesPublish) {
87
+ (0, utils_1.log)(this.importConfig, 'Publishing entries', 'info');
88
+ this.envs = utils_1.fileHelper.readFileSync(this.envPath);
89
+ for (let entryRequestOption of entryRequestOptions) {
90
+ await this.publishEntries(entryRequestOption).catch((error) => {
91
+ (0, utils_1.log)(this.importConfig, `Error in publishing entries of ${entryRequestOption.cTUid} in locale ${entryRequestOption.locale} ${(0, utils_1.formatError)(error)}`, 'error');
92
+ });
93
+ }
94
+ (0, utils_1.log)(this.importConfig, 'All the entries have been published successfully', 'success');
95
+ }
96
+ }
97
+ catch (error) {
98
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
99
+ throw new Error('Error while importing entries');
100
+ }
101
+ }
102
+ async disableMandatoryCTReferences() {
103
+ const onSuccess = ({ response: contentType, apiData: { uid } }) => {
104
+ (0, utils_1.log)(this.importConfig, `${uid} content type references removed temporarily`, 'success');
105
+ };
106
+ const onReject = ({ error, apiData: { uid } }) => {
107
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
108
+ throw new Error(`${uid} content type references removal failed`);
109
+ };
110
+ return await this.makeConcurrentCall({
111
+ processName: 'Update content types (removing mandatory references temporarily)',
112
+ apiContent: this.cTs,
113
+ apiParams: {
114
+ serializeData: this.serializeUpdateCTs.bind(this),
115
+ reject: onReject.bind(this),
116
+ resolve: onSuccess.bind(this),
117
+ entity: 'update-cts',
118
+ includeParamOnCompletion: true,
119
+ },
120
+ concurrencyLimit: this.importConcurrency,
121
+ }).then(() => {
122
+ utils_1.fsUtil.writeFile(this.modifiedCTsPath, this.modifiedCTs);
123
+ });
124
+ }
125
+ /**
126
+ * @method serializeUpdateCTs
127
+ * @param {ApiOptions} apiOptions ApiOptions
128
+ * @returns {ApiOptions} ApiOptions
129
+ */
130
+ serializeUpdateCTs(apiOptions) {
131
+ const { apiData: contentType } = apiOptions;
132
+ if (contentType.field_rules) {
133
+ delete contentType.field_rules;
134
+ }
135
+ const flag = {
136
+ suppressed: false,
137
+ references: false,
138
+ jsonRte: false,
139
+ jsonRteEmbeddedEntries: false,
140
+ };
141
+ (0, utils_1.suppressSchemaReference)(contentType.schema, flag);
142
+ // Check if suppress modified flag
143
+ if (flag.suppressed) {
144
+ this.modifiedCTs.push((0, lodash_1.find)(this.cTs, { uid: contentType.uid }));
145
+ }
146
+ else {
147
+ // Note: Skips the content type from update if no reference found
148
+ apiOptions.additionalInfo = { skip: true };
149
+ return apiOptions;
150
+ }
151
+ if (flag.references) {
152
+ this.refCTs.push(contentType.uid);
153
+ }
154
+ if (flag.jsonRte) {
155
+ this.jsonRteCTs.push(contentType.uid);
156
+ if (flag.jsonRteEmbeddedEntries) {
157
+ this.jsonRteCTsWithRef.push(contentType.uid);
158
+ if (this.refCTs.indexOf(contentType.uid) === -1) {
159
+ this.refCTs.push(contentType.uid);
160
+ }
161
+ }
162
+ }
163
+ (0, utils_1.lookupExtension)(this.importConfig, contentType.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
164
+ const contentTypePayload = this.stack.contentType(contentType.uid);
165
+ Object.assign(contentTypePayload, (0, lodash_1.cloneDeep)(contentType));
166
+ apiOptions.apiData = contentTypePayload;
167
+ return apiOptions;
168
+ }
169
+ populateEntryCreatePayload() {
170
+ const requestOptions = [];
171
+ for (let locale of this.locales) {
172
+ for (let contentType of this.cTs) {
173
+ requestOptions.push({
174
+ cTUid: contentType.uid,
175
+ locale: locale.code,
176
+ });
177
+ }
178
+ }
179
+ return requestOptions;
180
+ }
181
+ async createEntries({ cTUid, locale }) {
182
+ var _a, _b;
183
+ const processName = 'Create Entries';
184
+ const indexFileName = 'index.json';
185
+ const basePath = path.join(this.entriesPath, cTUid, locale);
186
+ const fs = new cli_utilities_1.FsUtility({ basePath, indexFileName });
187
+ const indexer = fs.indexFileContent;
188
+ const indexerCount = (0, lodash_1.values)(indexer).length;
189
+ if (indexerCount === 0) {
190
+ return Promise.resolve();
191
+ }
192
+ (0, utils_1.log)(this.importConfig, `Starting to create entries for ${cTUid} in locale ${locale}`, 'info');
193
+ const isMasterLocale = locale === ((_b = (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code);
194
+ // Write created entries
195
+ const entriesCreateFileHelper = new cli_utilities_1.FsUtility({
196
+ moduleName: 'created-entries',
197
+ indexFileName: 'index.json',
198
+ basePath: path.join(this.entriesMapperPath, cTUid, locale),
199
+ chunkFileSize: this.entriesConfig.chunkFileSize,
200
+ keepMetadata: false,
201
+ omitKeys: this.entriesConfig.invalidKeys,
202
+ });
203
+ const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
204
+ const onSuccess = ({ response, apiData: entry, additionalInfo: { entryFileName } }) => {
205
+ (0, utils_1.log)(this.importConfig, `Created entry: '${entry.title}' of content type ${cTUid} in locale ${locale}`, 'info');
206
+ this.entriesUidMapper[entry.uid] = response.uid;
207
+ entry.sourceEntryFilePath = path.join(basePath, entryFileName); // stores source file path temporarily
208
+ entry.entryOldUid = entry.uid; // stores old uid temporarily
209
+ if (!isMasterLocale) {
210
+ this.autoCreatedEntries.push({ cTUid, locale, entryUid: response.uid });
211
+ }
212
+ entriesCreateFileHelper.writeIntoFile({ [response.uid]: entry }, { mapKeyVal: true });
213
+ };
214
+ const onReject = ({ error, apiData: { uid, title } }) => {
215
+ (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to create`, 'error');
216
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
217
+ this.failedEntries.push({ content_type: cTUid, locale, entry: { uid, title } });
218
+ };
219
+ for (const index in indexer) {
220
+ const chunk = await fs.readChunkFiles.next().catch((error) => {
221
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
222
+ });
223
+ if (chunk) {
224
+ let apiContent = (0, lodash_1.values)(chunk);
225
+ await this.makeConcurrentCall({
226
+ apiContent,
227
+ processName,
228
+ indexerCount,
229
+ currentIndexer: +index,
230
+ apiParams: {
231
+ reject: onReject,
232
+ resolve: onSuccess,
233
+ entity: 'create-entries',
234
+ includeParamOnCompletion: true,
235
+ serializeData: this.serializeEntries.bind(this),
236
+ additionalInfo: { contentType, locale, cTUid, entryFileName: indexer[index] },
237
+ },
238
+ concurrencyLimit: this.importConcurrency,
239
+ }).then(() => {
240
+ entriesCreateFileHelper === null || entriesCreateFileHelper === void 0 ? void 0 : entriesCreateFileHelper.completeFile(true);
241
+ (0, utils_1.log)(this.importConfig, `Created entries for content type ${cTUid} in locale ${locale}`, 'success');
242
+ });
243
+ }
244
+ }
245
+ }
246
+ /**
247
+ * @method serializeEntries
248
+ * @param {ApiOptions} apiOptions ApiOptions
249
+ * @returns {ApiOptions} ApiOptions
250
+ */
251
+ serializeEntries(apiOptions) {
252
+ let { apiData: entry, additionalInfo: { cTUid, locale, contentType }, } = apiOptions;
253
+ if (this.jsonRteCTs.indexOf(cTUid) > -1) {
254
+ entry = (0, utils_1.removeUidsFromJsonRteFields)(entry, contentType.schema);
255
+ }
256
+ // remove entry references from json-rte fields
257
+ if (this.jsonRteCTsWithRef.indexOf(cTUid) > -1) {
258
+ entry = (0, utils_1.removeEntryRefsFromJSONRTE)(entry, contentType.schema);
259
+ }
260
+ // will replace all old asset uid/urls with new ones
261
+ entry = (0, utils_1.lookupAssets)({
262
+ content_type: contentType,
263
+ entry: entry,
264
+ }, this.assetUidMapper, this.assetUrlMapper, path.join(this.entriesPath, cTUid), this.installedExtensions);
265
+ delete entry.publish_details;
266
+ apiOptions.apiData = entry;
267
+ return apiOptions;
268
+ }
269
+ populateEntryUpdatePayload() {
270
+ const requestOptions = [];
271
+ for (let locale of this.locales) {
272
+ for (let cTUid of this.refCTs) {
273
+ requestOptions.push({
274
+ cTUid,
275
+ locale: locale.code,
276
+ });
277
+ }
278
+ }
279
+ return requestOptions;
280
+ }
281
+ async updateEntriesWithReferences({ cTUid, locale }) {
282
+ const processName = 'Update Entries';
283
+ const indexFileName = 'index.json';
284
+ const basePath = path.join(this.entriesMapperPath, cTUid, locale);
285
+ const fs = new cli_utilities_1.FsUtility({ basePath, indexFileName });
286
+ const indexer = fs.indexFileContent;
287
+ const indexerCount = (0, lodash_1.values)(indexer).length;
288
+ if (indexerCount === 0) {
289
+ return Promise.resolve();
290
+ }
291
+ (0, utils_1.log)(this.importConfig, `Starting to update entries with references for ${cTUid} in locale ${locale}`, 'info');
292
+ const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
293
+ const onSuccess = ({ response, apiData: { uid, url, title } }) => {
294
+ (0, utils_1.log)(this.importConfig, `Updated entry: '${title}' of content type ${cTUid} in locale ${locale}`, 'info');
295
+ };
296
+ const onReject = ({ error, apiData: { uid, title } }) => {
297
+ (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to update`, 'error');
298
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
299
+ this.failedEntries.push({ content_type: cTUid, locale, entry: { uid: this.entriesUidMapper[uid], title } });
300
+ };
301
+ for (const index in indexer) {
302
+ const chunk = await fs.readChunkFiles.next().catch((error) => {
303
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
304
+ });
305
+ if (chunk) {
306
+ let apiContent = (0, lodash_1.values)(chunk);
307
+ await this.makeConcurrentCall({
308
+ apiContent,
309
+ processName,
310
+ indexerCount,
311
+ currentIndexer: +index,
312
+ apiParams: {
313
+ reject: onReject,
314
+ resolve: onSuccess,
315
+ entity: 'update-entries',
316
+ includeParamOnCompletion: true,
317
+ serializeData: this.serializeUpdateEntries.bind(this),
318
+ additionalInfo: { contentType, locale, cTUid },
319
+ },
320
+ concurrencyLimit: this.importConcurrency,
321
+ }).then(() => {
322
+ (0, utils_1.log)(this.importConfig, `Updated entries for content type ${cTUid} in locale ${locale}`, 'success');
323
+ });
324
+ }
325
+ }
326
+ }
327
+ /**
328
+ * @method serializeUpdateEntries
329
+ * @param {ApiOptions} apiOptions ApiOptions
330
+ * @returns {ApiOptions} ApiOptions
331
+ */
332
+ serializeUpdateEntries(apiOptions) {
333
+ let { apiData: entry, additionalInfo: { cTUid, locale, contentType }, } = apiOptions;
334
+ const sourceEntryFilePath = entry.sourceEntryFilePath;
335
+ const sourceEntry = (utils_1.fsUtil.readFile(sourceEntryFilePath) || {})[entry.entryOldUid];
336
+ // Removing temp values
337
+ delete entry.sourceEntryFilePath;
338
+ delete entry.entryOldUid;
339
+ if (this.jsonRteCTs.indexOf(cTUid) > -1) {
340
+ // the entries stored in eSuccessFilePath, have the same uids as the entries from source data
341
+ entry = (0, utils_1.restoreJsonRteEntryRefs)(entry, sourceEntry, contentType.schema, {
342
+ mappedAssetUids: this.assetUidMapper,
343
+ mappedAssetUrls: this.assetUrlMapper,
344
+ });
345
+ }
346
+ entry = (0, utils_1.lookupEntries)({
347
+ content_type: contentType,
348
+ entry,
349
+ }, this.entriesUidMapper, path.join(this.entriesMapperPath, cTUid, locale));
350
+ const entryResponse = this.stack.contentType(contentType.uid).entry(this.entriesUidMapper[entry.uid]);
351
+ Object.assign(entryResponse, (0, lodash_1.cloneDeep)(entry));
352
+ delete entryResponse.publish_details;
353
+ apiOptions.apiData = entryResponse;
354
+ return apiOptions;
355
+ }
356
+ async enableMandatoryCTReferences() {
357
+ const onSuccess = ({ response: contentType, apiData: { uid } }) => {
358
+ (0, utils_1.log)(this.importConfig, `${uid} content type references updated`, 'success');
359
+ };
360
+ const onReject = ({ error, apiData: { uid } }) => {
361
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
362
+ throw new Error(`Failed to update references of content type ${uid}`);
363
+ };
364
+ return await this.makeConcurrentCall({
365
+ processName: 'Update content type references',
366
+ apiContent: this.modifiedCTs,
367
+ apiParams: {
368
+ serializeData: this.serializeUpdateCTsWithRef.bind(this),
369
+ reject: onReject.bind(this),
370
+ resolve: onSuccess.bind(this),
371
+ entity: 'update-cts',
372
+ includeParamOnCompletion: true,
373
+ },
374
+ concurrencyLimit: this.importConcurrency,
375
+ });
376
+ }
377
+ /**
378
+ * @method serializeUpdateCTsWithRef
379
+ * @param {ApiOptions} apiOptions ApiOptions
380
+ * @returns {ApiOptions} ApiOptions
381
+ */
382
+ serializeUpdateCTsWithRef(apiOptions) {
383
+ const { apiData: contentType } = apiOptions;
384
+ if (contentType.field_rules) {
385
+ delete contentType.field_rules;
386
+ }
387
+ (0, utils_1.lookupExtension)(this.importConfig, contentType.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
388
+ const contentTypePayload = this.stack.contentType(contentType.uid);
389
+ Object.assign(contentTypePayload, (0, lodash_1.cloneDeep)(contentType));
390
+ apiOptions.apiData = contentTypePayload;
391
+ return apiOptions;
392
+ }
393
+ async removeAutoCreatedEntries() {
394
+ const onSuccess = ({ response, apiData: { entryUid } }) => {
395
+ (0, utils_1.log)(this.importConfig, `Auto created entry in master locale removed - entry uid ${entryUid} `, 'success');
396
+ };
397
+ const onReject = ({ error, apiData: { entryUid } }) => {
398
+ (0, utils_1.log)(this.importConfig, `Failed to remove auto created entry in master locale - entry uid ${entryUid} \n ${(0, utils_1.formatError)(error)}`, 'error');
399
+ };
400
+ return await this.makeConcurrentCall({
401
+ processName: 'Remove auto created entry in master locale',
402
+ apiContent: this.autoCreatedEntries,
403
+ apiParams: {
404
+ reject: onReject.bind(this),
405
+ resolve: onSuccess.bind(this),
406
+ entity: 'delete-entries',
407
+ includeParamOnCompletion: true,
408
+ },
409
+ concurrencyLimit: this.importConcurrency,
410
+ });
411
+ }
412
+ async updateFieldRules() {
413
+ let cTsWithFieldRules = utils_1.fsUtil.readFile(path.join(this.cTsPath + '/field_rules_uid.json'));
414
+ if (!cTsWithFieldRules || (cTsWithFieldRules === null || cTsWithFieldRules === void 0 ? void 0 : cTsWithFieldRules.length) === 0) {
415
+ return;
416
+ }
417
+ for (let cTUid of cTsWithFieldRules) {
418
+ const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
419
+ if (contentType.field_rules) {
420
+ let fieldRuleLength = contentType.field_rules.length;
421
+ for (let k = 0; k < fieldRuleLength; k++) {
422
+ let fieldRuleConditionLength = contentType.field_rules[k].conditions.length;
423
+ for (let i = 0; i < fieldRuleConditionLength; i++) {
424
+ if (contentType.field_rules[k].conditions[i].operand_field === 'reference') {
425
+ let fieldRulesValue = contentType.field_rules[k].conditions[i].value;
426
+ let fieldRulesArray = fieldRulesValue.split('.');
427
+ let updatedValue = [];
428
+ for (const element of fieldRulesArray) {
429
+ let splittedFieldRulesValue = element;
430
+ if (this.entriesUidMapper.hasOwnProperty(splittedFieldRulesValue)) {
431
+ updatedValue.push(this.entriesUidMapper[splittedFieldRulesValue]);
432
+ }
433
+ else {
434
+ updatedValue.push(element);
435
+ }
436
+ }
437
+ contentType.field_rules[k].conditions[i].value = updatedValue.join('.');
438
+ }
439
+ }
440
+ }
441
+ const contentTypeResponse = await this.stack
442
+ .contentType(contentType.uid)
443
+ .fetch()
444
+ .catch((error) => {
445
+ (0, utils_1.log)(this.importConfig, `failed to update the field rules of ${cTUid} ${(0, utils_1.formatError)(error)}`, 'error');
446
+ });
447
+ if (!contentTypeResponse) {
448
+ continue;
449
+ }
450
+ contentTypeResponse.field_rules = contentType.field_rules;
451
+ await contentTypeResponse.update().catch((error) => {
452
+ (0, utils_1.log)(this.importConfig, `failed to update the field rules of ${cTUid} ${(0, utils_1.formatError)(error)}`, 'error');
453
+ });
454
+ (0, utils_1.log)(this.importConfig, `Updated the field rules of ${cTUid}`, 'info');
455
+ }
456
+ else {
457
+ (0, utils_1.log)(this.importConfig, `No field rules found in content type ${cTUid} to update`, 'error');
458
+ }
459
+ }
460
+ }
461
+ async publishEntries({ cTUid, locale }) {
462
+ const processName = 'Publish Entries';
463
+ const indexFileName = 'index.json';
464
+ const basePath = path.join(this.entriesPath, cTUid, locale);
465
+ const fs = new cli_utilities_1.FsUtility({ basePath, indexFileName });
466
+ const indexer = fs.indexFileContent;
467
+ const indexerCount = (0, lodash_1.values)(indexer).length;
468
+ const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
469
+ if (indexerCount === 0) {
470
+ return Promise.resolve();
471
+ }
472
+ (0, utils_1.log)(this.importConfig, `Starting publish entries for ${cTUid} in locale ${locale}`, 'info');
473
+ const onSuccess = ({ response, apiData: { environments }, additionalInfo: { entryUid } }) => {
474
+ (0, utils_1.log)(this.importConfig, `Published entry: '${entryUid}' of content type ${cTUid} and locale ${locale} in ${environments === null || environments === void 0 ? void 0 : environments.join(',')} environments`, 'info');
475
+ };
476
+ const onReject = ({ error, apiData, additionalInfo: { entryUid } }) => {
477
+ (0, utils_1.log)(this.importConfig, `${entryUid} entry of content type ${cTUid} in locale ${locale} failed to publish`, 'error');
478
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
479
+ };
480
+ for (const index in indexer) {
481
+ const chunk = await fs.readChunkFiles.next().catch((error) => {
482
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
483
+ });
484
+ if (chunk) {
485
+ let apiContent = (0, lodash_1.values)(chunk);
486
+ await this.makeConcurrentCall({
487
+ apiContent,
488
+ processName,
489
+ indexerCount,
490
+ currentIndexer: +index,
491
+ apiParams: {
492
+ reject: onReject,
493
+ resolve: onSuccess,
494
+ entity: 'publish-entries',
495
+ includeParamOnCompletion: true,
496
+ serializeData: this.serializePublishEntries.bind(this),
497
+ additionalInfo: { contentType, locale, cTUid },
498
+ },
499
+ concurrencyLimit: this.importConcurrency,
500
+ }).then(() => {
501
+ (0, utils_1.log)(this.importConfig, `Published entries for content type ${cTUid} in locale ${locale}`, 'success');
502
+ });
503
+ }
504
+ }
505
+ }
506
+ /**
507
+ * @method serializeEntries
508
+ * @param {ApiOptions} apiOptions ApiOptions
509
+ * @returns {ApiOptions} ApiOptions
510
+ */
511
+ serializePublishEntries(apiOptions) {
512
+ let { apiData: entry, additionalInfo } = apiOptions;
513
+ additionalInfo.entryUid = this.entriesUidMapper[entry.uid];
514
+ const requestObject = {
515
+ environments: [],
516
+ locales: [],
517
+ };
518
+ if (entry.publish_details && entry.publish_details.length > 0) {
519
+ (0, lodash_1.forEach)(entry.publish_details, (pubObject) => {
520
+ if (this.envs.hasOwnProperty(pubObject.environment) &&
521
+ (0, lodash_1.indexOf)(requestObject.environments, this.envs[pubObject.environment].name) === -1) {
522
+ requestObject.environments.push(this.envs[pubObject.environment].name);
523
+ }
524
+ if (pubObject.locale && (0, lodash_1.indexOf)(requestObject.locales, pubObject.locale) === -1) {
525
+ requestObject.locales.push(pubObject.locale);
526
+ }
527
+ });
528
+ }
529
+ else {
530
+ additionalInfo.skip = true;
531
+ }
532
+ apiOptions.apiData = requestObject;
533
+ return apiOptions;
534
+ }
535
+ }
536
+ exports.default = EntriesImport;
@@ -12,7 +12,7 @@ export default class ImportMarketplaceApps extends BaseClass {
12
12
  private appUidMapping;
13
13
  private installationUidMapping;
14
14
  private installedApps;
15
- private appOrginalName;
15
+ private appOriginalName;
16
16
  developerHubBaseUrl: string;
17
17
  sdkClient: ContentstackClient;
18
18
  nodeCrypto: NodeCrypto;
@@ -40,7 +40,10 @@ export default class ImportMarketplaceApps extends BaseClass {
40
40
  appCreationCallback(app: any, response: any, appSuffix: number): Promise<any>;
41
41
  /**
42
42
  * @method installApps
43
- * @returns {Void}
43
+ *
44
+ * @param {Record<string, any>} app
45
+ * @param {Record<string, any>[]} installedApps
46
+ * @returns {Promise<void>}
44
47
  */
45
48
  installApps(app: any): Promise<void>;
46
49
  /**