@strapi/content-releases 0.0.0-next.56199ab7a5f3320e0debcbe4a24fe0b8cd599e21 → 0.0.0-next.6d59515520a3850456f256fb0e4c54b75054ddf4
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-8J9a-MD5.mjs → App-L1jSxCiL.mjs} +2 -2
- package/dist/_chunks/{App-8J9a-MD5.mjs.map → App-L1jSxCiL.mjs.map} +1 -1
- package/dist/_chunks/{App-YFvVMqB8.js → App-_20W9dYa.js} +2 -2
- package/dist/_chunks/{App-YFvVMqB8.js.map → App-_20W9dYa.js.map} +1 -1
- package/dist/_chunks/{index-vxli-E-l.js → index-KJa1Rb5F.js} +5 -5
- package/dist/_chunks/{index-vxli-E-l.js.map → index-KJa1Rb5F.js.map} +1 -1
- package/dist/_chunks/{index-ej8MzbQl.mjs → index-c4zRX_sg.mjs} +5 -5
- package/dist/_chunks/{index-ej8MzbQl.mjs.map → index-c4zRX_sg.mjs.map} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +147 -110
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +148 -111
- package/dist/server/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/server/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { setCreatorFields, errors, validateYupSchema, yup as yup$1
|
|
1
|
+
import { contentTypes as contentTypes$1, mapAsync, setCreatorFields, errors, validateYupSchema, yup as yup$1 } from "@strapi/utils";
|
|
2
|
+
import { difference, keys } from "lodash";
|
|
2
3
|
import _ from "lodash/fp";
|
|
3
4
|
import EE from "@strapi/strapi/dist/utils/ee";
|
|
4
5
|
import * as yup from "yup";
|
|
@@ -48,40 +49,47 @@ const ACTIONS = [
|
|
|
48
49
|
pluginName: "content-releases"
|
|
49
50
|
}
|
|
50
51
|
];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
async function deleteActionsOnDisableDraftAndPublish({
|
|
53
|
+
oldContentTypes,
|
|
54
|
+
contentTypes: contentTypes2
|
|
55
|
+
}) {
|
|
56
|
+
if (!oldContentTypes) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
for (const uid in contentTypes2) {
|
|
60
|
+
if (!oldContentTypes[uid]) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const oldContentType = oldContentTypes[uid];
|
|
64
|
+
const contentType = contentTypes2[uid];
|
|
65
|
+
if (contentTypes$1.hasDraftAndPublish(oldContentType) && !contentTypes$1.hasDraftAndPublish(contentType)) {
|
|
66
|
+
await strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: uid }).execute();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
71
|
+
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes2)) ?? [];
|
|
72
|
+
if (deletedContentTypes.length) {
|
|
73
|
+
await mapAsync(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
74
|
+
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
54
78
|
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
55
79
|
const register = async ({ strapi: strapi2 }) => {
|
|
56
|
-
if (features$2.isEnabled("cms-content-releases")
|
|
80
|
+
if (features$2.isEnabled("cms-content-releases")) {
|
|
57
81
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const destroyContentTypeUpdateListener = strapi2.eventHub.on(
|
|
61
|
-
"content-type.update",
|
|
62
|
-
async ({ contentType }) => {
|
|
63
|
-
if (contentType.schema.options.draftAndPublish === false) {
|
|
64
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);
|
|
69
|
-
const destroyContentTypeDeleteListener = strapi2.eventHub.on(
|
|
70
|
-
"content-type.delete",
|
|
71
|
-
async ({ contentType }) => {
|
|
72
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
73
|
-
}
|
|
74
|
-
);
|
|
75
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);
|
|
82
|
+
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish);
|
|
83
|
+
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType);
|
|
76
84
|
}
|
|
77
85
|
};
|
|
78
86
|
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
79
87
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
80
|
-
if (features$1.isEnabled("cms-content-releases")
|
|
88
|
+
if (features$1.isEnabled("cms-content-releases")) {
|
|
81
89
|
strapi2.db.lifecycles.subscribe({
|
|
82
90
|
afterDelete(event) {
|
|
83
91
|
const { model, result } = event;
|
|
84
|
-
if (model.kind === "collectionType" && model.options
|
|
92
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
85
93
|
const { id } = result;
|
|
86
94
|
strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
87
95
|
where: {
|
|
@@ -97,7 +105,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
97
105
|
*/
|
|
98
106
|
async beforeDeleteMany(event) {
|
|
99
107
|
const { model, params } = event;
|
|
100
|
-
if (model.kind === "collectionType" && model.options
|
|
108
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
101
109
|
const { where } = params;
|
|
102
110
|
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
103
111
|
event.state.entriesToDelete = entriesToDelete;
|
|
@@ -212,15 +220,9 @@ const contentTypes = {
|
|
|
212
220
|
release: release$1,
|
|
213
221
|
"release-action": releaseAction$1
|
|
214
222
|
};
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
where: {
|
|
219
|
-
target_type: contentTypeUid
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
});
|
|
223
|
+
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
224
|
+
return strapi2.plugin("content-releases").service(name);
|
|
225
|
+
};
|
|
224
226
|
const getGroupName = (queryValue) => {
|
|
225
227
|
switch (queryValue) {
|
|
226
228
|
case "contentType":
|
|
@@ -236,7 +238,14 @@ const getGroupName = (queryValue) => {
|
|
|
236
238
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
237
239
|
async create(releaseData, { user }) {
|
|
238
240
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
239
|
-
|
|
241
|
+
const { validatePendingReleasesLimit, validateUniqueNameForPendingRelease } = getService(
|
|
242
|
+
"release-validation",
|
|
243
|
+
{ strapi: strapi2 }
|
|
244
|
+
);
|
|
245
|
+
await Promise.all([
|
|
246
|
+
validatePendingReleasesLimit(),
|
|
247
|
+
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name)
|
|
248
|
+
]);
|
|
240
249
|
return strapi2.entityService.create(RELEASE_MODEL_UID, {
|
|
241
250
|
data: releaseWithCreatorFields
|
|
242
251
|
});
|
|
@@ -258,51 +267,66 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
258
267
|
}
|
|
259
268
|
});
|
|
260
269
|
},
|
|
261
|
-
async
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
// Find all Releases where the content type entry is present
|
|
268
|
-
actions: {
|
|
269
|
-
target_type: contentTypeUid,
|
|
270
|
-
target_id: entryId
|
|
271
|
-
}
|
|
272
|
-
} : {
|
|
273
|
-
// Find all Releases where the content type entry is not present
|
|
274
|
-
$or: [
|
|
275
|
-
{
|
|
276
|
-
$not: {
|
|
277
|
-
actions: {
|
|
278
|
-
target_type: contentTypeUid,
|
|
279
|
-
target_id: entryId
|
|
280
|
-
}
|
|
281
|
-
}
|
|
270
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entryId) {
|
|
271
|
+
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
272
|
+
where: {
|
|
273
|
+
actions: {
|
|
274
|
+
target_type: contentTypeUid,
|
|
275
|
+
target_id: entryId
|
|
282
276
|
},
|
|
283
|
-
{
|
|
284
|
-
|
|
277
|
+
releasedAt: {
|
|
278
|
+
$null: true
|
|
285
279
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
280
|
+
},
|
|
281
|
+
populate: {
|
|
282
|
+
// Filter the action to get only the content type entry
|
|
283
|
+
actions: {
|
|
284
|
+
where: {
|
|
285
|
+
target_type: contentTypeUid,
|
|
286
|
+
target_id: entryId
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
return releases.map((release2) => {
|
|
292
|
+
if (release2.actions?.length) {
|
|
293
|
+
const [actionForEntry] = release2.actions;
|
|
294
|
+
delete release2.actions;
|
|
295
|
+
return {
|
|
296
|
+
...release2,
|
|
297
|
+
action: actionForEntry
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return release2;
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
async findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId) {
|
|
304
|
+
const releasesRelated = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
305
|
+
where: {
|
|
306
|
+
releasedAt: {
|
|
307
|
+
$null: true
|
|
308
|
+
},
|
|
309
|
+
actions: {
|
|
292
310
|
target_type: contentTypeUid,
|
|
293
311
|
target_id: entryId
|
|
294
312
|
}
|
|
295
313
|
}
|
|
296
|
-
}
|
|
314
|
+
});
|
|
297
315
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
298
316
|
where: {
|
|
299
|
-
|
|
317
|
+
$or: [
|
|
318
|
+
{
|
|
319
|
+
id: {
|
|
320
|
+
$notIn: releasesRelated.map((release2) => release2.id)
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
actions: null
|
|
325
|
+
}
|
|
326
|
+
],
|
|
300
327
|
releasedAt: {
|
|
301
328
|
$null: true
|
|
302
329
|
}
|
|
303
|
-
},
|
|
304
|
-
populate: {
|
|
305
|
-
...populateAttachedAction
|
|
306
330
|
}
|
|
307
331
|
});
|
|
308
332
|
return releases.map((release2) => {
|
|
@@ -501,7 +525,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
501
525
|
populate: {
|
|
502
526
|
actions: {
|
|
503
527
|
populate: {
|
|
504
|
-
entry:
|
|
528
|
+
entry: {
|
|
529
|
+
fields: ["id"]
|
|
530
|
+
}
|
|
505
531
|
}
|
|
506
532
|
}
|
|
507
533
|
}
|
|
@@ -521,25 +547,49 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
521
547
|
const contentTypeUid = action.contentType;
|
|
522
548
|
if (!actions[contentTypeUid]) {
|
|
523
549
|
actions[contentTypeUid] = {
|
|
524
|
-
|
|
525
|
-
|
|
550
|
+
entriestoPublishIds: [],
|
|
551
|
+
entriesToUnpublishIds: []
|
|
526
552
|
};
|
|
527
553
|
}
|
|
528
554
|
if (action.type === "publish") {
|
|
529
|
-
actions[contentTypeUid].
|
|
555
|
+
actions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
530
556
|
} else {
|
|
531
|
-
actions[contentTypeUid].
|
|
557
|
+
actions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
532
558
|
}
|
|
533
559
|
}
|
|
534
560
|
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
561
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
535
562
|
await strapi2.db.transaction(async () => {
|
|
536
563
|
for (const contentTypeUid of Object.keys(actions)) {
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
564
|
+
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
565
|
+
const { entriestoPublishIds, entriesToUnpublishIds } = actions[contentTypeUid];
|
|
566
|
+
const entriesToPublish = await strapi2.entityService.findMany(
|
|
567
|
+
contentTypeUid,
|
|
568
|
+
{
|
|
569
|
+
filters: {
|
|
570
|
+
id: {
|
|
571
|
+
$in: entriestoPublishIds
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
populate
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
578
|
+
contentTypeUid,
|
|
579
|
+
{
|
|
580
|
+
filters: {
|
|
581
|
+
id: {
|
|
582
|
+
$in: entriesToUnpublishIds
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
populate
|
|
586
|
+
}
|
|
587
|
+
);
|
|
588
|
+
if (entriesToPublish.length > 0) {
|
|
589
|
+
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
540
590
|
}
|
|
541
|
-
if (
|
|
542
|
-
await entityManagerService.unpublishMany(
|
|
591
|
+
if (entriesToUnpublish.length > 0) {
|
|
592
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);
|
|
543
593
|
}
|
|
544
594
|
}
|
|
545
595
|
});
|
|
@@ -637,31 +687,25 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
637
687
|
if (pendingReleasesCount >= maximumPendingReleases) {
|
|
638
688
|
throw new errors.ValidationError("You have reached the maximum number of pending releases");
|
|
639
689
|
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
state.destroyListenerCallbacks.push(destroyListenerCallback);
|
|
649
|
-
},
|
|
650
|
-
destroyAllListeners() {
|
|
651
|
-
if (!state.destroyListenerCallbacks.length) {
|
|
652
|
-
return;
|
|
690
|
+
},
|
|
691
|
+
async validateUniqueNameForPendingRelease(name) {
|
|
692
|
+
const pendingReleases = await strapi2.entityService.findMany(RELEASE_MODEL_UID, {
|
|
693
|
+
filters: {
|
|
694
|
+
releasedAt: {
|
|
695
|
+
$null: true
|
|
696
|
+
},
|
|
697
|
+
name
|
|
653
698
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
699
|
+
});
|
|
700
|
+
const isNameUnique = pendingReleases.length === 0;
|
|
701
|
+
if (!isNameUnique) {
|
|
702
|
+
throw new errors.ValidationError(`Release with name ${name} already exists`);
|
|
657
703
|
}
|
|
658
|
-
}
|
|
659
|
-
};
|
|
704
|
+
}
|
|
705
|
+
});
|
|
660
706
|
const services = {
|
|
661
707
|
release: createReleaseService,
|
|
662
|
-
"release-
|
|
663
|
-
"release-validation": createReleaseValidationService,
|
|
664
|
-
"event-manager": createEventManagerService
|
|
708
|
+
"release-validation": createReleaseValidationService
|
|
665
709
|
};
|
|
666
710
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
667
711
|
name: yup.string().trim().required()
|
|
@@ -681,9 +725,7 @@ const releaseController = {
|
|
|
681
725
|
const contentTypeUid = query.contentTypeUid;
|
|
682
726
|
const entryId = query.entryId;
|
|
683
727
|
const hasEntryAttached = typeof query.hasEntryAttached === "string" ? JSON.parse(query.hasEntryAttached) : false;
|
|
684
|
-
const data = await releaseService.
|
|
685
|
-
hasEntryAttached
|
|
686
|
-
});
|
|
728
|
+
const data = hasEntryAttached ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId) : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);
|
|
687
729
|
ctx.body = { data };
|
|
688
730
|
} else {
|
|
689
731
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
@@ -1040,19 +1082,14 @@ const routes = {
|
|
|
1040
1082
|
};
|
|
1041
1083
|
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1042
1084
|
const getPlugin = () => {
|
|
1043
|
-
if (features.isEnabled("cms-content-releases")
|
|
1085
|
+
if (features.isEnabled("cms-content-releases")) {
|
|
1044
1086
|
return {
|
|
1045
1087
|
register,
|
|
1046
1088
|
bootstrap,
|
|
1047
1089
|
contentTypes,
|
|
1048
1090
|
services,
|
|
1049
1091
|
controllers,
|
|
1050
|
-
routes
|
|
1051
|
-
destroy() {
|
|
1052
|
-
if (features.isEnabled("cms-content-releases") && strapi.features.future.isEnabled("contentReleases")) {
|
|
1053
|
-
getService("event-manager").destroyAllListeners();
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1092
|
+
routes
|
|
1056
1093
|
};
|
|
1057
1094
|
}
|
|
1058
1095
|
return {
|