@contentstack/cli-cm-bulk-publish 0.1.1-beta.3 → 1.0.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.
- package/LICENSE +21 -0
- package/README.md +533 -281
- package/oclif.manifest.json +1 -1
- package/package.json +27 -12
- package/src/commands/cm/assets/publish.js +233 -0
- package/src/commands/cm/assets/unpublish.js +179 -0
- package/src/commands/cm/bulk-publish/cross-publish.js +187 -68
- package/src/commands/cm/bulk-publish/index.js +5 -6
- package/src/commands/cm/entries/publish-modified.js +197 -0
- package/src/commands/cm/entries/publish-non-localized-fields.js +208 -0
- package/src/commands/cm/entries/publish-only-unpublished.js +109 -0
- package/src/commands/cm/entries/publish.js +254 -0
- package/src/commands/cm/entries/unpublish.js +184 -0
- package/src/commands/cm/entries/update-and-publish.js +191 -0
- package/src/commands/cm/stacks/publish-clear-logs.js +82 -0
- package/src/commands/cm/stacks/publish-configure.js +46 -0
- package/src/commands/cm/stacks/publish-revert.js +102 -0
- package/src/commands/cm/stacks/publish.js +110 -0
- package/src/commands/cm/stacks/unpublish.js +282 -0
- package/src/config/index.js +60 -99
- package/src/consumer/publish.js +600 -377
- package/src/producer/add-fields.js +209 -189
- package/src/producer/cross-publish.js +195 -136
- package/src/producer/nonlocalized-field-changes.js +235 -216
- package/src/producer/publish-assets.js +104 -98
- package/src/producer/publish-edits.js +126 -113
- package/src/producer/publish-entries.js +135 -112
- package/src/producer/publish-unpublished-env.js +126 -114
- package/src/producer/revert.js +261 -230
- package/src/producer/unpublish.js +175 -137
- package/src/services/publish-only-unpublished.js +130 -0
- package/src/util/client.js +21 -17
- package/src/util/command-helper.js +25 -0
- package/src/util/fs.js +10 -11
- package/src/util/index.js +15 -16
- package/src/util/logger.js +21 -25
- package/src/util/queue.js +13 -13
- package/src/util/retryfailed.js +8 -4
- package/src/util/store.js +44 -52
- package/src/commands/cm/bulk-publish/add-fields.js +0 -117
- package/src/commands/cm/bulk-publish/assets.js +0 -117
- package/src/commands/cm/bulk-publish/clear.js +0 -63
- package/src/commands/cm/bulk-publish/configure.js +0 -46
- package/src/commands/cm/bulk-publish/entries.js +0 -125
- package/src/commands/cm/bulk-publish/entry-edits.js +0 -123
- package/src/commands/cm/bulk-publish/nonlocalized-field-changes.js +0 -116
- package/src/commands/cm/bulk-publish/revert.js +0 -81
- package/src/commands/cm/bulk-publish/unpublish.js +0 -164
- package/src/commands/cm/bulk-publish/unpublished-entries.js +0 -122
- package/src/util/request.js +0 -57
|
@@ -3,63 +3,48 @@
|
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable complexity */
|
|
5
5
|
/* eslint-disable max-params */
|
|
6
|
-
const {getQueue} = require('../util/queue')
|
|
7
|
-
const defaults = require('../config/defaults.json')
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let
|
|
23
|
-
let bulkPublishAssetSet = []
|
|
24
|
-
let changedFlag = false
|
|
25
|
-
let logFileName
|
|
26
|
-
let filePath
|
|
6
|
+
const { getQueue } = require('../util/queue');
|
|
7
|
+
const defaults = require('../config/defaults.json');
|
|
8
|
+
const { performBulkPublish, publishEntry, publishAsset, initializeLogger } = require('../consumer/publish');
|
|
9
|
+
const retryFailedLogs = require('../util/retryfailed');
|
|
10
|
+
const { validateFile } = require('../util/fs');
|
|
11
|
+
const queue = getQueue();
|
|
12
|
+
const entryQueue = getQueue();
|
|
13
|
+
const assetQueue = getQueue();
|
|
14
|
+
const { Command } = require('@contentstack/cli-command');
|
|
15
|
+
const command = new Command();
|
|
16
|
+
const { isEmpty } = require('../util');
|
|
17
|
+
|
|
18
|
+
let bulkPublishSet = [];
|
|
19
|
+
let bulkPublishAssetSet = [];
|
|
20
|
+
let changedFlag = false;
|
|
21
|
+
let logFileName;
|
|
22
|
+
let filePath;
|
|
27
23
|
|
|
28
24
|
function getQueryParams(filter) {
|
|
29
|
-
let queryString = ''
|
|
30
|
-
Object.keys(filter).forEach(key => {
|
|
25
|
+
let queryString = '';
|
|
26
|
+
Object.keys(filter).forEach((key) => {
|
|
31
27
|
if (filter[key]) {
|
|
32
|
-
queryString = `${queryString}&${key}=${filter[key]}
|
|
28
|
+
queryString = `${queryString}&${key}=${filter[key]}`;
|
|
33
29
|
}
|
|
34
|
-
})
|
|
30
|
+
});
|
|
35
31
|
|
|
36
|
-
return queryString
|
|
32
|
+
return queryString;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
async function bulkAction(stack, items, bulkPublish, filter, destEnv) {
|
|
40
|
-
return new Promise(async resolve => {
|
|
36
|
+
return new Promise(async (resolve) => {
|
|
41
37
|
for (let index = 0; index < items.length; index++) {
|
|
42
|
-
changedFlag = true
|
|
43
|
-
|
|
44
|
-
if (!items[index].data.publish_details) {
|
|
45
|
-
// adding this condition because sometimes
|
|
46
|
-
// item.data.publish_details.locale failes because publish_details is undefined
|
|
47
|
-
items[index].data.publish_details = {}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (items[index].data.publish_details) {
|
|
51
|
-
items[index].data.publish_details.version = items[index].data._version
|
|
52
|
-
}
|
|
38
|
+
changedFlag = true;
|
|
53
39
|
|
|
54
40
|
if (bulkPublish) {
|
|
55
41
|
if (bulkPublishSet.length < 10 && items[index].type === 'entry_published') {
|
|
56
42
|
bulkPublishSet.push({
|
|
57
43
|
uid: items[index].data.uid,
|
|
58
44
|
content_type: items[index].content_type_uid,
|
|
59
|
-
locale: items[index].data.
|
|
60
|
-
version: items[index].data._version,
|
|
45
|
+
locale: items[index].data.locale || 'en-us',
|
|
61
46
|
publish_details: [items[index].data.publish_details] || [],
|
|
62
|
-
})
|
|
47
|
+
});
|
|
63
48
|
}
|
|
64
49
|
|
|
65
50
|
if (bulkPublishAssetSet.length < 10 && items[index].type === 'asset_published') {
|
|
@@ -67,155 +52,229 @@ async function bulkAction(stack, items, bulkPublish, filter, destEnv) {
|
|
|
67
52
|
uid: items[index].data.uid,
|
|
68
53
|
version: items[index].data._version,
|
|
69
54
|
publish_details: [items[index].data.publish_details] || [],
|
|
70
|
-
})
|
|
55
|
+
});
|
|
71
56
|
}
|
|
72
57
|
|
|
73
58
|
if (bulkPublishAssetSet.length === 10) {
|
|
74
59
|
await queue.Enqueue({
|
|
75
|
-
assets: bulkPublishAssetSet,
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
assets: bulkPublishAssetSet,
|
|
61
|
+
Type: 'asset',
|
|
62
|
+
locale: filter.locale,
|
|
63
|
+
environments: destEnv,
|
|
64
|
+
stack: stack,
|
|
65
|
+
});
|
|
66
|
+
bulkPublishAssetSet = [];
|
|
78
67
|
}
|
|
79
68
|
|
|
80
69
|
if (bulkPublishSet.length === 10) {
|
|
81
70
|
await queue.Enqueue({
|
|
82
|
-
entries: bulkPublishSet,
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
entries: bulkPublishSet,
|
|
72
|
+
locale: filter.locale,
|
|
73
|
+
Type: 'entry',
|
|
74
|
+
environments: destEnv,
|
|
75
|
+
stack: stack,
|
|
76
|
+
});
|
|
77
|
+
bulkPublishSet = [];
|
|
85
78
|
}
|
|
86
79
|
|
|
87
80
|
if (index === items.length - 1 && bulkPublishAssetSet.length <= 10 && bulkPublishAssetSet.length > 0) {
|
|
88
81
|
await queue.Enqueue({
|
|
89
|
-
assets: bulkPublishAssetSet,
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
assets: bulkPublishAssetSet,
|
|
83
|
+
Type: 'asset',
|
|
84
|
+
locale: filter.locale,
|
|
85
|
+
environments: destEnv,
|
|
86
|
+
stack: stack,
|
|
87
|
+
});
|
|
88
|
+
bulkPublishAssetSet = [];
|
|
92
89
|
}
|
|
93
90
|
|
|
94
91
|
if (index === items.length - 1 && bulkPublishSet.length <= 10 && bulkPublishSet.length > 0) {
|
|
95
92
|
await queue.Enqueue({
|
|
96
|
-
entries: bulkPublishSet,
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
entries: bulkPublishSet,
|
|
94
|
+
locale: filter.locale,
|
|
95
|
+
Type: 'entry',
|
|
96
|
+
environments: destEnv,
|
|
97
|
+
stack: stack,
|
|
98
|
+
});
|
|
99
|
+
bulkPublishSet = [];
|
|
99
100
|
}
|
|
100
101
|
} else {
|
|
101
102
|
if (items[index].type === 'entry_published') {
|
|
102
103
|
await entryQueue.Enqueue({
|
|
103
|
-
content_type: items[index].content_type_uid,
|
|
104
|
-
|
|
104
|
+
content_type: items[index].content_type_uid,
|
|
105
|
+
publish_details: [items[index].data.publish_details],
|
|
106
|
+
environments: destEnv,
|
|
107
|
+
entryUid: items[index].data.uid,
|
|
108
|
+
locale: items[index].data.locale || 'en-us',
|
|
109
|
+
Type: 'entry',
|
|
110
|
+
stack: stack,
|
|
111
|
+
});
|
|
105
112
|
}
|
|
106
113
|
if (items[index].type === 'asset_published') {
|
|
107
114
|
await assetQueue.Enqueue({
|
|
108
|
-
assetUid: items[index].data.uid,
|
|
109
|
-
|
|
115
|
+
assetUid: items[index].data.uid,
|
|
116
|
+
publish_details: [items[index].data.publish_details],
|
|
117
|
+
environments: destEnv,
|
|
118
|
+
Type: 'asset',
|
|
119
|
+
stack: stack,
|
|
120
|
+
});
|
|
110
121
|
}
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
|
-
return resolve()
|
|
114
|
-
})
|
|
124
|
+
return resolve();
|
|
125
|
+
});
|
|
115
126
|
}
|
|
116
127
|
|
|
117
|
-
async function getSyncEntries(
|
|
128
|
+
async function getSyncEntries(
|
|
129
|
+
stack,
|
|
130
|
+
config,
|
|
131
|
+
queryParams,
|
|
132
|
+
bulkPublish,
|
|
133
|
+
filter,
|
|
134
|
+
deliveryToken,
|
|
135
|
+
destEnv,
|
|
136
|
+
paginationToken = null,
|
|
137
|
+
) {
|
|
118
138
|
return new Promise(async (resolve, reject) => {
|
|
119
139
|
try {
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
140
|
+
const tokenDetails = command.getToken(config.alias);
|
|
141
|
+
const queryParamsObj = {};
|
|
142
|
+
const pairs = queryParams.split('&');
|
|
143
|
+
for (let i in pairs) {
|
|
144
|
+
const split = pairs[i].split('=');
|
|
145
|
+
queryParamsObj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const Stack = new command.deliveryAPIClient.Stack({
|
|
149
|
+
api_key: tokenDetails.apiKey,
|
|
150
|
+
delivery_token: deliveryToken,
|
|
151
|
+
environment: queryParamsObj.environment,
|
|
152
|
+
branch: config.branch,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const syncData = {};
|
|
156
|
+
|
|
157
|
+
if (paginationToken) {
|
|
158
|
+
syncData['pagination_token'] = paginationToken;
|
|
159
|
+
} else {
|
|
160
|
+
syncData['init'] = true;
|
|
127
161
|
}
|
|
128
|
-
|
|
162
|
+
if (queryParamsObj.locale) {
|
|
163
|
+
syncData['locale'] = queryParamsObj.locale;
|
|
164
|
+
}
|
|
165
|
+
if (queryParamsObj.type) {
|
|
166
|
+
syncData['type'] = queryParamsObj.type;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const entriesResponse = await Stack.sync(syncData);
|
|
170
|
+
|
|
129
171
|
if (entriesResponse.items.length > 0) {
|
|
130
|
-
await bulkAction(stack, entriesResponse.items, bulkPublish, filter, destEnv)
|
|
172
|
+
await bulkAction(stack, entriesResponse.items, bulkPublish, filter, destEnv);
|
|
131
173
|
}
|
|
132
174
|
if (!entriesResponse.pagination_token) {
|
|
133
|
-
if (!changedFlag) console.log('No Entries/Assets Found published on specified environment')
|
|
134
|
-
return resolve()
|
|
175
|
+
if (!changedFlag) console.log('No Entries/Assets Found published on specified environment');
|
|
176
|
+
return resolve();
|
|
135
177
|
}
|
|
136
178
|
setTimeout(async () => {
|
|
137
|
-
await getSyncEntries(
|
|
138
|
-
|
|
179
|
+
await getSyncEntries(
|
|
180
|
+
stack,
|
|
181
|
+
config,
|
|
182
|
+
queryParams,
|
|
183
|
+
bulkPublish,
|
|
184
|
+
filter,
|
|
185
|
+
deliveryToken,
|
|
186
|
+
destEnv,
|
|
187
|
+
entriesResponse.pagination_token,
|
|
188
|
+
);
|
|
189
|
+
}, 3000);
|
|
139
190
|
} catch (error) {
|
|
140
|
-
reject(error)
|
|
191
|
+
reject(error);
|
|
141
192
|
}
|
|
142
|
-
return resolve()
|
|
143
|
-
})
|
|
193
|
+
return resolve();
|
|
194
|
+
});
|
|
144
195
|
}
|
|
145
196
|
|
|
146
197
|
function setConfig(conf, bp) {
|
|
147
198
|
if (bp) {
|
|
148
|
-
logFileName = 'bulk-cross-publish'
|
|
149
|
-
queue.consumer =
|
|
199
|
+
logFileName = 'bulk-cross-publish';
|
|
200
|
+
queue.consumer = performBulkPublish;
|
|
150
201
|
} else {
|
|
151
|
-
logFileName = 'cross-publish'
|
|
152
|
-
entryQueue.consumer = publishEntry
|
|
153
|
-
assetQueue.consumer = publishAsset
|
|
202
|
+
logFileName = 'cross-publish';
|
|
203
|
+
entryQueue.consumer = publishEntry;
|
|
204
|
+
assetQueue.consumer = publishAsset;
|
|
154
205
|
}
|
|
155
206
|
|
|
156
|
-
queue.config = conf
|
|
157
|
-
entryQueue.config = conf
|
|
158
|
-
assetQueue.config = conf
|
|
159
|
-
filePath = initializeLogger(logFileName)
|
|
207
|
+
queue.config = conf;
|
|
208
|
+
entryQueue.config = conf;
|
|
209
|
+
assetQueue.config = conf;
|
|
210
|
+
filePath = initializeLogger(logFileName);
|
|
160
211
|
}
|
|
161
212
|
|
|
162
|
-
async function start(
|
|
213
|
+
async function start(
|
|
214
|
+
{
|
|
215
|
+
retryFailed,
|
|
216
|
+
bulkPublish,
|
|
217
|
+
_filter,
|
|
218
|
+
deliveryToken,
|
|
219
|
+
contentType,
|
|
220
|
+
environment,
|
|
221
|
+
locale,
|
|
222
|
+
onlyAssets,
|
|
223
|
+
onlyEntries,
|
|
224
|
+
destEnv,
|
|
225
|
+
f_types,
|
|
226
|
+
},
|
|
227
|
+
stack,
|
|
228
|
+
config,
|
|
229
|
+
) {
|
|
163
230
|
process.on('beforeExit', async () => {
|
|
164
|
-
const isErrorLogEmpty = await isEmpty(`${filePath}.error`)
|
|
165
|
-
const isSuccessLogEmpty = await isEmpty(`${filePath}.success`)
|
|
231
|
+
const isErrorLogEmpty = await isEmpty(`${filePath}.error`);
|
|
232
|
+
const isSuccessLogEmpty = await isEmpty(`${filePath}.success`);
|
|
166
233
|
if (!isErrorLogEmpty) {
|
|
167
|
-
console.log(`The error log for this session is stored at ${filePath}.error`)
|
|
234
|
+
console.log(`The error log for this session is stored at ${filePath}.error`);
|
|
168
235
|
} else if (!isSuccessLogEmpty) {
|
|
169
|
-
console.log(`The success log for this session is stored at ${filePath}.success`)
|
|
236
|
+
console.log(`The success log for this session is stored at ${filePath}.success`);
|
|
170
237
|
}
|
|
171
|
-
process.exit(0)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
if (retryFailed) {
|
|
176
|
-
if (typeof retryFailed === 'string' && retryFailed.length > 0) {
|
|
177
|
-
if (!validateFile(retryFailed, ['cross-publish', 'bulk-cross-publish'])) {
|
|
178
|
-
return false
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
bulkPublish = retryFailed.match(new RegExp('bulk')) ? true : false
|
|
182
|
-
setConfig(config, bulkPublish)
|
|
238
|
+
process.exit(0);
|
|
239
|
+
});
|
|
183
240
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
} else {
|
|
191
|
-
let filter = {
|
|
192
|
-
environment,
|
|
193
|
-
locale,
|
|
241
|
+
if (retryFailed) {
|
|
242
|
+
if (typeof retryFailed === 'string' && retryFailed.length > 0) {
|
|
243
|
+
if (!validateFile(retryFailed, ['cross-publish', 'bulk-cross-publish'])) {
|
|
244
|
+
return false;
|
|
194
245
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
filter.type = 'asset_published'
|
|
204
|
-
delete filter.content_type_uid
|
|
205
|
-
}
|
|
206
|
-
if (onlyEntries) {
|
|
207
|
-
filter.type = 'entry_published'
|
|
208
|
-
}
|
|
209
|
-
setConfig(config, bulkPublish)
|
|
210
|
-
const queryParams = getQueryParams(filter)
|
|
211
|
-
try {
|
|
212
|
-
await getSyncEntries(stack, config, queryParams, bulkPublish, filter, deliveryToken, destEnv)
|
|
213
|
-
} catch (error) {
|
|
214
|
-
throw error
|
|
246
|
+
|
|
247
|
+
bulkPublish = retryFailed.match(new RegExp('bulk')) ? true : false;
|
|
248
|
+
setConfig(config, bulkPublish);
|
|
249
|
+
|
|
250
|
+
if (bulkPublish) {
|
|
251
|
+
await retryFailedLogs(retryFailed, queue, 'bulk');
|
|
252
|
+
} else {
|
|
253
|
+
await retryFailedLogs(retryFailed, { entryQueue, assetQueue }, 'publish');
|
|
215
254
|
}
|
|
216
255
|
}
|
|
217
|
-
}
|
|
218
|
-
|
|
256
|
+
} else {
|
|
257
|
+
let filter = {
|
|
258
|
+
environment,
|
|
259
|
+
locale,
|
|
260
|
+
};
|
|
261
|
+
if (f_types) filter.type = f_types;
|
|
262
|
+
// filter.type = (f_types) ? f_types : types // types mentioned in the config file (f_types) are given preference
|
|
263
|
+
if (contentType) {
|
|
264
|
+
filter.content_type_uid = contentType;
|
|
265
|
+
filter.type = 'entry_published';
|
|
266
|
+
}
|
|
267
|
+
if (onlyAssets) {
|
|
268
|
+
filter.type = 'asset_published';
|
|
269
|
+
delete filter.content_type_uid;
|
|
270
|
+
}
|
|
271
|
+
if (onlyEntries) {
|
|
272
|
+
filter.type = 'entry_published';
|
|
273
|
+
}
|
|
274
|
+
setConfig(config, bulkPublish);
|
|
275
|
+
// filter.type = (f_types) ? f_types : types // types mentioned in the config file (f_types) are given preference
|
|
276
|
+
const queryParams = getQueryParams(filter);
|
|
277
|
+
await getSyncEntries(stack, config, queryParams, bulkPublish, filter, deliveryToken, destEnv);
|
|
219
278
|
}
|
|
220
279
|
}
|
|
221
280
|
|
|
@@ -224,4 +283,4 @@ module.exports = {
|
|
|
224
283
|
setConfig,
|
|
225
284
|
getQueryParams,
|
|
226
285
|
start,
|
|
227
|
-
}
|
|
286
|
+
};
|