@strapi/content-releases 4.20.5 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-bpzO2Ljh.mjs → App-dbdAcsz_.mjs} +286 -288
- package/dist/_chunks/App-dbdAcsz_.mjs.map +1 -0
- package/dist/_chunks/{App-p8aKBitd.js → App-zwe_jKPv.js} +292 -294
- package/dist/_chunks/App-zwe_jKPv.js.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-AECgcaDa.mjs → index-RBaVMtyr.mjs} +78 -69
- package/dist/_chunks/index-RBaVMtyr.mjs.map +1 -0
- package/dist/_chunks/{index-fP3qoWZ4.js → index-TBrVNrv9.js} +76 -67
- package/dist/_chunks/index-TBrVNrv9.js.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 +3 -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.js
CHANGED
|
@@ -3,7 +3,6 @@ const utils = require("@strapi/utils");
|
|
|
3
3
|
const isEqual = require("lodash/isEqual");
|
|
4
4
|
const lodash = require("lodash");
|
|
5
5
|
const _ = require("lodash/fp");
|
|
6
|
-
const EE = require("@strapi/strapi/dist/utils/ee");
|
|
7
6
|
const nodeSchedule = require("node-schedule");
|
|
8
7
|
const yup = require("yup");
|
|
9
8
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
@@ -27,7 +26,6 @@ function _interopNamespace(e) {
|
|
|
27
26
|
}
|
|
28
27
|
const isEqual__default = /* @__PURE__ */ _interopDefault(isEqual);
|
|
29
28
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
|
30
|
-
const EE__default = /* @__PURE__ */ _interopDefault(EE);
|
|
31
29
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
|
32
30
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
33
31
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -84,7 +82,10 @@ const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
|
84
82
|
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
85
83
|
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
86
84
|
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
87
|
-
const entry = await strapi2.
|
|
85
|
+
const entry = await strapi2.db.query(contentTypeUid).findOne({
|
|
86
|
+
where: { id: entryId },
|
|
87
|
+
populate
|
|
88
|
+
});
|
|
88
89
|
return entry;
|
|
89
90
|
};
|
|
90
91
|
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
@@ -101,28 +102,10 @@ const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 } =
|
|
|
101
102
|
return false;
|
|
102
103
|
}
|
|
103
104
|
};
|
|
104
|
-
async function deleteActionsOnDisableDraftAndPublish({
|
|
105
|
-
oldContentTypes,
|
|
106
|
-
contentTypes: contentTypes2
|
|
107
|
-
}) {
|
|
108
|
-
if (!oldContentTypes) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
for (const uid in contentTypes2) {
|
|
112
|
-
if (!oldContentTypes[uid]) {
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
const oldContentType = oldContentTypes[uid];
|
|
116
|
-
const contentType = contentTypes2[uid];
|
|
117
|
-
if (utils.contentTypes.hasDraftAndPublish(oldContentType) && !utils.contentTypes.hasDraftAndPublish(contentType)) {
|
|
118
|
-
await strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: uid }).execute();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
105
|
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
123
106
|
const deletedContentTypes = lodash.difference(lodash.keys(oldContentTypes), lodash.keys(contentTypes2)) ?? [];
|
|
124
107
|
if (deletedContentTypes.length) {
|
|
125
|
-
await utils.
|
|
108
|
+
await utils.async.map(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
126
109
|
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
127
110
|
});
|
|
128
111
|
}
|
|
@@ -141,7 +124,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
141
124
|
}
|
|
142
125
|
}
|
|
143
126
|
});
|
|
144
|
-
utils.
|
|
127
|
+
utils.async.map(releasesWithoutStatus, async (release2) => {
|
|
145
128
|
const actions = release2.actions;
|
|
146
129
|
const notValidatedActions = actions.filter((action) => action.isEntryValid === null);
|
|
147
130
|
for (const action of notValidatedActions) {
|
|
@@ -172,7 +155,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
172
155
|
}
|
|
173
156
|
}
|
|
174
157
|
});
|
|
175
|
-
utils.
|
|
158
|
+
utils.async.map(publishedReleases, async (release2) => {
|
|
176
159
|
return strapi.db.query(RELEASE_MODEL_UID).update({
|
|
177
160
|
where: {
|
|
178
161
|
id: release2.id
|
|
@@ -185,11 +168,9 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
185
168
|
}
|
|
186
169
|
async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
187
170
|
if (oldContentTypes !== void 0 && contentTypes2 !== void 0) {
|
|
188
|
-
const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes)
|
|
189
|
-
(uid) => oldContentTypes[uid]?.options?.draftAndPublish
|
|
190
|
-
);
|
|
171
|
+
const contentTypesWithDraftAndPublish = Object.keys(oldContentTypes);
|
|
191
172
|
const releasesAffected = /* @__PURE__ */ new Set();
|
|
192
|
-
utils.
|
|
173
|
+
utils.async.map(contentTypesWithDraftAndPublish, async (contentTypeUID) => {
|
|
193
174
|
const oldContentType = oldContentTypes[contentTypeUID];
|
|
194
175
|
const contentType = contentTypes2[contentTypeUID];
|
|
195
176
|
if (!isEqual__default.default(oldContentType?.attributes, contentType?.attributes)) {
|
|
@@ -202,7 +183,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
202
183
|
release: true
|
|
203
184
|
}
|
|
204
185
|
});
|
|
205
|
-
await utils.
|
|
186
|
+
await utils.async.map(actions, async (action) => {
|
|
206
187
|
if (action.entry && action.release) {
|
|
207
188
|
const populatedEntry = await getPopulatedEntry(contentTypeUID, action.entry.id, {
|
|
208
189
|
strapi
|
|
@@ -225,7 +206,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
225
206
|
});
|
|
226
207
|
}
|
|
227
208
|
}).then(() => {
|
|
228
|
-
utils.
|
|
209
|
+
utils.async.map(releasesAffected, async (releaseId) => {
|
|
229
210
|
return getService("release", { strapi }).updateReleaseStatus(releaseId);
|
|
230
211
|
});
|
|
231
212
|
});
|
|
@@ -271,11 +252,10 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
271
252
|
}
|
|
272
253
|
}
|
|
273
254
|
}
|
|
274
|
-
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
275
255
|
const register = async ({ strapi: strapi2 }) => {
|
|
276
|
-
if (features
|
|
256
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
277
257
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
278
|
-
strapi2.hook("strapi::content-types.beforeSync").register(
|
|
258
|
+
strapi2.hook("strapi::content-types.beforeSync").register(disableContentTypeLocalized);
|
|
279
259
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
280
260
|
}
|
|
281
261
|
if (strapi2.plugin("graphql")) {
|
|
@@ -284,12 +264,9 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
284
264
|
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
285
265
|
}
|
|
286
266
|
};
|
|
287
|
-
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
288
267
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
289
|
-
if (features
|
|
290
|
-
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes)
|
|
291
|
-
(uid) => strapi2.contentTypes[uid]?.options?.draftAndPublish
|
|
292
|
-
);
|
|
268
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
269
|
+
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes);
|
|
293
270
|
strapi2.db.lifecycles.subscribe({
|
|
294
271
|
models: contentTypesWithDraftAndPublish,
|
|
295
272
|
async afterDelete(event) {
|
|
@@ -325,7 +302,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
325
302
|
*/
|
|
326
303
|
async beforeDeleteMany(event) {
|
|
327
304
|
const { model, params } = event;
|
|
328
|
-
if (model.kind === "collectionType"
|
|
305
|
+
if (model.kind === "collectionType") {
|
|
329
306
|
const { where } = params;
|
|
330
307
|
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
331
308
|
event.state.entriesToDelete = entriesToDelete;
|
|
@@ -407,27 +384,23 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
407
384
|
}
|
|
408
385
|
}
|
|
409
386
|
});
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
});
|
|
420
|
-
}
|
|
387
|
+
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
388
|
+
strapi2.log.error(
|
|
389
|
+
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
390
|
+
);
|
|
391
|
+
throw err;
|
|
392
|
+
});
|
|
393
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
394
|
+
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
395
|
+
});
|
|
421
396
|
}
|
|
422
397
|
};
|
|
423
398
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
job.cancel();
|
|
430
|
-
}
|
|
399
|
+
const scheduledJobs = getService("scheduling", {
|
|
400
|
+
strapi: strapi2
|
|
401
|
+
}).getAll();
|
|
402
|
+
for (const [, job] of scheduledJobs) {
|
|
403
|
+
job.cancel();
|
|
431
404
|
}
|
|
432
405
|
};
|
|
433
406
|
const schema$1 = {
|
|
@@ -552,6 +525,94 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
552
525
|
release: release2
|
|
553
526
|
});
|
|
554
527
|
};
|
|
528
|
+
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
529
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
530
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
531
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
532
|
+
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
533
|
+
try {
|
|
534
|
+
if (actionType === "publish") {
|
|
535
|
+
await entityManagerService.publish(entry, uid);
|
|
536
|
+
} else {
|
|
537
|
+
await entityManagerService.unpublish(entry, uid);
|
|
538
|
+
}
|
|
539
|
+
} catch (error) {
|
|
540
|
+
if (error instanceof utils.errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
541
|
+
;
|
|
542
|
+
else {
|
|
543
|
+
throw error;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
548
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
549
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
550
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
551
|
+
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
552
|
+
filters: {
|
|
553
|
+
id: {
|
|
554
|
+
$in: entriesToPublishIds
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
populate
|
|
558
|
+
});
|
|
559
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
560
|
+
filters: {
|
|
561
|
+
id: {
|
|
562
|
+
$in: entriestoUnpublishIds
|
|
563
|
+
}
|
|
564
|
+
},
|
|
565
|
+
populate
|
|
566
|
+
});
|
|
567
|
+
if (entriesToPublish.length > 0) {
|
|
568
|
+
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
569
|
+
}
|
|
570
|
+
if (entriesToUnpublish.length > 0) {
|
|
571
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
const getFormattedActions = async (releaseId) => {
|
|
575
|
+
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
576
|
+
where: {
|
|
577
|
+
release: {
|
|
578
|
+
id: releaseId
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
populate: {
|
|
582
|
+
entry: {
|
|
583
|
+
fields: ["id"]
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
if (actions.length === 0) {
|
|
588
|
+
throw new utils.errors.ValidationError("No entries to publish");
|
|
589
|
+
}
|
|
590
|
+
const collectionTypeActions = {};
|
|
591
|
+
const singleTypeActions = [];
|
|
592
|
+
for (const action of actions) {
|
|
593
|
+
const contentTypeUid = action.contentType;
|
|
594
|
+
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
595
|
+
if (!collectionTypeActions[contentTypeUid]) {
|
|
596
|
+
collectionTypeActions[contentTypeUid] = {
|
|
597
|
+
entriesToPublishIds: [],
|
|
598
|
+
entriesToUnpublishIds: []
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
if (action.type === "publish") {
|
|
602
|
+
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
603
|
+
} else {
|
|
604
|
+
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
singleTypeActions.push({
|
|
608
|
+
uid: contentTypeUid,
|
|
609
|
+
action: action.type,
|
|
610
|
+
id: action.entry.id
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return { collectionTypeActions, singleTypeActions };
|
|
615
|
+
};
|
|
555
616
|
return {
|
|
556
617
|
async create(releaseData, { user }) {
|
|
557
618
|
const releaseWithCreatorFields = await utils.setCreatorFields({ user })(releaseData);
|
|
@@ -565,13 +626,13 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
565
626
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),
|
|
566
627
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
567
628
|
]);
|
|
568
|
-
const release2 = await strapi2.
|
|
629
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).create({
|
|
569
630
|
data: {
|
|
570
631
|
...releaseWithCreatorFields,
|
|
571
632
|
status: "empty"
|
|
572
633
|
}
|
|
573
634
|
});
|
|
574
|
-
if (
|
|
635
|
+
if (releaseWithCreatorFields.scheduledAt) {
|
|
575
636
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
576
637
|
await schedulingService.set(release2.id, release2.scheduledAt);
|
|
577
638
|
}
|
|
@@ -579,17 +640,19 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
579
640
|
return release2;
|
|
580
641
|
},
|
|
581
642
|
async findOne(id, query = {}) {
|
|
582
|
-
const
|
|
583
|
-
|
|
643
|
+
const dbQuery = utils.convertQueryParams.transformParamsToQuery(RELEASE_MODEL_UID, query);
|
|
644
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
645
|
+
...dbQuery,
|
|
646
|
+
where: { id }
|
|
584
647
|
});
|
|
585
648
|
return release2;
|
|
586
649
|
},
|
|
587
650
|
findPage(query) {
|
|
588
|
-
|
|
589
|
-
|
|
651
|
+
const dbQuery = utils.convertQueryParams.transformParamsToQuery(RELEASE_MODEL_UID, query ?? {});
|
|
652
|
+
return strapi2.db.query(RELEASE_MODEL_UID).findPage({
|
|
653
|
+
...dbQuery,
|
|
590
654
|
populate: {
|
|
591
655
|
actions: {
|
|
592
|
-
// @ts-expect-error Ignore missing properties
|
|
593
656
|
count: true
|
|
594
657
|
}
|
|
595
658
|
}
|
|
@@ -681,28 +744,22 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
681
744
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),
|
|
682
745
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
683
746
|
]);
|
|
684
|
-
const release2 = await strapi2.
|
|
747
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id } });
|
|
685
748
|
if (!release2) {
|
|
686
749
|
throw new utils.errors.NotFoundError(`No release found for id ${id}`);
|
|
687
750
|
}
|
|
688
751
|
if (release2.releasedAt) {
|
|
689
752
|
throw new utils.errors.ValidationError("Release already published");
|
|
690
753
|
}
|
|
691
|
-
const updatedRelease = await strapi2.
|
|
692
|
-
|
|
693
|
-
* The type returned from the entity service: Partial<Input<"plugin::content-releases.release">>
|
|
694
|
-
* is not compatible with the type we are passing here: UpdateRelease.Request['body']
|
|
695
|
-
*/
|
|
696
|
-
// @ts-expect-error see above
|
|
754
|
+
const updatedRelease = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
755
|
+
where: { id },
|
|
697
756
|
data: releaseWithCreatorFields
|
|
698
757
|
});
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
schedulingService.cancel(id);
|
|
705
|
-
}
|
|
758
|
+
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
759
|
+
if (releaseData.scheduledAt) {
|
|
760
|
+
await schedulingService.set(id, releaseData.scheduledAt);
|
|
761
|
+
} else if (release2.scheduledAt) {
|
|
762
|
+
schedulingService.cancel(id);
|
|
706
763
|
}
|
|
707
764
|
this.updateReleaseStatus(id);
|
|
708
765
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
@@ -716,7 +773,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
716
773
|
validateEntryContentType(action.entry.contentType),
|
|
717
774
|
validateUniqueEntry(releaseId, action)
|
|
718
775
|
]);
|
|
719
|
-
const release2 = await strapi2.
|
|
776
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
720
777
|
if (!release2) {
|
|
721
778
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
722
779
|
}
|
|
@@ -726,7 +783,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
726
783
|
const { entry, type } = action;
|
|
727
784
|
const populatedEntry = await getPopulatedEntry(entry.contentType, entry.id, { strapi: strapi2 });
|
|
728
785
|
const isEntryValid = await getEntryValidStatus(entry.contentType, populatedEntry, { strapi: strapi2 });
|
|
729
|
-
const releaseAction2 = await strapi2.
|
|
786
|
+
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
730
787
|
data: {
|
|
731
788
|
type,
|
|
732
789
|
contentType: entry.contentType,
|
|
@@ -739,32 +796,41 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
739
796
|
},
|
|
740
797
|
release: releaseId
|
|
741
798
|
},
|
|
742
|
-
populate: { release: {
|
|
799
|
+
populate: { release: { select: ["id"] }, entry: { select: ["id"] } }
|
|
743
800
|
});
|
|
744
801
|
this.updateReleaseStatus(releaseId);
|
|
745
802
|
return releaseAction2;
|
|
746
803
|
},
|
|
747
804
|
async findActions(releaseId, query) {
|
|
748
|
-
const release2 = await strapi2.
|
|
749
|
-
|
|
805
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
806
|
+
where: { id: releaseId },
|
|
807
|
+
select: ["id"]
|
|
750
808
|
});
|
|
751
809
|
if (!release2) {
|
|
752
810
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
753
811
|
}
|
|
754
|
-
|
|
755
|
-
|
|
812
|
+
const dbQuery = utils.convertQueryParams.transformParamsToQuery(
|
|
813
|
+
RELEASE_ACTION_MODEL_UID,
|
|
814
|
+
query ?? {}
|
|
815
|
+
);
|
|
816
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
817
|
+
...dbQuery,
|
|
756
818
|
populate: {
|
|
757
819
|
entry: {
|
|
758
820
|
populate: "*"
|
|
759
821
|
}
|
|
760
822
|
},
|
|
761
|
-
|
|
823
|
+
where: {
|
|
762
824
|
release: releaseId
|
|
763
825
|
}
|
|
764
826
|
});
|
|
765
827
|
},
|
|
766
828
|
async countActions(query) {
|
|
767
|
-
|
|
829
|
+
const dbQuery = utils.convertQueryParams.transformParamsToQuery(
|
|
830
|
+
RELEASE_ACTION_MODEL_UID,
|
|
831
|
+
query ?? {}
|
|
832
|
+
);
|
|
833
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
768
834
|
},
|
|
769
835
|
async groupActions(actions, groupBy) {
|
|
770
836
|
const contentTypeUids = actions.reduce((acc, action) => {
|
|
@@ -845,10 +911,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
845
911
|
return componentsMap;
|
|
846
912
|
},
|
|
847
913
|
async delete(releaseId) {
|
|
848
|
-
const release2 = await strapi2.
|
|
914
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
915
|
+
where: { id: releaseId },
|
|
849
916
|
populate: {
|
|
850
917
|
actions: {
|
|
851
|
-
|
|
918
|
+
select: ["id"]
|
|
852
919
|
}
|
|
853
920
|
}
|
|
854
921
|
});
|
|
@@ -866,9 +933,13 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
866
933
|
}
|
|
867
934
|
}
|
|
868
935
|
});
|
|
869
|
-
await strapi2.
|
|
936
|
+
await strapi2.db.query(RELEASE_MODEL_UID).delete({
|
|
937
|
+
where: {
|
|
938
|
+
id: releaseId
|
|
939
|
+
}
|
|
940
|
+
});
|
|
870
941
|
});
|
|
871
|
-
if (
|
|
942
|
+
if (release2.scheduledAt) {
|
|
872
943
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
873
944
|
await schedulingService.cancel(release2.id);
|
|
874
945
|
}
|
|
@@ -876,145 +947,71 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
876
947
|
return release2;
|
|
877
948
|
},
|
|
878
949
|
async publish(releaseId) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
actions: {
|
|
886
|
-
populate: {
|
|
887
|
-
entry: {
|
|
888
|
-
fields: ["id"]
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
);
|
|
895
|
-
if (!releaseWithPopulatedActionEntries) {
|
|
950
|
+
const {
|
|
951
|
+
release: release2,
|
|
952
|
+
error
|
|
953
|
+
} = await strapi2.db.transaction(async ({ trx }) => {
|
|
954
|
+
const lockedRelease = await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).select(["id", "name", "releasedAt", "status"]).first().transacting(trx).forUpdate().execute();
|
|
955
|
+
if (!lockedRelease) {
|
|
896
956
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
897
957
|
}
|
|
898
|
-
if (
|
|
958
|
+
if (lockedRelease.releasedAt) {
|
|
899
959
|
throw new utils.errors.ValidationError("Release already published");
|
|
900
960
|
}
|
|
901
|
-
if (
|
|
902
|
-
throw new utils.errors.ValidationError("
|
|
903
|
-
}
|
|
904
|
-
const collectionTypeActions = {};
|
|
905
|
-
const singleTypeActions = [];
|
|
906
|
-
for (const action of releaseWithPopulatedActionEntries.actions) {
|
|
907
|
-
const contentTypeUid = action.contentType;
|
|
908
|
-
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
909
|
-
if (!collectionTypeActions[contentTypeUid]) {
|
|
910
|
-
collectionTypeActions[contentTypeUid] = {
|
|
911
|
-
entriestoPublishIds: [],
|
|
912
|
-
entriesToUnpublishIds: []
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
if (action.type === "publish") {
|
|
916
|
-
collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
917
|
-
} else {
|
|
918
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
919
|
-
}
|
|
920
|
-
} else {
|
|
921
|
-
singleTypeActions.push({
|
|
922
|
-
uid: contentTypeUid,
|
|
923
|
-
action: action.type,
|
|
924
|
-
id: action.entry.id
|
|
925
|
-
});
|
|
926
|
-
}
|
|
961
|
+
if (lockedRelease.status === "failed") {
|
|
962
|
+
throw new utils.errors.ValidationError("Release failed to publish");
|
|
927
963
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
await entityManagerService.publish(entry, uid);
|
|
937
|
-
} else {
|
|
938
|
-
await entityManagerService.unpublish(entry, uid);
|
|
939
|
-
}
|
|
940
|
-
} catch (error) {
|
|
941
|
-
if (error instanceof utils.errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft")) {
|
|
942
|
-
} else {
|
|
943
|
-
throw error;
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
948
|
-
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
949
|
-
const { entriestoPublishIds, entriesToUnpublishIds } = collectionTypeActions[contentTypeUid];
|
|
950
|
-
const entriesToPublish = await strapi2.entityService.findMany(
|
|
951
|
-
contentTypeUid,
|
|
952
|
-
{
|
|
953
|
-
filters: {
|
|
954
|
-
id: {
|
|
955
|
-
$in: entriestoPublishIds
|
|
956
|
-
}
|
|
957
|
-
},
|
|
958
|
-
populate
|
|
959
|
-
}
|
|
960
|
-
);
|
|
961
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
962
|
-
contentTypeUid,
|
|
963
|
-
{
|
|
964
|
-
filters: {
|
|
965
|
-
id: {
|
|
966
|
-
$in: entriesToUnpublishIds
|
|
967
|
-
}
|
|
968
|
-
},
|
|
969
|
-
populate
|
|
970
|
-
}
|
|
971
|
-
);
|
|
972
|
-
if (entriesToPublish.length > 0) {
|
|
973
|
-
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
964
|
+
try {
|
|
965
|
+
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
966
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
967
|
+
releaseId
|
|
968
|
+
);
|
|
969
|
+
await strapi2.db.transaction(async () => {
|
|
970
|
+
for (const { uid, action, id } of singleTypeActions) {
|
|
971
|
+
await publishSingleTypeAction(uid, action, id);
|
|
974
972
|
}
|
|
975
|
-
|
|
976
|
-
|
|
973
|
+
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
974
|
+
const uid = contentTypeUid;
|
|
975
|
+
await publishCollectionTypeAction(
|
|
976
|
+
uid,
|
|
977
|
+
collectionTypeActions[uid].entriesToPublishIds,
|
|
978
|
+
collectionTypeActions[uid].entriesToUnpublishIds
|
|
979
|
+
);
|
|
977
980
|
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
releasedAt: /* @__PURE__ */ new Date()
|
|
987
|
-
},
|
|
988
|
-
populate: {
|
|
989
|
-
actions: {
|
|
990
|
-
// @ts-expect-error is not expecting count but it is working
|
|
991
|
-
count: true
|
|
981
|
+
});
|
|
982
|
+
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
983
|
+
where: {
|
|
984
|
+
id: releaseId
|
|
985
|
+
},
|
|
986
|
+
data: {
|
|
987
|
+
status: "done",
|
|
988
|
+
releasedAt: /* @__PURE__ */ new Date()
|
|
992
989
|
}
|
|
993
|
-
}
|
|
994
|
-
});
|
|
995
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
990
|
+
});
|
|
996
991
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
997
992
|
isPublished: true,
|
|
998
|
-
release:
|
|
993
|
+
release: release22
|
|
999
994
|
});
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
} catch (error) {
|
|
1004
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
995
|
+
strapi2.telemetry.send("didPublishContentRelease");
|
|
996
|
+
return { release: release22, error: null };
|
|
997
|
+
} catch (error2) {
|
|
1005
998
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
1006
999
|
isPublished: false,
|
|
1007
|
-
error
|
|
1000
|
+
error: error2
|
|
1008
1001
|
});
|
|
1009
|
-
|
|
1010
|
-
strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1011
|
-
where: { id: releaseId },
|
|
1012
|
-
data: {
|
|
1002
|
+
await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).update({
|
|
1013
1003
|
status: "failed"
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1004
|
+
}).transacting(trx).execute();
|
|
1005
|
+
return {
|
|
1006
|
+
release: null,
|
|
1007
|
+
error: error2
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
1011
|
+
if (error instanceof Error) {
|
|
1016
1012
|
throw error;
|
|
1017
1013
|
}
|
|
1014
|
+
return release2;
|
|
1018
1015
|
},
|
|
1019
1016
|
async updateAction(actionId, releaseId, update) {
|
|
1020
1017
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -1101,10 +1098,19 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1101
1098
|
}
|
|
1102
1099
|
};
|
|
1103
1100
|
};
|
|
1101
|
+
class AlreadyOnReleaseError extends utils.errors.ApplicationError {
|
|
1102
|
+
constructor(message) {
|
|
1103
|
+
super(message);
|
|
1104
|
+
this.name = "AlreadyOnReleaseError";
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1104
1107
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1105
1108
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1106
|
-
const release2 = await strapi2.
|
|
1107
|
-
|
|
1109
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
1110
|
+
where: {
|
|
1111
|
+
id: releaseId
|
|
1112
|
+
},
|
|
1113
|
+
populate: { actions: { populate: { entry: { select: ["id"] } } } }
|
|
1108
1114
|
});
|
|
1109
1115
|
if (!release2) {
|
|
1110
1116
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
@@ -1113,7 +1119,7 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1113
1119
|
(action) => Number(action.entry.id) === Number(releaseActionArgs.entry.id) && action.contentType === releaseActionArgs.entry.contentType
|
|
1114
1120
|
);
|
|
1115
1121
|
if (isEntryInRelease) {
|
|
1116
|
-
throw new
|
|
1122
|
+
throw new AlreadyOnReleaseError(
|
|
1117
1123
|
`Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`
|
|
1118
1124
|
);
|
|
1119
1125
|
}
|
|
@@ -1123,17 +1129,9 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1123
1129
|
if (!contentType) {
|
|
1124
1130
|
throw new utils.errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);
|
|
1125
1131
|
}
|
|
1126
|
-
if (!contentType.options?.draftAndPublish) {
|
|
1127
|
-
throw new utils.errors.ValidationError(
|
|
1128
|
-
`Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`
|
|
1129
|
-
);
|
|
1130
|
-
}
|
|
1131
1132
|
},
|
|
1132
1133
|
async validatePendingReleasesLimit() {
|
|
1133
|
-
const maximumPendingReleases = (
|
|
1134
|
-
// @ts-expect-error - options is not typed into features
|
|
1135
|
-
EE__default.default.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
1136
|
-
);
|
|
1134
|
+
const maximumPendingReleases = strapi2.ee.features.get("cms-content-releases")?.options?.maximumReleases || 3;
|
|
1137
1135
|
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
1138
1136
|
filters: {
|
|
1139
1137
|
releasedAt: {
|
|
@@ -1146,8 +1144,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1146
1144
|
}
|
|
1147
1145
|
},
|
|
1148
1146
|
async validateUniqueNameForPendingRelease(name, id) {
|
|
1149
|
-
const pendingReleases = await strapi2.
|
|
1150
|
-
|
|
1147
|
+
const pendingReleases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
1148
|
+
where: {
|
|
1151
1149
|
releasedAt: {
|
|
1152
1150
|
$null: true
|
|
1153
1151
|
},
|
|
@@ -1221,7 +1219,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1221
1219
|
const services = {
|
|
1222
1220
|
release: createReleaseService,
|
|
1223
1221
|
"release-validation": createReleaseValidationService,
|
|
1224
|
-
|
|
1222
|
+
scheduling: createSchedulingService
|
|
1225
1223
|
};
|
|
1226
1224
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
1227
1225
|
name: yup__namespace.string().trim().required(),
|
|
@@ -1274,7 +1272,7 @@ const releaseController = {
|
|
|
1274
1272
|
}
|
|
1275
1273
|
};
|
|
1276
1274
|
});
|
|
1277
|
-
const pendingReleasesCount = await strapi.query(RELEASE_MODEL_UID).count({
|
|
1275
|
+
const pendingReleasesCount = await strapi.db.query(RELEASE_MODEL_UID).count({
|
|
1278
1276
|
where: {
|
|
1279
1277
|
releasedAt: null
|
|
1280
1278
|
}
|
|
@@ -1397,6 +1395,38 @@ const releaseActionController = {
|
|
|
1397
1395
|
data: releaseAction2
|
|
1398
1396
|
};
|
|
1399
1397
|
},
|
|
1398
|
+
async createMany(ctx) {
|
|
1399
|
+
const releaseId = ctx.params.releaseId;
|
|
1400
|
+
const releaseActionsArgs = ctx.request.body;
|
|
1401
|
+
await Promise.all(
|
|
1402
|
+
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1403
|
+
);
|
|
1404
|
+
const releaseService = getService("release", { strapi });
|
|
1405
|
+
const releaseActions = await strapi.db.transaction(async () => {
|
|
1406
|
+
const releaseActions2 = await Promise.all(
|
|
1407
|
+
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1408
|
+
try {
|
|
1409
|
+
const action = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1410
|
+
return action;
|
|
1411
|
+
} catch (error) {
|
|
1412
|
+
if (error instanceof AlreadyOnReleaseError) {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
throw error;
|
|
1416
|
+
}
|
|
1417
|
+
})
|
|
1418
|
+
);
|
|
1419
|
+
return releaseActions2;
|
|
1420
|
+
});
|
|
1421
|
+
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1422
|
+
ctx.body = {
|
|
1423
|
+
data: newReleaseActions,
|
|
1424
|
+
meta: {
|
|
1425
|
+
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1426
|
+
totalEntries: releaseActions.length
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
},
|
|
1400
1430
|
async findMany(ctx) {
|
|
1401
1431
|
const releaseId = ctx.params.releaseId;
|
|
1402
1432
|
const permissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
@@ -1420,7 +1450,7 @@ const releaseActionController = {
|
|
|
1420
1450
|
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
1421
1451
|
return acc;
|
|
1422
1452
|
}, {});
|
|
1423
|
-
const sanitizedResults = await utils.
|
|
1453
|
+
const sanitizedResults = await utils.async.map(results, async (action) => ({
|
|
1424
1454
|
...action,
|
|
1425
1455
|
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
1426
1456
|
}));
|
|
@@ -1582,6 +1612,22 @@ const releaseAction = {
|
|
|
1582
1612
|
]
|
|
1583
1613
|
}
|
|
1584
1614
|
},
|
|
1615
|
+
{
|
|
1616
|
+
method: "POST",
|
|
1617
|
+
path: "/:releaseId/actions/bulk",
|
|
1618
|
+
handler: "release-action.createMany",
|
|
1619
|
+
config: {
|
|
1620
|
+
policies: [
|
|
1621
|
+
"admin::isAuthenticatedAdmin",
|
|
1622
|
+
{
|
|
1623
|
+
name: "admin::hasPermissions",
|
|
1624
|
+
config: {
|
|
1625
|
+
actions: ["plugin::content-releases.create-action"]
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
]
|
|
1629
|
+
}
|
|
1630
|
+
},
|
|
1585
1631
|
{
|
|
1586
1632
|
method: "GET",
|
|
1587
1633
|
path: "/:releaseId/actions",
|
|
@@ -1636,9 +1682,8 @@ const routes = {
|
|
|
1636
1682
|
release,
|
|
1637
1683
|
"release-action": releaseAction
|
|
1638
1684
|
};
|
|
1639
|
-
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1640
1685
|
const getPlugin = () => {
|
|
1641
|
-
if (features.isEnabled("cms-content-releases")) {
|
|
1686
|
+
if (strapi.ee.features.isEnabled("cms-content-releases")) {
|
|
1642
1687
|
return {
|
|
1643
1688
|
register,
|
|
1644
1689
|
bootstrap,
|