@strapi/content-releases 0.0.0-next.56199ab7a5f3320e0debcbe4a24fe0b8cd599e21 → 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-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.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const utils = require("@strapi/utils");
|
|
3
|
+
const lodash = require("lodash");
|
|
3
4
|
const _ = require("lodash/fp");
|
|
4
5
|
const EE = require("@strapi/strapi/dist/utils/ee");
|
|
5
6
|
const yup = require("yup");
|
|
@@ -71,40 +72,47 @@ const ACTIONS = [
|
|
|
71
72
|
pluginName: "content-releases"
|
|
72
73
|
}
|
|
73
74
|
];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
+
}
|
|
77
101
|
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
78
102
|
const register = async ({ strapi: strapi2 }) => {
|
|
79
|
-
if (features$2.isEnabled("cms-content-releases")
|
|
103
|
+
if (features$2.isEnabled("cms-content-releases")) {
|
|
80
104
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const destroyContentTypeUpdateListener = strapi2.eventHub.on(
|
|
84
|
-
"content-type.update",
|
|
85
|
-
async ({ contentType }) => {
|
|
86
|
-
if (contentType.schema.options.draftAndPublish === false) {
|
|
87
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);
|
|
92
|
-
const destroyContentTypeDeleteListener = strapi2.eventHub.on(
|
|
93
|
-
"content-type.delete",
|
|
94
|
-
async ({ contentType }) => {
|
|
95
|
-
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
96
|
-
}
|
|
97
|
-
);
|
|
98
|
-
eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);
|
|
105
|
+
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish);
|
|
106
|
+
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType);
|
|
99
107
|
}
|
|
100
108
|
};
|
|
101
109
|
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
102
110
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
103
|
-
if (features$1.isEnabled("cms-content-releases")
|
|
111
|
+
if (features$1.isEnabled("cms-content-releases")) {
|
|
104
112
|
strapi2.db.lifecycles.subscribe({
|
|
105
113
|
afterDelete(event) {
|
|
106
114
|
const { model, result } = event;
|
|
107
|
-
if (model.kind === "collectionType" && model.options
|
|
115
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
108
116
|
const { id } = result;
|
|
109
117
|
strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
110
118
|
where: {
|
|
@@ -120,7 +128,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
120
128
|
*/
|
|
121
129
|
async beforeDeleteMany(event) {
|
|
122
130
|
const { model, params } = event;
|
|
123
|
-
if (model.kind === "collectionType" && model.options
|
|
131
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
124
132
|
const { where } = params;
|
|
125
133
|
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
126
134
|
event.state.entriesToDelete = entriesToDelete;
|
|
@@ -235,15 +243,9 @@ const contentTypes = {
|
|
|
235
243
|
release: release$1,
|
|
236
244
|
"release-action": releaseAction$1
|
|
237
245
|
};
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
where: {
|
|
242
|
-
target_type: contentTypeUid
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
});
|
|
246
|
+
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
247
|
+
return strapi2.plugin("content-releases").service(name);
|
|
248
|
+
};
|
|
247
249
|
const getGroupName = (queryValue) => {
|
|
248
250
|
switch (queryValue) {
|
|
249
251
|
case "contentType":
|
|
@@ -259,7 +261,14 @@ const getGroupName = (queryValue) => {
|
|
|
259
261
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
260
262
|
async create(releaseData, { user }) {
|
|
261
263
|
const releaseWithCreatorFields = await utils.setCreatorFields({ user })(releaseData);
|
|
262
|
-
|
|
264
|
+
const { validatePendingReleasesLimit, validateUniqueNameForPendingRelease } = getService(
|
|
265
|
+
"release-validation",
|
|
266
|
+
{ strapi: strapi2 }
|
|
267
|
+
);
|
|
268
|
+
await Promise.all([
|
|
269
|
+
validatePendingReleasesLimit(),
|
|
270
|
+
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name)
|
|
271
|
+
]);
|
|
263
272
|
return strapi2.entityService.create(RELEASE_MODEL_UID, {
|
|
264
273
|
data: releaseWithCreatorFields
|
|
265
274
|
});
|
|
@@ -281,51 +290,66 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
281
290
|
}
|
|
282
291
|
});
|
|
283
292
|
},
|
|
284
|
-
async
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// Find all Releases where the content type entry is present
|
|
291
|
-
actions: {
|
|
292
|
-
target_type: contentTypeUid,
|
|
293
|
-
target_id: entryId
|
|
294
|
-
}
|
|
295
|
-
} : {
|
|
296
|
-
// Find all Releases where the content type entry is not present
|
|
297
|
-
$or: [
|
|
298
|
-
{
|
|
299
|
-
$not: {
|
|
300
|
-
actions: {
|
|
301
|
-
target_type: contentTypeUid,
|
|
302
|
-
target_id: entryId
|
|
303
|
-
}
|
|
304
|
-
}
|
|
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
|
|
305
299
|
},
|
|
306
|
-
{
|
|
307
|
-
|
|
300
|
+
releasedAt: {
|
|
301
|
+
$null: true
|
|
308
302
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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: {
|
|
315
333
|
target_type: contentTypeUid,
|
|
316
334
|
target_id: entryId
|
|
317
335
|
}
|
|
318
336
|
}
|
|
319
|
-
}
|
|
337
|
+
});
|
|
320
338
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
321
339
|
where: {
|
|
322
|
-
|
|
340
|
+
$or: [
|
|
341
|
+
{
|
|
342
|
+
id: {
|
|
343
|
+
$notIn: releasesRelated.map((release2) => release2.id)
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
actions: null
|
|
348
|
+
}
|
|
349
|
+
],
|
|
323
350
|
releasedAt: {
|
|
324
351
|
$null: true
|
|
325
352
|
}
|
|
326
|
-
},
|
|
327
|
-
populate: {
|
|
328
|
-
...populateAttachedAction
|
|
329
353
|
}
|
|
330
354
|
});
|
|
331
355
|
return releases.map((release2) => {
|
|
@@ -524,7 +548,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
524
548
|
populate: {
|
|
525
549
|
actions: {
|
|
526
550
|
populate: {
|
|
527
|
-
entry:
|
|
551
|
+
entry: {
|
|
552
|
+
fields: ["id"]
|
|
553
|
+
}
|
|
528
554
|
}
|
|
529
555
|
}
|
|
530
556
|
}
|
|
@@ -544,25 +570,49 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
544
570
|
const contentTypeUid = action.contentType;
|
|
545
571
|
if (!actions[contentTypeUid]) {
|
|
546
572
|
actions[contentTypeUid] = {
|
|
547
|
-
|
|
548
|
-
|
|
573
|
+
entriestoPublishIds: [],
|
|
574
|
+
entriesToUnpublishIds: []
|
|
549
575
|
};
|
|
550
576
|
}
|
|
551
577
|
if (action.type === "publish") {
|
|
552
|
-
actions[contentTypeUid].
|
|
578
|
+
actions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
553
579
|
} else {
|
|
554
|
-
actions[contentTypeUid].
|
|
580
|
+
actions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
555
581
|
}
|
|
556
582
|
}
|
|
557
583
|
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
584
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
558
585
|
await strapi2.db.transaction(async () => {
|
|
559
586
|
for (const contentTypeUid of Object.keys(actions)) {
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
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);
|
|
563
613
|
}
|
|
564
|
-
if (
|
|
565
|
-
await entityManagerService.unpublishMany(
|
|
614
|
+
if (entriesToUnpublish.length > 0) {
|
|
615
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);
|
|
566
616
|
}
|
|
567
617
|
}
|
|
568
618
|
});
|
|
@@ -660,31 +710,25 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
660
710
|
if (pendingReleasesCount >= maximumPendingReleases) {
|
|
661
711
|
throw new utils.errors.ValidationError("You have reached the maximum number of pending releases");
|
|
662
712
|
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
state.destroyListenerCallbacks.push(destroyListenerCallback);
|
|
672
|
-
},
|
|
673
|
-
destroyAllListeners() {
|
|
674
|
-
if (!state.destroyListenerCallbacks.length) {
|
|
675
|
-
return;
|
|
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
|
|
676
721
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
722
|
+
});
|
|
723
|
+
const isNameUnique = pendingReleases.length === 0;
|
|
724
|
+
if (!isNameUnique) {
|
|
725
|
+
throw new utils.errors.ValidationError(`Release with name ${name} already exists`);
|
|
680
726
|
}
|
|
681
|
-
}
|
|
682
|
-
};
|
|
727
|
+
}
|
|
728
|
+
});
|
|
683
729
|
const services = {
|
|
684
730
|
release: createReleaseService,
|
|
685
|
-
"release-
|
|
686
|
-
"release-validation": createReleaseValidationService,
|
|
687
|
-
"event-manager": createEventManagerService
|
|
731
|
+
"release-validation": createReleaseValidationService
|
|
688
732
|
};
|
|
689
733
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
690
734
|
name: yup__namespace.string().trim().required()
|
|
@@ -704,9 +748,7 @@ const releaseController = {
|
|
|
704
748
|
const contentTypeUid = query.contentTypeUid;
|
|
705
749
|
const entryId = query.entryId;
|
|
706
750
|
const hasEntryAttached = typeof query.hasEntryAttached === "string" ? JSON.parse(query.hasEntryAttached) : false;
|
|
707
|
-
const data = await releaseService.
|
|
708
|
-
hasEntryAttached
|
|
709
|
-
});
|
|
751
|
+
const data = hasEntryAttached ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId) : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);
|
|
710
752
|
ctx.body = { data };
|
|
711
753
|
} else {
|
|
712
754
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
@@ -1063,19 +1105,14 @@ const routes = {
|
|
|
1063
1105
|
};
|
|
1064
1106
|
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1065
1107
|
const getPlugin = () => {
|
|
1066
|
-
if (features.isEnabled("cms-content-releases")
|
|
1108
|
+
if (features.isEnabled("cms-content-releases")) {
|
|
1067
1109
|
return {
|
|
1068
1110
|
register,
|
|
1069
1111
|
bootstrap,
|
|
1070
1112
|
contentTypes,
|
|
1071
1113
|
services,
|
|
1072
1114
|
controllers,
|
|
1073
|
-
routes
|
|
1074
|
-
destroy() {
|
|
1075
|
-
if (features.isEnabled("cms-content-releases") && strapi.features.future.isEnabled("contentReleases")) {
|
|
1076
|
-
getService("event-manager").destroyAllListeners();
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1115
|
+
routes
|
|
1079
1116
|
};
|
|
1080
1117
|
}
|
|
1081
1118
|
return {
|