@strapi/content-releases 0.0.0-experimental.e5740babedd53cf5b6af99d74920b6b9ef1e4c11 → 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813
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-HVXzE3i3.mjs → App-BsUSTHVD.mjs} +243 -213
- package/dist/_chunks/App-BsUSTHVD.mjs.map +1 -0
- package/dist/_chunks/{App-l62gIUTX.js → App-CXRpb2hi.js} +258 -228
- package/dist/_chunks/App-CXRpb2hi.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-Be3acS2L.js} +8 -7
- package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +9 -8
- package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
- package/dist/_chunks/{en-RdapH-9X.mjs → en-B9Ur3VsE.mjs} +11 -2
- package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
- package/dist/_chunks/{en-faJDuv3q.js → en-DtFJ5ViE.js} +11 -2
- package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
- package/dist/_chunks/{index-ML_b3php.js → index-B6-lic1Q.js} +340 -113
- package/dist/_chunks/index-B6-lic1Q.js.map +1 -0
- package/dist/_chunks/{index-Ys87ROOe.mjs → index-DJLIZdZv.mjs} +339 -112
- package/dist/_chunks/index-DJLIZdZv.mjs.map +1 -0
- package/dist/admin/index.js +1 -15
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +2 -16
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/components/CMReleasesContainer.d.ts +22 -0
- package/dist/admin/src/components/RelativeTime.d.ts +28 -0
- package/dist/admin/src/components/ReleaseAction.d.ts +3 -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/ReleaseListCell.d.ts +0 -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 +429 -0
- package/dist/admin/src/store/hooks.d.ts +7 -0
- package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
- package/dist/admin/src/utils/time.d.ts +1 -0
- package/dist/server/index.js +152 -93
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +153 -93
- 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 +20 -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 +12 -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 +2096 -0
- package/dist/server/src/index.d.ts.map +1 -0
- package/dist/server/src/migrations/index.d.ts +13 -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 +182 -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 +26 -31
- package/dist/_chunks/App-HVXzE3i3.mjs.map +0 -1
- package/dist/_chunks/App-l62gIUTX.js.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
- package/dist/_chunks/en-RdapH-9X.mjs.map +0 -1
- package/dist/_chunks/en-faJDuv3q.js.map +0 -1
- package/dist/_chunks/index-ML_b3php.js.map +0 -1
- package/dist/_chunks/index-Ys87ROOe.mjs.map +0 -1
package/dist/server/index.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { contentTypes as contentTypes$1,
|
|
1
|
+
import { contentTypes as contentTypes$1, async, setCreatorFields, 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";
|
|
@@ -54,16 +53,19 @@ const ACTIONS = [
|
|
|
54
53
|
const ALLOWED_WEBHOOK_EVENTS = {
|
|
55
54
|
RELEASES_PUBLISH: "releases.publish"
|
|
56
55
|
};
|
|
57
|
-
const getService = (name, { strapi: strapi2 }
|
|
56
|
+
const getService = (name, { strapi: strapi2 }) => {
|
|
58
57
|
return strapi2.plugin("content-releases").service(name);
|
|
59
58
|
};
|
|
60
|
-
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 }
|
|
59
|
+
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 }) => {
|
|
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
|
-
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 }
|
|
68
|
+
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 }) => {
|
|
67
69
|
try {
|
|
68
70
|
await strapi2.entityValidator.validateEntityCreation(
|
|
69
71
|
strapi2.getModel(contentTypeUid),
|
|
@@ -98,7 +100,7 @@ async function deleteActionsOnDisableDraftAndPublish({
|
|
|
98
100
|
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
99
101
|
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes2)) ?? [];
|
|
100
102
|
if (deletedContentTypes.length) {
|
|
101
|
-
await
|
|
103
|
+
await async.map(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
102
104
|
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
103
105
|
});
|
|
104
106
|
}
|
|
@@ -117,7 +119,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
});
|
|
120
|
-
|
|
122
|
+
async.map(releasesWithoutStatus, async (release2) => {
|
|
121
123
|
const actions = release2.actions;
|
|
122
124
|
const notValidatedActions = actions.filter((action) => action.isEntryValid === null);
|
|
123
125
|
for (const action of notValidatedActions) {
|
|
@@ -148,7 +150,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
});
|
|
151
|
-
|
|
153
|
+
async.map(publishedReleases, async (release2) => {
|
|
152
154
|
return strapi.db.query(RELEASE_MODEL_UID).update({
|
|
153
155
|
where: {
|
|
154
156
|
id: release2.id
|
|
@@ -165,7 +167,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
165
167
|
(uid) => oldContentTypes[uid]?.options?.draftAndPublish
|
|
166
168
|
);
|
|
167
169
|
const releasesAffected = /* @__PURE__ */ new Set();
|
|
168
|
-
|
|
170
|
+
async.map(contentTypesWithDraftAndPublish, async (contentTypeUID) => {
|
|
169
171
|
const oldContentType = oldContentTypes[contentTypeUID];
|
|
170
172
|
const contentType = contentTypes2[contentTypeUID];
|
|
171
173
|
if (!isEqual(oldContentType?.attributes, contentType?.attributes)) {
|
|
@@ -178,7 +180,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
178
180
|
release: true
|
|
179
181
|
}
|
|
180
182
|
});
|
|
181
|
-
await
|
|
183
|
+
await async.map(actions, async (action) => {
|
|
182
184
|
if (action.entry && action.release) {
|
|
183
185
|
const populatedEntry = await getPopulatedEntry(contentTypeUID, action.entry.id, {
|
|
184
186
|
strapi
|
|
@@ -201,7 +203,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
201
203
|
});
|
|
202
204
|
}
|
|
203
205
|
}).then(() => {
|
|
204
|
-
|
|
206
|
+
async.map(releasesAffected, async (releaseId) => {
|
|
205
207
|
return getService("release", { strapi }).updateReleaseStatus(releaseId);
|
|
206
208
|
});
|
|
207
209
|
});
|
|
@@ -211,13 +213,16 @@ async function disableContentTypeLocalized({ oldContentTypes, contentTypes: cont
|
|
|
211
213
|
if (!oldContentTypes) {
|
|
212
214
|
return;
|
|
213
215
|
}
|
|
216
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
217
|
+
if (!i18nPlugin) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
214
220
|
for (const uid in contentTypes2) {
|
|
215
221
|
if (!oldContentTypes[uid]) {
|
|
216
222
|
continue;
|
|
217
223
|
}
|
|
218
224
|
const oldContentType = oldContentTypes[uid];
|
|
219
225
|
const contentType = contentTypes2[uid];
|
|
220
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
221
226
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
222
227
|
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
223
228
|
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -230,13 +235,16 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
230
235
|
if (!oldContentTypes) {
|
|
231
236
|
return;
|
|
232
237
|
}
|
|
238
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
239
|
+
if (!i18nPlugin) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
233
242
|
for (const uid in contentTypes2) {
|
|
234
243
|
if (!oldContentTypes[uid]) {
|
|
235
244
|
continue;
|
|
236
245
|
}
|
|
237
246
|
const oldContentType = oldContentTypes[uid];
|
|
238
247
|
const contentType = contentTypes2[uid];
|
|
239
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
240
248
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
241
249
|
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
242
250
|
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
@@ -247,11 +255,10 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
247
255
|
}
|
|
248
256
|
}
|
|
249
257
|
}
|
|
250
|
-
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
251
258
|
const register = async ({ strapi: strapi2 }) => {
|
|
252
|
-
if (features
|
|
253
|
-
await strapi2.admin
|
|
254
|
-
strapi2.hook("strapi::content-types.beforeSync").register(
|
|
259
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
260
|
+
await strapi2.service("admin::permission").actionProvider.registerMany(ACTIONS);
|
|
261
|
+
strapi2.hook("strapi::content-types.beforeSync").register(disableContentTypeLocalized).register(deleteActionsOnDisableDraftAndPublish);
|
|
255
262
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
256
263
|
}
|
|
257
264
|
if (strapi2.plugin("graphql")) {
|
|
@@ -260,9 +267,8 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
260
267
|
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
261
268
|
}
|
|
262
269
|
};
|
|
263
|
-
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
264
270
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
265
|
-
if (features
|
|
271
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
266
272
|
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes).filter(
|
|
267
273
|
(uid) => strapi2.contentTypes[uid]?.options?.draftAndPublish
|
|
268
274
|
);
|
|
@@ -321,9 +327,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
321
327
|
actions: {
|
|
322
328
|
target_type: model.uid,
|
|
323
329
|
target_id: {
|
|
324
|
-
$in: entriesToDelete.map(
|
|
325
|
-
(entry) => entry.id
|
|
326
|
-
)
|
|
330
|
+
$in: entriesToDelete.map((entry) => entry.id)
|
|
327
331
|
}
|
|
328
332
|
}
|
|
329
333
|
}
|
|
@@ -350,13 +354,9 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
350
354
|
try {
|
|
351
355
|
const { model, result } = event;
|
|
352
356
|
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
353
|
-
const isEntryValid = await getEntryValidStatus(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
{
|
|
357
|
-
strapi: strapi2
|
|
358
|
-
}
|
|
359
|
-
);
|
|
357
|
+
const isEntryValid = await getEntryValidStatus(model.uid, result, {
|
|
358
|
+
strapi: strapi2
|
|
359
|
+
});
|
|
360
360
|
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
361
361
|
where: {
|
|
362
362
|
target_type: model.uid,
|
|
@@ -390,7 +390,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
390
390
|
throw err;
|
|
391
391
|
});
|
|
392
392
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
393
|
-
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
393
|
+
strapi2.get("webhookStore").addAllowedEvent(key, value);
|
|
394
394
|
});
|
|
395
395
|
}
|
|
396
396
|
};
|
|
@@ -625,7 +625,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
625
625
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),
|
|
626
626
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
627
627
|
]);
|
|
628
|
-
const release2 = await strapi2.
|
|
628
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).create({
|
|
629
629
|
data: {
|
|
630
630
|
...releaseWithCreatorFields,
|
|
631
631
|
status: "empty"
|
|
@@ -639,28 +639,36 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
639
639
|
return release2;
|
|
640
640
|
},
|
|
641
641
|
async findOne(id, query = {}) {
|
|
642
|
-
const
|
|
643
|
-
|
|
642
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_MODEL_UID, query);
|
|
643
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
644
|
+
...dbQuery,
|
|
645
|
+
where: { id }
|
|
644
646
|
});
|
|
645
647
|
return release2;
|
|
646
648
|
},
|
|
647
649
|
findPage(query) {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_MODEL_UID, query ?? {});
|
|
651
|
+
return strapi2.db.query(RELEASE_MODEL_UID).findPage({
|
|
652
|
+
...dbQuery,
|
|
650
653
|
populate: {
|
|
651
654
|
actions: {
|
|
652
|
-
// @ts-expect-error Ignore missing properties
|
|
653
655
|
count: true
|
|
654
656
|
}
|
|
655
657
|
}
|
|
656
658
|
});
|
|
657
659
|
},
|
|
658
|
-
async findManyWithContentTypeEntryAttached(contentTypeUid,
|
|
660
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entriesIds) {
|
|
661
|
+
let entries = entriesIds;
|
|
662
|
+
if (!Array.isArray(entriesIds)) {
|
|
663
|
+
entries = [entriesIds];
|
|
664
|
+
}
|
|
659
665
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
660
666
|
where: {
|
|
661
667
|
actions: {
|
|
662
668
|
target_type: contentTypeUid,
|
|
663
|
-
target_id:
|
|
669
|
+
target_id: {
|
|
670
|
+
$in: entries
|
|
671
|
+
}
|
|
664
672
|
},
|
|
665
673
|
releasedAt: {
|
|
666
674
|
$null: true
|
|
@@ -671,18 +679,25 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
671
679
|
actions: {
|
|
672
680
|
where: {
|
|
673
681
|
target_type: contentTypeUid,
|
|
674
|
-
target_id:
|
|
682
|
+
target_id: {
|
|
683
|
+
$in: entries
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
populate: {
|
|
687
|
+
entry: {
|
|
688
|
+
select: ["id"]
|
|
689
|
+
}
|
|
675
690
|
}
|
|
676
691
|
}
|
|
677
692
|
}
|
|
678
693
|
});
|
|
679
694
|
return releases.map((release2) => {
|
|
680
695
|
if (release2.actions?.length) {
|
|
681
|
-
const
|
|
696
|
+
const actionsForEntry = release2.actions;
|
|
682
697
|
delete release2.actions;
|
|
683
698
|
return {
|
|
684
699
|
...release2,
|
|
685
|
-
|
|
700
|
+
actions: actionsForEntry
|
|
686
701
|
};
|
|
687
702
|
}
|
|
688
703
|
return release2;
|
|
@@ -741,19 +756,15 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
741
756
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),
|
|
742
757
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
743
758
|
]);
|
|
744
|
-
const release2 = await strapi2.
|
|
759
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id } });
|
|
745
760
|
if (!release2) {
|
|
746
761
|
throw new errors.NotFoundError(`No release found for id ${id}`);
|
|
747
762
|
}
|
|
748
763
|
if (release2.releasedAt) {
|
|
749
764
|
throw new errors.ValidationError("Release already published");
|
|
750
765
|
}
|
|
751
|
-
const updatedRelease = await strapi2.
|
|
752
|
-
|
|
753
|
-
* The type returned from the entity service: Partial<Input<"plugin::content-releases.release">>
|
|
754
|
-
* is not compatible with the type we are passing here: UpdateRelease.Request['body']
|
|
755
|
-
*/
|
|
756
|
-
// @ts-expect-error see above
|
|
766
|
+
const updatedRelease = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
767
|
+
where: { id },
|
|
757
768
|
data: releaseWithCreatorFields
|
|
758
769
|
});
|
|
759
770
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
@@ -774,7 +785,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
774
785
|
validateEntryContentType(action.entry.contentType),
|
|
775
786
|
validateUniqueEntry(releaseId, action)
|
|
776
787
|
]);
|
|
777
|
-
const release2 = await strapi2.
|
|
788
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
778
789
|
if (!release2) {
|
|
779
790
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
780
791
|
}
|
|
@@ -784,7 +795,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
784
795
|
const { entry, type } = action;
|
|
785
796
|
const populatedEntry = await getPopulatedEntry(entry.contentType, entry.id, { strapi: strapi2 });
|
|
786
797
|
const isEntryValid = await getEntryValidStatus(entry.contentType, populatedEntry, { strapi: strapi2 });
|
|
787
|
-
const releaseAction2 = await strapi2.
|
|
798
|
+
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
788
799
|
data: {
|
|
789
800
|
type,
|
|
790
801
|
contentType: entry.contentType,
|
|
@@ -797,32 +808,35 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
797
808
|
},
|
|
798
809
|
release: releaseId
|
|
799
810
|
},
|
|
800
|
-
populate: { release: {
|
|
811
|
+
populate: { release: { select: ["id"] }, entry: { select: ["id"] } }
|
|
801
812
|
});
|
|
802
813
|
this.updateReleaseStatus(releaseId);
|
|
803
814
|
return releaseAction2;
|
|
804
815
|
},
|
|
805
816
|
async findActions(releaseId, query) {
|
|
806
|
-
const release2 = await strapi2.
|
|
807
|
-
|
|
817
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
818
|
+
where: { id: releaseId },
|
|
819
|
+
select: ["id"]
|
|
808
820
|
});
|
|
809
821
|
if (!release2) {
|
|
810
822
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
811
823
|
}
|
|
812
|
-
|
|
813
|
-
|
|
824
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
825
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
826
|
+
...dbQuery,
|
|
814
827
|
populate: {
|
|
815
828
|
entry: {
|
|
816
829
|
populate: "*"
|
|
817
830
|
}
|
|
818
831
|
},
|
|
819
|
-
|
|
832
|
+
where: {
|
|
820
833
|
release: releaseId
|
|
821
834
|
}
|
|
822
835
|
});
|
|
823
836
|
},
|
|
824
837
|
async countActions(query) {
|
|
825
|
-
|
|
838
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
839
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
826
840
|
},
|
|
827
841
|
async groupActions(actions, groupBy) {
|
|
828
842
|
const contentTypeUids = actions.reduce((acc, action) => {
|
|
@@ -831,9 +845,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
831
845
|
}
|
|
832
846
|
return acc;
|
|
833
847
|
}, []);
|
|
834
|
-
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
835
|
-
contentTypeUids
|
|
836
|
-
);
|
|
848
|
+
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(contentTypeUids);
|
|
837
849
|
const allLocalesDictionary = await this.getLocalesDataForActions();
|
|
838
850
|
const formattedData = actions.map((action) => {
|
|
839
851
|
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
@@ -903,10 +915,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
903
915
|
return componentsMap;
|
|
904
916
|
},
|
|
905
917
|
async delete(releaseId) {
|
|
906
|
-
const release2 = await strapi2.
|
|
918
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
919
|
+
where: { id: releaseId },
|
|
907
920
|
populate: {
|
|
908
921
|
actions: {
|
|
909
|
-
|
|
922
|
+
select: ["id"]
|
|
910
923
|
}
|
|
911
924
|
}
|
|
912
925
|
});
|
|
@@ -924,7 +937,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
924
937
|
}
|
|
925
938
|
}
|
|
926
939
|
});
|
|
927
|
-
await strapi2.
|
|
940
|
+
await strapi2.db.query(RELEASE_MODEL_UID).delete({
|
|
941
|
+
where: {
|
|
942
|
+
id: releaseId
|
|
943
|
+
}
|
|
944
|
+
});
|
|
928
945
|
});
|
|
929
946
|
if (release2.scheduledAt) {
|
|
930
947
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
@@ -950,9 +967,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
950
967
|
}
|
|
951
968
|
try {
|
|
952
969
|
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
953
|
-
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
954
|
-
releaseId
|
|
955
|
-
);
|
|
970
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(releaseId);
|
|
956
971
|
await strapi2.db.transaction(async () => {
|
|
957
972
|
for (const { uid, action, id } of singleTypeActions) {
|
|
958
973
|
await publishSingleTypeAction(uid, action, id);
|
|
@@ -995,7 +1010,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
995
1010
|
};
|
|
996
1011
|
}
|
|
997
1012
|
});
|
|
998
|
-
if (error) {
|
|
1013
|
+
if (error instanceof Error) {
|
|
999
1014
|
throw error;
|
|
1000
1015
|
}
|
|
1001
1016
|
return release2;
|
|
@@ -1093,8 +1108,11 @@ class AlreadyOnReleaseError extends errors.ApplicationError {
|
|
|
1093
1108
|
}
|
|
1094
1109
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1095
1110
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1096
|
-
const release2 = await strapi2.
|
|
1097
|
-
|
|
1111
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
1112
|
+
where: {
|
|
1113
|
+
id: releaseId
|
|
1114
|
+
},
|
|
1115
|
+
populate: { actions: { populate: { entry: { select: ["id"] } } } }
|
|
1098
1116
|
});
|
|
1099
1117
|
if (!release2) {
|
|
1100
1118
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
@@ -1120,10 +1138,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1120
1138
|
}
|
|
1121
1139
|
},
|
|
1122
1140
|
async validatePendingReleasesLimit() {
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
EE.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
1126
|
-
);
|
|
1141
|
+
const featureCfg = strapi2.ee.features.get("cms-content-releases");
|
|
1142
|
+
const maximumPendingReleases = typeof featureCfg === "object" && featureCfg?.options?.maximumReleases || 3;
|
|
1127
1143
|
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
1128
1144
|
filters: {
|
|
1129
1145
|
releasedAt: {
|
|
@@ -1136,8 +1152,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1136
1152
|
}
|
|
1137
1153
|
},
|
|
1138
1154
|
async validateUniqueNameForPendingRelease(name, id) {
|
|
1139
|
-
const pendingReleases = await strapi2.
|
|
1140
|
-
|
|
1155
|
+
const pendingReleases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
1156
|
+
where: {
|
|
1141
1157
|
releasedAt: {
|
|
1142
1158
|
$null: true
|
|
1143
1159
|
},
|
|
@@ -1166,7 +1182,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1166
1182
|
}
|
|
1167
1183
|
const job = scheduleJob(scheduleDate, async () => {
|
|
1168
1184
|
try {
|
|
1169
|
-
await getService("release").publish(releaseId);
|
|
1185
|
+
await getService("release", { strapi: strapi2 }).publish(releaseId);
|
|
1170
1186
|
} catch (error) {
|
|
1171
1187
|
}
|
|
1172
1188
|
this.cancel(releaseId);
|
|
@@ -1236,7 +1252,7 @@ const RELEASE_SCHEMA = yup.object().shape({
|
|
|
1236
1252
|
const validateRelease = validateYupSchema(RELEASE_SCHEMA);
|
|
1237
1253
|
const releaseController = {
|
|
1238
1254
|
async findMany(ctx) {
|
|
1239
|
-
const permissionsManager = strapi.admin
|
|
1255
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1240
1256
|
ability: ctx.state.userAbility,
|
|
1241
1257
|
model: RELEASE_MODEL_UID
|
|
1242
1258
|
});
|
|
@@ -1264,7 +1280,7 @@ const releaseController = {
|
|
|
1264
1280
|
}
|
|
1265
1281
|
};
|
|
1266
1282
|
});
|
|
1267
|
-
const pendingReleasesCount = await strapi.query(RELEASE_MODEL_UID).count({
|
|
1283
|
+
const pendingReleasesCount = await strapi.db.query(RELEASE_MODEL_UID).count({
|
|
1268
1284
|
where: {
|
|
1269
1285
|
releasedAt: null
|
|
1270
1286
|
}
|
|
@@ -1286,7 +1302,7 @@ const releaseController = {
|
|
|
1286
1302
|
});
|
|
1287
1303
|
const sanitizedRelease = {
|
|
1288
1304
|
...release2,
|
|
1289
|
-
createdBy: release2.createdBy ? strapi.admin
|
|
1305
|
+
createdBy: release2.createdBy ? strapi.service("admin::user").sanitizeUser(release2.createdBy) : null
|
|
1290
1306
|
};
|
|
1291
1307
|
const data = {
|
|
1292
1308
|
...sanitizedRelease,
|
|
@@ -1298,19 +1314,48 @@ const releaseController = {
|
|
|
1298
1314
|
};
|
|
1299
1315
|
ctx.body = { data };
|
|
1300
1316
|
},
|
|
1317
|
+
async mapEntriesToReleases(ctx) {
|
|
1318
|
+
const { contentTypeUid, entriesIds } = ctx.query;
|
|
1319
|
+
if (!contentTypeUid || !entriesIds) {
|
|
1320
|
+
throw new errors.ValidationError("Missing required query parameters");
|
|
1321
|
+
}
|
|
1322
|
+
const releaseService = getService("release", { strapi });
|
|
1323
|
+
const releasesWithActions = await releaseService.findManyWithContentTypeEntryAttached(
|
|
1324
|
+
contentTypeUid,
|
|
1325
|
+
entriesIds
|
|
1326
|
+
);
|
|
1327
|
+
const mappedEntriesInReleases = releasesWithActions.reduce(
|
|
1328
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1329
|
+
(acc, release2) => {
|
|
1330
|
+
release2.actions.forEach((action) => {
|
|
1331
|
+
if (!acc[action.entry.id]) {
|
|
1332
|
+
acc[action.entry.id] = [{ id: release2.id, name: release2.name }];
|
|
1333
|
+
} else {
|
|
1334
|
+
acc[action.entry.id].push({ id: release2.id, name: release2.name });
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
return acc;
|
|
1338
|
+
},
|
|
1339
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1340
|
+
{}
|
|
1341
|
+
);
|
|
1342
|
+
ctx.body = {
|
|
1343
|
+
data: mappedEntriesInReleases
|
|
1344
|
+
};
|
|
1345
|
+
},
|
|
1301
1346
|
async create(ctx) {
|
|
1302
1347
|
const user = ctx.state.user;
|
|
1303
1348
|
const releaseArgs = ctx.request.body;
|
|
1304
1349
|
await validateRelease(releaseArgs);
|
|
1305
1350
|
const releaseService = getService("release", { strapi });
|
|
1306
1351
|
const release2 = await releaseService.create(releaseArgs, { user });
|
|
1307
|
-
const permissionsManager = strapi.admin
|
|
1352
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1308
1353
|
ability: ctx.state.userAbility,
|
|
1309
1354
|
model: RELEASE_MODEL_UID
|
|
1310
1355
|
});
|
|
1311
|
-
ctx.
|
|
1356
|
+
ctx.created({
|
|
1312
1357
|
data: await permissionsManager.sanitizeOutput(release2)
|
|
1313
|
-
};
|
|
1358
|
+
});
|
|
1314
1359
|
},
|
|
1315
1360
|
async update(ctx) {
|
|
1316
1361
|
const user = ctx.state.user;
|
|
@@ -1319,7 +1364,7 @@ const releaseController = {
|
|
|
1319
1364
|
await validateRelease(releaseArgs);
|
|
1320
1365
|
const releaseService = getService("release", { strapi });
|
|
1321
1366
|
const release2 = await releaseService.update(id, releaseArgs, { user });
|
|
1322
|
-
const permissionsManager = strapi.admin
|
|
1367
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1323
1368
|
ability: ctx.state.userAbility,
|
|
1324
1369
|
model: RELEASE_MODEL_UID
|
|
1325
1370
|
});
|
|
@@ -1383,9 +1428,9 @@ const releaseActionController = {
|
|
|
1383
1428
|
await validateReleaseAction(releaseActionArgs);
|
|
1384
1429
|
const releaseService = getService("release", { strapi });
|
|
1385
1430
|
const releaseAction2 = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1386
|
-
ctx.
|
|
1431
|
+
ctx.created({
|
|
1387
1432
|
data: releaseAction2
|
|
1388
|
-
};
|
|
1433
|
+
});
|
|
1389
1434
|
},
|
|
1390
1435
|
async createMany(ctx) {
|
|
1391
1436
|
const releaseId = ctx.params.releaseId;
|
|
@@ -1411,17 +1456,17 @@ const releaseActionController = {
|
|
|
1411
1456
|
return releaseActions2;
|
|
1412
1457
|
});
|
|
1413
1458
|
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1414
|
-
ctx.
|
|
1459
|
+
ctx.created({
|
|
1415
1460
|
data: newReleaseActions,
|
|
1416
1461
|
meta: {
|
|
1417
1462
|
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1418
1463
|
totalEntries: releaseActions.length
|
|
1419
1464
|
}
|
|
1420
|
-
};
|
|
1465
|
+
});
|
|
1421
1466
|
},
|
|
1422
1467
|
async findMany(ctx) {
|
|
1423
1468
|
const releaseId = ctx.params.releaseId;
|
|
1424
|
-
const permissionsManager = strapi.admin
|
|
1469
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1425
1470
|
ability: ctx.state.userAbility,
|
|
1426
1471
|
model: RELEASE_ACTION_MODEL_UID
|
|
1427
1472
|
});
|
|
@@ -1435,14 +1480,14 @@ const releaseActionController = {
|
|
|
1435
1480
|
if (acc[action.contentType]) {
|
|
1436
1481
|
return acc;
|
|
1437
1482
|
}
|
|
1438
|
-
const contentTypePermissionsManager = strapi.admin
|
|
1483
|
+
const contentTypePermissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1439
1484
|
ability: ctx.state.userAbility,
|
|
1440
1485
|
model: action.contentType
|
|
1441
1486
|
});
|
|
1442
1487
|
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
1443
1488
|
return acc;
|
|
1444
1489
|
}, {});
|
|
1445
|
-
const sanitizedResults = await
|
|
1490
|
+
const sanitizedResults = await async.map(results, async (action) => ({
|
|
1446
1491
|
...action,
|
|
1447
1492
|
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
1448
1493
|
}));
|
|
@@ -1487,6 +1532,22 @@ const controllers = { release: releaseController, "release-action": releaseActio
|
|
|
1487
1532
|
const release = {
|
|
1488
1533
|
type: "admin",
|
|
1489
1534
|
routes: [
|
|
1535
|
+
{
|
|
1536
|
+
method: "GET",
|
|
1537
|
+
path: "/mapEntriesToReleases",
|
|
1538
|
+
handler: "release.mapEntriesToReleases",
|
|
1539
|
+
config: {
|
|
1540
|
+
policies: [
|
|
1541
|
+
"admin::isAuthenticatedAdmin",
|
|
1542
|
+
{
|
|
1543
|
+
name: "admin::hasPermissions",
|
|
1544
|
+
config: {
|
|
1545
|
+
actions: ["plugin::content-releases.read"]
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
]
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1490
1551
|
{
|
|
1491
1552
|
method: "POST",
|
|
1492
1553
|
path: "/",
|
|
@@ -1674,9 +1735,8 @@ const routes = {
|
|
|
1674
1735
|
release,
|
|
1675
1736
|
"release-action": releaseAction
|
|
1676
1737
|
};
|
|
1677
|
-
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1678
1738
|
const getPlugin = () => {
|
|
1679
|
-
if (features.isEnabled("cms-content-releases")) {
|
|
1739
|
+
if (strapi.ee.features.isEnabled("cms-content-releases")) {
|
|
1680
1740
|
return {
|
|
1681
1741
|
register,
|
|
1682
1742
|
bootstrap,
|