@strapi/content-releases 0.0.0-next.37dd1e3ff22e1635b69683abadd444912ae0dbff → 0.0.0-next.6a58621932ad3d83bf9d6928c1871e7906adcd59
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/dist/_chunks/{App-J4jrthEu.mjs → App-L1jSxCiL.mjs} +81 -16
- package/dist/_chunks/App-L1jSxCiL.mjs.map +1 -0
- package/dist/_chunks/{App-5PRKHpa2.js → App-_20W9dYa.js} +79 -14
- package/dist/_chunks/App-_20W9dYa.js.map +1 -0
- package/dist/_chunks/{en-ngTk74JV.mjs → en-MyLPoISH.mjs} +2 -1
- package/dist/_chunks/en-MyLPoISH.mjs.map +1 -0
- package/dist/_chunks/{en-haKSQIo8.js → en-gYDqKYFd.js} +2 -1
- package/dist/_chunks/en-gYDqKYFd.js.map +1 -0
- package/dist/_chunks/{index-PEkKIRyJ.js → index-KJa1Rb5F.js} +91 -32
- package/dist/_chunks/index-KJa1Rb5F.js.map +1 -0
- package/dist/_chunks/{index-_Zsj8MUA.mjs → index-c4zRX_sg.mjs} +102 -43
- package/dist/_chunks/index-c4zRX_sg.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +3 -2
- package/dist/admin/index.mjs.map +1 -1
- package/dist/server/index.js +236 -128
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +236 -129
- package/dist/server/index.mjs.map +1 -1
- package/package.json +10 -9
- package/dist/_chunks/App-5PRKHpa2.js.map +0 -1
- package/dist/_chunks/App-J4jrthEu.mjs.map +0 -1
- package/dist/_chunks/en-haKSQIo8.js.map +0 -1
- package/dist/_chunks/en-ngTk74JV.mjs.map +0 -1
- package/dist/_chunks/index-PEkKIRyJ.js.map +0 -1
- package/dist/_chunks/index-_Zsj8MUA.mjs.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const utils = require("@strapi/utils");
|
|
3
|
+
const lodash = require("lodash");
|
|
3
4
|
const _ = require("lodash/fp");
|
|
5
|
+
const EE = require("@strapi/strapi/dist/utils/ee");
|
|
4
6
|
const yup = require("yup");
|
|
5
7
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
6
8
|
function _interopNamespace(e) {
|
|
@@ -22,6 +24,7 @@ function _interopNamespace(e) {
|
|
|
22
24
|
return Object.freeze(n);
|
|
23
25
|
}
|
|
24
26
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
|
27
|
+
const EE__default = /* @__PURE__ */ _interopDefault(EE);
|
|
25
28
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
|
26
29
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
27
30
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -69,40 +72,47 @@ const ACTIONS = [
|
|
|
69
72
|
pluginName: "content-releases"
|
|
70
73
|
}
|
|
71
74
|
];
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
async function deleteActionsOnDisableDraftAndPublish({
|
|
76
|
+
oldContentTypes,
|
|
77
|
+
contentTypes: contentTypes2
|
|
78
|
+
}) {
|
|
79
|
+
if (!oldContentTypes) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
for (const uid in contentTypes2) {
|
|
83
|
+
if (!oldContentTypes[uid]) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const oldContentType = oldContentTypes[uid];
|
|
87
|
+
const contentType = contentTypes2[uid];
|
|
88
|
+
if (utils.contentTypes.hasDraftAndPublish(oldContentType) && !utils.contentTypes.hasDraftAndPublish(contentType)) {
|
|
89
|
+
await strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: uid }).execute();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
94
|
+
const deletedContentTypes = lodash.difference(lodash.keys(oldContentTypes), lodash.keys(contentTypes2)) ?? [];
|
|
95
|
+
if (deletedContentTypes.length) {
|
|
96
|
+
await utils.mapAsync(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
97
|
+
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
75
101
|
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
76
102
|
const register = async ({ strapi: strapi2 }) => {
|
|
77
|
-
if (features$2.isEnabled("cms-content-releases")
|
|
103
|
+
if (features$2.isEnabled("cms-content-releases")) {
|
|
78
104
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const destroyContentTypeUpdateListener = strapi2.eventHub.on(
|
|
82
|
-
"content-type.update",
|
|
83
|
-
async ({ contentType }) => {
|
|
84
|
-
if (contentType.schema.options.draftAndPublish === false) {
|
|
85
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
);
|
|
89
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);
|
|
90
|
-
const destroyContentTypeDeleteListener = strapi2.eventHub.on(
|
|
91
|
-
"content-type.delete",
|
|
92
|
-
async ({ contentType }) => {
|
|
93
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
94
|
-
}
|
|
95
|
-
);
|
|
96
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);
|
|
105
|
+
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish);
|
|
106
|
+
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType);
|
|
97
107
|
}
|
|
98
108
|
};
|
|
99
109
|
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
100
110
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
101
|
-
if (features$1.isEnabled("cms-content-releases")
|
|
111
|
+
if (features$1.isEnabled("cms-content-releases")) {
|
|
102
112
|
strapi2.db.lifecycles.subscribe({
|
|
103
113
|
afterDelete(event) {
|
|
104
114
|
const { model, result } = event;
|
|
105
|
-
if (model.kind === "collectionType" && model.options
|
|
115
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
106
116
|
const { id } = result;
|
|
107
117
|
strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
108
118
|
where: {
|
|
@@ -118,7 +128,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
118
128
|
*/
|
|
119
129
|
async beforeDeleteMany(event) {
|
|
120
130
|
const { model, params } = event;
|
|
121
|
-
if (model.kind === "collectionType" && model.options
|
|
131
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
122
132
|
const { where } = params;
|
|
123
133
|
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
124
134
|
event.state.entriesToDelete = entriesToDelete;
|
|
@@ -233,30 +243,32 @@ const contentTypes = {
|
|
|
233
243
|
release: release$1,
|
|
234
244
|
"release-action": releaseAction$1
|
|
235
245
|
};
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
where: {
|
|
240
|
-
target_type: contentTypeUid
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
});
|
|
246
|
+
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
247
|
+
return strapi2.plugin("content-releases").service(name);
|
|
248
|
+
};
|
|
245
249
|
const getGroupName = (queryValue) => {
|
|
246
250
|
switch (queryValue) {
|
|
247
251
|
case "contentType":
|
|
248
|
-
return "
|
|
252
|
+
return "contentType.displayName";
|
|
249
253
|
case "action":
|
|
250
254
|
return "type";
|
|
251
255
|
case "locale":
|
|
252
|
-
return ___default.default.getOr("No locale", "
|
|
256
|
+
return ___default.default.getOr("No locale", "locale.name");
|
|
253
257
|
default:
|
|
254
|
-
return "
|
|
258
|
+
return "contentType.displayName";
|
|
255
259
|
}
|
|
256
260
|
};
|
|
257
261
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
258
262
|
async create(releaseData, { user }) {
|
|
259
263
|
const releaseWithCreatorFields = await utils.setCreatorFields({ user })(releaseData);
|
|
264
|
+
const { validatePendingReleasesLimit, validateUniqueNameForPendingRelease } = getService(
|
|
265
|
+
"release-validation",
|
|
266
|
+
{ strapi: strapi2 }
|
|
267
|
+
);
|
|
268
|
+
await Promise.all([
|
|
269
|
+
validatePendingReleasesLimit(),
|
|
270
|
+
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name)
|
|
271
|
+
]);
|
|
260
272
|
return strapi2.entityService.create(RELEASE_MODEL_UID, {
|
|
261
273
|
data: releaseWithCreatorFields
|
|
262
274
|
});
|
|
@@ -278,51 +290,66 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
278
290
|
}
|
|
279
291
|
});
|
|
280
292
|
},
|
|
281
|
-
async
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// Find all Releases where the content type entry is present
|
|
288
|
-
actions: {
|
|
289
|
-
target_type: contentTypeUid,
|
|
290
|
-
target_id: entryId
|
|
291
|
-
}
|
|
292
|
-
} : {
|
|
293
|
-
// Find all Releases where the content type entry is not present
|
|
294
|
-
$or: [
|
|
295
|
-
{
|
|
296
|
-
$not: {
|
|
297
|
-
actions: {
|
|
298
|
-
target_type: contentTypeUid,
|
|
299
|
-
target_id: entryId
|
|
300
|
-
}
|
|
301
|
-
}
|
|
293
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entryId) {
|
|
294
|
+
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
295
|
+
where: {
|
|
296
|
+
actions: {
|
|
297
|
+
target_type: contentTypeUid,
|
|
298
|
+
target_id: entryId
|
|
302
299
|
},
|
|
303
|
-
{
|
|
304
|
-
|
|
300
|
+
releasedAt: {
|
|
301
|
+
$null: true
|
|
305
302
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
303
|
+
},
|
|
304
|
+
populate: {
|
|
305
|
+
// Filter the action to get only the content type entry
|
|
306
|
+
actions: {
|
|
307
|
+
where: {
|
|
308
|
+
target_type: contentTypeUid,
|
|
309
|
+
target_id: entryId
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
return releases.map((release2) => {
|
|
315
|
+
if (release2.actions?.length) {
|
|
316
|
+
const [actionForEntry] = release2.actions;
|
|
317
|
+
delete release2.actions;
|
|
318
|
+
return {
|
|
319
|
+
...release2,
|
|
320
|
+
action: actionForEntry
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return release2;
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
async findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId) {
|
|
327
|
+
const releasesRelated = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
328
|
+
where: {
|
|
329
|
+
releasedAt: {
|
|
330
|
+
$null: true
|
|
331
|
+
},
|
|
332
|
+
actions: {
|
|
312
333
|
target_type: contentTypeUid,
|
|
313
334
|
target_id: entryId
|
|
314
335
|
}
|
|
315
336
|
}
|
|
316
|
-
}
|
|
337
|
+
});
|
|
317
338
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
318
339
|
where: {
|
|
319
|
-
|
|
340
|
+
$or: [
|
|
341
|
+
{
|
|
342
|
+
id: {
|
|
343
|
+
$notIn: releasesRelated.map((release2) => release2.id)
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
actions: null
|
|
348
|
+
}
|
|
349
|
+
],
|
|
320
350
|
releasedAt: {
|
|
321
351
|
$null: true
|
|
322
352
|
}
|
|
323
|
-
},
|
|
324
|
-
populate: {
|
|
325
|
-
...populateAttachedAction
|
|
326
353
|
}
|
|
327
354
|
});
|
|
328
355
|
return releases.map((release2) => {
|
|
@@ -397,7 +424,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
397
424
|
return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
|
|
398
425
|
...query,
|
|
399
426
|
populate: {
|
|
400
|
-
entry:
|
|
427
|
+
entry: {
|
|
428
|
+
populate: "*"
|
|
429
|
+
}
|
|
401
430
|
},
|
|
402
431
|
filters: {
|
|
403
432
|
release: releaseId
|
|
@@ -417,29 +446,32 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
417
446
|
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
418
447
|
contentTypeUids
|
|
419
448
|
);
|
|
420
|
-
const
|
|
421
|
-
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
422
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
423
|
-
return acc;
|
|
424
|
-
}, {});
|
|
449
|
+
const allLocalesDictionary = await this.getLocalesDataForActions();
|
|
425
450
|
const formattedData = actions.map((action) => {
|
|
426
451
|
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
427
452
|
return {
|
|
428
453
|
...action,
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
},
|
|
435
|
-
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
436
|
-
status: action.entry.publishedAt ? "published" : "draft"
|
|
454
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
455
|
+
contentType: {
|
|
456
|
+
displayName,
|
|
457
|
+
mainFieldValue: action.entry[mainField],
|
|
458
|
+
uid: action.contentType
|
|
437
459
|
}
|
|
438
460
|
};
|
|
439
461
|
});
|
|
440
462
|
const groupName = getGroupName(groupBy);
|
|
441
463
|
return ___default.default.groupBy(groupName)(formattedData);
|
|
442
464
|
},
|
|
465
|
+
async getLocalesDataForActions() {
|
|
466
|
+
if (!strapi2.plugin("i18n")) {
|
|
467
|
+
return {};
|
|
468
|
+
}
|
|
469
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find() || [];
|
|
470
|
+
return allLocales.reduce((acc, locale) => {
|
|
471
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
472
|
+
return acc;
|
|
473
|
+
}, {});
|
|
474
|
+
},
|
|
443
475
|
async getContentTypesDataForActions(contentTypesUids) {
|
|
444
476
|
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
445
477
|
const contentTypesData = {};
|
|
@@ -454,6 +486,34 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
454
486
|
}
|
|
455
487
|
return contentTypesData;
|
|
456
488
|
},
|
|
489
|
+
getContentTypeModelsFromActions(actions) {
|
|
490
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
491
|
+
if (!acc.includes(action.contentType)) {
|
|
492
|
+
acc.push(action.contentType);
|
|
493
|
+
}
|
|
494
|
+
return acc;
|
|
495
|
+
}, []);
|
|
496
|
+
const contentTypeModelsMap = contentTypeUids.reduce(
|
|
497
|
+
(acc, contentTypeUid) => {
|
|
498
|
+
acc[contentTypeUid] = strapi2.getModel(contentTypeUid);
|
|
499
|
+
return acc;
|
|
500
|
+
},
|
|
501
|
+
{}
|
|
502
|
+
);
|
|
503
|
+
return contentTypeModelsMap;
|
|
504
|
+
},
|
|
505
|
+
async getAllComponents() {
|
|
506
|
+
const contentManagerComponentsService = strapi2.plugin("content-manager").service("components");
|
|
507
|
+
const components = await contentManagerComponentsService.findAllComponents();
|
|
508
|
+
const componentsMap = components.reduce(
|
|
509
|
+
(acc, component) => {
|
|
510
|
+
acc[component.uid] = component;
|
|
511
|
+
return acc;
|
|
512
|
+
},
|
|
513
|
+
{}
|
|
514
|
+
);
|
|
515
|
+
return componentsMap;
|
|
516
|
+
},
|
|
457
517
|
async delete(releaseId) {
|
|
458
518
|
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
459
519
|
populate: {
|
|
@@ -488,7 +548,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
488
548
|
populate: {
|
|
489
549
|
actions: {
|
|
490
550
|
populate: {
|
|
491
|
-
entry:
|
|
551
|
+
entry: {
|
|
552
|
+
fields: ["id"]
|
|
553
|
+
}
|
|
492
554
|
}
|
|
493
555
|
}
|
|
494
556
|
}
|
|
@@ -508,25 +570,49 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
508
570
|
const contentTypeUid = action.contentType;
|
|
509
571
|
if (!actions[contentTypeUid]) {
|
|
510
572
|
actions[contentTypeUid] = {
|
|
511
|
-
|
|
512
|
-
|
|
573
|
+
entriestoPublishIds: [],
|
|
574
|
+
entriesToUnpublishIds: []
|
|
513
575
|
};
|
|
514
576
|
}
|
|
515
577
|
if (action.type === "publish") {
|
|
516
|
-
actions[contentTypeUid].
|
|
578
|
+
actions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
517
579
|
} else {
|
|
518
|
-
actions[contentTypeUid].
|
|
580
|
+
actions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
519
581
|
}
|
|
520
582
|
}
|
|
521
583
|
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
584
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
522
585
|
await strapi2.db.transaction(async () => {
|
|
523
586
|
for (const contentTypeUid of Object.keys(actions)) {
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
587
|
+
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
588
|
+
const { entriestoPublishIds, entriesToUnpublishIds } = actions[contentTypeUid];
|
|
589
|
+
const entriesToPublish = await strapi2.entityService.findMany(
|
|
590
|
+
contentTypeUid,
|
|
591
|
+
{
|
|
592
|
+
filters: {
|
|
593
|
+
id: {
|
|
594
|
+
$in: entriestoPublishIds
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
populate
|
|
598
|
+
}
|
|
599
|
+
);
|
|
600
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
601
|
+
contentTypeUid,
|
|
602
|
+
{
|
|
603
|
+
filters: {
|
|
604
|
+
id: {
|
|
605
|
+
$in: entriesToUnpublishIds
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
populate
|
|
609
|
+
}
|
|
610
|
+
);
|
|
611
|
+
if (entriesToPublish.length > 0) {
|
|
612
|
+
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
527
613
|
}
|
|
528
|
-
if (
|
|
529
|
-
await entityManagerService.unpublishMany(
|
|
614
|
+
if (entriesToUnpublish.length > 0) {
|
|
615
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);
|
|
530
616
|
}
|
|
531
617
|
}
|
|
532
618
|
});
|
|
@@ -608,31 +694,41 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
608
694
|
`Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`
|
|
609
695
|
);
|
|
610
696
|
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (!state.destroyListenerCallbacks.length) {
|
|
623
|
-
return;
|
|
697
|
+
},
|
|
698
|
+
async validatePendingReleasesLimit() {
|
|
699
|
+
const maximumPendingReleases = (
|
|
700
|
+
// @ts-expect-error - options is not typed into features
|
|
701
|
+
EE__default.default.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
702
|
+
);
|
|
703
|
+
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
704
|
+
filters: {
|
|
705
|
+
releasedAt: {
|
|
706
|
+
$null: true
|
|
707
|
+
}
|
|
624
708
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
709
|
+
});
|
|
710
|
+
if (pendingReleasesCount >= maximumPendingReleases) {
|
|
711
|
+
throw new utils.errors.ValidationError("You have reached the maximum number of pending releases");
|
|
628
712
|
}
|
|
629
|
-
}
|
|
630
|
-
|
|
713
|
+
},
|
|
714
|
+
async validateUniqueNameForPendingRelease(name) {
|
|
715
|
+
const pendingReleases = await strapi2.entityService.findMany(RELEASE_MODEL_UID, {
|
|
716
|
+
filters: {
|
|
717
|
+
releasedAt: {
|
|
718
|
+
$null: true
|
|
719
|
+
},
|
|
720
|
+
name
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
const isNameUnique = pendingReleases.length === 0;
|
|
724
|
+
if (!isNameUnique) {
|
|
725
|
+
throw new utils.errors.ValidationError(`Release with name ${name} already exists`);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
});
|
|
631
729
|
const services = {
|
|
632
730
|
release: createReleaseService,
|
|
633
|
-
"release-
|
|
634
|
-
"release-validation": createReleaseValidationService,
|
|
635
|
-
"event-manager": createEventManagerService
|
|
731
|
+
"release-validation": createReleaseValidationService
|
|
636
732
|
};
|
|
637
733
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
638
734
|
name: yup__namespace.string().trim().required()
|
|
@@ -652,9 +748,7 @@ const releaseController = {
|
|
|
652
748
|
const contentTypeUid = query.contentTypeUid;
|
|
653
749
|
const entryId = query.entryId;
|
|
654
750
|
const hasEntryAttached = typeof query.hasEntryAttached === "string" ? JSON.parse(query.hasEntryAttached) : false;
|
|
655
|
-
const data = await releaseService.
|
|
656
|
-
hasEntryAttached
|
|
657
|
-
});
|
|
751
|
+
const data = hasEntryAttached ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId) : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);
|
|
658
752
|
ctx.body = { data };
|
|
659
753
|
} else {
|
|
660
754
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
@@ -782,11 +876,30 @@ const releaseActionController = {
|
|
|
782
876
|
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
783
877
|
...query
|
|
784
878
|
});
|
|
785
|
-
const
|
|
879
|
+
const contentTypeOutputSanitizers = results.reduce((acc, action) => {
|
|
880
|
+
if (acc[action.contentType]) {
|
|
881
|
+
return acc;
|
|
882
|
+
}
|
|
883
|
+
const contentTypePermissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
884
|
+
ability: ctx.state.userAbility,
|
|
885
|
+
model: action.contentType
|
|
886
|
+
});
|
|
887
|
+
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
888
|
+
return acc;
|
|
889
|
+
}, {});
|
|
890
|
+
const sanitizedResults = await utils.mapAsync(results, async (action) => ({
|
|
891
|
+
...action,
|
|
892
|
+
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
893
|
+
}));
|
|
894
|
+
const groupedData = await releaseService.groupActions(sanitizedResults, query.groupBy);
|
|
895
|
+
const contentTypes2 = releaseService.getContentTypeModelsFromActions(results);
|
|
896
|
+
const components = await releaseService.getAllComponents();
|
|
786
897
|
ctx.body = {
|
|
787
898
|
data: groupedData,
|
|
788
899
|
meta: {
|
|
789
|
-
pagination
|
|
900
|
+
pagination,
|
|
901
|
+
contentTypes: contentTypes2,
|
|
902
|
+
components
|
|
790
903
|
}
|
|
791
904
|
};
|
|
792
905
|
},
|
|
@@ -992,19 +1105,14 @@ const routes = {
|
|
|
992
1105
|
};
|
|
993
1106
|
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
994
1107
|
const getPlugin = () => {
|
|
995
|
-
if (features.isEnabled("cms-content-releases")
|
|
1108
|
+
if (features.isEnabled("cms-content-releases")) {
|
|
996
1109
|
return {
|
|
997
1110
|
register,
|
|
998
1111
|
bootstrap,
|
|
999
1112
|
contentTypes,
|
|
1000
1113
|
services,
|
|
1001
1114
|
controllers,
|
|
1002
|
-
routes
|
|
1003
|
-
destroy() {
|
|
1004
|
-
if (features.isEnabled("cms-content-releases") && strapi.features.future.isEnabled("contentReleases")) {
|
|
1005
|
-
getService("event-manager").destroyAllListeners();
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1115
|
+
routes
|
|
1008
1116
|
};
|
|
1009
1117
|
}
|
|
1010
1118
|
return {
|