@strapi/content-releases 0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0 → 0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602

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 (29) hide show
  1. package/dist/_chunks/{App-IQIHCiSO.js → App-1hHIqUoZ.js} +106 -105
  2. package/dist/_chunks/App-1hHIqUoZ.js.map +1 -0
  3. package/dist/_chunks/{App-WkwjSaDY.mjs → App-U6GbyLIE.mjs} +108 -107
  4. package/dist/_chunks/App-U6GbyLIE.mjs.map +1 -0
  5. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs +51 -0
  6. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +1 -0
  7. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js +51 -0
  8. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +1 -0
  9. package/dist/_chunks/{en-m9eTk4UF.mjs → en-GqXgfmzl.mjs} +3 -1
  10. package/dist/_chunks/en-GqXgfmzl.mjs.map +1 -0
  11. package/dist/_chunks/{en-r9YocBH0.js → en-bDhIlw-B.js} +3 -1
  12. package/dist/_chunks/en-bDhIlw-B.js.map +1 -0
  13. package/dist/_chunks/{index-CyVlvX8h.mjs → index-gkExFBa0.mjs} +52 -12
  14. package/dist/_chunks/index-gkExFBa0.mjs.map +1 -0
  15. package/dist/_chunks/{index-u_da7WHb.js → index-l-FvkQlQ.js} +52 -12
  16. package/dist/_chunks/index-l-FvkQlQ.js.map +1 -0
  17. package/dist/admin/index.js +1 -1
  18. package/dist/admin/index.mjs +1 -1
  19. package/dist/server/index.js +76 -6
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/server/index.mjs +76 -6
  22. package/dist/server/index.mjs.map +1 -1
  23. package/package.json +9 -9
  24. package/dist/_chunks/App-IQIHCiSO.js.map +0 -1
  25. package/dist/_chunks/App-WkwjSaDY.mjs.map +0 -1
  26. package/dist/_chunks/en-m9eTk4UF.mjs.map +0 -1
  27. package/dist/_chunks/en-r9YocBH0.js.map +0 -1
  28. package/dist/_chunks/index-CyVlvX8h.mjs.map +0 -1
  29. package/dist/_chunks/index-u_da7WHb.js.map +0 -1
@@ -84,6 +84,9 @@ const register = async ({ strapi: strapi2 }) => {
84
84
  strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType);
85
85
  }
86
86
  };
87
+ const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
88
+ return strapi2.plugin("content-releases").service(name);
89
+ };
87
90
  const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
88
91
  const bootstrap = async ({ strapi: strapi2 }) => {
89
92
  if (features$1.isEnabled("cms-content-releases")) {
@@ -131,6 +134,24 @@ const bootstrap = async ({ strapi: strapi2 }) => {
131
134
  }
132
135
  }
133
136
  });
137
+ if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
138
+ getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
139
+ strapi2.log.error(
140
+ "Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
141
+ );
142
+ throw err;
143
+ });
144
+ }
145
+ }
146
+ };
147
+ const destroy = async ({ strapi: strapi2 }) => {
148
+ if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
149
+ const scheduledJobs = getService("scheduling", {
150
+ strapi: strapi2
151
+ }).getAll();
152
+ for (const [, job] of scheduledJobs) {
153
+ job.cancel();
154
+ }
134
155
  }
135
156
  };
136
157
  const schema$1 = {
@@ -162,6 +183,9 @@ const schema$1 = {
162
183
  scheduledAt: {
163
184
  type: "datetime"
164
185
  },
186
+ timezone: {
187
+ type: "string"
188
+ },
165
189
  actions: {
166
190
  type: "relation",
167
191
  relation: "oneToMany",
@@ -224,9 +248,6 @@ const contentTypes = {
224
248
  release: release$1,
225
249
  "release-action": releaseAction$1
226
250
  };
227
- const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
228
- return strapi2.plugin("content-releases").service(name);
229
- };
230
251
  const getGroupName = (queryValue) => {
231
252
  switch (queryValue) {
232
253
  case "contentType":
@@ -354,6 +375,14 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
354
375
  },
355
376
  async update(id, releaseData, { user }) {
356
377
  const releaseWithCreatorFields = await setCreatorFields({ user, isEdition: true })(releaseData);
378
+ const { validateUniqueNameForPendingRelease, validateScheduledAtIsLaterThanNow } = getService(
379
+ "release-validation",
380
+ { strapi: strapi2 }
381
+ );
382
+ await Promise.all([
383
+ validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),
384
+ validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt)
385
+ ]);
357
386
  const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, id);
358
387
  if (!release2) {
359
388
  throw new errors.NotFoundError(`No release found for id ${id}`);
@@ -369,6 +398,14 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
369
398
  // @ts-expect-error see above
370
399
  data: releaseWithCreatorFields
371
400
  });
401
+ if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
402
+ const schedulingService = getService("scheduling", { strapi: strapi2 });
403
+ if (releaseData.scheduledAt) {
404
+ await schedulingService.set(id, releaseData.scheduledAt);
405
+ } else if (release2.scheduledAt) {
406
+ schedulingService.cancel(id);
407
+ }
408
+ }
372
409
  return updatedRelease;
373
410
  },
374
411
  async createAction(releaseId, action) {
@@ -526,6 +563,10 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
526
563
  });
527
564
  await strapi2.entityService.delete(RELEASE_MODEL_UID, releaseId);
528
565
  });
566
+ if (strapi2.features.future.isEnabled("contentReleasesScheduling") && release2.scheduledAt) {
567
+ const schedulingService = getService("scheduling", { strapi: strapi2 });
568
+ await schedulingService.cancel(release2.id);
569
+ }
529
570
  return release2;
530
571
  },
531
572
  async publish(releaseId) {
@@ -725,13 +766,14 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
725
766
  throw new errors.ValidationError("You have reached the maximum number of pending releases");
726
767
  }
727
768
  },
728
- async validateUniqueNameForPendingRelease(name) {
769
+ async validateUniqueNameForPendingRelease(name, id) {
729
770
  const pendingReleases = await strapi2.entityService.findMany(RELEASE_MODEL_UID, {
730
771
  filters: {
731
772
  releasedAt: {
732
773
  $null: true
733
774
  },
734
- name
775
+ name,
776
+ ...id && { id: { $ne: id } }
735
777
  }
736
778
  });
737
779
  const isNameUnique = pendingReleases.length === 0;
@@ -772,6 +814,28 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
772
814
  scheduledJobs.delete(releaseId);
773
815
  }
774
816
  return scheduledJobs;
817
+ },
818
+ getAll() {
819
+ return scheduledJobs;
820
+ },
821
+ /**
822
+ * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released
823
+ * This is useful in case the server was restarted and the scheduled jobs were lost
824
+ * This also could be used to sync different Strapi instances in case of a cluster
825
+ */
826
+ async syncFromDatabase() {
827
+ const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
828
+ where: {
829
+ scheduledAt: {
830
+ $gte: /* @__PURE__ */ new Date()
831
+ },
832
+ releasedAt: null
833
+ }
834
+ });
835
+ for (const release2 of releases) {
836
+ this.set(release2.id, release2.scheduledAt);
837
+ }
838
+ return scheduledJobs;
775
839
  }
776
840
  };
777
841
  };
@@ -783,7 +847,12 @@ const services = {
783
847
  const RELEASE_SCHEMA = yup.object().shape({
784
848
  name: yup.string().trim().required(),
785
849
  // scheduledAt is a date, but we always receive strings from the client
786
- scheduledAt: yup.string()
850
+ scheduledAt: yup.string().nullable(),
851
+ timezone: yup.string().when("scheduledAt", {
852
+ is: (scheduledAt) => !!scheduledAt,
853
+ then: yup.string().required(),
854
+ otherwise: yup.string().nullable()
855
+ })
787
856
  }).required().noUnknown();
788
857
  const validateRelease = validateYupSchema(RELEASE_SCHEMA);
789
858
  const releaseController = {
@@ -1179,6 +1248,7 @@ const getPlugin = () => {
1179
1248
  return {
1180
1249
  register,
1181
1250
  bootstrap,
1251
+ destroy,
1182
1252
  contentTypes,
1183
1253
  services,
1184
1254
  controllers,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../server/src/constants.ts","../../server/src/migrations/index.ts","../../server/src/register.ts","../../server/src/bootstrap.ts","../../server/src/content-types/release/schema.ts","../../server/src/content-types/release/index.ts","../../server/src/content-types/release-action/schema.ts","../../server/src/content-types/release-action/index.ts","../../server/src/content-types/index.ts","../../server/src/utils/index.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/scheduling.ts","../../server/src/services/index.ts","../../shared/validation-schemas.ts","../../server/src/controllers/validation/release.ts","../../server/src/controllers/release.ts","../../server/src/controllers/validation/release-action.ts","../../server/src/controllers/release-action.ts","../../server/src/controllers/index.ts","../../server/src/routes/release.ts","../../server/src/routes/release-action.ts","../../server/src/routes/index.ts","../../server/src/index.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n];\n","import type { Schema } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, mapAsync } from '@strapi/utils';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await mapAsync(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi } from '@strapi/types';\n\nimport { ACTIONS } from './constants';\nimport {\n deleteActionsOnDeleteContentType,\n deleteActionsOnDisableDraftAndPublish,\n} from './migrations';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (features.isEnabled('cms-content-releases')) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n\n strapi.hook('strapi::content-types.beforeSync').register(deleteActionsOnDisableDraftAndPublish);\n strapi.hook('strapi::content-types.afterSync').register(deleteActionsOnDeleteContentType);\n }\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID } from './constants';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (features.isEnabled('cms-content-releases')) {\n // Clean up release-actions when an entry is deleted\n strapi.db.lifecycles.subscribe({\n afterDelete(event) {\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n const { model, result } = event;\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { id } = result;\n strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: model.uid,\n target_id: id,\n },\n });\n }\n },\n /**\n * deleteMany hook doesn't return the deleted entries ids\n * so we need to fetch them before deleting the entries to save the ids on our state\n */\n async beforeDeleteMany(event) {\n const { model, params } = event;\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = params;\n const entriesToDelete = await strapi.db\n .query(model.uid)\n .findMany({ select: ['id'], where });\n event.state.entriesToDelete = entriesToDelete;\n }\n },\n /**\n * We delete the release actions related to deleted entries\n * We make this only after deleteMany is succesfully executed to avoid errors\n */\n async afterDeleteMany(event) {\n const { model, state } = event;\n const entriesToDelete = state.entriesToDelete;\n if (entriesToDelete) {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: model.uid,\n target_id: {\n $in: (entriesToDelete as Array<{ id: StrapiEntity.ID }>).map((entry) => entry.id),\n },\n },\n });\n }\n },\n });\n }\n};\n","import { RELEASE_ACTION_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_releases',\n info: {\n singularName: 'release',\n pluralName: 'releases',\n displayName: 'Release',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n required: true,\n },\n releasedAt: {\n type: 'datetime',\n },\n scheduledAt: {\n type: 'datetime',\n },\n actions: {\n type: 'relation',\n relation: 'oneToMany',\n target: RELEASE_ACTION_MODEL_UID,\n mappedBy: 'release',\n },\n },\n};\n","import schema from './schema';\n\nexport const release = {\n schema,\n};\n","import { RELEASE_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_release_actions',\n info: {\n singularName: 'release-action',\n pluralName: 'release-actions',\n displayName: 'Release Action',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n type: {\n type: 'enumeration',\n enum: ['publish', 'unpublish'],\n required: true,\n },\n entry: {\n type: 'relation',\n relation: 'morphToOne',\n configurable: false,\n },\n contentType: {\n type: 'string',\n required: true,\n },\n locale: {\n type: 'string',\n },\n release: {\n type: 'relation',\n relation: 'manyToOne',\n target: RELEASE_MODEL_UID,\n inversedBy: 'actions',\n },\n },\n};\n","import schema from './schema';\n\nexport const releaseAction = {\n schema,\n};\n","import { release } from './release';\nimport { releaseAction } from './release-action';\n\nexport const contentTypes = {\n release,\n 'release-action': releaseAction,\n};\n","export const getService = (\n name: 'release' | 'release-validation' | 'scheduling' | 'release-action' | 'event-manager',\n { strapi } = { strapi: global.strapi }\n) => {\n return strapi.plugin('content-releases').service(name);\n};\n","import { setCreatorFields, errors } from '@strapi/utils';\n\nimport type { LoadedStrapi, EntityService, UID, Schema } from '@strapi/types';\n\nimport _ from 'lodash/fp';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport type {\n GetReleases,\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n} from '../../../shared/contracts/releases';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n ReleaseAction,\n UpdateReleaseAction,\n DeleteReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type { Entity, UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\nexport interface Locale extends Entity {\n name: string;\n code: string;\n}\n\ntype LocaleDictionary = {\n [key: Locale['code']]: Pick<Locale, 'name' | 'code'>;\n};\n\nconst getGroupName = (queryValue?: ReleaseActionGroupBy) => {\n switch (queryValue) {\n case 'contentType':\n return 'contentType.displayName';\n case 'action':\n return 'type';\n case 'locale':\n return _.getOr('No locale', 'locale.name');\n default:\n return 'contentType.displayName';\n }\n};\n\nconst createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async create(releaseData: CreateRelease.Request['body'], { user }: { user: UserInfo }) {\n const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);\n\n const {\n validatePendingReleasesLimit,\n validateUniqueNameForPendingRelease,\n validateScheduledAtIsLaterThanNow,\n } = getService('release-validation', { strapi });\n\n await Promise.all([\n validatePendingReleasesLimit(),\n validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),\n validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt),\n ]);\n\n const release = await strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\n\n if (\n strapi.features.future.isEnabled('contentReleasesScheduling') &&\n releaseWithCreatorFields.scheduledAt\n ) {\n const schedulingService = getService('scheduling', { strapi });\n\n await schedulingService.set(release.id, release.scheduledAt);\n }\n\n return release;\n },\n\n async findOne(id: GetRelease.Request['params']['id'], query = {}) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id, {\n ...query,\n });\n\n return release;\n },\n\n findPage(query?: GetReleases.Request['query']) {\n return strapi.entityService.findPage(RELEASE_MODEL_UID, {\n ...query,\n populate: {\n actions: {\n // @ts-expect-error Ignore missing properties\n count: true,\n },\n },\n });\n },\n\n async findManyWithContentTypeEntryAttached(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId']\n ) {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n // Filter the action to get only the content type entry\n actions: {\n where: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async findManyWithoutContentTypeEntryAttached(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId']\n ) {\n // We get the list of releases where the entry is present\n const releasesRelated = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n releasedAt: {\n $null: true,\n },\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n });\n\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n $or: [\n {\n id: {\n $notIn: releasesRelated.map((release) => release.id),\n },\n },\n {\n actions: null,\n },\n ],\n releasedAt: {\n $null: true,\n },\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async update(\n id: number,\n releaseData: UpdateRelease.Request['body'],\n { user }: { user: UserInfo }\n ) {\n const releaseWithCreatorFields = await setCreatorFields({ user, isEdition: true })(releaseData);\n\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id);\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${id}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n const updatedRelease = await strapi.entityService.update(RELEASE_MODEL_UID, id, {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">>\n * is not compatible with the type we are passing here: UpdateRelease.Request['body']\n */\n // @ts-expect-error see above\n data: releaseWithCreatorFields,\n });\n\n return updatedRelease;\n },\n\n async createAction(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n action: Pick<CreateReleaseAction.Request['body'], 'type' | 'entry'>\n ) {\n const { validateEntryContentType, validateUniqueEntry } = getService('release-validation', {\n strapi,\n });\n\n await Promise.all([\n validateEntryContentType(action.entry.contentType),\n validateUniqueEntry(releaseId, action),\n ]);\n\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId);\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n const { entry, type } = action;\n\n return strapi.entityService.create(RELEASE_ACTION_MODEL_UID, {\n data: {\n type,\n contentType: entry.contentType,\n locale: entry.locale,\n entry: {\n id: entry.id,\n __type: entry.contentType,\n __pivot: { field: 'entry' },\n },\n release: releaseId,\n },\n populate: { release: { fields: ['id'] }, entry: { fields: ['id'] } },\n });\n },\n\n async findActions(\n releaseId: GetReleaseActions.Request['params']['releaseId'],\n query?: GetReleaseActions.Request['query']\n ) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n fields: ['id'],\n });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n return strapi.entityService.findPage(RELEASE_ACTION_MODEL_UID, {\n ...query,\n populate: {\n entry: {\n populate: '*',\n },\n },\n filters: {\n release: releaseId,\n },\n });\n },\n\n async countActions(query: EntityService.Params.Pick<typeof RELEASE_ACTION_MODEL_UID, 'filters'>) {\n return strapi.entityService.count(RELEASE_ACTION_MODEL_UID, query);\n },\n\n async groupActions(actions: ReleaseAction[], groupBy: ReleaseActionGroupBy) {\n const contentTypeUids = actions.reduce<ReleaseAction['contentType'][]>((acc, action) => {\n if (!acc.includes(action.contentType)) {\n acc.push(action.contentType);\n }\n\n return acc;\n }, []);\n const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(\n contentTypeUids\n );\n const allLocalesDictionary = await this.getLocalesDataForActions();\n\n const formattedData = actions.map((action: ReleaseAction) => {\n const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];\n\n return {\n ...action,\n locale: action.locale ? allLocalesDictionary[action.locale] : null,\n contentType: {\n displayName,\n mainFieldValue: action.entry[mainField],\n uid: action.contentType,\n },\n };\n });\n\n const groupName = getGroupName(groupBy);\n return _.groupBy(groupName)(formattedData);\n },\n\n async getLocalesDataForActions() {\n if (!strapi.plugin('i18n')) {\n return {};\n }\n\n const allLocales: Locale[] = (await strapi.plugin('i18n').service('locales').find()) || [];\n return allLocales.reduce<LocaleDictionary>((acc, locale) => {\n acc[locale.code] = { name: locale.name, code: locale.code };\n\n return acc;\n }, {});\n },\n\n async getContentTypesDataForActions(contentTypesUids: ReleaseAction['contentType'][]) {\n const contentManagerContentTypeService = strapi\n .plugin('content-manager')\n .service('content-types');\n\n const contentTypesData: Record<UID.ContentType, { mainField: string; displayName: string }> =\n {};\n for (const contentTypeUid of contentTypesUids) {\n const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({\n uid: contentTypeUid,\n });\n\n contentTypesData[contentTypeUid] = {\n mainField: contentTypeConfig.settings.mainField,\n displayName: strapi.getModel(contentTypeUid).info.displayName,\n };\n }\n\n return contentTypesData;\n },\n\n getContentTypeModelsFromActions(actions: ReleaseAction[]) {\n const contentTypeUids = actions.reduce<ReleaseAction['contentType'][]>((acc, action) => {\n if (!acc.includes(action.contentType)) {\n acc.push(action.contentType);\n }\n\n return acc;\n }, []);\n\n const contentTypeModelsMap = contentTypeUids.reduce(\n (\n acc: { [key: ReleaseAction['contentType']]: Schema.ContentType },\n contentTypeUid: ReleaseAction['contentType']\n ) => {\n acc[contentTypeUid] = strapi.getModel(contentTypeUid);\n\n return acc;\n },\n {}\n );\n\n return contentTypeModelsMap;\n },\n\n async getAllComponents() {\n const contentManagerComponentsService = strapi.plugin('content-manager').service('components');\n\n const components = await contentManagerComponentsService.findAllComponents();\n\n const componentsMap = components.reduce(\n (acc: { [key: Schema.Component['uid']]: Schema.Component }, component: Schema.Component) => {\n acc[component.uid] = component;\n\n return acc;\n },\n {}\n );\n\n return componentsMap;\n },\n\n async delete(releaseId: DeleteRelease.Request['params']['id']) {\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: {\n actions: {\n fields: ['id'],\n },\n },\n })) as unknown as Release;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n // Only delete the release and its actions is you in fact can delete all the actions and the release\n // Otherwise, if the transaction fails it throws an error\n await strapi.db.transaction(async () => {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n id: {\n $in: release.actions.map((action) => action.id),\n },\n },\n });\n await strapi.entityService.delete(RELEASE_MODEL_UID, releaseId);\n });\n\n return release;\n },\n\n async publish(releaseId: PublishRelease.Request['params']['id']) {\n // We need to pass the type because entityService.findOne is not returning the correct type\n const releaseWithPopulatedActionEntries = (await strapi.entityService.findOne(\n RELEASE_MODEL_UID,\n releaseId,\n {\n populate: {\n actions: {\n populate: {\n entry: {\n fields: ['id'],\n },\n },\n },\n },\n }\n )) as unknown as Release;\n\n if (!releaseWithPopulatedActionEntries) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (releaseWithPopulatedActionEntries.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n if (releaseWithPopulatedActionEntries.actions.length === 0) {\n throw new errors.ValidationError('No entries to publish');\n }\n\n /**\n * We separate publish and unpublish actions, grouping them by contentType and extracting only their IDs. Then we can fetch more data for each entry\n * We need to separate collectionTypes from singleTypes because findMany work as findOne for singleTypes and publishMany can't be used for singleTypes\n */\n const collectionTypeActions: {\n [key: UID.ContentType]: {\n entriestoPublishIds: ReleaseAction['entry']['id'][];\n entriesToUnpublishIds: ReleaseAction['entry']['id'][];\n };\n } = {};\n const singleTypeActions: {\n uid: UID.ContentType;\n id: ReleaseAction['entry']['id'];\n action: ReleaseAction['type'];\n }[] = [];\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (strapi.contentTypes[contentTypeUid].kind === 'collectionType') {\n if (!collectionTypeActions[contentTypeUid]) {\n collectionTypeActions[contentTypeUid] = {\n entriestoPublishIds: [],\n entriesToUnpublishIds: [],\n };\n }\n\n if (action.type === 'publish') {\n collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);\n } else {\n collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);\n }\n } else {\n singleTypeActions.push({\n uid: contentTypeUid,\n action: action.type,\n id: action.entry.id,\n });\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\n const populateBuilderService = strapi.plugin('content-manager').service('populate-builder');\n\n // Only publish the release if all action updates are applied successfully to their entry, otherwise leave everything as is\n await strapi.db.transaction(async () => {\n // First we publish all the singleTypes\n for (const { uid, action, id } of singleTypeActions) {\n // @ts-expect-error - populateBuilderService should be a function but is returning service\n const populate = await populateBuilderService(uid).populateDeep(Infinity).build();\n\n const entry = await strapi.entityService.findOne(uid, id, { populate });\n\n try {\n if (action === 'publish') {\n await entityManagerService.publish(entry, uid);\n } else {\n await entityManagerService.unpublish(entry, uid);\n }\n } catch (error) {\n if (\n error instanceof errors.ApplicationError &&\n (error.message === 'already.published' || error.message === 'already.draft')\n ) {\n // We don't want throw an error if the entry is already published or draft\n } else {\n throw error;\n }\n }\n }\n\n // Then, we can continue with publishing the collectionTypes\n for (const contentTypeUid of Object.keys(collectionTypeActions)) {\n // @ts-expect-error - populateBuilderService should be a function but is returning service\n const populate = await populateBuilderService(contentTypeUid)\n .populateDeep(Infinity)\n .build();\n\n const { entriestoPublishIds, entriesToUnpublishIds } =\n collectionTypeActions[contentTypeUid as UID.ContentType];\n\n /**\n * We need to get the populate entries to be able to publish without errors on components/relations/dynamicZones\n * Considering that populate doesn't work well with morph relations we can't get the entries from the Release model\n * So, we need to fetch them manually\n */\n const entriesToPublish = (await strapi.entityService.findMany(\n contentTypeUid as UID.ContentType,\n {\n filters: {\n id: {\n $in: entriestoPublishIds,\n },\n },\n populate,\n }\n )) as Entity[];\n\n const entriesToUnpublish = (await strapi.entityService.findMany(\n contentTypeUid as UID.ContentType,\n {\n filters: {\n id: {\n $in: entriesToUnpublishIds,\n },\n },\n populate,\n }\n )) as Entity[];\n\n if (entriesToPublish.length > 0) {\n await entityManagerService.publishMany(entriesToPublish, contentTypeUid);\n }\n\n if (entriesToUnpublish.length > 0) {\n await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);\n }\n }\n });\n\n // When the transaction fails it throws an error, when it is successful proceed to updating the release\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, releaseId, {\n data: {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">> looks like it's wrong\n */\n // @ts-expect-error see above\n releasedAt: new Date(),\n },\n });\n\n return release;\n },\n\n async updateAction(\n actionId: UpdateReleaseAction.Request['params']['actionId'],\n releaseId: UpdateReleaseAction.Request['params']['releaseId'],\n update: UpdateReleaseAction.Request['body']\n ) {\n const updatedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: actionId,\n release: {\n id: releaseId,\n releasedAt: {\n $null: true,\n },\n },\n },\n data: update,\n });\n\n if (!updatedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId} or it is already published`\n );\n }\n\n return updatedAction;\n },\n\n async deleteAction(\n actionId: DeleteReleaseAction.Request['params']['actionId'],\n releaseId: DeleteReleaseAction.Request['params']['releaseId']\n ) {\n const deletedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).delete({\n where: {\n id: actionId,\n release: {\n id: releaseId,\n releasedAt: {\n $null: true,\n },\n },\n },\n });\n\n if (!deletedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId} or it is already published`\n );\n }\n\n return deletedAction;\n },\n});\n\nexport default createReleaseService;\n","import { errors } from '@strapi/utils';\nimport { LoadedStrapi } from '@strapi/types';\nimport EE from '@strapi/strapi/dist/utils/ee';\nimport type { Release, CreateRelease } from '../../../shared/contracts/releases';\nimport type { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createReleaseValidationService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async validateUniqueEntry(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n releaseActionArgs: CreateReleaseAction.Request['body']\n ) {\n /**\n * Asserting the type, otherwise TS complains: 'release.actions' is of type 'unknown', even though the types come through for non-populated fields...\n * Possibly related to the comment on GetValues: https://github.com/strapi/strapi/blob/main/packages/core/types/src/modules/entity-service/result.ts\n */\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: { actions: { populate: { entry: { fields: ['id'] } } } },\n })) as Release | null;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const isEntryInRelease = release.actions.some(\n (action) =>\n Number(action.entry.id) === Number(releaseActionArgs.entry.id) &&\n action.contentType === releaseActionArgs.entry.contentType\n );\n\n if (isEntryInRelease) {\n throw new errors.ValidationError(\n `Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`\n );\n }\n },\n validateEntryContentType(\n contentTypeUid: CreateReleaseAction.Request['body']['entry']['contentType']\n ) {\n const contentType = strapi.contentType(contentTypeUid);\n\n if (!contentType) {\n throw new errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);\n }\n\n // TODO: V5 migration - All contentType will have draftAndPublish enabled\n if (!contentType.options?.draftAndPublish) {\n throw new errors.ValidationError(\n `Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`\n );\n }\n },\n async validatePendingReleasesLimit() {\n // Use the maximum releases option if it exists, otherwise default to 3\n const maximumPendingReleases =\n // @ts-expect-error - options is not typed into features\n EE.features.get('cms-content-releases')?.options?.maximumReleases || 3;\n\n const [, pendingReleasesCount] = await strapi.db.query(RELEASE_MODEL_UID).findWithCount({\n filters: {\n releasedAt: {\n $null: true,\n },\n },\n });\n\n // Unlimited is a number that will never be reached like 9999\n if (pendingReleasesCount >= maximumPendingReleases) {\n throw new errors.ValidationError('You have reached the maximum number of pending releases');\n }\n },\n async validateUniqueNameForPendingRelease(name: CreateRelease.Request['body']['name']) {\n const pendingReleases = (await strapi.entityService.findMany(RELEASE_MODEL_UID, {\n filters: {\n releasedAt: {\n $null: true,\n },\n name,\n },\n })) as Release[];\n\n const isNameUnique = pendingReleases.length === 0;\n\n if (!isNameUnique) {\n throw new errors.ValidationError(`Release with name ${name} already exists`);\n }\n },\n async validateScheduledAtIsLaterThanNow(\n scheduledAt: CreateRelease.Request['body']['scheduledAt']\n ) {\n if (scheduledAt && new Date(scheduledAt) <= new Date()) {\n throw new errors.ValidationError('Scheduled at must be later than now');\n }\n },\n});\n\nexport default createReleaseValidationService;\n","import { scheduleJob, Job } from 'node-schedule';\nimport { LoadedStrapi } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: LoadedStrapi }) => {\n const scheduledJobs = new Map<Release['id'], Job>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const job = scheduleJob(scheduleDate, async () => {\n try {\n await getService('release').publish(releaseId);\n // @TODO: Trigger webhook with success message\n } catch (error) {\n // @TODO: Trigger webhook with error message\n }\n\n this.cancel(releaseId);\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, job);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n scheduledJobs.get(releaseId)!.cancel();\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n","import release from './release';\nimport releaseValidation from './validation';\nimport scheduling from './scheduling';\n\nexport const services = {\n release,\n 'release-validation': releaseValidation,\n ...(strapi.features.future.isEnabled('contentReleasesScheduling') ? { scheduling } : {}),\n};\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n // scheduledAt is a date, but we always receive strings from the client\n scheduledAt: yup.string(),\n })\n .required()\n .noUnknown();\n","import { validateYupSchema } from '@strapi/utils';\nimport { RELEASE_SCHEMA } from '../../../../shared/validation-schemas';\n\nexport const validateRelease = validateYupSchema(RELEASE_SCHEMA);\n","import type Koa from 'koa';\nimport { errors } from '@strapi/utils';\nimport { RELEASE_MODEL_UID } from '../constants';\nimport { validateRelease } from './validation/release';\nimport type {\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n} from '../../../shared/contracts/releases';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\ntype ReleaseWithPopulatedActions = Release & { actions: { count: number } };\n\nconst releaseController = {\n async findMany(ctx: Koa.Context) {\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n\n // Handle requests for releases filtered by content type entry\n const isFindManyForContentTypeEntry = Boolean(ctx.query?.contentTypeUid && ctx.query?.entryId);\n if (isFindManyForContentTypeEntry) {\n const query: GetContentTypeEntryReleases.Request['query'] =\n await permissionsManager.sanitizeQuery(ctx.query);\n\n const contentTypeUid = query.contentTypeUid;\n const entryId = query.entryId;\n // Parse the string value or fallback to a default\n const hasEntryAttached: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] =\n typeof query.hasEntryAttached === 'string' ? JSON.parse(query.hasEntryAttached) : false;\n\n const data = hasEntryAttached\n ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId)\n : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);\n\n ctx.body = { data };\n } else {\n const query: GetReleases.Request['query'] = await permissionsManager.sanitizeQuery(ctx.query);\n const { results, pagination } = await releaseService.findPage(query);\n\n const data = results.map((release: ReleaseWithPopulatedActions) => {\n const { actions, ...releaseData } = release;\n\n return {\n ...releaseData,\n actions: {\n meta: {\n count: actions.count,\n },\n },\n };\n });\n\n ctx.body = { data, meta: { pagination } };\n }\n },\n\n async findOne(ctx: Koa.Context) {\n const id: GetRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\n }\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n const sanitizedRelease = {\n ...release,\n createdBy: release.createdBy\n ? strapi.admin.services.user.sanitizeUser(release.createdBy)\n : null,\n };\n\n // Format the data object\n const data = {\n ...sanitizedRelease,\n actions: {\n meta: {\n count,\n },\n },\n };\n\n ctx.body = { data };\n },\n\n async create(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: CreateRelease.Request['body'] = ctx.request.body;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.create(releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async update(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: UpdateRelease.Request['body'] = ctx.request.body;\n const id: UpdateRelease.Request['params']['id'] = ctx.params.id;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.update(id, releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async delete(ctx: Koa.Context) {\n const id: DeleteRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.delete(id);\n\n ctx.body = {\n data: release,\n };\n },\n\n async publish(ctx: Koa.Context) {\n const user: PublishRelease.Request['state']['user'] = ctx.state.user;\n const id: PublishRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.publish(id, { user });\n\n const [countPublishActions, countUnpublishActions] = await Promise.all([\n releaseService.countActions({\n filters: {\n release: id,\n type: 'publish',\n },\n }),\n releaseService.countActions({\n filters: {\n release: id,\n type: 'unpublish',\n },\n }),\n ]);\n\n ctx.body = {\n data: release,\n meta: {\n totalEntries: countPublishActions + countUnpublishActions,\n totalPublishedEntries: countPublishActions,\n totalUnpublishedEntries: countUnpublishActions,\n },\n };\n },\n};\n\nexport default releaseController;\n","import { yup, validateYupSchema } from '@strapi/utils';\n\nconst RELEASE_ACTION_SCHEMA = yup.object().shape({\n entry: yup\n .object()\n .shape({\n id: yup.strapiID().required(),\n contentType: yup.string().required(),\n })\n .required(),\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nconst RELEASE_ACTION_UPDATE_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nexport const validateReleaseAction = validateYupSchema(RELEASE_ACTION_SCHEMA);\nexport const validateReleaseActionUpdateSchema = validateYupSchema(RELEASE_ACTION_UPDATE_SCHEMA);\n","import type Koa from 'koa';\n\nimport { mapAsync } from '@strapi/utils';\nimport {\n validateReleaseAction,\n validateReleaseActionUpdateSchema,\n} from './validation/release-action';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n UpdateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { getService } from '../utils';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\nconst releaseActionController = {\n async create(ctx: Koa.Context) {\n const releaseId: CreateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionArgs: CreateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseAction(releaseActionArgs);\n\n const releaseService = getService('release', { strapi });\n const releaseAction = await releaseService.createAction(releaseId, releaseActionArgs);\n\n ctx.body = {\n data: releaseAction,\n };\n },\n\n async findMany(ctx: Koa.Context) {\n const releaseId: GetReleaseActions.Request['params']['releaseId'] = ctx.params.releaseId;\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_ACTION_MODEL_UID,\n });\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n const { results, pagination } = await releaseService.findActions(releaseId, {\n sort: query.groupBy === 'action' ? 'type' : query.groupBy,\n ...query,\n });\n\n /**\n * Release actions can be related to entries of different content types.\n * We need to sanitize the entry output according to that content type.\n * So, we group the sanitized output function by content type.\n */\n const contentTypeOutputSanitizers = results.reduce((acc, action) => {\n if (acc[action.contentType]) {\n return acc;\n }\n\n const contentTypePermissionsManager =\n strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: action.contentType,\n });\n\n acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;\n\n return acc;\n }, {});\n\n /**\n * sanitizeOutput doesn't work if you use it directly on the Release Action model, it doesn't sanitize the entries\n * So, we need to sanitize manually each entry inside a Release Action\n */\n const sanitizedResults = await mapAsync(results, async (action) => ({\n ...action,\n entry: await contentTypeOutputSanitizers[action.contentType](action.entry),\n }));\n\n const groupedData = await releaseService.groupActions(sanitizedResults, query.groupBy);\n\n const contentTypes = releaseService.getContentTypeModelsFromActions(results);\n const components = await releaseService.getAllComponents();\n\n ctx.body = {\n data: groupedData,\n meta: {\n pagination,\n contentTypes,\n components,\n },\n };\n },\n\n async update(ctx: Koa.Context) {\n const actionId: UpdateReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: UpdateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionUpdateArgs: UpdateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseActionUpdateSchema(releaseActionUpdateArgs);\n\n const releaseService = getService('release', { strapi });\n\n const updatedAction = await releaseService.updateAction(\n actionId,\n releaseId,\n releaseActionUpdateArgs\n );\n\n ctx.body = {\n data: updatedAction,\n };\n },\n\n async delete(ctx: Koa.Context) {\n const actionId: DeleteReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: DeleteReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n\n const releaseService = getService('release', { strapi });\n\n const deletedReleaseAction = await releaseService.deleteAction(actionId, releaseId);\n\n ctx.body = {\n data: deletedReleaseAction,\n };\n },\n};\n\nexport default releaseActionController;\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const controllers = { release, 'release-action': releaseAction };\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/',\n handler: 'release.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/',\n handler: 'release.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:id',\n handler: 'release.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:id',\n handler: 'release.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:id',\n handler: 'release.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/:id/publish',\n handler: 'release.publish',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.publish'],\n },\n },\n ],\n },\n },\n ],\n};\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/:releaseId/actions',\n handler: 'release-action.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create-action'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:releaseId/actions',\n handler: 'release-action.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete-action'],\n },\n },\n ],\n },\n },\n ],\n};\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const routes = {\n release,\n 'release-action': releaseAction,\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { register } from './register';\nimport { bootstrap } from './bootstrap';\nimport { contentTypes } from './content-types';\nimport { services } from './services';\nimport { controllers } from './controllers';\nimport { routes } from './routes';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (features.isEnabled('cms-content-releases')) {\n return {\n register,\n bootstrap,\n contentTypes,\n services,\n controllers,\n routes,\n };\n }\n\n // We keep returning contentTypes to avoid lost the data if feature is disabled\n return {\n contentTypes,\n };\n};\n\nexport default getPlugin();\n"],"names":["contentTypes","contentTypesUtils","features","strapi","release","schema","releaseAction","releaseValidation","scheduling","yup"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../server/src/constants.ts","../../server/src/migrations/index.ts","../../server/src/register.ts","../../server/src/utils/index.ts","../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/content-types/release/schema.ts","../../server/src/content-types/release/index.ts","../../server/src/content-types/release-action/schema.ts","../../server/src/content-types/release-action/index.ts","../../server/src/content-types/index.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/scheduling.ts","../../server/src/services/index.ts","../../shared/validation-schemas.ts","../../server/src/controllers/validation/release.ts","../../server/src/controllers/release.ts","../../server/src/controllers/validation/release-action.ts","../../server/src/controllers/release-action.ts","../../server/src/controllers/index.ts","../../server/src/routes/release.ts","../../server/src/routes/release-action.ts","../../server/src/routes/index.ts","../../server/src/index.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n];\n","import type { Schema } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, mapAsync } from '@strapi/utils';\n\nimport { difference, keys } from 'lodash';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\ninterface Input {\n oldContentTypes: Record<string, Schema.ContentType>;\n contentTypes: Record<string, Schema.ContentType>;\n}\n\nexport async function deleteActionsOnDisableDraftAndPublish({\n oldContentTypes,\n contentTypes,\n}: Input) {\n if (!oldContentTypes) {\n return;\n }\n\n for (const uid in contentTypes) {\n if (!oldContentTypes[uid]) {\n continue;\n }\n\n const oldContentType = oldContentTypes[uid];\n const contentType = contentTypes[uid];\n\n if (\n contentTypesUtils.hasDraftAndPublish(oldContentType) &&\n !contentTypesUtils.hasDraftAndPublish(contentType)\n ) {\n await strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: uid })\n .execute();\n }\n }\n}\n\nexport async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {\n const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];\n\n if (deletedContentTypes.length) {\n await mapAsync(deletedContentTypes, async (deletedContentTypeUID: unknown) => {\n return strapi.db\n ?.queryBuilder(RELEASE_ACTION_MODEL_UID)\n .delete()\n .where({ contentType: deletedContentTypeUID })\n .execute();\n });\n }\n}\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi } from '@strapi/types';\n\nimport { ACTIONS } from './constants';\nimport {\n deleteActionsOnDeleteContentType,\n deleteActionsOnDisableDraftAndPublish,\n} from './migrations';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (features.isEnabled('cms-content-releases')) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n\n strapi.hook('strapi::content-types.beforeSync').register(deleteActionsOnDisableDraftAndPublish);\n strapi.hook('strapi::content-types.afterSync').register(deleteActionsOnDeleteContentType);\n }\n};\n","export const getService = (\n name: 'release' | 'release-validation' | 'scheduling' | 'release-action' | 'event-manager',\n { strapi } = { strapi: global.strapi }\n) => {\n return strapi.plugin('content-releases').service(name);\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';\n\nimport { RELEASE_ACTION_MODEL_UID } from './constants';\nimport { getService } from './utils';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (features.isEnabled('cms-content-releases')) {\n // Clean up release-actions when an entry is deleted\n strapi.db.lifecycles.subscribe({\n afterDelete(event) {\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n const { model, result } = event;\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { id } = result;\n strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: model.uid,\n target_id: id,\n },\n });\n }\n },\n /**\n * deleteMany hook doesn't return the deleted entries ids\n * so we need to fetch them before deleting the entries to save the ids on our state\n */\n async beforeDeleteMany(event) {\n const { model, params } = event;\n // @ts-expect-error TODO: lifecycles types looks like are not 100% finished\n if (model.kind === 'collectionType' && model.options?.draftAndPublish) {\n const { where } = params;\n const entriesToDelete = await strapi.db\n .query(model.uid)\n .findMany({ select: ['id'], where });\n event.state.entriesToDelete = entriesToDelete;\n }\n },\n /**\n * We delete the release actions related to deleted entries\n * We make this only after deleteMany is succesfully executed to avoid errors\n */\n async afterDeleteMany(event) {\n const { model, state } = event;\n const entriesToDelete = state.entriesToDelete;\n if (entriesToDelete) {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: model.uid,\n target_id: {\n $in: (entriesToDelete as Array<{ id: StrapiEntity.ID }>).map((entry) => entry.id),\n },\n },\n });\n }\n },\n });\n\n if (strapi.features.future.isEnabled('contentReleasesScheduling')) {\n getService('scheduling', { strapi })\n .syncFromDatabase()\n .catch((err: Error) => {\n strapi.log.error(\n 'Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling.'\n );\n\n throw err;\n });\n }\n }\n};\n","import { Job } from 'node-schedule';\nimport { LoadedStrapi } from '@strapi/types';\n\nimport { Release } from '../../shared/contracts/releases';\nimport { getService } from './utils';\n\nexport const destroy = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (strapi.features.future.isEnabled('contentReleasesScheduling')) {\n const scheduledJobs: Map<Release['id'], Job> = getService('scheduling', {\n strapi,\n }).getAll();\n\n for (const [, job] of scheduledJobs) {\n job.cancel();\n }\n }\n};\n","import { RELEASE_ACTION_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_releases',\n info: {\n singularName: 'release',\n pluralName: 'releases',\n displayName: 'Release',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n required: true,\n },\n releasedAt: {\n type: 'datetime',\n },\n scheduledAt: {\n type: 'datetime',\n },\n timezone: {\n type: 'string',\n },\n actions: {\n type: 'relation',\n relation: 'oneToMany',\n target: RELEASE_ACTION_MODEL_UID,\n mappedBy: 'release',\n },\n },\n};\n","import schema from './schema';\n\nexport const release = {\n schema,\n};\n","import { RELEASE_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_release_actions',\n info: {\n singularName: 'release-action',\n pluralName: 'release-actions',\n displayName: 'Release Action',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n type: {\n type: 'enumeration',\n enum: ['publish', 'unpublish'],\n required: true,\n },\n entry: {\n type: 'relation',\n relation: 'morphToOne',\n configurable: false,\n },\n contentType: {\n type: 'string',\n required: true,\n },\n locale: {\n type: 'string',\n },\n release: {\n type: 'relation',\n relation: 'manyToOne',\n target: RELEASE_MODEL_UID,\n inversedBy: 'actions',\n },\n },\n};\n","import schema from './schema';\n\nexport const releaseAction = {\n schema,\n};\n","import { release } from './release';\nimport { releaseAction } from './release-action';\n\nexport const contentTypes = {\n release,\n 'release-action': releaseAction,\n};\n","import { setCreatorFields, errors } from '@strapi/utils';\n\nimport type { LoadedStrapi, EntityService, UID, Schema } from '@strapi/types';\n\nimport _ from 'lodash/fp';\n\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport type {\n GetReleases,\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n} from '../../../shared/contracts/releases';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n ReleaseAction,\n UpdateReleaseAction,\n DeleteReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type { Entity, UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\nexport interface Locale extends Entity {\n name: string;\n code: string;\n}\n\ntype LocaleDictionary = {\n [key: Locale['code']]: Pick<Locale, 'name' | 'code'>;\n};\n\nconst getGroupName = (queryValue?: ReleaseActionGroupBy) => {\n switch (queryValue) {\n case 'contentType':\n return 'contentType.displayName';\n case 'action':\n return 'type';\n case 'locale':\n return _.getOr('No locale', 'locale.name');\n default:\n return 'contentType.displayName';\n }\n};\n\nconst createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async create(releaseData: CreateRelease.Request['body'], { user }: { user: UserInfo }) {\n const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);\n\n const {\n validatePendingReleasesLimit,\n validateUniqueNameForPendingRelease,\n validateScheduledAtIsLaterThanNow,\n } = getService('release-validation', { strapi });\n\n await Promise.all([\n validatePendingReleasesLimit(),\n validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),\n validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt),\n ]);\n\n const release = await strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\n\n if (\n strapi.features.future.isEnabled('contentReleasesScheduling') &&\n releaseWithCreatorFields.scheduledAt\n ) {\n const schedulingService = getService('scheduling', { strapi });\n\n await schedulingService.set(release.id, release.scheduledAt);\n }\n\n return release;\n },\n\n async findOne(id: GetRelease.Request['params']['id'], query = {}) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id, {\n ...query,\n });\n\n return release;\n },\n\n findPage(query?: GetReleases.Request['query']) {\n return strapi.entityService.findPage(RELEASE_MODEL_UID, {\n ...query,\n populate: {\n actions: {\n // @ts-expect-error Ignore missing properties\n count: true,\n },\n },\n });\n },\n\n async findManyWithContentTypeEntryAttached(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId']\n ) {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n // Filter the action to get only the content type entry\n actions: {\n where: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async findManyWithoutContentTypeEntryAttached(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId']\n ) {\n // We get the list of releases where the entry is present\n const releasesRelated = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n releasedAt: {\n $null: true,\n },\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n });\n\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n $or: [\n {\n id: {\n $notIn: releasesRelated.map((release) => release.id),\n },\n },\n {\n actions: null,\n },\n ],\n releasedAt: {\n $null: true,\n },\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async update(\n id: number,\n releaseData: UpdateRelease.Request['body'],\n { user }: { user: UserInfo }\n ) {\n const releaseWithCreatorFields = await setCreatorFields({ user, isEdition: true })(releaseData);\n\n const { validateUniqueNameForPendingRelease, validateScheduledAtIsLaterThanNow } = getService(\n 'release-validation',\n { strapi }\n );\n\n await Promise.all([\n validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),\n validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt),\n ]);\n\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id);\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${id}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n const updatedRelease = await strapi.entityService.update(RELEASE_MODEL_UID, id, {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">>\n * is not compatible with the type we are passing here: UpdateRelease.Request['body']\n */\n // @ts-expect-error see above\n data: releaseWithCreatorFields,\n });\n\n if (strapi.features.future.isEnabled('contentReleasesScheduling')) {\n const schedulingService = getService('scheduling', { strapi });\n\n if (releaseData.scheduledAt) {\n // set function always cancel the previous job if it exists, so we can call it directly\n await schedulingService.set(id, releaseData.scheduledAt);\n } else if (release.scheduledAt) {\n // When user don't send a scheduledAt and we have one on the release, means that user want to unschedule it\n schedulingService.cancel(id);\n }\n }\n\n return updatedRelease;\n },\n\n async createAction(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n action: Pick<CreateReleaseAction.Request['body'], 'type' | 'entry'>\n ) {\n const { validateEntryContentType, validateUniqueEntry } = getService('release-validation', {\n strapi,\n });\n\n await Promise.all([\n validateEntryContentType(action.entry.contentType),\n validateUniqueEntry(releaseId, action),\n ]);\n\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId);\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n const { entry, type } = action;\n\n return strapi.entityService.create(RELEASE_ACTION_MODEL_UID, {\n data: {\n type,\n contentType: entry.contentType,\n locale: entry.locale,\n entry: {\n id: entry.id,\n __type: entry.contentType,\n __pivot: { field: 'entry' },\n },\n release: releaseId,\n },\n populate: { release: { fields: ['id'] }, entry: { fields: ['id'] } },\n });\n },\n\n async findActions(\n releaseId: GetReleaseActions.Request['params']['releaseId'],\n query?: GetReleaseActions.Request['query']\n ) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n fields: ['id'],\n });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n return strapi.entityService.findPage(RELEASE_ACTION_MODEL_UID, {\n ...query,\n populate: {\n entry: {\n populate: '*',\n },\n },\n filters: {\n release: releaseId,\n },\n });\n },\n\n async countActions(query: EntityService.Params.Pick<typeof RELEASE_ACTION_MODEL_UID, 'filters'>) {\n return strapi.entityService.count(RELEASE_ACTION_MODEL_UID, query);\n },\n\n async groupActions(actions: ReleaseAction[], groupBy: ReleaseActionGroupBy) {\n const contentTypeUids = actions.reduce<ReleaseAction['contentType'][]>((acc, action) => {\n if (!acc.includes(action.contentType)) {\n acc.push(action.contentType);\n }\n\n return acc;\n }, []);\n const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(\n contentTypeUids\n );\n const allLocalesDictionary = await this.getLocalesDataForActions();\n\n const formattedData = actions.map((action: ReleaseAction) => {\n const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];\n\n return {\n ...action,\n locale: action.locale ? allLocalesDictionary[action.locale] : null,\n contentType: {\n displayName,\n mainFieldValue: action.entry[mainField],\n uid: action.contentType,\n },\n };\n });\n\n const groupName = getGroupName(groupBy);\n return _.groupBy(groupName)(formattedData);\n },\n\n async getLocalesDataForActions() {\n if (!strapi.plugin('i18n')) {\n return {};\n }\n\n const allLocales: Locale[] = (await strapi.plugin('i18n').service('locales').find()) || [];\n return allLocales.reduce<LocaleDictionary>((acc, locale) => {\n acc[locale.code] = { name: locale.name, code: locale.code };\n\n return acc;\n }, {});\n },\n\n async getContentTypesDataForActions(contentTypesUids: ReleaseAction['contentType'][]) {\n const contentManagerContentTypeService = strapi\n .plugin('content-manager')\n .service('content-types');\n\n const contentTypesData: Record<UID.ContentType, { mainField: string; displayName: string }> =\n {};\n for (const contentTypeUid of contentTypesUids) {\n const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({\n uid: contentTypeUid,\n });\n\n contentTypesData[contentTypeUid] = {\n mainField: contentTypeConfig.settings.mainField,\n displayName: strapi.getModel(contentTypeUid).info.displayName,\n };\n }\n\n return contentTypesData;\n },\n\n getContentTypeModelsFromActions(actions: ReleaseAction[]) {\n const contentTypeUids = actions.reduce<ReleaseAction['contentType'][]>((acc, action) => {\n if (!acc.includes(action.contentType)) {\n acc.push(action.contentType);\n }\n\n return acc;\n }, []);\n\n const contentTypeModelsMap = contentTypeUids.reduce(\n (\n acc: { [key: ReleaseAction['contentType']]: Schema.ContentType },\n contentTypeUid: ReleaseAction['contentType']\n ) => {\n acc[contentTypeUid] = strapi.getModel(contentTypeUid);\n\n return acc;\n },\n {}\n );\n\n return contentTypeModelsMap;\n },\n\n async getAllComponents() {\n const contentManagerComponentsService = strapi.plugin('content-manager').service('components');\n\n const components = await contentManagerComponentsService.findAllComponents();\n\n const componentsMap = components.reduce(\n (acc: { [key: Schema.Component['uid']]: Schema.Component }, component: Schema.Component) => {\n acc[component.uid] = component;\n\n return acc;\n },\n {}\n );\n\n return componentsMap;\n },\n\n async delete(releaseId: DeleteRelease.Request['params']['id']) {\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: {\n actions: {\n fields: ['id'],\n },\n },\n })) as unknown as Release;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n // Only delete the release and its actions is you in fact can delete all the actions and the release\n // Otherwise, if the transaction fails it throws an error\n await strapi.db.transaction(async () => {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n id: {\n $in: release.actions.map((action) => action.id),\n },\n },\n });\n await strapi.entityService.delete(RELEASE_MODEL_UID, releaseId);\n });\n\n if (strapi.features.future.isEnabled('contentReleasesScheduling') && release.scheduledAt) {\n const schedulingService = getService('scheduling', { strapi });\n await schedulingService.cancel(release.id);\n }\n\n return release;\n },\n\n async publish(releaseId: PublishRelease.Request['params']['id']) {\n // We need to pass the type because entityService.findOne is not returning the correct type\n const releaseWithPopulatedActionEntries = (await strapi.entityService.findOne(\n RELEASE_MODEL_UID,\n releaseId,\n {\n populate: {\n actions: {\n populate: {\n entry: {\n fields: ['id'],\n },\n },\n },\n },\n }\n )) as unknown as Release;\n\n if (!releaseWithPopulatedActionEntries) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (releaseWithPopulatedActionEntries.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n if (releaseWithPopulatedActionEntries.actions.length === 0) {\n throw new errors.ValidationError('No entries to publish');\n }\n\n /**\n * We separate publish and unpublish actions, grouping them by contentType and extracting only their IDs. Then we can fetch more data for each entry\n * We need to separate collectionTypes from singleTypes because findMany work as findOne for singleTypes and publishMany can't be used for singleTypes\n */\n const collectionTypeActions: {\n [key: UID.ContentType]: {\n entriestoPublishIds: ReleaseAction['entry']['id'][];\n entriesToUnpublishIds: ReleaseAction['entry']['id'][];\n };\n } = {};\n const singleTypeActions: {\n uid: UID.ContentType;\n id: ReleaseAction['entry']['id'];\n action: ReleaseAction['type'];\n }[] = [];\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (strapi.contentTypes[contentTypeUid].kind === 'collectionType') {\n if (!collectionTypeActions[contentTypeUid]) {\n collectionTypeActions[contentTypeUid] = {\n entriestoPublishIds: [],\n entriesToUnpublishIds: [],\n };\n }\n\n if (action.type === 'publish') {\n collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);\n } else {\n collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);\n }\n } else {\n singleTypeActions.push({\n uid: contentTypeUid,\n action: action.type,\n id: action.entry.id,\n });\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\n const populateBuilderService = strapi.plugin('content-manager').service('populate-builder');\n\n // Only publish the release if all action updates are applied successfully to their entry, otherwise leave everything as is\n await strapi.db.transaction(async () => {\n // First we publish all the singleTypes\n for (const { uid, action, id } of singleTypeActions) {\n // @ts-expect-error - populateBuilderService should be a function but is returning service\n const populate = await populateBuilderService(uid).populateDeep(Infinity).build();\n\n const entry = await strapi.entityService.findOne(uid, id, { populate });\n\n try {\n if (action === 'publish') {\n await entityManagerService.publish(entry, uid);\n } else {\n await entityManagerService.unpublish(entry, uid);\n }\n } catch (error) {\n if (\n error instanceof errors.ApplicationError &&\n (error.message === 'already.published' || error.message === 'already.draft')\n ) {\n // We don't want throw an error if the entry is already published or draft\n } else {\n throw error;\n }\n }\n }\n\n // Then, we can continue with publishing the collectionTypes\n for (const contentTypeUid of Object.keys(collectionTypeActions)) {\n // @ts-expect-error - populateBuilderService should be a function but is returning service\n const populate = await populateBuilderService(contentTypeUid)\n .populateDeep(Infinity)\n .build();\n\n const { entriestoPublishIds, entriesToUnpublishIds } =\n collectionTypeActions[contentTypeUid as UID.ContentType];\n\n /**\n * We need to get the populate entries to be able to publish without errors on components/relations/dynamicZones\n * Considering that populate doesn't work well with morph relations we can't get the entries from the Release model\n * So, we need to fetch them manually\n */\n const entriesToPublish = (await strapi.entityService.findMany(\n contentTypeUid as UID.ContentType,\n {\n filters: {\n id: {\n $in: entriestoPublishIds,\n },\n },\n populate,\n }\n )) as Entity[];\n\n const entriesToUnpublish = (await strapi.entityService.findMany(\n contentTypeUid as UID.ContentType,\n {\n filters: {\n id: {\n $in: entriesToUnpublishIds,\n },\n },\n populate,\n }\n )) as Entity[];\n\n if (entriesToPublish.length > 0) {\n await entityManagerService.publishMany(entriesToPublish, contentTypeUid);\n }\n\n if (entriesToUnpublish.length > 0) {\n await entityManagerService.unpublishMany(entriesToUnpublish, contentTypeUid);\n }\n }\n });\n\n // When the transaction fails it throws an error, when it is successful proceed to updating the release\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, releaseId, {\n data: {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">> looks like it's wrong\n */\n // @ts-expect-error see above\n releasedAt: new Date(),\n },\n });\n\n return release;\n },\n\n async updateAction(\n actionId: UpdateReleaseAction.Request['params']['actionId'],\n releaseId: UpdateReleaseAction.Request['params']['releaseId'],\n update: UpdateReleaseAction.Request['body']\n ) {\n const updatedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: actionId,\n release: {\n id: releaseId,\n releasedAt: {\n $null: true,\n },\n },\n },\n data: update,\n });\n\n if (!updatedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId} or it is already published`\n );\n }\n\n return updatedAction;\n },\n\n async deleteAction(\n actionId: DeleteReleaseAction.Request['params']['actionId'],\n releaseId: DeleteReleaseAction.Request['params']['releaseId']\n ) {\n const deletedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).delete({\n where: {\n id: actionId,\n release: {\n id: releaseId,\n releasedAt: {\n $null: true,\n },\n },\n },\n });\n\n if (!deletedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId} or it is already published`\n );\n }\n\n return deletedAction;\n },\n});\n\nexport default createReleaseService;\n","import { errors } from '@strapi/utils';\nimport { LoadedStrapi } from '@strapi/types';\nimport EE from '@strapi/strapi/dist/utils/ee';\nimport type { Release, CreateRelease, UpdateRelease } from '../../../shared/contracts/releases';\nimport type { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createReleaseValidationService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async validateUniqueEntry(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n releaseActionArgs: CreateReleaseAction.Request['body']\n ) {\n /**\n * Asserting the type, otherwise TS complains: 'release.actions' is of type 'unknown', even though the types come through for non-populated fields...\n * Possibly related to the comment on GetValues: https://github.com/strapi/strapi/blob/main/packages/core/types/src/modules/entity-service/result.ts\n */\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: { actions: { populate: { entry: { fields: ['id'] } } } },\n })) as Release | null;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const isEntryInRelease = release.actions.some(\n (action) =>\n Number(action.entry.id) === Number(releaseActionArgs.entry.id) &&\n action.contentType === releaseActionArgs.entry.contentType\n );\n\n if (isEntryInRelease) {\n throw new errors.ValidationError(\n `Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`\n );\n }\n },\n validateEntryContentType(\n contentTypeUid: CreateReleaseAction.Request['body']['entry']['contentType']\n ) {\n const contentType = strapi.contentType(contentTypeUid);\n\n if (!contentType) {\n throw new errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);\n }\n\n // TODO: V5 migration - All contentType will have draftAndPublish enabled\n if (!contentType.options?.draftAndPublish) {\n throw new errors.ValidationError(\n `Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`\n );\n }\n },\n async validatePendingReleasesLimit() {\n // Use the maximum releases option if it exists, otherwise default to 3\n const maximumPendingReleases =\n // @ts-expect-error - options is not typed into features\n EE.features.get('cms-content-releases')?.options?.maximumReleases || 3;\n\n const [, pendingReleasesCount] = await strapi.db.query(RELEASE_MODEL_UID).findWithCount({\n filters: {\n releasedAt: {\n $null: true,\n },\n },\n });\n\n // Unlimited is a number that will never be reached like 9999\n if (pendingReleasesCount >= maximumPendingReleases) {\n throw new errors.ValidationError('You have reached the maximum number of pending releases');\n }\n },\n async validateUniqueNameForPendingRelease(\n name: CreateRelease.Request['body']['name'],\n id?: UpdateRelease.Request['params']['id']\n ) {\n const pendingReleases = (await strapi.entityService.findMany(RELEASE_MODEL_UID, {\n filters: {\n releasedAt: {\n $null: true,\n },\n name,\n ...(id && { id: { $ne: id } }),\n },\n })) as Release[];\n\n const isNameUnique = pendingReleases.length === 0;\n\n if (!isNameUnique) {\n throw new errors.ValidationError(`Release with name ${name} already exists`);\n }\n },\n async validateScheduledAtIsLaterThanNow(\n scheduledAt: CreateRelease.Request['body']['scheduledAt']\n ) {\n if (scheduledAt && new Date(scheduledAt) <= new Date()) {\n throw new errors.ValidationError('Scheduled at must be later than now');\n }\n },\n});\n\nexport default createReleaseValidationService;\n","import { scheduleJob, Job } from 'node-schedule';\nimport { LoadedStrapi } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: LoadedStrapi }) => {\n const scheduledJobs = new Map<Release['id'], Job>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const job = scheduleJob(scheduleDate, async () => {\n try {\n await getService('release').publish(releaseId);\n // @TODO: Trigger webhook with success message\n } catch (error) {\n // @TODO: Trigger webhook with error message\n }\n\n this.cancel(releaseId);\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, job);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n scheduledJobs.get(releaseId)!.cancel();\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n\n getAll() {\n return scheduledJobs;\n },\n\n /**\n * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released\n * This is useful in case the server was restarted and the scheduled jobs were lost\n * This also could be used to sync different Strapi instances in case of a cluster\n */\n async syncFromDatabase() {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n scheduledAt: {\n $gte: new Date(),\n },\n releasedAt: null,\n },\n });\n\n for (const release of releases) {\n this.set(release.id, release.scheduledAt);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n","import release from './release';\nimport releaseValidation from './validation';\nimport scheduling from './scheduling';\n\nexport const services = {\n release,\n 'release-validation': releaseValidation,\n ...(strapi.features.future.isEnabled('contentReleasesScheduling') ? { scheduling } : {}),\n};\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n // scheduledAt is a date, but we always receive strings from the client\n scheduledAt: yup.string().nullable(),\n timezone: yup.string().when('scheduledAt', {\n is: (scheduledAt: string) => !!scheduledAt,\n then: yup.string().required(),\n otherwise: yup.string().nullable(),\n }),\n })\n .required()\n .noUnknown();\n","import { validateYupSchema } from '@strapi/utils';\nimport { RELEASE_SCHEMA } from '../../../../shared/validation-schemas';\n\nexport const validateRelease = validateYupSchema(RELEASE_SCHEMA);\n","import type Koa from 'koa';\nimport { errors } from '@strapi/utils';\nimport { RELEASE_MODEL_UID } from '../constants';\nimport { validateRelease } from './validation/release';\nimport type {\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n} from '../../../shared/contracts/releases';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\ntype ReleaseWithPopulatedActions = Release & { actions: { count: number } };\n\nconst releaseController = {\n async findMany(ctx: Koa.Context) {\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n\n // Handle requests for releases filtered by content type entry\n const isFindManyForContentTypeEntry = Boolean(ctx.query?.contentTypeUid && ctx.query?.entryId);\n if (isFindManyForContentTypeEntry) {\n const query: GetContentTypeEntryReleases.Request['query'] =\n await permissionsManager.sanitizeQuery(ctx.query);\n\n const contentTypeUid = query.contentTypeUid;\n const entryId = query.entryId;\n // Parse the string value or fallback to a default\n const hasEntryAttached: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] =\n typeof query.hasEntryAttached === 'string' ? JSON.parse(query.hasEntryAttached) : false;\n\n const data = hasEntryAttached\n ? await releaseService.findManyWithContentTypeEntryAttached(contentTypeUid, entryId)\n : await releaseService.findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId);\n\n ctx.body = { data };\n } else {\n const query: GetReleases.Request['query'] = await permissionsManager.sanitizeQuery(ctx.query);\n const { results, pagination } = await releaseService.findPage(query);\n\n const data = results.map((release: ReleaseWithPopulatedActions) => {\n const { actions, ...releaseData } = release;\n\n return {\n ...releaseData,\n actions: {\n meta: {\n count: actions.count,\n },\n },\n };\n });\n\n ctx.body = { data, meta: { pagination } };\n }\n },\n\n async findOne(ctx: Koa.Context) {\n const id: GetRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\n }\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n const sanitizedRelease = {\n ...release,\n createdBy: release.createdBy\n ? strapi.admin.services.user.sanitizeUser(release.createdBy)\n : null,\n };\n\n // Format the data object\n const data = {\n ...sanitizedRelease,\n actions: {\n meta: {\n count,\n },\n },\n };\n\n ctx.body = { data };\n },\n\n async create(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: CreateRelease.Request['body'] = ctx.request.body;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.create(releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async update(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: UpdateRelease.Request['body'] = ctx.request.body;\n const id: UpdateRelease.Request['params']['id'] = ctx.params.id;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.update(id, releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async delete(ctx: Koa.Context) {\n const id: DeleteRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.delete(id);\n\n ctx.body = {\n data: release,\n };\n },\n\n async publish(ctx: Koa.Context) {\n const user: PublishRelease.Request['state']['user'] = ctx.state.user;\n const id: PublishRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.publish(id, { user });\n\n const [countPublishActions, countUnpublishActions] = await Promise.all([\n releaseService.countActions({\n filters: {\n release: id,\n type: 'publish',\n },\n }),\n releaseService.countActions({\n filters: {\n release: id,\n type: 'unpublish',\n },\n }),\n ]);\n\n ctx.body = {\n data: release,\n meta: {\n totalEntries: countPublishActions + countUnpublishActions,\n totalPublishedEntries: countPublishActions,\n totalUnpublishedEntries: countUnpublishActions,\n },\n };\n },\n};\n\nexport default releaseController;\n","import { yup, validateYupSchema } from '@strapi/utils';\n\nconst RELEASE_ACTION_SCHEMA = yup.object().shape({\n entry: yup\n .object()\n .shape({\n id: yup.strapiID().required(),\n contentType: yup.string().required(),\n })\n .required(),\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nconst RELEASE_ACTION_UPDATE_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nexport const validateReleaseAction = validateYupSchema(RELEASE_ACTION_SCHEMA);\nexport const validateReleaseActionUpdateSchema = validateYupSchema(RELEASE_ACTION_UPDATE_SCHEMA);\n","import type Koa from 'koa';\n\nimport { mapAsync } from '@strapi/utils';\nimport {\n validateReleaseAction,\n validateReleaseActionUpdateSchema,\n} from './validation/release-action';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n UpdateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { getService } from '../utils';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\nconst releaseActionController = {\n async create(ctx: Koa.Context) {\n const releaseId: CreateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionArgs: CreateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseAction(releaseActionArgs);\n\n const releaseService = getService('release', { strapi });\n const releaseAction = await releaseService.createAction(releaseId, releaseActionArgs);\n\n ctx.body = {\n data: releaseAction,\n };\n },\n\n async findMany(ctx: Koa.Context) {\n const releaseId: GetReleaseActions.Request['params']['releaseId'] = ctx.params.releaseId;\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_ACTION_MODEL_UID,\n });\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n const { results, pagination } = await releaseService.findActions(releaseId, {\n sort: query.groupBy === 'action' ? 'type' : query.groupBy,\n ...query,\n });\n\n /**\n * Release actions can be related to entries of different content types.\n * We need to sanitize the entry output according to that content type.\n * So, we group the sanitized output function by content type.\n */\n const contentTypeOutputSanitizers = results.reduce((acc, action) => {\n if (acc[action.contentType]) {\n return acc;\n }\n\n const contentTypePermissionsManager =\n strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: action.contentType,\n });\n\n acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;\n\n return acc;\n }, {});\n\n /**\n * sanitizeOutput doesn't work if you use it directly on the Release Action model, it doesn't sanitize the entries\n * So, we need to sanitize manually each entry inside a Release Action\n */\n const sanitizedResults = await mapAsync(results, async (action) => ({\n ...action,\n entry: await contentTypeOutputSanitizers[action.contentType](action.entry),\n }));\n\n const groupedData = await releaseService.groupActions(sanitizedResults, query.groupBy);\n\n const contentTypes = releaseService.getContentTypeModelsFromActions(results);\n const components = await releaseService.getAllComponents();\n\n ctx.body = {\n data: groupedData,\n meta: {\n pagination,\n contentTypes,\n components,\n },\n };\n },\n\n async update(ctx: Koa.Context) {\n const actionId: UpdateReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: UpdateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionUpdateArgs: UpdateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseActionUpdateSchema(releaseActionUpdateArgs);\n\n const releaseService = getService('release', { strapi });\n\n const updatedAction = await releaseService.updateAction(\n actionId,\n releaseId,\n releaseActionUpdateArgs\n );\n\n ctx.body = {\n data: updatedAction,\n };\n },\n\n async delete(ctx: Koa.Context) {\n const actionId: DeleteReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: DeleteReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n\n const releaseService = getService('release', { strapi });\n\n const deletedReleaseAction = await releaseService.deleteAction(actionId, releaseId);\n\n ctx.body = {\n data: deletedReleaseAction,\n };\n },\n};\n\nexport default releaseActionController;\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const controllers = { release, 'release-action': releaseAction };\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/',\n handler: 'release.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/',\n handler: 'release.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:id',\n handler: 'release.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:id',\n handler: 'release.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:id',\n handler: 'release.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/:id/publish',\n handler: 'release.publish',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.publish'],\n },\n },\n ],\n },\n },\n ],\n};\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/:releaseId/actions',\n handler: 'release-action.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create-action'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:releaseId/actions',\n handler: 'release-action.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete-action'],\n },\n },\n ],\n },\n },\n ],\n};\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const routes = {\n release,\n 'release-action': releaseAction,\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { register } from './register';\nimport { bootstrap } from './bootstrap';\nimport { destroy } from './destroy';\nimport { contentTypes } from './content-types';\nimport { services } from './services';\nimport { controllers } from './controllers';\nimport { routes } from './routes';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (features.isEnabled('cms-content-releases')) {\n return {\n register,\n bootstrap,\n destroy,\n contentTypes,\n services,\n controllers,\n routes,\n };\n }\n\n // We keep returning contentTypes to avoid lost the data if feature is disabled\n return {\n contentTypes,\n };\n};\n\nexport default getPlugin();\n"],"names":["contentTypes","contentTypesUtils","features","strapi","release","schema","releaseAction","releaseValidation","scheduling","yup"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/content-releases",
3
- "version": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
3
+ "version": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
4
4
  "description": "Strapi plugin for organizing and releasing content",
5
5
  "repository": {
6
6
  "type": "git",
@@ -56,10 +56,10 @@
56
56
  "dependencies": {
57
57
  "@reduxjs/toolkit": "1.9.7",
58
58
  "@strapi/design-system": "1.14.1",
59
- "@strapi/helper-plugin": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
59
+ "@strapi/helper-plugin": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
60
60
  "@strapi/icons": "1.14.1",
61
- "@strapi/types": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
62
- "@strapi/utils": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
61
+ "@strapi/types": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
62
+ "@strapi/utils": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
63
63
  "axios": "1.6.0",
64
64
  "formik": "2.4.0",
65
65
  "lodash": "4.17.21",
@@ -69,10 +69,10 @@
69
69
  "yup": "0.32.9"
70
70
  },
71
71
  "devDependencies": {
72
- "@strapi/admin": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
73
- "@strapi/admin-test-utils": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
74
- "@strapi/pack-up": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
75
- "@strapi/strapi": "0.0.0-next.6d384ed205b7f0792d9bea79195f01b30463cfa0",
72
+ "@strapi/admin": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
73
+ "@strapi/admin-test-utils": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
74
+ "@strapi/pack-up": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
75
+ "@strapi/strapi": "0.0.0-next.7abe81e395faf152048bfba0b088b9062e8ac602",
76
76
  "@testing-library/react": "14.0.0",
77
77
  "@testing-library/user-event": "14.4.3",
78
78
  "@types/koa": "2.13.4",
@@ -109,5 +109,5 @@
109
109
  "displayName": "Releases",
110
110
  "required": true
111
111
  },
112
- "gitHead": "6d384ed205b7f0792d9bea79195f01b30463cfa0"
112
+ "gitHead": "7abe81e395faf152048bfba0b088b9062e8ac602"
113
113
  }