@contentstack/cli-cm-bulk-publish 1.10.2 → 1.10.4

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Contentstack
3
+ Copyright (c) 2026 Contentstack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-cm-bulk-publish
18
18
  $ csdx COMMAND
19
19
  running command...
20
20
  $ csdx (--version)
21
- @contentstack/cli-cm-bulk-publish/1.10.1 darwin-arm64 node-v22.14.0
21
+ @contentstack/cli-cm-bulk-publish/1.10.4 darwin-arm64 node-v22.14.0
22
22
  $ csdx --help [COMMAND]
23
23
  USAGE
24
24
  $ csdx COMMAND
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-bulk-publish",
3
3
  "description": "Contentstack CLI plugin for bulk publish actions",
4
- "version": "1.10.2",
4
+ "version": "1.10.4",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-command": "~1.6.1",
9
- "@contentstack/cli-config": "~1.15.0",
10
- "@contentstack/cli-utilities": "~1.14.4",
8
+ "@contentstack/cli-command": "~1.7.1",
9
+ "@contentstack/cli-config": "~1.16.2",
10
+ "@contentstack/cli-utilities": "~1.16.0",
11
11
  "@oclif/core": "^4.3.0",
12
12
  "@oclif/plugin-help": "^6.2.28",
13
13
  "chalk": "^4.1.2",
14
14
  "dotenv": "^16.5.0",
15
- "inquirer": "8.2.6",
15
+ "inquirer": "8.2.7",
16
16
  "lodash": "^4.17.21",
17
17
  "winston": "^3.17.0"
18
18
  },
@@ -50,7 +50,7 @@ class AssetsPublishCommand extends Command {
50
50
  } else if (updatedFlags['stack-api-key']) {
51
51
  config.stackApiKey = updatedFlags['stack-api-key'];
52
52
  } else {
53
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
53
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
54
54
  }
55
55
  updatedFlags.bulkPublish = updatedFlags.bulkPublish === 'false' ? false : true;
56
56
  if (updatedFlags.folderUid === undefined) {
@@ -104,10 +104,10 @@ class AssetsPublishCommand extends Command {
104
104
  this.error(message, { exit: 2 });
105
105
  }
106
106
  } else {
107
- this.error('Confirmation failed');
107
+ this.error('Confirmation failed.');
108
108
  }
109
109
  } else {
110
- this.error('Validation failed');
110
+ this.error('Validation failed.');
111
111
  }
112
112
  }
113
113
 
@@ -118,7 +118,7 @@ class AssetsPublishCommand extends Command {
118
118
  }
119
119
 
120
120
  if (sourceEnv && !deliveryToken) {
121
- this.error('Specify source environment delivery token. Please check --help for more details', { exit: 2 });
121
+ this.error('Specify the source environment delivery token. Run --help for more details.', { exit: 2 });
122
122
  }
123
123
 
124
124
  if (!environments || environments.length === 0) {
@@ -53,7 +53,7 @@ class UnpublishCommand extends Command {
53
53
  } else if (updatedFlags['stack-api-key']) {
54
54
  config.stackApiKey = updatedFlags['stack-api-key'];
55
55
  } else {
56
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
56
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
57
57
  }
58
58
  if (!updatedFlags.deliveryToken) {
59
59
  updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
@@ -62,7 +62,7 @@ class UnpublishCommand extends Command {
62
62
  stack = await getStack(config);
63
63
  }
64
64
  if (!updatedFlags.deliveryToken && updatedFlags.deliveryToken.length === 0) {
65
- this.error('Delivery Token is required for executing this command', { exit: 2 });
65
+ this.error('A delivery token is required to execute this command.', { exit: 2 });
66
66
  }
67
67
 
68
68
  if (await this.confirmFlags(updatedFlags)) {
@@ -41,7 +41,7 @@ class CrossPublishCommand extends Command {
41
41
  } else if (updatedFlags['stack-api-key']) {
42
42
  config.stackApiKey = updatedFlags['stack-api-key'];
43
43
  } else {
44
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
44
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
45
45
  }
46
46
  if (!updatedFlags.deliveryToken) {
47
47
  updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
@@ -52,7 +52,7 @@ class CrossPublishCommand extends Command {
52
52
  }
53
53
 
54
54
  if (!updatedFlags.deliveryToken && updatedFlags.deliveryToken.length === 0) {
55
- this.error('Delivery Token is required for executing this command', { exit: 2 });
55
+ this.error('A delivery token is required to execute this command.', { exit: 2 });
56
56
  }
57
57
 
58
58
  if (await this.confirmFlags(updatedFlags)) {
@@ -51,7 +51,7 @@ class PublishModifiedCommand extends Command {
51
51
  } else if (updatedFlags['stack-api-key']) {
52
52
  config.stackApiKey = updatedFlags['stack-api-key'];
53
53
  } else {
54
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
54
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
55
55
  }
56
56
  updatedFlags.bulkPublish = updatedFlags.bulkPublish !== 'false';
57
57
  stack = await getStack(config);
@@ -60,7 +60,7 @@ class NonlocalizedFieldChangesCommand extends Command {
60
60
  } else if (updatedFlags['stack-api-key']) {
61
61
  config.stackApiKey = updatedFlags['stack-api-key'];
62
62
  } else {
63
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
63
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
64
64
  }
65
65
  stack = await getStack(config);
66
66
  }
@@ -8,7 +8,7 @@ class PublishOnlyUnpublished extends Command {
8
8
  try {
9
9
  await publishOnlyUnpublishedService.apply(this, [PublishOnlyUnpublished]);
10
10
  } catch (error) {
11
- this.error(error, { exit: 2 });
11
+ this.error(error?.message || error, { exit: 2 });
12
12
  }
13
13
  }
14
14
  }
@@ -64,7 +64,7 @@ class PublishEntriesCommand extends Command {
64
64
  } else if (updatedFlags['stack-api-key']) {
65
65
  config.stackApiKey = updatedFlags['stack-api-key'];
66
66
  } else {
67
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
67
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
68
68
  }
69
69
  updatedFlags.bulkPublish = updatedFlags.bulkPublish !== 'false';
70
70
  stack = await getStack(config);
@@ -131,7 +131,7 @@ class PublishEntriesCommand extends Command {
131
131
  }
132
132
 
133
133
  if (sourceEnv && !deliveryToken) {
134
- this.error('Specify source environment delivery token. Please check --help for more details', { exit: 2 });
134
+ this.error('Specify the source environment delivery token. Run --help for more details.', { exit: 2 });
135
135
  }
136
136
 
137
137
  if (publishAllContentTypes && contentTypes && contentTypes.length > 0) {
@@ -56,7 +56,7 @@ class UnpublishCommand extends Command {
56
56
  } else if (updatedFlags['stack-api-key']) {
57
57
  config.stackApiKey = updatedFlags['stack-api-key'];
58
58
  } else {
59
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
59
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
60
60
  }
61
61
  if (!updatedFlags.deliveryToken) {
62
62
  updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
@@ -65,7 +65,7 @@ class UnpublishCommand extends Command {
65
65
  stack = await getStack(config);
66
66
  }
67
67
  if (!updatedFlags.deliveryToken && updatedFlags.deliveryToken.length === 0) {
68
- this.error('Delivery Token is required for executing this command', { exit: 2 });
68
+ this.error('A delivery token is required to execute this command.', { exit: 2 });
69
69
  }
70
70
 
71
71
  if (await this.confirmFlags(updatedFlags)) {
@@ -50,7 +50,7 @@ class UpdateAndPublishCommand extends Command {
50
50
  } else if (updatedFlags['stack-api-key']) {
51
51
  config.stackApiKey = updatedFlags['stack-api-key'];
52
52
  } else {
53
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
53
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
54
54
  }
55
55
  updatedFlags.bulkPublish = updatedFlags.bulkPublish === 'false' ? false : true;
56
56
 
@@ -37,7 +37,7 @@ class ClearCommand extends Command {
37
37
  }
38
38
  this.log('Log files have been cleared');
39
39
  } else {
40
- this.error(`The log directory doesn't exist.`);
40
+ this.error(`The log directory does not exist.`);
41
41
  }
42
42
  } catch (e) {
43
43
  return;
@@ -50,7 +50,7 @@ class ClearCommand extends Command {
50
50
  this.log('Total number of log files - ', files.length);
51
51
  });
52
52
  } else {
53
- this.error(`The log directory doesn't exist.`);
53
+ this.error(`The log directory does not exist.`);
54
54
  }
55
55
  }
56
56
  }
@@ -13,12 +13,12 @@ class ConfigureCommand extends Command {
13
13
  try {
14
14
  this.getToken(configureFlags.alias);
15
15
  } catch (error) {
16
- this.error(`The configured management token alias ${configureFlags.alias} has not been added yet. Add it using 'csdx auth:tokens:add -a ${configureFlags.alias}'`, { exit: 2 })
16
+ this.error(`The configured management token alias '${configureFlags.alias}' has not been added yet. Add it using 'csdx auth:tokens:add -a ${configureFlags.alias}'.`, { exit: 2 })
17
17
  }
18
18
  } else if (configureFlags['stack-api-key']) {
19
19
  configureFlags.stackApiKey = configureFlags['stack-api-key'];
20
20
  } else {
21
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
21
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
22
22
  }
23
23
 
24
24
  this.setConfig(configureFlags);
@@ -57,7 +57,7 @@ class UnpublishCommand extends Command {
57
57
  } else if (updatedFlags['stack-api-key']) {
58
58
  config.stackApiKey = updatedFlags['stack-api-key'];
59
59
  } else {
60
- this.error('Please use `--alias` or `--stack-api-key` to proceed.', { exit: 2 });
60
+ this.error('Use the `--alias` or `--stack-api-key` flag to proceed.', { exit: 2 });
61
61
  }
62
62
  if (!updatedFlags.deliveryToken) {
63
63
  updatedFlags.deliveryToken = await cliux.prompt('Enter delivery token of your source environment');
@@ -66,7 +66,7 @@ class UnpublishCommand extends Command {
66
66
  stack = await getStack(config);
67
67
  }
68
68
  if (!updatedFlags.deliveryToken && updatedFlags.deliveryToken.length === 0) {
69
- this.error('Delivery Token is required for executing this command', { exit: 2 });
69
+ this.error('A delivery token is required to execute this command.', { exit: 2 });
70
70
  }
71
71
 
72
72
  if (await this.confirmFlags(updatedFlags)) {
@@ -35,22 +35,25 @@ function removePublishDetails(elements) {
35
35
  function displayEntriesDetails(sanitizedData, action, mapping = []) {
36
36
  if (action === 'bulk_publish') {
37
37
  sanitizedData.forEach((entry) => {
38
- entry?.publish_details.forEach((pd) => {
39
- if (Object.keys(mapping).includes(pd.environment)) {
38
+ if (Array.isArray(entry?.publish_details) && entry.publish_details.length > 0) {
39
+ const matchingPublishDetails = entry.publish_details.filter((pd) =>
40
+ Object.keys(mapping).includes(pd.environment)
41
+ );
42
+ if (matchingPublishDetails.length > 0) {
43
+ const pd = matchingPublishDetails[0];
40
44
  console.log(
41
45
  chalk.green(
42
- `Entry UID '${entry.uid}' of CT '${entry.content_type}' in locale '${entry.locale}' version '${pd.version}' in environment '${pd.environment}'`,
46
+ `Entry UID: '${entry.uid}', Content Type: '${entry.content_type}', Locale: '${entry.locale}', Version: '${pd.version}', Environment: '${pd.environment}'`,
43
47
  ),
44
- )
48
+ );
45
49
  }
46
- });
47
- if(!Array.isArray(entry.publish_details)){
48
- console.log(chalk.green(`Entry UID '${entry.uid}' of CT '${entry.content_type}' in locale '${entry.locale}'`));
50
+ } else if (!Array.isArray(entry.publish_details)) {
51
+ console.log(chalk.green(`Entry UID: '${entry.uid}', Content Type: '${entry.content_type}', Locale: '${entry.locale}'`));
49
52
  }
50
53
  });
51
54
  } else if (action === 'bulk_unpublish') {
52
55
  sanitizedData.forEach((entry) => {
53
- console.log(chalk.green(`Entry UID '${entry.uid}' of CT '${entry.content_type}' in locale '${entry.locale}'`));
56
+ console.log(chalk.green(`Entry UID: '${entry.uid}', Content Type: '${entry.content_type}', Locale: '${entry.locale}'`));
54
57
  });
55
58
  }
56
59
  }
@@ -62,9 +65,9 @@ function displayAssetsDetails(sanitizedData, action, mapping) {
62
65
  if (Object.keys(mapping).includes(pd.environment)) {
63
66
  console.log(
64
67
  chalk.green(
65
- `Asset UID '${asset.uid}' ${pd.version ? `and version '${pd.version}'` : ''} ${
66
- asset.locale ? `in locale '${asset.locale}'` : ''
67
- } in environment ${pd.environment}`,
68
+ `Asset UID: '${asset.uid}'${pd.version ? `, Version: '${pd.version}'` : ''}${
69
+ asset.locale ? `, Locale: '${asset.locale}'` : ''
70
+ }, Environment: ${pd.environment}`,
68
71
  ),
69
72
  );
70
73
  }
@@ -74,8 +77,8 @@ function displayAssetsDetails(sanitizedData, action, mapping) {
74
77
  sanitizedData.forEach((asset) => {
75
78
  console.log(
76
79
  chalk.green(
77
- `Asset UID '${asset.uid}' ${asset.version ? `and version '${asset.version}'` : ''} ${
78
- asset.locale ? `in locale '${asset.locale}'` : ''
80
+ `Asset UID: '${asset.uid}'${asset.version ? `, Version: '${asset.version}'` : ''}${
81
+ asset.locale ? `, Locale: '${asset.locale}'` : ''
79
82
  }`,
80
83
  ),
81
84
  );
@@ -98,7 +101,7 @@ async function publishEntry(data, _config, queue) {
98
101
  if (!publishEntryResponse.error_message) {
99
102
  console.log(
100
103
  chalk.green(
101
- `entry published with ContentType uid=${entryObj.content_type} Entry uid=${entryObj.entryUid} locale=${entryObj.locale}`,
104
+ `Entry published. Content Type UID: ${entryObj.content_type}, Entry UID: ${entryObj.entryUid}, Locale: ${entryObj.locale}`,
102
105
  ),
103
106
  );
104
107
  delete entryObj.stack;
@@ -119,9 +122,9 @@ async function publishEntry(data, _config, queue) {
119
122
  delete entryObj.stack;
120
123
  console.log(
121
124
  chalk.red(
122
- `entry could not be published with ContentType uid=${entryObj.content_type} entry uid=${
125
+ `Entry could not be published. Content Type UID: ${entryObj.content_type}, Entry UID: ${
123
126
  entryObj.entryUid
124
- } locale=${entryObj.locale} error=${formatError(error)}`,
127
+ }, Locale: ${entryObj.locale}, Error: ${formatError(error)}`,
125
128
  ),
126
129
  );
127
130
  addLogs(
@@ -147,7 +150,7 @@ async function publishAsset(data, _config, queue) {
147
150
  .publish({ publishDetails: { environments: assetobj.environments, locales: [assetobj.locale || 'en-us'] } })
148
151
  .then((publishAssetResponse) => {
149
152
  if (!publishAssetResponse.error_message) {
150
- console.log(chalk.green(`asset published with Asset uid=${assetobj.assetUid}, locale=${assetobj.locale}`));
153
+ console.log(chalk.green(`Asset published. Asset UID: ${assetobj.assetUid}, Locale: ${assetobj.locale}`));
151
154
  delete assetobj.stack;
152
155
  addLogs(
153
156
  logger,
@@ -164,7 +167,7 @@ async function publishAsset(data, _config, queue) {
164
167
  queue.Enqueue(data);
165
168
  } else {
166
169
  delete assetobj.stack;
167
- console.log(chalk.red(`Could not publish because of Error=${formatError(error)}`));
170
+ console.log(chalk.red(`Could not publish. Error: ${formatError(error)}`));
168
171
  addLogs(
169
172
  logger,
170
173
  {
@@ -193,7 +196,7 @@ async function UnpublishEntry(data, _config, queue) {
193
196
  delete entryObj.stack;
194
197
  console.log(
195
198
  chalk.green(
196
- `Entry unpublished with ContentType uid=${entryObj.content_type} Entry uid=${entryObj.entryUid} locale=${entryObj.locale}`,
199
+ `Entry unpublished. Content Type UID: ${entryObj.content_type}, Entry UID: ${entryObj.entryUid}, Locale: ${entryObj.locale}`,
197
200
  ),
198
201
  );
199
202
  addLogs(
@@ -213,9 +216,9 @@ async function UnpublishEntry(data, _config, queue) {
213
216
  delete entryObj.stack;
214
217
  console.log(
215
218
  chalk.red(
216
- `Entry could not be unpublished with ContentType uid=${entryObj.content_type} Entry uid=${
219
+ `Entry could not be unpublished. Content Type UID: ${entryObj.content_type}, Entry UID: ${
217
220
  entryObj.entryUid
218
- } locale=${entryObj.locale} error=${formatError(error)}`,
221
+ }, Locale: ${entryObj.locale}, Error: ${formatError(error)}`,
219
222
  ),
220
223
  );
221
224
  addLogs(
@@ -237,7 +240,7 @@ async function UnpublishAsset(data, _config, queue) {
237
240
  .then((unpublishAssetResponse) => {
238
241
  if (!unpublishAssetResponse.error_message) {
239
242
  delete assetobj.stack;
240
- console.log(`Asset unpublished with Asset uid=${assetobj.assetUid}`);
243
+ console.log(`The asset with UID '${assetobj.assetUid}' has been unpublished.`);
241
244
  addLogs(
242
245
  logger,
243
246
  { options: assetobj, api_key: stack.stackHeaders.api_key, alias: stack.alias, host: stack.host },
@@ -253,7 +256,7 @@ async function UnpublishAsset(data, _config, queue) {
253
256
  queue.Enqueue(data);
254
257
  } else {
255
258
  delete assetobj.stack;
256
- console.log(chalk.red(`Could not Unpublish because of error=${formatError(error)}`));
259
+ console.log(chalk.red(`Could not unpublish. Error: ${formatError(error)}`));
257
260
  addLogs(
258
261
  logger,
259
262
  { options: assetobj, api_key: stack.stackHeaders.api_key, alias: stack.alias, host: stack.host },
@@ -330,7 +333,7 @@ async function performBulkPublish(data, _config, queue) {
330
333
  queue.Enqueue(data);
331
334
  } else {
332
335
  delete bulkPublishObj.stack;
333
- console.log(chalk.red(`Bulk entries failed to publish with error ${formatError(error)}`));
336
+ console.log(chalk.red(`Bulk entries failed to publish. Error: ${formatError(error)}`));
334
337
  displayEntriesDetails(bulkPublishObj.entries, 'bulk_publish', mapping);
335
338
  addLogs(
336
339
  logger,
@@ -385,7 +388,7 @@ async function performBulkPublish(data, _config, queue) {
385
388
  queue.Enqueue(data);
386
389
  } else {
387
390
  delete bulkPublishObj.stack;
388
- console.log(chalk.red(`Bulk assets failed to publish with error ${formatError(error)}`));
391
+ console.log(chalk.red(`Bulk assets failed to publish. Error: ${formatError(error)}`));
389
392
 
390
393
  displayAssetsDetails(sanitizedData, 'bulk_publish', mapping);
391
394
  addLogs(
@@ -397,7 +400,7 @@ async function performBulkPublish(data, _config, queue) {
397
400
  });
398
401
  break;
399
402
  default:
400
- console.log('No such type');
403
+ console.log('No such type found. If it is for a content type, use "No such content type found."');
401
404
  }
402
405
  }
403
406
 
@@ -455,7 +458,7 @@ async function performBulkUnPublish(data, _config, queue) {
455
458
  queue.Enqueue(data);
456
459
  } else {
457
460
  delete bulkUnPublishObj.stack;
458
- console.log(chalk.red(`Bulk entries failed to Unpublish with error ${formatError(error)}`));
461
+ console.log(chalk.red(`Bulk entries failed to unpublish. Error: ${formatError(error)}`));
459
462
  displayEntriesDetails(bulkUnPublishObj.entries, 'bulk_unpublish');
460
463
  addLogs(
461
464
  logger,
@@ -510,7 +513,7 @@ async function performBulkUnPublish(data, _config, queue) {
510
513
  queue.Enqueue(data);
511
514
  } else {
512
515
  delete bulkUnPublishObj.stack;
513
- console.log(chalk.red(`Bulk assets failed to Unpublish with error ${formatError(error)}`));
516
+ console.log(chalk.red(`Bulk assets failed to unpublish. Error: ${formatError(error)}`));
514
517
  displayAssetsDetails(bulkUnPublishObj.assets, 'bulk_unpublish');
515
518
  addLogs(
516
519
  logger,
@@ -643,7 +646,7 @@ async function publishUsingVersion(data, _config, queue) {
643
646
  }
644
647
  }
645
648
 
646
- console.log(chalk.red(`Entry=${entry.uid} failed to publish with error ${formatError(error)}`));
649
+ console.log(chalk.red(`Entry '${entry.uid}' failed to publish. Error: ${formatError(error)}`));
647
650
  }
648
651
  });
649
652
  });
@@ -62,6 +62,124 @@ function removeUnwanted(entry, unwantedkeys) {
62
62
  return entry;
63
63
  }
64
64
 
65
+ function isLinkObject(obj, keyName) {
66
+ if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) {
67
+ return false;
68
+ }
69
+
70
+ const linkKeyNames = ['link', 'card_link'];
71
+ if (linkKeyNames.includes(keyName)) {
72
+ return true;
73
+ }
74
+
75
+ const hasTitle = 'title' in obj && obj.title !== undefined;
76
+ const hasUrl = 'url' in obj && obj.url !== undefined;
77
+ const hasHref = 'href' in obj && obj.href !== undefined;
78
+
79
+ return hasTitle && (hasUrl || hasHref);
80
+ }
81
+
82
+ function ensureHrefIsString(linkObj) {
83
+ if (linkObj.href === undefined || linkObj.href === null) {
84
+ linkObj.href = '';
85
+ } else if (typeof linkObj.href !== 'string') {
86
+ linkObj.href = String(linkObj.href);
87
+ }
88
+ }
89
+
90
+ function isValidJsonRte(obj) {
91
+ return obj !== null &&
92
+ typeof obj === 'object' &&
93
+ !Array.isArray(obj) &&
94
+ typeof obj.type === 'string' &&
95
+ obj.type !== '';
96
+ }
97
+
98
+ function cleanJsonFields(obj) {
99
+ if (obj === null || obj === undefined || typeof obj !== 'object') {
100
+ return obj;
101
+ }
102
+
103
+ if (Array.isArray(obj)) {
104
+ return obj.map((item) => cleanJsonFields(item));
105
+ }
106
+
107
+ const cleaned = {};
108
+ for (const key in obj) {
109
+ if (!obj.hasOwnProperty(key)) {
110
+ continue;
111
+ }
112
+ let value = obj[key];
113
+ const isJsonField = key.endsWith('_rte') || key === 'json_rte';
114
+ const isAccessibilityField = key.endsWith('_accessibility') || key === 'image_preset_accessibility';
115
+
116
+ if (isJsonField) {
117
+ if (value === '' || value === null || value === undefined) {
118
+ continue;
119
+ }
120
+ if (typeof value === 'object' && !Array.isArray(value)) {
121
+ const keyCount = Object.keys(value).length;
122
+ if (keyCount === 0) {
123
+ continue;
124
+ }
125
+ if (!isValidJsonRte(value)) {
126
+ continue;
127
+ }
128
+ cleaned[key] = value;
129
+ } else {
130
+ continue;
131
+ }
132
+ } else if (isAccessibilityField && value === '') {
133
+ cleaned[key] = {};
134
+ } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
135
+ value = cleanJsonFields(value);
136
+ if (value !== null && typeof value === 'object') {
137
+ cleaned[key] = value;
138
+ }
139
+ } else {
140
+ cleaned[key] = value;
141
+ }
142
+ }
143
+ return cleaned;
144
+ }
145
+
146
+ function convertUrlToHref(obj) {
147
+ if (obj === null || obj === undefined) {
148
+ return obj;
149
+ }
150
+
151
+ if (Array.isArray(obj)) {
152
+ return obj.map((item) => convertUrlToHref(item));
153
+ }
154
+
155
+ if (typeof obj === 'object') {
156
+ const converted = {};
157
+ for (const key in obj) {
158
+ const value = obj[key];
159
+
160
+ if (isLinkObject(value, key)) {
161
+ converted[key] = { ...value };
162
+ if (converted[key].url !== undefined && converted[key].href === undefined) {
163
+ if (typeof converted[key].url === 'string') {
164
+ converted[key].href = converted[key].url;
165
+ } else if (converted[key].url === null || converted[key].url === undefined) {
166
+ converted[key].href = '';
167
+ } else {
168
+ converted[key].href = String(converted[key].url);
169
+ }
170
+ delete converted[key].url;
171
+ }
172
+ ensureHrefIsString(converted[key]);
173
+ } else {
174
+ converted[key] = convertUrlToHref(value);
175
+ }
176
+ }
177
+ return converted;
178
+ }
179
+
180
+ return obj;
181
+ }
182
+
65
183
  function fileFields(entry, uid, multiple) {
66
184
  if (entry[uid]) {
67
185
  if (typeof entry[uid] === 'object' || Array.isArray(entry[uid])) {
@@ -106,6 +224,11 @@ function addFields(contentType, entry) {
106
224
  }
107
225
  } else if (schema.enum) {
108
226
  entry[schema.uid] = null;
227
+ } else if (schema.data_type === 'json') {
228
+ const isJsonRteField = schema.uid && (schema.uid.endsWith('_rte') || schema.uid === 'json_rte');
229
+ if (!isJsonRteField) {
230
+ entry[schema.uid] = {};
231
+ }
109
232
  } else if (Object.prototype.hasOwnProperty.call(defaults, schema.data_type)) {
110
233
  entry[schema.uid] = defaults[schema.data_type];
111
234
  } else {
@@ -126,19 +249,31 @@ function addFields(contentType, entry) {
126
249
 
127
250
  if (schema.data_type === 'group' && !schema.multiple) {
128
251
  addFields(schema.schema, entry[schema.uid]);
252
+ if (entry[schema.uid]) {
253
+ entry[schema.uid] = convertUrlToHref(entry[schema.uid]);
254
+ }
129
255
  }
130
256
  if (schema.data_type === 'group' && schema.multiple) {
131
257
  entry[schema.uid].forEach((field) => {
132
258
  addFields(schema.schema, field);
133
259
  });
260
+ if (entry[schema.uid]) {
261
+ entry[schema.uid] = convertUrlToHref(entry[schema.uid]);
262
+ }
134
263
  }
135
264
  if (schema.data_type === 'global_field' && !schema.multiple) {
136
265
  addFields(schema.schema, entry[schema.uid]);
266
+ if (entry[schema.uid]) {
267
+ entry[schema.uid] = convertUrlToHref(entry[schema.uid]);
268
+ }
137
269
  }
138
270
  if (schema.data_type === 'global_field' && schema.multiple) {
139
271
  entry[schema.uid].forEach((field) => {
140
272
  addFields(schema.schema, field);
141
273
  });
274
+ if (entry[schema.uid]) {
275
+ entry[schema.uid] = convertUrlToHref(entry[schema.uid]);
276
+ }
142
277
  }
143
278
  if (schema.data_type === 'blocks') {
144
279
  if (!entry[schema.uid] && !Array.isArray(entry[schema.uid])) {
@@ -156,6 +291,9 @@ function addFields(contentType, entry) {
156
291
  if (filterBlockFields.length > 0) {
157
292
  filterBlockFields.forEach((bfield) => {
158
293
  addFields(block.schema, bfield[block.uid]);
294
+ if (bfield[block.uid]) {
295
+ bfield[block.uid] = convertUrlToHref(bfield[block.uid]);
296
+ }
159
297
  });
160
298
  } else {
161
299
  entry[schema.uid].push({ [block.uid]: {} });
@@ -169,6 +307,9 @@ function addFields(contentType, entry) {
169
307
  if (filterBlockFields.length > 0) {
170
308
  filterBlockFields.forEach((bfield) => {
171
309
  addFields(block.schema, bfield[block.uid]);
310
+ if (bfield[block.uid]) {
311
+ bfield[block.uid] = convertUrlToHref(bfield[block.uid]);
312
+ }
172
313
  });
173
314
  }
174
315
  }
@@ -221,8 +362,14 @@ async function getEntries(
221
362
  for (let index = 0; index < entriesResponse.items.length; index++) {
222
363
  let updatedEntry = addFields(schema, entries[index]);
223
364
  if (updatedEntry.changedFlag || forceUpdate) {
224
- updatedEntry = removeUnwanted(entries[index], deleteFields);
225
- const flag = await updateEntry(updatedEntry, locale);
365
+ let entryData = JSON.parse(JSON.stringify(updatedEntry.entry));
366
+ entryData = removeUnwanted(entryData, deleteFields);
367
+ entryData = cleanJsonFields(entryData);
368
+ entryData = convertUrlToHref(entryData);
369
+ entryData = cleanJsonFields(entryData);
370
+ const entry = stack.contentType(contentType).entry(entries[index].uid);
371
+ Object.assign(entry, entryData);
372
+ const flag = await updateEntry(entry, locale);
226
373
  if (flag) {
227
374
  if (bulkPublish) {
228
375
  if (bulkPublishSet.length < bulkPublishLimit) {
@@ -256,10 +403,10 @@ async function getEntries(
256
403
  });
257
404
  }
258
405
  } else {
259
- console.log(`Update Failed for entryUid ${entries[index].uid} with contentType ${contentType}`);
406
+ console.log(`Update failed for entry UID '${entries[index].uid}' of content type '${contentType}'.`);
260
407
  }
261
408
  } else {
262
- console.log(`No change Observed for contentType ${contentType} with entry ${entries[index].uid}`);
409
+ console.log(`No changes detected for content type '${contentType}' and entry UID '${entries[index].uid}'.`);
263
410
  }
264
411
 
265
412
  if (index === entriesResponse.items.length - 1 && bulkPublishSet.length > 0 && bulkPublishSet.length < bulkPublishLimit) {
@@ -342,19 +489,17 @@ async function start(
342
489
  bulkPublishLimit
343
490
  );
344
491
  } catch (err) {
345
- console.log(`Failed to get Entries with contentType ${contentTypes[i]} and locale ${locales[j]}`);
492
+ console.log(`Failed to retrieve entries for content type '${contentTypes[i]}' and locale '${locales[j]}'.`);
346
493
  }
347
494
  }
348
495
  })
349
496
  .catch((err) => {
350
- console.log(`Failed to fetch schema${JSON.stringify(err)}`);
497
+ console.log(`Failed to fetch schema: ${JSON.stringify(err)}`);
351
498
  });
352
499
  }
353
500
  }
354
501
  }
355
502
 
356
- // start()
357
-
358
503
  module.exports = {
359
504
  start,
360
505
  getContentTypeSchema,
@@ -225,7 +225,7 @@ async function getSyncEntries(
225
225
  await bulkAction(stack, entriesResponse.items, bulkPublish, filter, destEnv, apiVersion, bulkPublishLimit, variantsFlag);
226
226
  }
227
227
  if (!entriesResponse.pagination_token) {
228
- if (!changedFlag) console.log('No Entries/Assets Found published on specified environment');
228
+ if (!changedFlag) console.log('No entries or assets found published in the specified environment.');
229
229
  return resolve();
230
230
  }
231
231
  setTimeout(async () => {
@@ -107,7 +107,7 @@ async function getEntries(stack, contentType, environmentUid, locale, bulkPublis
107
107
  }
108
108
  if (responseEntries.count === skipCount) {
109
109
  if (!changedFlag)
110
- console.log(`No Edits Were observed on specified Environment for contentType ${contentType}`);
110
+ console.log(`No edits were detected in the specified environment for content type ${contentType}`);
111
111
  bulkPublishSet = [];
112
112
  return resolve();
113
113
  }
@@ -122,7 +122,7 @@ async function getEntries(stack, contentType, environmentUid, locale, bulkPublis
122
122
  }
123
123
  }
124
124
  if (responseEntries.count === skipCount) {
125
- if (!changedFlag) console.log(`No Draft Entries of contentType ${contentType} was found`);
125
+ if (!changedFlag) console.log(`No draft entries found for content type ${contentType}`);
126
126
  bulkPublishSet = [];
127
127
  return resolve();
128
128
  }
@@ -229,7 +229,7 @@ async function getSyncEntries(
229
229
  await bulkAction(stack, entriesResponse.items, bulkUnpublish, environment, locale, apiVersion, bulkPublishLimit, false);
230
230
  }
231
231
  if (entriesResponse.items.length === 0 && !entriesResponse.pagination_token) {
232
- if (!changedFlag) console.log('No Entries/Assets Found published on specified environment');
232
+ if (!changedFlag) console.log('No entries or assets found published in the specified environment.');
233
233
  return resolve();
234
234
  }
235
235
 
package/src/util/index.js CHANGED
@@ -2,7 +2,7 @@ const chalk = require('chalk');
2
2
  const fs = require('fs');
3
3
 
4
4
  function prettyPrint(data) {
5
- console.log(chalk.yellow('Configuration to be used for executing this command:'));
5
+ console.log(chalk.yellow('Configuration to use for executing this command:'));
6
6
  Object.keys(data).forEach((key, _index) => {
7
7
  console.log(chalk.grey(`${key}: ${data[key]}`));
8
8
  });
@@ -47,7 +47,7 @@ module.exports.addLogs = (logger, data, Type) => {
47
47
  logger.info(data);
48
48
  break;
49
49
  default:
50
- console.log('Unknown logging level');
50
+ console.log('Unknown log level.');
51
51
  }
52
52
  };
53
53
 
package/src/util/store.js CHANGED
@@ -12,7 +12,7 @@ function save(key, data) {
12
12
  console.log(chalk.red(error));
13
13
  return;
14
14
  }
15
- console.log(chalk.green(`Configuration file has been successfully created at ${filePath}`));
15
+ console.log(chalk.green(`Configuration file successfully created at '${filePath}'.`));
16
16
  });
17
17
  }
18
18
 
@@ -53,7 +53,7 @@ function updateMissing(key, flags) {
53
53
  savedConfig = get(key, pathValidator(flags.config));
54
54
  Object.keys(savedConfig).forEach((element) => {
55
55
  if (flags[element] === undefined) {
56
- console.log(`Using ${element} from config file`);
56
+ console.log(`Using '${element}' from the configuration file.`);
57
57
  flags[element] = savedConfig[element];
58
58
  }
59
59
  });