@strapi/content-releases 4.20.5 → 5.0.0-alpha.1
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-p8aKBitd.js → App-vS3MaAL8.js} +277 -279
- package/dist/_chunks/App-vS3MaAL8.js.map +1 -0
- package/dist/_chunks/{App-bpzO2Ljh.mjs → App-wYLtVioz.mjs} +271 -273
- package/dist/_chunks/App-wYLtVioz.mjs.map +1 -0
- package/dist/_chunks/{en-WuuhP6Bn.mjs → en-RdapH-9X.mjs} +1 -2
- package/dist/_chunks/en-RdapH-9X.mjs.map +1 -0
- package/dist/_chunks/{en-gcJJ5htG.js → en-faJDuv3q.js} +1 -2
- package/dist/_chunks/en-faJDuv3q.js.map +1 -0
- package/dist/_chunks/{index-fP3qoWZ4.js → index-EoKpj3V5.js} +70 -61
- package/dist/_chunks/index-EoKpj3V5.js.map +1 -0
- package/dist/_chunks/{index-AECgcaDa.mjs → index-RhLsjv0x.mjs} +72 -63
- package/dist/_chunks/index-RhLsjv0x.mjs.map +1 -0
- package/dist/admin/index.js +1 -14
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -14
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/components/CMReleasesContainer.d.ts +1 -0
- package/dist/admin/src/components/RelativeTime.d.ts +28 -0
- package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
- package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
- package/dist/admin/src/components/ReleaseModal.d.ts +16 -0
- package/dist/admin/src/constants.d.ts +58 -0
- package/dist/admin/src/index.d.ts +3 -0
- package/dist/admin/src/pages/App.d.ts +1 -0
- package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
- package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
- package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
- package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
- package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
- package/dist/admin/src/pluginId.d.ts +1 -0
- package/dist/admin/src/services/axios.d.ts +29 -0
- package/dist/admin/src/services/release.d.ts +369 -0
- package/dist/admin/src/store/hooks.d.ts +7 -0
- package/dist/admin/src/utils/time.d.ts +1 -0
- package/dist/server/index.js +277 -232
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +278 -232
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts +5 -0
- package/dist/server/src/bootstrap.d.ts.map +1 -0
- package/dist/server/src/constants.d.ts +12 -0
- package/dist/server/src/constants.d.ts.map +1 -0
- package/dist/server/src/content-types/index.d.ts +99 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -0
- package/dist/server/src/content-types/release/index.d.ts +48 -0
- package/dist/server/src/content-types/release/index.d.ts.map +1 -0
- package/dist/server/src/content-types/release/schema.d.ts +47 -0
- package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
- package/dist/server/src/content-types/release-action/index.d.ts +50 -0
- package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
- package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
- package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
- package/dist/server/src/controllers/index.d.ts +19 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -0
- package/dist/server/src/controllers/release-action.d.ts +10 -0
- package/dist/server/src/controllers/release-action.d.ts.map +1 -0
- package/dist/server/src/controllers/release.d.ts +11 -0
- package/dist/server/src/controllers/release.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
- package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/release.d.ts +2 -0
- package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
- package/dist/server/src/destroy.d.ts +5 -0
- package/dist/server/src/destroy.d.ts.map +1 -0
- package/dist/server/src/index.d.ts +2095 -0
- package/dist/server/src/index.d.ts.map +1 -0
- package/dist/server/src/migrations/index.d.ts +12 -0
- package/dist/server/src/migrations/index.d.ts.map +1 -0
- package/dist/server/src/register.d.ts +5 -0
- package/dist/server/src/register.d.ts.map +1 -0
- package/dist/server/src/routes/index.d.ts +35 -0
- package/dist/server/src/routes/index.d.ts.map +1 -0
- package/dist/server/src/routes/release-action.d.ts +18 -0
- package/dist/server/src/routes/release-action.d.ts.map +1 -0
- package/dist/server/src/routes/release.d.ts +18 -0
- package/dist/server/src/routes/release.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +1826 -0
- package/dist/server/src/services/index.d.ts.map +1 -0
- package/dist/server/src/services/release.d.ts +66 -0
- package/dist/server/src/services/release.d.ts.map +1 -0
- package/dist/server/src/services/scheduling.d.ts +18 -0
- package/dist/server/src/services/scheduling.d.ts.map +1 -0
- package/dist/server/src/services/validation.d.ts +18 -0
- package/dist/server/src/services/validation.d.ts.map +1 -0
- package/dist/server/src/utils/index.d.ts +14 -0
- package/dist/server/src/utils/index.d.ts.map +1 -0
- package/dist/shared/contracts/release-actions.d.ts +131 -0
- package/dist/shared/contracts/release-actions.d.ts.map +1 -0
- package/dist/shared/contracts/releases.d.ts +166 -0
- package/dist/shared/contracts/releases.d.ts.map +1 -0
- package/dist/shared/types.d.ts +24 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/validation-schemas.d.ts +2 -0
- package/dist/shared/validation-schemas.d.ts.map +1 -0
- package/package.json +22 -28
- package/dist/_chunks/App-bpzO2Ljh.mjs.map +0 -1
- package/dist/_chunks/App-p8aKBitd.js.map +0 -1
- package/dist/_chunks/en-WuuhP6Bn.mjs.map +0 -1
- package/dist/_chunks/en-gcJJ5htG.js.map +0 -1
- package/dist/_chunks/index-AECgcaDa.mjs.map +0 -1
- package/dist/_chunks/index-fP3qoWZ4.js.map +0 -1
package/dist/server/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { async, setCreatorFields, convertQueryParams, errors, validateYupSchema, yup as yup$1 } from "@strapi/utils";
|
|
2
2
|
import isEqual from "lodash/isEqual";
|
|
3
3
|
import { difference, keys } from "lodash";
|
|
4
4
|
import _ from "lodash/fp";
|
|
5
|
-
import EE from "@strapi/strapi/dist/utils/ee";
|
|
6
5
|
import { scheduleJob } from "node-schedule";
|
|
7
6
|
import * as yup from "yup";
|
|
8
7
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
@@ -60,7 +59,10 @@ const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
|
60
59
|
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
61
60
|
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
62
61
|
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
63
|
-
const entry = await strapi2.
|
|
62
|
+
const entry = await strapi2.db.query(contentTypeUid).findOne({
|
|
63
|
+
where: { id: entryId },
|
|
64
|
+
populate
|
|
65
|
+
});
|
|
64
66
|
return entry;
|
|
65
67
|
};
|
|
66
68
|
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
@@ -77,28 +79,10 @@ const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 } =
|
|
|
77
79
|
return false;
|
|
78
80
|
}
|
|
79
81
|
};
|
|
80
|
-
async function deleteActionsOnDisableDraftAndPublish({
|
|
81
|
-
oldContentTypes,
|
|
82
|
-
contentTypes: contentTypes2
|
|
83
|
-
}) {
|
|
84
|
-
if (!oldContentTypes) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
for (const uid in contentTypes2) {
|
|
88
|
-
if (!oldContentTypes[uid]) {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const oldContentType = oldContentTypes[uid];
|
|
92
|
-
const contentType = contentTypes2[uid];
|
|
93
|
-
if (contentTypes$1.hasDraftAndPublish(oldContentType) && !contentTypes$1.hasDraftAndPublish(contentType)) {
|
|
94
|
-
await strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: uid }).execute();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
82
|
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
99
83
|
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes2)) ?? [];
|
|
100
84
|
if (deletedContentTypes.length) {
|
|
101
|
-
await
|
|
85
|
+
await async.map(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
102
86
|
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
103
87
|
});
|
|
104
88
|
}
|
|
@@ -117,7 +101,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
117
101
|
}
|
|
118
102
|
}
|
|
119
103
|
});
|
|
120
|
-
|
|
104
|
+
async.map(releasesWithoutStatus, async (release2) => {
|
|
121
105
|
const actions = release2.actions;
|
|
122
106
|
const notValidatedActions = actions.filter((action) => action.isEntryValid === null);
|
|
123
107
|
for (const action of notValidatedActions) {
|
|
@@ -148,7 +132,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
148
132
|
}
|
|
149
133
|
}
|
|
150
134
|
});
|
|
151
|
-
|
|
135
|
+
async.map(publishedReleases, async (release2) => {
|
|
152
136
|
return strapi.db.query(RELEASE_MODEL_UID).update({
|
|
153
137
|
where: {
|
|
154
138
|
id: release2.id
|
|
@@ -161,11 +145,9 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
161
145
|
}
|
|
162
146
|
async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
163
147
|
if (oldContentTypes !== void 0 && contentTypes2 !== void 0) {
|
|
164
|
-
const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes)
|
|
165
|
-
(uid) => oldContentTypes[uid]?.options?.draftAndPublish
|
|
166
|
-
);
|
|
148
|
+
const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes);
|
|
167
149
|
const releasesAffected = /* @__PURE__ */ new Set();
|
|
168
|
-
|
|
150
|
+
async.map(contentTypesWithDraftAndPublish, async (contentTypeUID) => {
|
|
169
151
|
const oldContentType = oldContentTypes[contentTypeUID];
|
|
170
152
|
const contentType = contentTypes2[contentTypeUID];
|
|
171
153
|
if (!isEqual(oldContentType?.attributes, contentType?.attributes)) {
|
|
@@ -178,7 +160,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
178
160
|
release: true
|
|
179
161
|
}
|
|
180
162
|
});
|
|
181
|
-
await
|
|
163
|
+
await async.map(actions, async (action) => {
|
|
182
164
|
if (action.entry && action.release) {
|
|
183
165
|
const populatedEntry = await getPopulatedEntry(contentTypeUID, action.entry.id, {
|
|
184
166
|
strapi
|
|
@@ -201,7 +183,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
201
183
|
});
|
|
202
184
|
}
|
|
203
185
|
}).then(() => {
|
|
204
|
-
|
|
186
|
+
async.map(releasesAffected, async (releaseId) => {
|
|
205
187
|
return getService("release", { strapi }).updateReleaseStatus(releaseId);
|
|
206
188
|
});
|
|
207
189
|
});
|
|
@@ -247,11 +229,10 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
247
229
|
}
|
|
248
230
|
}
|
|
249
231
|
}
|
|
250
|
-
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
251
232
|
const register = async ({ strapi: strapi2 }) => {
|
|
252
|
-
if (features
|
|
233
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
253
234
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
254
|
-
strapi2.hook("strapi::content-types.beforeSync").register(
|
|
235
|
+
strapi2.hook("strapi::content-types.beforeSync").register(disableContentTypeLocalized);
|
|
255
236
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
256
237
|
}
|
|
257
238
|
if (strapi2.plugin("graphql")) {
|
|
@@ -260,12 +241,9 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
260
241
|
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
261
242
|
}
|
|
262
243
|
};
|
|
263
|
-
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
264
244
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
265
|
-
if (features
|
|
266
|
-
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes)
|
|
267
|
-
(uid) => strapi2.contentTypes[uid]?.options?.draftAndPublish
|
|
268
|
-
);
|
|
245
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
246
|
+
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes);
|
|
269
247
|
strapi2.db.lifecycles.subscribe({
|
|
270
248
|
models: contentTypesWithDraftAndPublish,
|
|
271
249
|
async afterDelete(event) {
|
|
@@ -301,7 +279,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
301
279
|
*/
|
|
302
280
|
async beforeDeleteMany(event) {
|
|
303
281
|
const { model, params } = event;
|
|
304
|
-
if (model.kind === "collectionType"
|
|
282
|
+
if (model.kind === "collectionType") {
|
|
305
283
|
const { where } = params;
|
|
306
284
|
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
307
285
|
event.state.entriesToDelete = entriesToDelete;
|
|
@@ -383,27 +361,23 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
383
361
|
}
|
|
384
362
|
}
|
|
385
363
|
});
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
});
|
|
396
|
-
}
|
|
364
|
+
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
365
|
+
strapi2.log.error(
|
|
366
|
+
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
367
|
+
);
|
|
368
|
+
throw err;
|
|
369
|
+
});
|
|
370
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
371
|
+
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
372
|
+
});
|
|
397
373
|
}
|
|
398
374
|
};
|
|
399
375
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
job.cancel();
|
|
406
|
-
}
|
|
376
|
+
const scheduledJobs = getService("scheduling", {
|
|
377
|
+
strapi: strapi2
|
|
378
|
+
}).getAll();
|
|
379
|
+
for (const [, job] of scheduledJobs) {
|
|
380
|
+
job.cancel();
|
|
407
381
|
}
|
|
408
382
|
};
|
|
409
383
|
const schema$1 = {
|
|
@@ -528,6 +502,94 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
528
502
|
release: release2
|
|
529
503
|
});
|
|
530
504
|
};
|
|
505
|
+
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
506
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
507
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
508
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
509
|
+
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
510
|
+
try {
|
|
511
|
+
if (actionType === "publish") {
|
|
512
|
+
await entityManagerService.publish(entry, uid);
|
|
513
|
+
} else {
|
|
514
|
+
await entityManagerService.unpublish(entry, uid);
|
|
515
|
+
}
|
|
516
|
+
} catch (error) {
|
|
517
|
+
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
518
|
+
;
|
|
519
|
+
else {
|
|
520
|
+
throw error;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
525
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
526
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
527
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
528
|
+
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
529
|
+
filters: {
|
|
530
|
+
id: {
|
|
531
|
+
$in: entriesToPublishIds
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
populate
|
|
535
|
+
});
|
|
536
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
537
|
+
filters: {
|
|
538
|
+
id: {
|
|
539
|
+
$in: entriestoUnpublishIds
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
populate
|
|
543
|
+
});
|
|
544
|
+
if (entriesToPublish.length > 0) {
|
|
545
|
+
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
546
|
+
}
|
|
547
|
+
if (entriesToUnpublish.length > 0) {
|
|
548
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const getFormattedActions = async (releaseId) => {
|
|
552
|
+
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
553
|
+
where: {
|
|
554
|
+
release: {
|
|
555
|
+
id: releaseId
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
populate: {
|
|
559
|
+
entry: {
|
|
560
|
+
fields: ["id"]
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
if (actions.length === 0) {
|
|
565
|
+
throw new errors.ValidationError("No entries to publish");
|
|
566
|
+
}
|
|
567
|
+
const collectionTypeActions = {};
|
|
568
|
+
const singleTypeActions = [];
|
|
569
|
+
for (const action of actions) {
|
|
570
|
+
const contentTypeUid = action.contentType;
|
|
571
|
+
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
572
|
+
if (!collectionTypeActions[contentTypeUid]) {
|
|
573
|
+
collectionTypeActions[contentTypeUid] = {
|
|
574
|
+
entriesToPublishIds: [],
|
|
575
|
+
entriesToUnpublishIds: []
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
if (action.type === "publish") {
|
|
579
|
+
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
580
|
+
} else {
|
|
581
|
+
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
singleTypeActions.push({
|
|
585
|
+
uid: contentTypeUid,
|
|
586
|
+
action: action.type,
|
|
587
|
+
id: action.entry.id
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return { collectionTypeActions, singleTypeActions };
|
|
592
|
+
};
|
|
531
593
|
return {
|
|
532
594
|
async create(releaseData, { user }) {
|
|
533
595
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
@@ -541,13 +603,13 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
541
603
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),
|
|
542
604
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
543
605
|
]);
|
|
544
|
-
const release2 = await strapi2.
|
|
606
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).create({
|
|
545
607
|
data: {
|
|
546
608
|
...releaseWithCreatorFields,
|
|
547
609
|
status: "empty"
|
|
548
610
|
}
|
|
549
611
|
});
|
|
550
|
-
if (
|
|
612
|
+
if (releaseWithCreatorFields.scheduledAt) {
|
|
551
613
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
552
614
|
await schedulingService.set(release2.id, release2.scheduledAt);
|
|
553
615
|
}
|
|
@@ -555,17 +617,19 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
555
617
|
return release2;
|
|
556
618
|
},
|
|
557
619
|
async findOne(id, query = {}) {
|
|
558
|
-
const
|
|
559
|
-
|
|
620
|
+
const dbQuery = convertQueryParams.transformParamsToQuery(RELEASE_MODEL_UID, query);
|
|
621
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
622
|
+
...dbQuery,
|
|
623
|
+
where: { id }
|
|
560
624
|
});
|
|
561
625
|
return release2;
|
|
562
626
|
},
|
|
563
627
|
findPage(query) {
|
|
564
|
-
|
|
565
|
-
|
|
628
|
+
const dbQuery = convertQueryParams.transformParamsToQuery(RELEASE_MODEL_UID, query ?? {});
|
|
629
|
+
return strapi2.db.query(RELEASE_MODEL_UID).findPage({
|
|
630
|
+
...dbQuery,
|
|
566
631
|
populate: {
|
|
567
632
|
actions: {
|
|
568
|
-
// @ts-expect-error Ignore missing properties
|
|
569
633
|
count: true
|
|
570
634
|
}
|
|
571
635
|
}
|
|
@@ -657,28 +721,22 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
657
721
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),
|
|
658
722
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
659
723
|
]);
|
|
660
|
-
const release2 = await strapi2.
|
|
724
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id } });
|
|
661
725
|
if (!release2) {
|
|
662
726
|
throw new errors.NotFoundError(`No release found for id ${id}`);
|
|
663
727
|
}
|
|
664
728
|
if (release2.releasedAt) {
|
|
665
729
|
throw new errors.ValidationError("Release already published");
|
|
666
730
|
}
|
|
667
|
-
const updatedRelease = await strapi2.
|
|
668
|
-
|
|
669
|
-
* The type returned from the entity service: Partial<Input<"plugin::content-releases.release">>
|
|
670
|
-
* is not compatible with the type we are passing here: UpdateRelease.Request['body']
|
|
671
|
-
*/
|
|
672
|
-
// @ts-expect-error see above
|
|
731
|
+
const updatedRelease = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
732
|
+
where: { id },
|
|
673
733
|
data: releaseWithCreatorFields
|
|
674
734
|
});
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
schedulingService.cancel(id);
|
|
681
|
-
}
|
|
735
|
+
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
736
|
+
if (releaseData.scheduledAt) {
|
|
737
|
+
await schedulingService.set(id, releaseData.scheduledAt);
|
|
738
|
+
} else if (release2.scheduledAt) {
|
|
739
|
+
schedulingService.cancel(id);
|
|
682
740
|
}
|
|
683
741
|
this.updateReleaseStatus(id);
|
|
684
742
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
@@ -692,7 +750,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
692
750
|
validateEntryContentType(action.entry.contentType),
|
|
693
751
|
validateUniqueEntry(releaseId, action)
|
|
694
752
|
]);
|
|
695
|
-
const release2 = await strapi2.
|
|
753
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
696
754
|
if (!release2) {
|
|
697
755
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
698
756
|
}
|
|
@@ -702,7 +760,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
702
760
|
const { entry, type } = action;
|
|
703
761
|
const populatedEntry = await getPopulatedEntry(entry.contentType, entry.id, { strapi: strapi2 });
|
|
704
762
|
const isEntryValid = await getEntryValidStatus(entry.contentType, populatedEntry, { strapi: strapi2 });
|
|
705
|
-
const releaseAction2 = await strapi2.
|
|
763
|
+
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
706
764
|
data: {
|
|
707
765
|
type,
|
|
708
766
|
contentType: entry.contentType,
|
|
@@ -715,32 +773,41 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
715
773
|
},
|
|
716
774
|
release: releaseId
|
|
717
775
|
},
|
|
718
|
-
populate: { release: {
|
|
776
|
+
populate: { release: { select: ["id"] }, entry: { select: ["id"] } }
|
|
719
777
|
});
|
|
720
778
|
this.updateReleaseStatus(releaseId);
|
|
721
779
|
return releaseAction2;
|
|
722
780
|
},
|
|
723
781
|
async findActions(releaseId, query) {
|
|
724
|
-
const release2 = await strapi2.
|
|
725
|
-
|
|
782
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
783
|
+
where: { id: releaseId },
|
|
784
|
+
select: ["id"]
|
|
726
785
|
});
|
|
727
786
|
if (!release2) {
|
|
728
787
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
729
788
|
}
|
|
730
|
-
|
|
731
|
-
|
|
789
|
+
const dbQuery = convertQueryParams.transformParamsToQuery(
|
|
790
|
+
RELEASE_ACTION_MODEL_UID,
|
|
791
|
+
query ?? {}
|
|
792
|
+
);
|
|
793
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
794
|
+
...dbQuery,
|
|
732
795
|
populate: {
|
|
733
796
|
entry: {
|
|
734
797
|
populate: "*"
|
|
735
798
|
}
|
|
736
799
|
},
|
|
737
|
-
|
|
800
|
+
where: {
|
|
738
801
|
release: releaseId
|
|
739
802
|
}
|
|
740
803
|
});
|
|
741
804
|
},
|
|
742
805
|
async countActions(query) {
|
|
743
|
-
|
|
806
|
+
const dbQuery = convertQueryParams.transformParamsToQuery(
|
|
807
|
+
RELEASE_ACTION_MODEL_UID,
|
|
808
|
+
query ?? {}
|
|
809
|
+
);
|
|
810
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
744
811
|
},
|
|
745
812
|
async groupActions(actions, groupBy) {
|
|
746
813
|
const contentTypeUids = actions.reduce((acc, action) => {
|
|
@@ -821,10 +888,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
821
888
|
return componentsMap;
|
|
822
889
|
},
|
|
823
890
|
async delete(releaseId) {
|
|
824
|
-
const release2 = await strapi2.
|
|
891
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
892
|
+
where: { id: releaseId },
|
|
825
893
|
populate: {
|
|
826
894
|
actions: {
|
|
827
|
-
|
|
895
|
+
select: ["id"]
|
|
828
896
|
}
|
|
829
897
|
}
|
|
830
898
|
});
|
|
@@ -842,9 +910,13 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
842
910
|
}
|
|
843
911
|
}
|
|
844
912
|
});
|
|
845
|
-
await strapi2.
|
|
913
|
+
await strapi2.db.query(RELEASE_MODEL_UID).delete({
|
|
914
|
+
where: {
|
|
915
|
+
id: releaseId
|
|
916
|
+
}
|
|
917
|
+
});
|
|
846
918
|
});
|
|
847
|
-
if (
|
|
919
|
+
if (release2.scheduledAt) {
|
|
848
920
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
849
921
|
await schedulingService.cancel(release2.id);
|
|
850
922
|
}
|
|
@@ -852,145 +924,71 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
852
924
|
return release2;
|
|
853
925
|
},
|
|
854
926
|
async publish(releaseId) {
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
actions: {
|
|
862
|
-
populate: {
|
|
863
|
-
entry: {
|
|
864
|
-
fields: ["id"]
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
);
|
|
871
|
-
if (!releaseWithPopulatedActionEntries) {
|
|
927
|
+
const {
|
|
928
|
+
release: release2,
|
|
929
|
+
error
|
|
930
|
+
} = await strapi2.db.transaction(async ({ trx }) => {
|
|
931
|
+
const lockedRelease = await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).select(["id", "name", "releasedAt", "status"]).first().transacting(trx).forUpdate().execute();
|
|
932
|
+
if (!lockedRelease) {
|
|
872
933
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
873
934
|
}
|
|
874
|
-
if (
|
|
935
|
+
if (lockedRelease.releasedAt) {
|
|
875
936
|
throw new errors.ValidationError("Release already published");
|
|
876
937
|
}
|
|
877
|
-
if (
|
|
878
|
-
throw new errors.ValidationError("
|
|
879
|
-
}
|
|
880
|
-
const collectionTypeActions = {};
|
|
881
|
-
const singleTypeActions = [];
|
|
882
|
-
for (const action of releaseWithPopulatedActionEntries.actions) {
|
|
883
|
-
const contentTypeUid = action.contentType;
|
|
884
|
-
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
885
|
-
if (!collectionTypeActions[contentTypeUid]) {
|
|
886
|
-
collectionTypeActions[contentTypeUid] = {
|
|
887
|
-
entriestoPublishIds: [],
|
|
888
|
-
entriesToUnpublishIds: []
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
if (action.type === "publish") {
|
|
892
|
-
collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
893
|
-
} else {
|
|
894
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
895
|
-
}
|
|
896
|
-
} else {
|
|
897
|
-
singleTypeActions.push({
|
|
898
|
-
uid: contentTypeUid,
|
|
899
|
-
action: action.type,
|
|
900
|
-
id: action.entry.id
|
|
901
|
-
});
|
|
902
|
-
}
|
|
938
|
+
if (lockedRelease.status === "failed") {
|
|
939
|
+
throw new errors.ValidationError("Release failed to publish");
|
|
903
940
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
await entityManagerService.publish(entry, uid);
|
|
913
|
-
} else {
|
|
914
|
-
await entityManagerService.unpublish(entry, uid);
|
|
915
|
-
}
|
|
916
|
-
} catch (error) {
|
|
917
|
-
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft")) {
|
|
918
|
-
} else {
|
|
919
|
-
throw error;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
924
|
-
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
925
|
-
const { entriestoPublishIds, entriesToUnpublishIds } = collectionTypeActions[contentTypeUid];
|
|
926
|
-
const entriesToPublish = await strapi2.entityService.findMany(
|
|
927
|
-
contentTypeUid,
|
|
928
|
-
{
|
|
929
|
-
filters: {
|
|
930
|
-
id: {
|
|
931
|
-
$in: entriestoPublishIds
|
|
932
|
-
}
|
|
933
|
-
},
|
|
934
|
-
populate
|
|
935
|
-
}
|
|
936
|
-
);
|
|
937
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
938
|
-
contentTypeUid,
|
|
939
|
-
{
|
|
940
|
-
filters: {
|
|
941
|
-
id: {
|
|
942
|
-
$in: entriesToUnpublishIds
|
|
943
|
-
}
|
|
944
|
-
},
|
|
945
|
-
populate
|
|
946
|
-
}
|
|
947
|
-
);
|
|
948
|
-
if (entriesToPublish.length > 0) {
|
|
949
|
-
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
941
|
+
try {
|
|
942
|
+
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
943
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
944
|
+
releaseId
|
|
945
|
+
);
|
|
946
|
+
await strapi2.db.transaction(async () => {
|
|
947
|
+
for (const { uid, action, id } of singleTypeActions) {
|
|
948
|
+
await publishSingleTypeAction(uid, action, id);
|
|
950
949
|
}
|
|
951
|
-
|
|
952
|
-
|
|
950
|
+
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
951
|
+
const uid = contentTypeUid;
|
|
952
|
+
await publishCollectionTypeAction(
|
|
953
|
+
uid,
|
|
954
|
+
collectionTypeActions[uid].entriesToPublishIds,
|
|
955
|
+
collectionTypeActions[uid].entriesToUnpublishIds
|
|
956
|
+
);
|
|
953
957
|
}
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
releasedAt: /* @__PURE__ */ new Date()
|
|
963
|
-
},
|
|
964
|
-
populate: {
|
|
965
|
-
actions: {
|
|
966
|
-
// @ts-expect-error is not expecting count but it is working
|
|
967
|
-
count: true
|
|
958
|
+
});
|
|
959
|
+
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
960
|
+
where: {
|
|
961
|
+
id: releaseId
|
|
962
|
+
},
|
|
963
|
+
data: {
|
|
964
|
+
status: "done",
|
|
965
|
+
releasedAt: /* @__PURE__ */ new Date()
|
|
968
966
|
}
|
|
969
|
-
}
|
|
970
|
-
});
|
|
971
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
967
|
+
});
|
|
972
968
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
973
969
|
isPublished: true,
|
|
974
|
-
release:
|
|
970
|
+
release: release22
|
|
975
971
|
});
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
} catch (error) {
|
|
980
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
972
|
+
strapi2.telemetry.send("didPublishContentRelease");
|
|
973
|
+
return { release: release22, error: null };
|
|
974
|
+
} catch (error2) {
|
|
981
975
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
982
976
|
isPublished: false,
|
|
983
|
-
error
|
|
977
|
+
error: error2
|
|
984
978
|
});
|
|
985
|
-
|
|
986
|
-
strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
987
|
-
where: { id: releaseId },
|
|
988
|
-
data: {
|
|
979
|
+
await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).update({
|
|
989
980
|
status: "failed"
|
|
990
|
-
}
|
|
991
|
-
|
|
981
|
+
}).transacting(trx).execute();
|
|
982
|
+
return {
|
|
983
|
+
release: null,
|
|
984
|
+
error: error2
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
if (error instanceof Error) {
|
|
992
989
|
throw error;
|
|
993
990
|
}
|
|
991
|
+
return release2;
|
|
994
992
|
},
|
|
995
993
|
async updateAction(actionId, releaseId, update) {
|
|
996
994
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -1077,10 +1075,19 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1077
1075
|
}
|
|
1078
1076
|
};
|
|
1079
1077
|
};
|
|
1078
|
+
class AlreadyOnReleaseError extends errors.ApplicationError {
|
|
1079
|
+
constructor(message) {
|
|
1080
|
+
super(message);
|
|
1081
|
+
this.name = "AlreadyOnReleaseError";
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1080
1084
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1081
1085
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1082
|
-
const release2 = await strapi2.
|
|
1083
|
-
|
|
1086
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
1087
|
+
where: {
|
|
1088
|
+
id: releaseId
|
|
1089
|
+
},
|
|
1090
|
+
populate: { actions: { populate: { entry: { select: ["id"] } } } }
|
|
1084
1091
|
});
|
|
1085
1092
|
if (!release2) {
|
|
1086
1093
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
@@ -1089,7 +1096,7 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1089
1096
|
(action) => Number(action.entry.id) === Number(releaseActionArgs.entry.id) && action.contentType === releaseActionArgs.entry.contentType
|
|
1090
1097
|
);
|
|
1091
1098
|
if (isEntryInRelease) {
|
|
1092
|
-
throw new
|
|
1099
|
+
throw new AlreadyOnReleaseError(
|
|
1093
1100
|
`Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`
|
|
1094
1101
|
);
|
|
1095
1102
|
}
|
|
@@ -1099,17 +1106,9 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1099
1106
|
if (!contentType) {
|
|
1100
1107
|
throw new errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);
|
|
1101
1108
|
}
|
|
1102
|
-
if (!contentType.options?.draftAndPublish) {
|
|
1103
|
-
throw new errors.ValidationError(
|
|
1104
|
-
`Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`
|
|
1105
|
-
);
|
|
1106
|
-
}
|
|
1107
1109
|
},
|
|
1108
1110
|
async validatePendingReleasesLimit() {
|
|
1109
|
-
const maximumPendingReleases = (
|
|
1110
|
-
// @ts-expect-error - options is not typed into features
|
|
1111
|
-
EE.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
1112
|
-
);
|
|
1111
|
+
const maximumPendingReleases = strapi2.ee.features.get("cms-content-releases")?.options?.maximumReleases || 3;
|
|
1113
1112
|
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
1114
1113
|
filters: {
|
|
1115
1114
|
releasedAt: {
|
|
@@ -1122,8 +1121,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1122
1121
|
}
|
|
1123
1122
|
},
|
|
1124
1123
|
async validateUniqueNameForPendingRelease(name, id) {
|
|
1125
|
-
const pendingReleases = await strapi2.
|
|
1126
|
-
|
|
1124
|
+
const pendingReleases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
1125
|
+
where: {
|
|
1127
1126
|
releasedAt: {
|
|
1128
1127
|
$null: true
|
|
1129
1128
|
},
|
|
@@ -1197,7 +1196,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1197
1196
|
const services = {
|
|
1198
1197
|
release: createReleaseService,
|
|
1199
1198
|
"release-validation": createReleaseValidationService,
|
|
1200
|
-
|
|
1199
|
+
scheduling: createSchedulingService
|
|
1201
1200
|
};
|
|
1202
1201
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
1203
1202
|
name: yup.string().trim().required(),
|
|
@@ -1250,7 +1249,7 @@ const releaseController = {
|
|
|
1250
1249
|
}
|
|
1251
1250
|
};
|
|
1252
1251
|
});
|
|
1253
|
-
const pendingReleasesCount = await strapi.query(RELEASE_MODEL_UID).count({
|
|
1252
|
+
const pendingReleasesCount = await strapi.db.query(RELEASE_MODEL_UID).count({
|
|
1254
1253
|
where: {
|
|
1255
1254
|
releasedAt: null
|
|
1256
1255
|
}
|
|
@@ -1373,6 +1372,38 @@ const releaseActionController = {
|
|
|
1373
1372
|
data: releaseAction2
|
|
1374
1373
|
};
|
|
1375
1374
|
},
|
|
1375
|
+
async createMany(ctx) {
|
|
1376
|
+
const releaseId = ctx.params.releaseId;
|
|
1377
|
+
const releaseActionsArgs = ctx.request.body;
|
|
1378
|
+
await Promise.all(
|
|
1379
|
+
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1380
|
+
);
|
|
1381
|
+
const releaseService = getService("release", { strapi });
|
|
1382
|
+
const releaseActions = await strapi.db.transaction(async () => {
|
|
1383
|
+
const releaseActions2 = await Promise.all(
|
|
1384
|
+
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1385
|
+
try {
|
|
1386
|
+
const action = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1387
|
+
return action;
|
|
1388
|
+
} catch (error) {
|
|
1389
|
+
if (error instanceof AlreadyOnReleaseError) {
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
throw error;
|
|
1393
|
+
}
|
|
1394
|
+
})
|
|
1395
|
+
);
|
|
1396
|
+
return releaseActions2;
|
|
1397
|
+
});
|
|
1398
|
+
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1399
|
+
ctx.body = {
|
|
1400
|
+
data: newReleaseActions,
|
|
1401
|
+
meta: {
|
|
1402
|
+
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1403
|
+
totalEntries: releaseActions.length
|
|
1404
|
+
}
|
|
1405
|
+
};
|
|
1406
|
+
},
|
|
1376
1407
|
async findMany(ctx) {
|
|
1377
1408
|
const releaseId = ctx.params.releaseId;
|
|
1378
1409
|
const permissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
@@ -1396,7 +1427,7 @@ const releaseActionController = {
|
|
|
1396
1427
|
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
1397
1428
|
return acc;
|
|
1398
1429
|
}, {});
|
|
1399
|
-
const sanitizedResults = await
|
|
1430
|
+
const sanitizedResults = await async.map(results, async (action) => ({
|
|
1400
1431
|
...action,
|
|
1401
1432
|
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
1402
1433
|
}));
|
|
@@ -1558,6 +1589,22 @@ const releaseAction = {
|
|
|
1558
1589
|
]
|
|
1559
1590
|
}
|
|
1560
1591
|
},
|
|
1592
|
+
{
|
|
1593
|
+
method: "POST",
|
|
1594
|
+
path: "/:releaseId/actions/bulk",
|
|
1595
|
+
handler: "release-action.createMany",
|
|
1596
|
+
config: {
|
|
1597
|
+
policies: [
|
|
1598
|
+
"admin::isAuthenticatedAdmin",
|
|
1599
|
+
{
|
|
1600
|
+
name: "admin::hasPermissions",
|
|
1601
|
+
config: {
|
|
1602
|
+
actions: ["plugin::content-releases.create-action"]
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
]
|
|
1606
|
+
}
|
|
1607
|
+
},
|
|
1561
1608
|
{
|
|
1562
1609
|
method: "GET",
|
|
1563
1610
|
path: "/:releaseId/actions",
|
|
@@ -1612,9 +1659,8 @@ const routes = {
|
|
|
1612
1659
|
release,
|
|
1613
1660
|
"release-action": releaseAction
|
|
1614
1661
|
};
|
|
1615
|
-
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1616
1662
|
const getPlugin = () => {
|
|
1617
|
-
if (features.isEnabled("cms-content-releases")) {
|
|
1663
|
+
if (strapi.ee.features.isEnabled("cms-content-releases")) {
|
|
1618
1664
|
return {
|
|
1619
1665
|
register,
|
|
1620
1666
|
bootstrap,
|