@strapi/content-releases 0.0.0-experimental.e47108ccbbc4ad1bfaf4526fa6b70d6ace1ca7a9 → 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-XbK-TdJn.mjs → App-BsUSTHVD.mjs} +241 -210
- package/dist/_chunks/App-BsUSTHVD.mjs.map +1 -0
- package/dist/_chunks/{App-ftICpqDz.js → App-CXRpb2hi.js} +256 -225
- package/dist/_chunks/App-CXRpb2hi.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
- package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
- package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
- package/dist/_chunks/{en-pOJ6G5fC.mjs → en-B9Ur3VsE.mjs} +10 -1
- package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
- package/dist/_chunks/{en-4CUzVH2g.js → en-DtFJ5ViE.js} +10 -1
- package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
- package/dist/_chunks/{index-RYVGXFeL.js → index-B6-lic1Q.js} +340 -113
- package/dist/_chunks/index-B6-lic1Q.js.map +1 -0
- package/dist/_chunks/{index-8LrruHqK.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-XbK-TdJn.mjs.map +0 -1
- package/dist/_chunks/App-ftICpqDz.js.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +0 -1
- package/dist/_chunks/en-4CUzVH2g.js.map +0 -1
- package/dist/_chunks/en-pOJ6G5fC.mjs.map +0 -1
- package/dist/_chunks/index-8LrruHqK.mjs.map +0 -1
- package/dist/_chunks/index-RYVGXFeL.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";
|
|
@@ -78,16 +76,19 @@ const ACTIONS = [
|
|
|
78
76
|
const ALLOWED_WEBHOOK_EVENTS = {
|
|
79
77
|
RELEASES_PUBLISH: "releases.publish"
|
|
80
78
|
};
|
|
81
|
-
const getService = (name, { strapi: strapi2 }
|
|
79
|
+
const getService = (name, { strapi: strapi2 }) => {
|
|
82
80
|
return strapi2.plugin("content-releases").service(name);
|
|
83
81
|
};
|
|
84
|
-
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 }
|
|
82
|
+
const getPopulatedEntry = async (contentTypeUid, entryId, { strapi: strapi2 }) => {
|
|
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
|
-
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 }
|
|
91
|
+
const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 }) => {
|
|
91
92
|
try {
|
|
92
93
|
await strapi2.entityValidator.validateEntityCreation(
|
|
93
94
|
strapi2.getModel(contentTypeUid),
|
|
@@ -122,7 +123,7 @@ async function deleteActionsOnDisableDraftAndPublish({
|
|
|
122
123
|
async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
123
124
|
const deletedContentTypes = lodash.difference(lodash.keys(oldContentTypes), lodash.keys(contentTypes2)) ?? [];
|
|
124
125
|
if (deletedContentTypes.length) {
|
|
125
|
-
await utils.
|
|
126
|
+
await utils.async.map(deletedContentTypes, async (deletedContentTypeUID) => {
|
|
126
127
|
return strapi.db?.queryBuilder(RELEASE_ACTION_MODEL_UID).delete().where({ contentType: deletedContentTypeUID }).execute();
|
|
127
128
|
});
|
|
128
129
|
}
|
|
@@ -141,7 +142,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
});
|
|
144
|
-
utils.
|
|
145
|
+
utils.async.map(releasesWithoutStatus, async (release2) => {
|
|
145
146
|
const actions = release2.actions;
|
|
146
147
|
const notValidatedActions = actions.filter((action) => action.isEntryValid === null);
|
|
147
148
|
for (const action of notValidatedActions) {
|
|
@@ -172,7 +173,7 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
172
173
|
}
|
|
173
174
|
}
|
|
174
175
|
});
|
|
175
|
-
utils.
|
|
176
|
+
utils.async.map(publishedReleases, async (release2) => {
|
|
176
177
|
return strapi.db.query(RELEASE_MODEL_UID).update({
|
|
177
178
|
where: {
|
|
178
179
|
id: release2.id
|
|
@@ -189,7 +190,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
189
190
|
(uid) => oldContentTypes[uid]?.options?.draftAndPublish
|
|
190
191
|
);
|
|
191
192
|
const releasesAffected = /* @__PURE__ */ new Set();
|
|
192
|
-
utils.
|
|
193
|
+
utils.async.map(contentTypesWithDraftAndPublish, async (contentTypeUID) => {
|
|
193
194
|
const oldContentType = oldContentTypes[contentTypeUID];
|
|
194
195
|
const contentType = contentTypes2[contentTypeUID];
|
|
195
196
|
if (!isEqual__default.default(oldContentType?.attributes, contentType?.attributes)) {
|
|
@@ -202,7 +203,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
202
203
|
release: true
|
|
203
204
|
}
|
|
204
205
|
});
|
|
205
|
-
await utils.
|
|
206
|
+
await utils.async.map(actions, async (action) => {
|
|
206
207
|
if (action.entry && action.release) {
|
|
207
208
|
const populatedEntry = await getPopulatedEntry(contentTypeUID, action.entry.id, {
|
|
208
209
|
strapi
|
|
@@ -225,7 +226,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
225
226
|
});
|
|
226
227
|
}
|
|
227
228
|
}).then(() => {
|
|
228
|
-
utils.
|
|
229
|
+
utils.async.map(releasesAffected, async (releaseId) => {
|
|
229
230
|
return getService("release", { strapi }).updateReleaseStatus(releaseId);
|
|
230
231
|
});
|
|
231
232
|
});
|
|
@@ -235,13 +236,16 @@ async function disableContentTypeLocalized({ oldContentTypes, contentTypes: cont
|
|
|
235
236
|
if (!oldContentTypes) {
|
|
236
237
|
return;
|
|
237
238
|
}
|
|
239
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
240
|
+
if (!i18nPlugin) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
238
243
|
for (const uid in contentTypes2) {
|
|
239
244
|
if (!oldContentTypes[uid]) {
|
|
240
245
|
continue;
|
|
241
246
|
}
|
|
242
247
|
const oldContentType = oldContentTypes[uid];
|
|
243
248
|
const contentType = contentTypes2[uid];
|
|
244
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
245
249
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
246
250
|
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
247
251
|
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -254,13 +258,16 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
254
258
|
if (!oldContentTypes) {
|
|
255
259
|
return;
|
|
256
260
|
}
|
|
261
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
262
|
+
if (!i18nPlugin) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
257
265
|
for (const uid in contentTypes2) {
|
|
258
266
|
if (!oldContentTypes[uid]) {
|
|
259
267
|
continue;
|
|
260
268
|
}
|
|
261
269
|
const oldContentType = oldContentTypes[uid];
|
|
262
270
|
const contentType = contentTypes2[uid];
|
|
263
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
264
271
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
265
272
|
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
266
273
|
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
@@ -271,11 +278,10 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
271
278
|
}
|
|
272
279
|
}
|
|
273
280
|
}
|
|
274
|
-
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
275
281
|
const register = async ({ strapi: strapi2 }) => {
|
|
276
|
-
if (features
|
|
277
|
-
await strapi2.admin
|
|
278
|
-
strapi2.hook("strapi::content-types.beforeSync").register(
|
|
282
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
283
|
+
await strapi2.service("admin::permission").actionProvider.registerMany(ACTIONS);
|
|
284
|
+
strapi2.hook("strapi::content-types.beforeSync").register(disableContentTypeLocalized).register(deleteActionsOnDisableDraftAndPublish);
|
|
279
285
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
280
286
|
}
|
|
281
287
|
if (strapi2.plugin("graphql")) {
|
|
@@ -284,9 +290,8 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
284
290
|
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
285
291
|
}
|
|
286
292
|
};
|
|
287
|
-
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
288
293
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
289
|
-
if (features
|
|
294
|
+
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
290
295
|
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes).filter(
|
|
291
296
|
(uid) => strapi2.contentTypes[uid]?.options?.draftAndPublish
|
|
292
297
|
);
|
|
@@ -345,9 +350,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
345
350
|
actions: {
|
|
346
351
|
target_type: model.uid,
|
|
347
352
|
target_id: {
|
|
348
|
-
$in: entriesToDelete.map(
|
|
349
|
-
(entry) => entry.id
|
|
350
|
-
)
|
|
353
|
+
$in: entriesToDelete.map((entry) => entry.id)
|
|
351
354
|
}
|
|
352
355
|
}
|
|
353
356
|
}
|
|
@@ -374,13 +377,9 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
374
377
|
try {
|
|
375
378
|
const { model, result } = event;
|
|
376
379
|
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
377
|
-
const isEntryValid = await getEntryValidStatus(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
{
|
|
381
|
-
strapi: strapi2
|
|
382
|
-
}
|
|
383
|
-
);
|
|
380
|
+
const isEntryValid = await getEntryValidStatus(model.uid, result, {
|
|
381
|
+
strapi: strapi2
|
|
382
|
+
});
|
|
384
383
|
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
385
384
|
where: {
|
|
386
385
|
target_type: model.uid,
|
|
@@ -414,7 +413,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
414
413
|
throw err;
|
|
415
414
|
});
|
|
416
415
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
417
|
-
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
416
|
+
strapi2.get("webhookStore").addAllowedEvent(key, value);
|
|
418
417
|
});
|
|
419
418
|
}
|
|
420
419
|
};
|
|
@@ -649,7 +648,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
649
648
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),
|
|
650
649
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
651
650
|
]);
|
|
652
|
-
const release2 = await strapi2.
|
|
651
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).create({
|
|
653
652
|
data: {
|
|
654
653
|
...releaseWithCreatorFields,
|
|
655
654
|
status: "empty"
|
|
@@ -663,28 +662,36 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
663
662
|
return release2;
|
|
664
663
|
},
|
|
665
664
|
async findOne(id, query = {}) {
|
|
666
|
-
const
|
|
667
|
-
|
|
665
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_MODEL_UID, query);
|
|
666
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
667
|
+
...dbQuery,
|
|
668
|
+
where: { id }
|
|
668
669
|
});
|
|
669
670
|
return release2;
|
|
670
671
|
},
|
|
671
672
|
findPage(query) {
|
|
672
|
-
|
|
673
|
-
|
|
673
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_MODEL_UID, query ?? {});
|
|
674
|
+
return strapi2.db.query(RELEASE_MODEL_UID).findPage({
|
|
675
|
+
...dbQuery,
|
|
674
676
|
populate: {
|
|
675
677
|
actions: {
|
|
676
|
-
// @ts-expect-error Ignore missing properties
|
|
677
678
|
count: true
|
|
678
679
|
}
|
|
679
680
|
}
|
|
680
681
|
});
|
|
681
682
|
},
|
|
682
|
-
async findManyWithContentTypeEntryAttached(contentTypeUid,
|
|
683
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entriesIds) {
|
|
684
|
+
let entries = entriesIds;
|
|
685
|
+
if (!Array.isArray(entriesIds)) {
|
|
686
|
+
entries = [entriesIds];
|
|
687
|
+
}
|
|
683
688
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
684
689
|
where: {
|
|
685
690
|
actions: {
|
|
686
691
|
target_type: contentTypeUid,
|
|
687
|
-
target_id:
|
|
692
|
+
target_id: {
|
|
693
|
+
$in: entries
|
|
694
|
+
}
|
|
688
695
|
},
|
|
689
696
|
releasedAt: {
|
|
690
697
|
$null: true
|
|
@@ -695,18 +702,25 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
695
702
|
actions: {
|
|
696
703
|
where: {
|
|
697
704
|
target_type: contentTypeUid,
|
|
698
|
-
target_id:
|
|
705
|
+
target_id: {
|
|
706
|
+
$in: entries
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
populate: {
|
|
710
|
+
entry: {
|
|
711
|
+
select: ["id"]
|
|
712
|
+
}
|
|
699
713
|
}
|
|
700
714
|
}
|
|
701
715
|
}
|
|
702
716
|
});
|
|
703
717
|
return releases.map((release2) => {
|
|
704
718
|
if (release2.actions?.length) {
|
|
705
|
-
const
|
|
719
|
+
const actionsForEntry = release2.actions;
|
|
706
720
|
delete release2.actions;
|
|
707
721
|
return {
|
|
708
722
|
...release2,
|
|
709
|
-
|
|
723
|
+
actions: actionsForEntry
|
|
710
724
|
};
|
|
711
725
|
}
|
|
712
726
|
return release2;
|
|
@@ -765,19 +779,15 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
765
779
|
validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),
|
|
766
780
|
validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
|
|
767
781
|
]);
|
|
768
|
-
const release2 = await strapi2.
|
|
782
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id } });
|
|
769
783
|
if (!release2) {
|
|
770
784
|
throw new utils.errors.NotFoundError(`No release found for id ${id}`);
|
|
771
785
|
}
|
|
772
786
|
if (release2.releasedAt) {
|
|
773
787
|
throw new utils.errors.ValidationError("Release already published");
|
|
774
788
|
}
|
|
775
|
-
const updatedRelease = await strapi2.
|
|
776
|
-
|
|
777
|
-
* The type returned from the entity service: Partial<Input<"plugin::content-releases.release">>
|
|
778
|
-
* is not compatible with the type we are passing here: UpdateRelease.Request['body']
|
|
779
|
-
*/
|
|
780
|
-
// @ts-expect-error see above
|
|
789
|
+
const updatedRelease = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
790
|
+
where: { id },
|
|
781
791
|
data: releaseWithCreatorFields
|
|
782
792
|
});
|
|
783
793
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
@@ -798,7 +808,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
798
808
|
validateEntryContentType(action.entry.contentType),
|
|
799
809
|
validateUniqueEntry(releaseId, action)
|
|
800
810
|
]);
|
|
801
|
-
const release2 = await strapi2.
|
|
811
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
802
812
|
if (!release2) {
|
|
803
813
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
804
814
|
}
|
|
@@ -808,7 +818,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
808
818
|
const { entry, type } = action;
|
|
809
819
|
const populatedEntry = await getPopulatedEntry(entry.contentType, entry.id, { strapi: strapi2 });
|
|
810
820
|
const isEntryValid = await getEntryValidStatus(entry.contentType, populatedEntry, { strapi: strapi2 });
|
|
811
|
-
const releaseAction2 = await strapi2.
|
|
821
|
+
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
812
822
|
data: {
|
|
813
823
|
type,
|
|
814
824
|
contentType: entry.contentType,
|
|
@@ -821,32 +831,35 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
821
831
|
},
|
|
822
832
|
release: releaseId
|
|
823
833
|
},
|
|
824
|
-
populate: { release: {
|
|
834
|
+
populate: { release: { select: ["id"] }, entry: { select: ["id"] } }
|
|
825
835
|
});
|
|
826
836
|
this.updateReleaseStatus(releaseId);
|
|
827
837
|
return releaseAction2;
|
|
828
838
|
},
|
|
829
839
|
async findActions(releaseId, query) {
|
|
830
|
-
const release2 = await strapi2.
|
|
831
|
-
|
|
840
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
841
|
+
where: { id: releaseId },
|
|
842
|
+
select: ["id"]
|
|
832
843
|
});
|
|
833
844
|
if (!release2) {
|
|
834
845
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
835
846
|
}
|
|
836
|
-
|
|
837
|
-
|
|
847
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
848
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
849
|
+
...dbQuery,
|
|
838
850
|
populate: {
|
|
839
851
|
entry: {
|
|
840
852
|
populate: "*"
|
|
841
853
|
}
|
|
842
854
|
},
|
|
843
|
-
|
|
855
|
+
where: {
|
|
844
856
|
release: releaseId
|
|
845
857
|
}
|
|
846
858
|
});
|
|
847
859
|
},
|
|
848
860
|
async countActions(query) {
|
|
849
|
-
|
|
861
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
862
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
850
863
|
},
|
|
851
864
|
async groupActions(actions, groupBy) {
|
|
852
865
|
const contentTypeUids = actions.reduce((acc, action) => {
|
|
@@ -855,9 +868,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
855
868
|
}
|
|
856
869
|
return acc;
|
|
857
870
|
}, []);
|
|
858
|
-
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
859
|
-
contentTypeUids
|
|
860
|
-
);
|
|
871
|
+
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(contentTypeUids);
|
|
861
872
|
const allLocalesDictionary = await this.getLocalesDataForActions();
|
|
862
873
|
const formattedData = actions.map((action) => {
|
|
863
874
|
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
@@ -927,10 +938,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
927
938
|
return componentsMap;
|
|
928
939
|
},
|
|
929
940
|
async delete(releaseId) {
|
|
930
|
-
const release2 = await strapi2.
|
|
941
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
942
|
+
where: { id: releaseId },
|
|
931
943
|
populate: {
|
|
932
944
|
actions: {
|
|
933
|
-
|
|
945
|
+
select: ["id"]
|
|
934
946
|
}
|
|
935
947
|
}
|
|
936
948
|
});
|
|
@@ -948,7 +960,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
948
960
|
}
|
|
949
961
|
}
|
|
950
962
|
});
|
|
951
|
-
await strapi2.
|
|
963
|
+
await strapi2.db.query(RELEASE_MODEL_UID).delete({
|
|
964
|
+
where: {
|
|
965
|
+
id: releaseId
|
|
966
|
+
}
|
|
967
|
+
});
|
|
952
968
|
});
|
|
953
969
|
if (release2.scheduledAt) {
|
|
954
970
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
@@ -974,9 +990,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
974
990
|
}
|
|
975
991
|
try {
|
|
976
992
|
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
977
|
-
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
978
|
-
releaseId
|
|
979
|
-
);
|
|
993
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(releaseId);
|
|
980
994
|
await strapi2.db.transaction(async () => {
|
|
981
995
|
for (const { uid, action, id } of singleTypeActions) {
|
|
982
996
|
await publishSingleTypeAction(uid, action, id);
|
|
@@ -1019,7 +1033,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1019
1033
|
};
|
|
1020
1034
|
}
|
|
1021
1035
|
});
|
|
1022
|
-
if (error) {
|
|
1036
|
+
if (error instanceof Error) {
|
|
1023
1037
|
throw error;
|
|
1024
1038
|
}
|
|
1025
1039
|
return release2;
|
|
@@ -1117,8 +1131,11 @@ class AlreadyOnReleaseError extends utils.errors.ApplicationError {
|
|
|
1117
1131
|
}
|
|
1118
1132
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1119
1133
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1120
|
-
const release2 = await strapi2.
|
|
1121
|
-
|
|
1134
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
1135
|
+
where: {
|
|
1136
|
+
id: releaseId
|
|
1137
|
+
},
|
|
1138
|
+
populate: { actions: { populate: { entry: { select: ["id"] } } } }
|
|
1122
1139
|
});
|
|
1123
1140
|
if (!release2) {
|
|
1124
1141
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
@@ -1144,10 +1161,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1144
1161
|
}
|
|
1145
1162
|
},
|
|
1146
1163
|
async validatePendingReleasesLimit() {
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
EE__default.default.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
1150
|
-
);
|
|
1164
|
+
const featureCfg = strapi2.ee.features.get("cms-content-releases");
|
|
1165
|
+
const maximumPendingReleases = typeof featureCfg === "object" && featureCfg?.options?.maximumReleases || 3;
|
|
1151
1166
|
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
1152
1167
|
filters: {
|
|
1153
1168
|
releasedAt: {
|
|
@@ -1160,8 +1175,8 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1160
1175
|
}
|
|
1161
1176
|
},
|
|
1162
1177
|
async validateUniqueNameForPendingRelease(name, id) {
|
|
1163
|
-
const pendingReleases = await strapi2.
|
|
1164
|
-
|
|
1178
|
+
const pendingReleases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
1179
|
+
where: {
|
|
1165
1180
|
releasedAt: {
|
|
1166
1181
|
$null: true
|
|
1167
1182
|
},
|
|
@@ -1190,7 +1205,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1190
1205
|
}
|
|
1191
1206
|
const job = nodeSchedule.scheduleJob(scheduleDate, async () => {
|
|
1192
1207
|
try {
|
|
1193
|
-
await getService("release").publish(releaseId);
|
|
1208
|
+
await getService("release", { strapi: strapi2 }).publish(releaseId);
|
|
1194
1209
|
} catch (error) {
|
|
1195
1210
|
}
|
|
1196
1211
|
this.cancel(releaseId);
|
|
@@ -1260,7 +1275,7 @@ const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
|
1260
1275
|
const validateRelease = utils.validateYupSchema(RELEASE_SCHEMA);
|
|
1261
1276
|
const releaseController = {
|
|
1262
1277
|
async findMany(ctx) {
|
|
1263
|
-
const permissionsManager = strapi.admin
|
|
1278
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1264
1279
|
ability: ctx.state.userAbility,
|
|
1265
1280
|
model: RELEASE_MODEL_UID
|
|
1266
1281
|
});
|
|
@@ -1288,7 +1303,7 @@ const releaseController = {
|
|
|
1288
1303
|
}
|
|
1289
1304
|
};
|
|
1290
1305
|
});
|
|
1291
|
-
const pendingReleasesCount = await strapi.query(RELEASE_MODEL_UID).count({
|
|
1306
|
+
const pendingReleasesCount = await strapi.db.query(RELEASE_MODEL_UID).count({
|
|
1292
1307
|
where: {
|
|
1293
1308
|
releasedAt: null
|
|
1294
1309
|
}
|
|
@@ -1310,7 +1325,7 @@ const releaseController = {
|
|
|
1310
1325
|
});
|
|
1311
1326
|
const sanitizedRelease = {
|
|
1312
1327
|
...release2,
|
|
1313
|
-
createdBy: release2.createdBy ? strapi.admin
|
|
1328
|
+
createdBy: release2.createdBy ? strapi.service("admin::user").sanitizeUser(release2.createdBy) : null
|
|
1314
1329
|
};
|
|
1315
1330
|
const data = {
|
|
1316
1331
|
...sanitizedRelease,
|
|
@@ -1322,19 +1337,48 @@ const releaseController = {
|
|
|
1322
1337
|
};
|
|
1323
1338
|
ctx.body = { data };
|
|
1324
1339
|
},
|
|
1340
|
+
async mapEntriesToReleases(ctx) {
|
|
1341
|
+
const { contentTypeUid, entriesIds } = ctx.query;
|
|
1342
|
+
if (!contentTypeUid || !entriesIds) {
|
|
1343
|
+
throw new utils.errors.ValidationError("Missing required query parameters");
|
|
1344
|
+
}
|
|
1345
|
+
const releaseService = getService("release", { strapi });
|
|
1346
|
+
const releasesWithActions = await releaseService.findManyWithContentTypeEntryAttached(
|
|
1347
|
+
contentTypeUid,
|
|
1348
|
+
entriesIds
|
|
1349
|
+
);
|
|
1350
|
+
const mappedEntriesInReleases = releasesWithActions.reduce(
|
|
1351
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1352
|
+
(acc, release2) => {
|
|
1353
|
+
release2.actions.forEach((action) => {
|
|
1354
|
+
if (!acc[action.entry.id]) {
|
|
1355
|
+
acc[action.entry.id] = [{ id: release2.id, name: release2.name }];
|
|
1356
|
+
} else {
|
|
1357
|
+
acc[action.entry.id].push({ id: release2.id, name: release2.name });
|
|
1358
|
+
}
|
|
1359
|
+
});
|
|
1360
|
+
return acc;
|
|
1361
|
+
},
|
|
1362
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1363
|
+
{}
|
|
1364
|
+
);
|
|
1365
|
+
ctx.body = {
|
|
1366
|
+
data: mappedEntriesInReleases
|
|
1367
|
+
};
|
|
1368
|
+
},
|
|
1325
1369
|
async create(ctx) {
|
|
1326
1370
|
const user = ctx.state.user;
|
|
1327
1371
|
const releaseArgs = ctx.request.body;
|
|
1328
1372
|
await validateRelease(releaseArgs);
|
|
1329
1373
|
const releaseService = getService("release", { strapi });
|
|
1330
1374
|
const release2 = await releaseService.create(releaseArgs, { user });
|
|
1331
|
-
const permissionsManager = strapi.admin
|
|
1375
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1332
1376
|
ability: ctx.state.userAbility,
|
|
1333
1377
|
model: RELEASE_MODEL_UID
|
|
1334
1378
|
});
|
|
1335
|
-
ctx.
|
|
1379
|
+
ctx.created({
|
|
1336
1380
|
data: await permissionsManager.sanitizeOutput(release2)
|
|
1337
|
-
};
|
|
1381
|
+
});
|
|
1338
1382
|
},
|
|
1339
1383
|
async update(ctx) {
|
|
1340
1384
|
const user = ctx.state.user;
|
|
@@ -1343,7 +1387,7 @@ const releaseController = {
|
|
|
1343
1387
|
await validateRelease(releaseArgs);
|
|
1344
1388
|
const releaseService = getService("release", { strapi });
|
|
1345
1389
|
const release2 = await releaseService.update(id, releaseArgs, { user });
|
|
1346
|
-
const permissionsManager = strapi.admin
|
|
1390
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1347
1391
|
ability: ctx.state.userAbility,
|
|
1348
1392
|
model: RELEASE_MODEL_UID
|
|
1349
1393
|
});
|
|
@@ -1407,9 +1451,9 @@ const releaseActionController = {
|
|
|
1407
1451
|
await validateReleaseAction(releaseActionArgs);
|
|
1408
1452
|
const releaseService = getService("release", { strapi });
|
|
1409
1453
|
const releaseAction2 = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1410
|
-
ctx.
|
|
1454
|
+
ctx.created({
|
|
1411
1455
|
data: releaseAction2
|
|
1412
|
-
};
|
|
1456
|
+
});
|
|
1413
1457
|
},
|
|
1414
1458
|
async createMany(ctx) {
|
|
1415
1459
|
const releaseId = ctx.params.releaseId;
|
|
@@ -1435,17 +1479,17 @@ const releaseActionController = {
|
|
|
1435
1479
|
return releaseActions2;
|
|
1436
1480
|
});
|
|
1437
1481
|
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1438
|
-
ctx.
|
|
1482
|
+
ctx.created({
|
|
1439
1483
|
data: newReleaseActions,
|
|
1440
1484
|
meta: {
|
|
1441
1485
|
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1442
1486
|
totalEntries: releaseActions.length
|
|
1443
1487
|
}
|
|
1444
|
-
};
|
|
1488
|
+
});
|
|
1445
1489
|
},
|
|
1446
1490
|
async findMany(ctx) {
|
|
1447
1491
|
const releaseId = ctx.params.releaseId;
|
|
1448
|
-
const permissionsManager = strapi.admin
|
|
1492
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1449
1493
|
ability: ctx.state.userAbility,
|
|
1450
1494
|
model: RELEASE_ACTION_MODEL_UID
|
|
1451
1495
|
});
|
|
@@ -1459,14 +1503,14 @@ const releaseActionController = {
|
|
|
1459
1503
|
if (acc[action.contentType]) {
|
|
1460
1504
|
return acc;
|
|
1461
1505
|
}
|
|
1462
|
-
const contentTypePermissionsManager = strapi.admin
|
|
1506
|
+
const contentTypePermissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1463
1507
|
ability: ctx.state.userAbility,
|
|
1464
1508
|
model: action.contentType
|
|
1465
1509
|
});
|
|
1466
1510
|
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
1467
1511
|
return acc;
|
|
1468
1512
|
}, {});
|
|
1469
|
-
const sanitizedResults = await utils.
|
|
1513
|
+
const sanitizedResults = await utils.async.map(results, async (action) => ({
|
|
1470
1514
|
...action,
|
|
1471
1515
|
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
1472
1516
|
}));
|
|
@@ -1511,6 +1555,22 @@ const controllers = { release: releaseController, "release-action": releaseActio
|
|
|
1511
1555
|
const release = {
|
|
1512
1556
|
type: "admin",
|
|
1513
1557
|
routes: [
|
|
1558
|
+
{
|
|
1559
|
+
method: "GET",
|
|
1560
|
+
path: "/mapEntriesToReleases",
|
|
1561
|
+
handler: "release.mapEntriesToReleases",
|
|
1562
|
+
config: {
|
|
1563
|
+
policies: [
|
|
1564
|
+
"admin::isAuthenticatedAdmin",
|
|
1565
|
+
{
|
|
1566
|
+
name: "admin::hasPermissions",
|
|
1567
|
+
config: {
|
|
1568
|
+
actions: ["plugin::content-releases.read"]
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
]
|
|
1572
|
+
}
|
|
1573
|
+
},
|
|
1514
1574
|
{
|
|
1515
1575
|
method: "POST",
|
|
1516
1576
|
path: "/",
|
|
@@ -1698,9 +1758,8 @@ const routes = {
|
|
|
1698
1758
|
release,
|
|
1699
1759
|
"release-action": releaseAction
|
|
1700
1760
|
};
|
|
1701
|
-
const { features } = require("@strapi/strapi/dist/utils/ee");
|
|
1702
1761
|
const getPlugin = () => {
|
|
1703
|
-
if (features.isEnabled("cms-content-releases")) {
|
|
1762
|
+
if (strapi.ee.features.isEnabled("cms-content-releases")) {
|
|
1704
1763
|
return {
|
|
1705
1764
|
register,
|
|
1706
1765
|
bootstrap,
|