@contentstack/cli-cm-import 1.8.4 → 1.9.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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/bin/dev +4 -15
  3. package/lib/commands/cm/stacks/import.js +5 -4
  4. package/lib/config/index.js +2 -16
  5. package/lib/import/module-importer.js +3 -6
  6. package/lib/import/modules/assets.js +5 -2
  7. package/lib/import/modules/base-class.js +29 -14
  8. package/lib/import/modules/custom-roles.d.ts +1 -1
  9. package/lib/import/modules/custom-roles.js +12 -7
  10. package/lib/import/modules/entries.js +119 -68
  11. package/lib/import/modules/environments.d.ts +1 -1
  12. package/lib/import/modules/environments.js +3 -4
  13. package/lib/import/modules/extensions.js +3 -4
  14. package/lib/import/modules/global-fields.js +3 -2
  15. package/lib/import/modules/labels.d.ts +2 -2
  16. package/lib/import/modules/labels.js +6 -7
  17. package/lib/import/modules/marketplace-apps.d.ts +1 -0
  18. package/lib/import/modules/marketplace-apps.js +11 -5
  19. package/lib/import/modules/webhooks.d.ts +1 -1
  20. package/lib/import/modules/webhooks.js +3 -4
  21. package/lib/import/modules/workflows.js +6 -6
  22. package/lib/import/modules-js/marketplace-apps.d.ts +1 -0
  23. package/lib/import/modules-js/marketplace-apps.js +9 -2
  24. package/lib/types/default-config.d.ts +0 -2
  25. package/lib/types/import-config.d.ts +1 -0
  26. package/lib/utils/asset-helper.d.ts +1 -1
  27. package/lib/utils/backup-handler.js +37 -17
  28. package/lib/utils/common-helper.js +5 -16
  29. package/lib/utils/entries-helper.d.ts +6 -3
  30. package/lib/utils/entries-helper.js +11 -10
  31. package/lib/utils/import-config-handler.js +7 -0
  32. package/lib/utils/logger.js +1 -1
  33. package/lib/utils/marketplace-app-helper.js +9 -2
  34. package/oclif.manifest.json +1 -1
  35. package/package.json +7 -6
package/README.md CHANGED
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
47
47
  $ csdx COMMAND
48
48
  running command...
49
49
  $ csdx (--version)
50
- @contentstack/cli-cm-import/1.8.4 linux-x64 node-v18.17.1
50
+ @contentstack/cli-cm-import/1.9.1 linux-x64 node-v18.18.0
51
51
  $ csdx --help [COMMAND]
52
52
  USAGE
53
53
  $ csdx COMMAND
package/bin/dev CHANGED
@@ -1,17 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const oclif = require('@oclif/core');
4
-
5
- const path = require('path');
6
- const project = path.join(__dirname, '..', 'tsconfig.json');
7
-
8
- // In dev mode -> use ts-node and dev plugins
9
- process.env.NODE_ENV = 'development';
10
-
11
- require('ts-node').register({ project });
12
-
13
- // In dev mode, always show stack traces
14
- oclif.settings.debug = true;
15
-
16
- // Start the CLI
17
- oclif.run().then(oclif.flush).catch(oclif.Errors.handle);
3
+ (async () => {
4
+ const oclif = require('@oclif/core');
5
+ await oclif.execute({ type: 'cjs', development: true, dir: __dirname });
6
+ })();
@@ -11,21 +11,22 @@ class ImportCommand extends cli_command_1.Command {
11
11
  // setup import config
12
12
  // initialize the importer
13
13
  // start import
14
- let contentDir;
14
+ let backupDir;
15
15
  try {
16
16
  const { flags } = await this.parse(ImportCommand);
17
17
  let importConfig = await (0, utils_1.setupImportConfig)(flags);
18
18
  // Note setting host to create cma client
19
19
  importConfig.host = this.cmaHost;
20
- contentDir = importConfig.contentDir;
20
+ backupDir = importConfig.backupDir;
21
21
  const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(importConfig);
22
22
  const moduleImporter = new import_1.ModuleImporter(managementAPIClient, importConfig);
23
23
  await moduleImporter.start();
24
24
  (0, utils_1.log)(importConfig, `The content has been imported to the stack ${importConfig.apiKey} successfully!`, 'success');
25
+ (0, utils_1.log)(importConfig, `The log has been stored at '${node_path_1.default.join(importConfig.backupDir, 'logs', 'import')}'`, 'success');
25
26
  }
26
27
  catch (error) {
27
- (0, utils_1.log)({ data: contentDir }, `Failed to import stack content - ${(0, utils_1.formatError)(error)}`, 'error');
28
- (0, utils_1.log)({ data: contentDir }, `The log has been stored at ${{ data: contentDir } ? node_path_1.default.join(contentDir || __dirname, 'logs', 'import') : node_path_1.default.join(__dirname, 'logs')}`, 'info');
28
+ (0, utils_1.log)({ data: backupDir }, `Failed to import stack content - ${(0, utils_1.formatError)(error)}`, 'error');
29
+ (0, utils_1.log)({ data: backupDir }, `The log has been stored at ${{ data: backupDir } ? node_path_1.default.join(backupDir || __dirname, 'logs', 'import') : node_path_1.default.join(__dirname, 'logs')}`, 'info');
29
30
  }
30
31
  }
31
32
  }
@@ -84,9 +84,9 @@ const config = {
84
84
  publishAssets: true,
85
85
  fileName: 'assets.json',
86
86
  importSameStructure: true,
87
- uploadAssetsConcurrency: 10,
87
+ uploadAssetsConcurrency: 2,
88
88
  displayExecutionTime: false,
89
- importFoldersConcurrency: 10,
89
+ importFoldersConcurrency: 1,
90
90
  includeVersionedAssets: false,
91
91
  host: 'https://api.contentstack.io',
92
92
  folderValidKeys: ['name', 'parent_uid'],
@@ -367,19 +367,6 @@ const config = {
367
367
  stacks: '/stacks/',
368
368
  labels: '/labels/',
369
369
  },
370
- updatedModules: [
371
- 'assets',
372
- 'extensions',
373
- 'locales',
374
- 'marketplace-apps',
375
- 'labels',
376
- 'global-fields',
377
- 'content-types',
378
- 'webhooks',
379
- 'custom-roles',
380
- 'workflows',
381
- 'entries',
382
- ],
383
370
  rateLimit: 5,
384
371
  preserveStackVersion: false,
385
372
  entriesPublish: true,
@@ -390,7 +377,6 @@ const config = {
390
377
  developerHubBaseUrl: '',
391
378
  marketplaceAppEncryptionKey: 'nF2ejRQcTv',
392
379
  getEncryptionKeyMaxRetry: 3,
393
- useNewModuleStructure: false,
394
380
  // useBackedupDir: '',
395
381
  // backupConcurrency: 10,
396
382
  };
@@ -23,7 +23,7 @@ class ModuleImporter {
23
23
  const httpClient = new cli_utilities_1.HttpClient({
24
24
  headers: { api_key: this.importConfig.apiKey, authorization: this.importConfig.management_token },
25
25
  });
26
- const { data } = await httpClient.post('https://api.contentstack.io/v3/locales', {
26
+ const { data } = await httpClient.post(`https://${this.importConfig.host}/v3/locales`, {
27
27
  locale: {
28
28
  name: 'English',
29
29
  code: 'en-us',
@@ -47,6 +47,7 @@ class ModuleImporter {
47
47
  return this.import();
48
48
  }
49
49
  async import() {
50
+ (0, utils_1.log)(this.importConfig, `Starting to import content version ${this.importConfig.contentVersion}`, 'info');
50
51
  // checks for single module or all modules
51
52
  if (this.importConfig.singleModuleImport) {
52
53
  return this.importByModuleByName(this.importConfig.moduleName);
@@ -55,14 +56,10 @@ class ModuleImporter {
55
56
  }
56
57
  async importByModuleByName(moduleName) {
57
58
  (0, utils_1.log)(this.importConfig, `Starting import of ${moduleName} module`, 'info');
58
- const basePath = `${this.importConfig.backupDir}/${moduleName}`;
59
59
  // import the modules by name
60
60
  // calls the module runner which inturn calls the module itself
61
61
  // Todo: Implement a mechanism to determine whether module is new or old
62
- if (this.importConfig.useNewModuleStructure &&
63
- this.importConfig.updatedModules.indexOf(moduleName) !== -1
64
- //&& new FsUtility({ basePath }).isNewFsStructure
65
- ) {
62
+ if (this.importConfig.contentVersion === 2) {
66
63
  return (0, modules_1.default)({
67
64
  stackAPIClient: this.stackAPIClient,
68
65
  importConfig: this.importConfig,
@@ -7,6 +7,7 @@ const filter_1 = tslib_1.__importDefault(require("lodash/filter"));
7
7
  const unionBy_1 = tslib_1.__importDefault(require("lodash/unionBy"));
8
8
  const orderBy_1 = tslib_1.__importDefault(require("lodash/orderBy"));
9
9
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
10
+ const uniq_1 = tslib_1.__importDefault(require("lodash/uniq"));
10
11
  const node_fs_1 = require("node:fs");
11
12
  const includes_1 = tslib_1.__importDefault(require("lodash/includes"));
12
13
  const node_path_1 = require("node:path");
@@ -210,9 +211,11 @@ class ImportAssets extends base_class_1.default {
210
211
  };
211
212
  const serializeData = (apiOptions) => {
212
213
  const { apiData: asset } = apiOptions;
213
- const publishDetails = (0, filter_1.default)(asset.publish_details, 'environment');
214
+ const publishDetails = (0, filter_1.default)(asset.publish_details, ({ environment }) => {
215
+ return this.environments.hasOwnProperty(environment);
216
+ });
217
+ const environments = (0, uniq_1.default)((0, map_1.default)(publishDetails, ({ environment }) => this.environments[environment].name));
214
218
  const locales = (0, map_1.default)(publishDetails, 'locale');
215
- const environments = (0, map_1.default)(publishDetails, ({ environment }) => this.environments[environment].name);
216
219
  asset.locales = locales;
217
220
  asset.environments = environments;
218
221
  apiOptions.uid = this.assetsUidMap[asset.uid];
@@ -90,7 +90,7 @@ class BaseClass {
90
90
  // info: Batch No. 20 of import assets is complete
91
91
  if (currentIndexer)
92
92
  batchMsg += `Current chunk processing is (${currentIndexer}/${indexerCount})`;
93
- (0, utils_1.log)(this.importConfig, `Batch No. (${batchNo}/${totelBatches}) of ${processName} is complete. ${batchMsg}`, 'success');
93
+ (0, utils_1.log)(this.importConfig, `Batch No. (${batchNo}/${totelBatches}) of ${processName} is complete`, 'success');
94
94
  }
95
95
  if (this.importConfig.modules.assets.displayExecutionTime) {
96
96
  console.log(`Time taken to execute: ${exeTime} milliseconds; wait time: ${exeTime < 1000 ? 1000 - exeTime : 0} milliseconds`);
@@ -105,7 +105,7 @@ class BaseClass {
105
105
  * @return {Promise} Promise<void>
106
106
  */
107
107
  makeAPICall(apiOptions, isLastRequest = false) {
108
- var _a, _b;
108
+ var _a;
109
109
  if (apiOptions.serializeData instanceof Function) {
110
110
  apiOptions = apiOptions.serializeData(apiOptions);
111
111
  }
@@ -169,18 +169,21 @@ class BaseClass {
169
169
  case 'create-cts':
170
170
  return this.stack.contentType().create(apiData).then(onSuccess).catch(onReject);
171
171
  case 'update-cts':
172
- if (additionalInfo.skip) {
173
- return Promise.resolve(onSuccess(apiData));
172
+ if (!apiData) {
173
+ return Promise.resolve();
174
174
  }
175
175
  return apiData.update().then(onSuccess).catch(onReject);
176
176
  case 'update-gfs':
177
+ if (!apiData) {
178
+ return Promise.resolve();
179
+ }
177
180
  return apiData.update().then(onSuccess).catch(onReject);
178
181
  case 'create-environments':
179
- // return this.stack
180
- // .environment()
181
- // .create({ environment: omit(apiData, ['uid']) as EnvironmentData })
182
- // .then(onSuccess)
183
- // .catch(onReject);
182
+ return this.stack
183
+ .environment()
184
+ .create({ environment: (0, omit_1.default)(apiData, ['uid']) })
185
+ .then(onSuccess)
186
+ .catch(onReject);
184
187
  case 'create-labels':
185
188
  return this.stack
186
189
  .label()
@@ -215,6 +218,12 @@ class BaseClass {
215
218
  .then(onSuccess)
216
219
  .catch(onReject);
217
220
  case 'create-entries':
221
+ if (!apiData) {
222
+ return Promise.resolve();
223
+ }
224
+ if ((_a = additionalInfo[apiData === null || apiData === void 0 ? void 0 : apiData.uid]) === null || _a === void 0 ? void 0 : _a.isLocalized) {
225
+ return apiData.update({ locale: additionalInfo.locale }).then(onSuccess).catch(onReject);
226
+ }
218
227
  return this.stack
219
228
  .contentType(additionalInfo.cTUid)
220
229
  .entry()
@@ -222,22 +231,28 @@ class BaseClass {
222
231
  .then(onSuccess)
223
232
  .catch(onReject);
224
233
  case 'update-entries':
234
+ if (!apiData) {
235
+ return Promise.resolve();
236
+ }
225
237
  return apiData.update({ locale: additionalInfo.locale }).then(onSuccess).catch(onReject);
226
238
  case 'publish-entries':
227
- if (additionalInfo.skip) {
228
- return Promise.resolve(onSuccess(apiData));
239
+ if (!apiData || !apiData.entryUid) {
240
+ return Promise.resolve();
229
241
  }
230
242
  return this.stack
231
243
  .contentType(additionalInfo.cTUid)
232
- .entry(additionalInfo.entryUid)
233
- .publish({ publishDetails: apiData, locale: additionalInfo.locale })
244
+ .entry(apiData.entryUid)
245
+ .publish({
246
+ publishDetails: { environments: apiData.environments, locales: apiData.locales },
247
+ locale: additionalInfo.locale,
248
+ })
234
249
  .then(onSuccess)
235
250
  .catch(onReject);
236
251
  case 'delete-entries':
237
252
  return this.stack
238
253
  .contentType(apiData.cTUid)
239
254
  .entry(apiData.entryUid)
240
- .delete({ locale: (_b = (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code })
255
+ .delete({ locale: additionalInfo.locale })
241
256
  .then(onSuccess)
242
257
  .catch(onReject);
243
258
  default:
@@ -26,7 +26,7 @@ export default class ImportCustomRoles extends BaseClass {
26
26
  */
27
27
  start(): Promise<void>;
28
28
  getLocalesUidMap(): Promise<void>;
29
- importCustomRoles(): Promise<string>;
29
+ importCustomRoles(): Promise<void>;
30
30
  /**
31
31
  * @method serializeWebhooks
32
32
  * @param {ApiOptions} apiOptions ApiOptions
@@ -4,7 +4,6 @@ const tslib_1 = require("tslib");
4
4
  const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
5
5
  const values_1 = tslib_1.__importDefault(require("lodash/values"));
6
6
  const node_path_1 = require("node:path");
7
- const config_1 = tslib_1.__importDefault(require("../../config"));
8
7
  const utils_1 = require("../../utils");
9
8
  const base_class_1 = tslib_1.__importDefault(require("./base-class"));
10
9
  const lodash_1 = require("lodash");
@@ -13,17 +12,23 @@ class ImportCustomRoles extends base_class_1.default {
13
12
  super({ importConfig, stackAPIClient });
14
13
  this.getTransformUidsFactory = (rule) => {
15
14
  if (rule.module === 'environment') {
16
- rule.environments = (0, lodash_1.map)(rule.environments, (env) => this.environmentsUidMap[env]);
15
+ if (!(0, isEmpty_1.default)(this.environmentsUidMap)) {
16
+ rule.environments = (0, lodash_1.map)(rule.environments, (env) => this.environmentsUidMap[env]);
17
+ }
17
18
  }
18
19
  else if (rule.module === 'locale') {
19
- rule.locales = (0, lodash_1.map)(rule.locales, (locale) => this.localesUidMap[locale]);
20
+ if (!(0, isEmpty_1.default)(this.localesUidMap)) {
21
+ rule.locales = (0, lodash_1.map)(rule.locales, (locale) => this.localesUidMap[locale]);
22
+ }
20
23
  }
21
24
  else if (rule.module === 'entry') {
22
- rule.entries = (0, lodash_1.map)(rule.entries, (entry) => this.entriesUidMap[entry]);
25
+ if (!(0, isEmpty_1.default)(this.entriesUidMap)) {
26
+ rule.entries = (0, lodash_1.map)(rule.entries, (entry) => this.entriesUidMap[entry]);
27
+ }
23
28
  }
24
29
  return rule;
25
30
  };
26
- this.customRolesConfig = config_1.default.modules.customRoles;
31
+ this.customRolesConfig = importConfig.modules.customRoles;
27
32
  this.customRolesMapperPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'custom-roles');
28
33
  this.customRolesFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.customRolesConfig.dirName);
29
34
  this.customRolesUidMapperPath = (0, node_path_1.join)(this.customRolesMapperPath, 'uid-mapping.json');
@@ -102,7 +107,7 @@ class ImportCustomRoles extends base_class_1.default {
102
107
  async importCustomRoles() {
103
108
  if (this.customRoles === undefined || (0, isEmpty_1.default)(this.customRoles)) {
104
109
  (0, utils_1.log)(this.importConfig, 'No custom-roles found', 'info');
105
- return (0, node_path_1.resolve)();
110
+ return;
106
111
  }
107
112
  const apiContent = (0, values_1.default)(this.customRoles);
108
113
  const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
@@ -134,7 +139,7 @@ class ImportCustomRoles extends base_class_1.default {
134
139
  entity: 'create-custom-role',
135
140
  includeParamOnCompletion: true,
136
141
  },
137
- concurrencyLimit: config_1.default.fetchConcurrency || 1,
142
+ concurrencyLimit: this.importConfig.fetchConcurrency || 1,
138
143
  }, undefined, false);
139
144
  }
140
145
  /**
@@ -35,6 +35,7 @@ class EntriesImport extends base_class_1.default {
35
35
  this.jsonRteCTsWithRef = [];
36
36
  this.envs = {};
37
37
  this.autoCreatedEntries = [];
38
+ this.failedEntries = [];
38
39
  }
39
40
  async start() {
40
41
  try {
@@ -57,6 +58,12 @@ class EntriesImport extends base_class_1.default {
57
58
  }
58
59
  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
60
  utils_1.fsUtil.writeFile(path.join(this.entriesMapperPath, 'failed-entries.json'), this.failedEntries);
61
+ if (this.autoCreatedEntries.length > 0) {
62
+ (0, utils_1.log)(this.importConfig, 'Removing entries from master language which got created by default', 'info');
63
+ await this.removeAutoCreatedEntries().catch((error) => {
64
+ (0, utils_1.log)(this.importConfig, `Error while removing auto created entries in master locale ${(0, utils_1.formatError)(error)}`, 'error');
65
+ });
66
+ }
60
67
  // Update entries with references
61
68
  const entryUpdateRequestOptions = this.populateEntryUpdatePayload();
62
69
  for (let entryUpdateRequestOption of entryUpdateRequestOptions) {
@@ -70,12 +77,6 @@ class EntriesImport extends base_class_1.default {
70
77
  await this.enableMandatoryCTReferences().catch((error) => {
71
78
  (0, utils_1.log)(this.importConfig, `Error while updating content type references ${(0, utils_1.formatError)(error)}`, 'error');
72
79
  });
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
80
  // Update field rule of content types which are got removed earlier
80
81
  (0, utils_1.log)(this.importConfig, 'Updating the field rules of content type', 'info');
81
82
  await this.updateFieldRules().catch((error) => {
@@ -139,15 +140,6 @@ class EntriesImport extends base_class_1.default {
139
140
  jsonRteEmbeddedEntries: false,
140
141
  };
141
142
  (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
143
  if (flag.references) {
152
144
  this.refCTs.push(contentType.uid);
153
145
  }
@@ -160,6 +152,15 @@ class EntriesImport extends base_class_1.default {
160
152
  }
161
153
  }
162
154
  }
155
+ // Check if suppress modified flag
156
+ if (flag.suppressed) {
157
+ this.modifiedCTs.push((0, lodash_1.find)(this.cTs, { uid: contentType.uid }));
158
+ }
159
+ else {
160
+ // Note: Skips the content type from update if no reference found
161
+ apiOptions.apiData = null;
162
+ return apiOptions;
163
+ }
163
164
  (0, utils_1.lookupExtension)(this.importConfig, contentType.schema, this.importConfig.preserveStackVersion, this.installedExtensions);
164
165
  const contentTypePayload = this.stack.contentType(contentType.uid);
165
166
  Object.assign(contentTypePayload, (0, lodash_1.cloneDeep)(contentType));
@@ -189,11 +190,11 @@ class EntriesImport extends base_class_1.default {
189
190
  if (indexerCount === 0) {
190
191
  return Promise.resolve();
191
192
  }
192
- (0, utils_1.log)(this.importConfig, `Starting to create entries for ${cTUid} in locale ${locale}`, 'info');
193
+ // log(this.importConfig, `Starting to create entries for ${cTUid} in locale ${locale}`, 'info');
193
194
  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
195
  // Write created entries
195
196
  const entriesCreateFileHelper = new cli_utilities_1.FsUtility({
196
- moduleName: 'created-entries',
197
+ moduleName: 'entries',
197
198
  indexFileName: 'index.json',
198
199
  basePath: path.join(this.entriesMapperPath, cTUid, locale),
199
200
  chunkFileSize: this.entriesConfig.chunkFileSize,
@@ -201,15 +202,30 @@ class EntriesImport extends base_class_1.default {
201
202
  omitKeys: this.entriesConfig.invalidKeys,
202
203
  });
203
204
  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 });
205
+ const onSuccess = ({ response, apiData: entry, additionalInfo }) => {
206
+ var _a, _b;
207
+ if ((_a = additionalInfo[entry.uid]) === null || _a === void 0 ? void 0 : _a.isLocalized) {
208
+ let oldUid = additionalInfo[entry.uid].entryOldUid;
209
+ (0, utils_1.log)(this.importConfig, `Localized entry: '${entry.title}' of content type ${cTUid} in locale ${locale}`, 'info');
210
+ entry.uid = oldUid;
211
+ entry.entryOldUid = oldUid;
212
+ entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
213
+ entriesCreateFileHelper.writeIntoFile({ [oldUid]: entry }, { mapKeyVal: true });
214
+ }
215
+ else {
216
+ (0, utils_1.log)(this.importConfig, `Created entry: '${entry.title}' of content type ${cTUid} in locale ${locale}`, 'info');
217
+ // This is for creating localized entries that do not have a counterpart in master locale.
218
+ // For example : To create entry1 in fr-fr, where en-us is the master locale
219
+ // entry1 will get created in en-us first, then fr-fr version will be created
220
+ // thus entry1 has to be removed from en-us at the end.
221
+ if (!isMasterLocale && !((_b = additionalInfo[entry.uid]) === null || _b === void 0 ? void 0 : _b.isLocalized)) {
222
+ this.autoCreatedEntries.push({ cTUid, locale, entryUid: response.uid });
223
+ }
224
+ this.entriesUidMapper[entry.uid] = response.uid;
225
+ entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
226
+ entry.entryOldUid = entry.uid; // stores old uid temporarily
227
+ entriesCreateFileHelper.writeIntoFile({ [entry.uid]: entry }, { mapKeyVal: true });
211
228
  }
212
- entriesCreateFileHelper.writeIntoFile({ [response.uid]: entry }, { mapKeyVal: true });
213
229
  };
214
230
  const onReject = ({ error, apiData: { uid, title } }) => {
215
231
  (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to create`, 'error');
@@ -233,7 +249,7 @@ class EntriesImport extends base_class_1.default {
233
249
  entity: 'create-entries',
234
250
  includeParamOnCompletion: true,
235
251
  serializeData: this.serializeEntries.bind(this),
236
- additionalInfo: { contentType, locale, cTUid, entryFileName: indexer[index] },
252
+ additionalInfo: { contentType, locale, cTUid, entryFileName: indexer[index], isMasterLocale },
237
253
  },
238
254
  concurrencyLimit: this.importConcurrency,
239
255
  }).then(() => {
@@ -249,21 +265,40 @@ class EntriesImport extends base_class_1.default {
249
265
  * @returns {ApiOptions} ApiOptions
250
266
  */
251
267
  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);
268
+ let { apiData: entry, additionalInfo: { cTUid, locale, contentType, isMasterLocale }, } = apiOptions;
269
+ try {
270
+ if (this.jsonRteCTs.indexOf(cTUid) > -1) {
271
+ entry = (0, utils_1.removeUidsFromJsonRteFields)(entry, contentType.schema);
272
+ }
273
+ // remove entry references from json-rte fields
274
+ if (this.jsonRteCTsWithRef.indexOf(cTUid) > -1) {
275
+ entry = (0, utils_1.removeEntryRefsFromJSONRTE)(entry, contentType.schema);
276
+ }
277
+ // will replace all old asset uid/urls with new ones
278
+ entry = (0, utils_1.lookupAssets)({
279
+ content_type: contentType,
280
+ entry: entry,
281
+ }, this.assetUidMapper, this.assetUrlMapper, path.join(this.entriesPath, cTUid), this.installedExtensions);
282
+ delete entry.publish_details;
283
+ // checking the entry is a localized one or not
284
+ if (!isMasterLocale && this.entriesUidMapper.hasOwnProperty(entry.uid)) {
285
+ const entryResponse = this.stack.contentType(contentType.uid).entry(this.entriesUidMapper[entry.uid]);
286
+ Object.assign(entryResponse, (0, lodash_1.cloneDeep)(entry), { uid: this.entriesUidMapper[entry.uid] });
287
+ apiOptions.apiData = entryResponse;
288
+ apiOptions.additionalInfo[entryResponse.uid] = {
289
+ isLocalized: true,
290
+ entryOldUid: entry.uid
291
+ };
292
+ return apiOptions;
293
+ }
294
+ apiOptions.apiData = entry;
255
295
  }
256
- // remove entry references from json-rte fields
257
- if (this.jsonRteCTsWithRef.indexOf(cTUid) > -1) {
258
- entry = (0, utils_1.removeEntryRefsFromJSONRTE)(entry, contentType.schema);
296
+ catch (error) {
297
+ (0, utils_1.log)(this.importConfig, `${entry.title} entry of content type ${cTUid} in locale ${locale} failed to create`, 'error');
298
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
299
+ this.failedEntries.push({ content_type: cTUid, locale, entry: { uid: entry.uid, title: entry.title } });
300
+ apiOptions.apiData = null;
259
301
  }
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
302
  return apiOptions;
268
303
  }
269
304
  populateEntryUpdatePayload() {
@@ -288,7 +323,7 @@ class EntriesImport extends base_class_1.default {
288
323
  if (indexerCount === 0) {
289
324
  return Promise.resolve();
290
325
  }
291
- (0, utils_1.log)(this.importConfig, `Starting to update entries with references for ${cTUid} in locale ${locale}`, 'info');
326
+ // log(this.importConfig, `Starting to update entries with references for ${cTUid} in locale ${locale}`, 'info');
292
327
  const contentType = (0, lodash_1.find)(this.cTs, { uid: cTUid });
293
328
  const onSuccess = ({ response, apiData: { uid, url, title } }) => {
294
329
  (0, utils_1.log)(this.importConfig, `Updated entry: '${title}' of content type ${cTUid} in locale ${locale}`, 'info');
@@ -296,7 +331,12 @@ class EntriesImport extends base_class_1.default {
296
331
  const onReject = ({ error, apiData: { uid, title } }) => {
297
332
  (0, utils_1.log)(this.importConfig, `${title} entry of content type ${cTUid} in locale ${locale} failed to update`, 'error');
298
333
  (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 } });
334
+ this.failedEntries.push({
335
+ content_type: cTUid,
336
+ locale,
337
+ entry: { uid: this.entriesUidMapper[uid], title },
338
+ entryId: uid,
339
+ });
300
340
  };
301
341
  for (const index in indexer) {
302
342
  const chunk = await fs.readChunkFiles.next().catch((error) => {
@@ -331,26 +371,34 @@ class EntriesImport extends base_class_1.default {
331
371
  */
332
372
  serializeUpdateEntries(apiOptions) {
333
373
  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
- });
374
+ try {
375
+ const sourceEntryFilePath = entry.sourceEntryFilePath;
376
+ const sourceEntry = (utils_1.fsUtil.readFile(sourceEntryFilePath) || {})[entry.entryOldUid];
377
+ const newUid = this.entriesUidMapper[entry.entryOldUid];
378
+ // Removing temp values
379
+ delete entry.sourceEntryFilePath;
380
+ delete entry.entryOldUid;
381
+ if (this.jsonRteCTs.indexOf(cTUid) > -1) {
382
+ // the entries stored in eSuccessFilePath, have the same uids as the entries from source data
383
+ entry = (0, utils_1.restoreJsonRteEntryRefs)(entry, sourceEntry, contentType.schema, {
384
+ mappedAssetUids: this.assetUidMapper,
385
+ mappedAssetUrls: this.assetUrlMapper,
386
+ });
387
+ }
388
+ entry = (0, utils_1.lookupEntries)({
389
+ content_type: contentType,
390
+ entry,
391
+ }, this.entriesUidMapper, path.join(this.entriesMapperPath, cTUid, locale));
392
+ const entryResponse = this.stack.contentType(contentType.uid).entry(newUid);
393
+ Object.assign(entryResponse, (0, lodash_1.cloneDeep)(entry), { uid: newUid });
394
+ delete entryResponse.publish_details;
395
+ apiOptions.apiData = entryResponse;
396
+ }
397
+ catch (error) {
398
+ (0, utils_1.log)(this.importConfig, `${entry.title} entry of content type ${cTUid} in locale ${locale} failed to update`, 'error');
399
+ (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
400
+ apiOptions.apiData = null;
345
401
  }
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
402
  return apiOptions;
355
403
  }
356
404
  async enableMandatoryCTReferences() {
@@ -391,6 +439,7 @@ class EntriesImport extends base_class_1.default {
391
439
  return apiOptions;
392
440
  }
393
441
  async removeAutoCreatedEntries() {
442
+ var _a, _b;
394
443
  const onSuccess = ({ response, apiData: { entryUid } }) => {
395
444
  (0, utils_1.log)(this.importConfig, `Auto created entry in master locale removed - entry uid ${entryUid} `, 'success');
396
445
  };
@@ -405,6 +454,7 @@ class EntriesImport extends base_class_1.default {
405
454
  resolve: onSuccess.bind(this),
406
455
  entity: 'delete-entries',
407
456
  includeParamOnCompletion: true,
457
+ additionalInfo: { locale: (_b = (_a = this.importConfig) === null || _a === void 0 ? void 0 : _a.master_locale) === null || _b === void 0 ? void 0 : _b.code },
408
458
  },
409
459
  concurrencyLimit: this.importConcurrency,
410
460
  });
@@ -418,12 +468,12 @@ class EntriesImport extends base_class_1.default {
418
468
  const cTs = utils_1.fsUtil.readFile(path.join(this.cTsPath, 'schema.json'));
419
469
  const contentType = (0, lodash_1.find)(cTs, { uid: cTUid });
420
470
  if (contentType.field_rules) {
421
- let fieldRuleLength = contentType.field_rules.length;
422
471
  const fieldDatatypeMap = {};
423
472
  for (let i = 0; i < contentType.schema.length; i++) {
424
473
  const field = contentType.schema[i].uid;
425
474
  fieldDatatypeMap[field] = contentType.schema[i].data_type;
426
475
  }
476
+ let fieldRuleLength = contentType.field_rules.length;
427
477
  for (let k = 0; k < fieldRuleLength; k++) {
428
478
  let fieldRuleConditionLength = contentType.field_rules[k].conditions.length;
429
479
  for (let i = 0; i < fieldRuleConditionLength; i++) {
@@ -460,7 +510,7 @@ class EntriesImport extends base_class_1.default {
460
510
  (0, utils_1.log)(this.importConfig, `Updated the field rules of ${cTUid}`, 'info');
461
511
  }
462
512
  else {
463
- (0, utils_1.log)(this.importConfig, `No field rules found in content type ${cTUid} to update`, 'error');
513
+ (0, utils_1.log)(this.importConfig, `No field rules found in content type ${cTUid} to update`, 'info');
464
514
  }
465
515
  }
466
516
  }
@@ -475,12 +525,12 @@ class EntriesImport extends base_class_1.default {
475
525
  if (indexerCount === 0) {
476
526
  return Promise.resolve();
477
527
  }
478
- (0, utils_1.log)(this.importConfig, `Starting publish entries for ${cTUid} in locale ${locale}`, 'info');
479
- const onSuccess = ({ response, apiData: { environments }, additionalInfo: { entryUid } }) => {
528
+ // log(this.importConfig, `Starting publish entries for ${cTUid} in locale ${locale}`, 'info');
529
+ const onSuccess = ({ response, apiData: { environments, entryUid }, additionalInfo }) => {
480
530
  (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');
481
531
  };
482
- const onReject = ({ error, apiData, additionalInfo: { entryUid } }) => {
483
- (0, utils_1.log)(this.importConfig, `${entryUid} entry of content type ${cTUid} in locale ${locale} failed to publish`, 'error');
532
+ const onReject = ({ error, apiData, additionalInfo }) => {
533
+ (0, utils_1.log)(this.importConfig, `${apiData.entryUid} entry of content type ${cTUid} in locale ${locale} failed to publish`, 'error');
484
534
  (0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
485
535
  };
486
536
  for (const index in indexer) {
@@ -516,10 +566,10 @@ class EntriesImport extends base_class_1.default {
516
566
  */
517
567
  serializePublishEntries(apiOptions) {
518
568
  let { apiData: entry, additionalInfo } = apiOptions;
519
- additionalInfo.entryUid = this.entriesUidMapper[entry.uid];
520
569
  const requestObject = {
521
570
  environments: [],
522
571
  locales: [],
572
+ entryUid: this.entriesUidMapper[entry.uid],
523
573
  };
524
574
  if (entry.publish_details && entry.publish_details.length > 0) {
525
575
  (0, lodash_1.forEach)(entry.publish_details, (pubObject) => {
@@ -533,7 +583,8 @@ class EntriesImport extends base_class_1.default {
533
583
  });
534
584
  }
535
585
  else {
536
- additionalInfo.skip = true;
586
+ apiOptions.apiData = null;
587
+ return apiOptions;
537
588
  }
538
589
  apiOptions.apiData = requestObject;
539
590
  return apiOptions;