@strapi/content-releases 0.0.0-experimental.d5b46d578a5c055b8dcc66939e1b5d540976fafb → 0.0.0-experimental.d954d57341a6623992a0d211daaec8e245c3517d

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.
Files changed (110) hide show
  1. package/dist/_chunks/{App-OP70yd5M.js → App-CqbuK4M6.js} +440 -433
  2. package/dist/_chunks/App-CqbuK4M6.js.map +1 -0
  3. package/dist/_chunks/{App-x6Tjj3HN.mjs → App-Do-Rnv0A.mjs} +418 -410
  4. package/dist/_chunks/App-Do-Rnv0A.mjs.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  9. package/dist/_chunks/{en-bpHsnU0n.mjs → en-B9Ur3VsE.mjs} +2 -1
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-3SGjiVyR.js → en-DtFJ5ViE.js} +2 -1
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-1ejXLtzt.mjs → index-D_pgdqQL.mjs} +227 -420
  14. package/dist/_chunks/index-D_pgdqQL.mjs.map +1 -0
  15. package/dist/_chunks/{index-ydocdaZ0.js → index-Tedsw4GC.js} +227 -422
  16. package/dist/_chunks/index-Tedsw4GC.js.map +1 -0
  17. package/dist/admin/index.js +1 -15
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +2 -16
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/admin/src/components/CMReleasesContainer.d.ts +22 -0
  22. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  23. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  24. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  25. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  26. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  27. package/dist/admin/src/components/ReleaseModal.d.ts +17 -0
  28. package/dist/admin/src/constants.d.ts +58 -0
  29. package/dist/admin/src/index.d.ts +3 -0
  30. package/dist/admin/src/pages/App.d.ts +1 -0
  31. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  32. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  33. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  34. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  35. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  36. package/dist/admin/src/pluginId.d.ts +1 -0
  37. package/dist/admin/src/services/release.d.ts +105 -0
  38. package/dist/admin/src/store/hooks.d.ts +7 -0
  39. package/dist/admin/src/utils/api.d.ts +6 -0
  40. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  41. package/dist/admin/src/utils/time.d.ts +1 -0
  42. package/dist/server/index.js +152 -93
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +153 -93
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts +5 -0
  47. package/dist/server/src/bootstrap.d.ts.map +1 -0
  48. package/dist/server/src/constants.d.ts +12 -0
  49. package/dist/server/src/constants.d.ts.map +1 -0
  50. package/dist/server/src/content-types/index.d.ts +99 -0
  51. package/dist/server/src/content-types/index.d.ts.map +1 -0
  52. package/dist/server/src/content-types/release/index.d.ts +48 -0
  53. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  54. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  55. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  56. package/dist/server/src/content-types/release-action/index.d.ts +50 -0
  57. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  58. package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
  59. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  60. package/dist/server/src/controllers/index.d.ts +20 -0
  61. package/dist/server/src/controllers/index.d.ts.map +1 -0
  62. package/dist/server/src/controllers/release-action.d.ts +10 -0
  63. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  64. package/dist/server/src/controllers/release.d.ts +12 -0
  65. package/dist/server/src/controllers/release.d.ts.map +1 -0
  66. package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
  67. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  68. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  69. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  70. package/dist/server/src/destroy.d.ts +5 -0
  71. package/dist/server/src/destroy.d.ts.map +1 -0
  72. package/dist/server/src/index.d.ts +2096 -0
  73. package/dist/server/src/index.d.ts.map +1 -0
  74. package/dist/server/src/migrations/index.d.ts +13 -0
  75. package/dist/server/src/migrations/index.d.ts.map +1 -0
  76. package/dist/server/src/register.d.ts +5 -0
  77. package/dist/server/src/register.d.ts.map +1 -0
  78. package/dist/server/src/routes/index.d.ts +35 -0
  79. package/dist/server/src/routes/index.d.ts.map +1 -0
  80. package/dist/server/src/routes/release-action.d.ts +18 -0
  81. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  82. package/dist/server/src/routes/release.d.ts +18 -0
  83. package/dist/server/src/routes/release.d.ts.map +1 -0
  84. package/dist/server/src/services/index.d.ts +1826 -0
  85. package/dist/server/src/services/index.d.ts.map +1 -0
  86. package/dist/server/src/services/release.d.ts +66 -0
  87. package/dist/server/src/services/release.d.ts.map +1 -0
  88. package/dist/server/src/services/scheduling.d.ts +18 -0
  89. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  90. package/dist/server/src/services/validation.d.ts +18 -0
  91. package/dist/server/src/services/validation.d.ts.map +1 -0
  92. package/dist/server/src/utils/index.d.ts +14 -0
  93. package/dist/server/src/utils/index.d.ts.map +1 -0
  94. package/dist/shared/contracts/release-actions.d.ts +131 -0
  95. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  96. package/dist/shared/contracts/releases.d.ts +182 -0
  97. package/dist/shared/contracts/releases.d.ts.map +1 -0
  98. package/dist/shared/types.d.ts +24 -0
  99. package/dist/shared/types.d.ts.map +1 -0
  100. package/dist/shared/validation-schemas.d.ts +2 -0
  101. package/dist/shared/validation-schemas.d.ts.map +1 -0
  102. package/package.json +29 -36
  103. package/dist/_chunks/App-OP70yd5M.js.map +0 -1
  104. package/dist/_chunks/App-x6Tjj3HN.mjs.map +0 -1
  105. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +0 -1
  106. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +0 -1
  107. package/dist/_chunks/en-3SGjiVyR.js.map +0 -1
  108. package/dist/_chunks/en-bpHsnU0n.mjs.map +0 -1
  109. package/dist/_chunks/index-1ejXLtzt.mjs.map +0 -1
  110. package/dist/_chunks/index-ydocdaZ0.js.map +0 -1
@@ -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 } = { strapi: global.strapi }) => {
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 } = { strapi: global.strapi }) => {
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.entityService.findOne(contentTypeUid, entryId, { populate });
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 } = { strapi: global.strapi }) => {
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.mapAsync(deletedContentTypes, async (deletedContentTypeUID) => {
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.mapAsync(releasesWithoutStatus, async (release2) => {
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.mapAsync(publishedReleases, async (release2) => {
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.mapAsync(contentTypesWithDraftAndPublish, async (contentTypeUID) => {
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.mapAsync(actions, async (action) => {
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.mapAsync(releasesAffected, async (releaseId) => {
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$2.isEnabled("cms-content-releases")) {
277
- await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
278
- strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish).register(disableContentTypeLocalized);
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$1.isEnabled("cms-content-releases")) {
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
- model.uid,
379
- result,
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.entityService.create(RELEASE_MODEL_UID, {
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 release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, id, {
667
- ...query
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
- return strapi2.entityService.findPage(RELEASE_MODEL_UID, {
673
- ...query,
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, entryId) {
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: entryId
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: entryId
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 [actionForEntry] = release2.actions;
719
+ const actionsForEntry = release2.actions;
706
720
  delete release2.actions;
707
721
  return {
708
722
  ...release2,
709
- action: actionForEntry
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.entityService.findOne(RELEASE_MODEL_UID, id);
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.entityService.update(RELEASE_MODEL_UID, id, {
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.entityService.findOne(RELEASE_MODEL_UID, releaseId);
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.entityService.create(RELEASE_ACTION_MODEL_UID, {
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: { fields: ["id"] }, entry: { fields: ["id"] } }
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.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
831
- fields: ["id"]
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
- return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
837
- ...query,
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
- filters: {
855
+ where: {
844
856
  release: releaseId
845
857
  }
846
858
  });
847
859
  },
848
860
  async countActions(query) {
849
- return strapi2.entityService.count(RELEASE_ACTION_MODEL_UID, query);
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.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
941
+ const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
942
+ where: { id: releaseId },
931
943
  populate: {
932
944
  actions: {
933
- fields: ["id"]
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.entityService.delete(RELEASE_MODEL_UID, releaseId);
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.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
1121
- populate: { actions: { populate: { entry: { fields: ["id"] } } } }
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 maximumPendingReleases = (
1148
- // @ts-expect-error - options is not typed into features
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.entityService.findMany(RELEASE_MODEL_UID, {
1164
- filters: {
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.services.permission.createPermissionsManager({
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.services.user.sanitizeUser(release2.createdBy) : null
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.services.permission.createPermissionsManager({
1375
+ const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
1332
1376
  ability: ctx.state.userAbility,
1333
1377
  model: RELEASE_MODEL_UID
1334
1378
  });
1335
- ctx.body = {
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.services.permission.createPermissionsManager({
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.body = {
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.body = {
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.services.permission.createPermissionsManager({
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.services.permission.createPermissionsManager({
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.mapAsync(results, async (action) => ({
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,