@strapi/content-releases 0.0.0-next.37dd1e3ff22e1635b69683abadd444912ae0dbff → 0.0.0-next.56199ab7a5f3320e0debcbe4a24fe0b8cd599e21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-J4jrthEu.mjs → App-8J9a-MD5.mjs} +81 -16
- package/dist/_chunks/App-8J9a-MD5.mjs.map +1 -0
- package/dist/_chunks/{App-5PRKHpa2.js → App-YFvVMqB8.js} +79 -14
- package/dist/_chunks/App-YFvVMqB8.js.map +1 -0
- package/dist/_chunks/{en-ngTk74JV.mjs → en-MyLPoISH.mjs} +2 -1
- package/dist/_chunks/en-MyLPoISH.mjs.map +1 -0
- package/dist/_chunks/{en-haKSQIo8.js → en-gYDqKYFd.js} +2 -1
- package/dist/_chunks/en-gYDqKYFd.js.map +1 -0
- package/dist/_chunks/{index-_Zsj8MUA.mjs → index-ej8MzbQl.mjs} +101 -42
- package/dist/_chunks/index-ej8MzbQl.mjs.map +1 -0
- package/dist/_chunks/{index-PEkKIRyJ.js → index-vxli-E-l.js} +90 -31
- package/dist/_chunks/index-vxli-E-l.js.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +3 -2
- package/dist/admin/index.mjs.map +1 -1
- package/dist/server/index.js +90 -19
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +90 -20
- package/dist/server/index.mjs.map +1 -1
- package/package.json +10 -9
- package/dist/_chunks/App-5PRKHpa2.js.map +0 -1
- package/dist/_chunks/App-J4jrthEu.mjs.map +0 -1
- package/dist/_chunks/en-haKSQIo8.js.map +0 -1
- package/dist/_chunks/en-ngTk74JV.mjs.map +0 -1
- package/dist/_chunks/index-PEkKIRyJ.js.map +0 -1
- package/dist/_chunks/index-_Zsj8MUA.mjs.map +0 -1
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../server/src/constants.ts","../../server/src/utils/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/services/release-action.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/event-manager.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","export const getService = (\n name: 'release' | 'release-validation' | '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 } from '@strapi/types';\nimport { ACTIONS } from './constants';\n\nimport { getService } from './utils';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n\n const releaseActionService = getService('release-action', { strapi });\n const eventManager = getService('event-manager', { strapi });\n // Clean up release-actions when draft and publish is disabled\n const destroyContentTypeUpdateListener = strapi.eventHub.on(\n 'content-type.update',\n async ({ contentType }) => {\n if (contentType.schema.options.draftAndPublish === false) {\n await releaseActionService.deleteManyForContentType(contentType.uid);\n }\n }\n );\n eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);\n // Clean up release-actions when a content-type is deleted\n const destroyContentTypeDeleteListener = strapi.eventHub.on(\n 'content-type.delete',\n async ({ contentType }) => {\n await releaseActionService.deleteManyForContentType(contentType.uid);\n }\n );\n eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);\n }\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';\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 (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\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\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\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 /**\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\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\n const entriesToDelete = await strapi.db\n .query(model.uid)\n .findMany({ select: ['id'], where });\n\n event.state.entriesToDelete = entriesToDelete;\n }\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\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 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 type { LoadedStrapi } from '@strapi/types';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\nimport type { ReleaseAction } from '../../../shared/contracts/release-actions';\n\nconst createReleaseActionService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async deleteManyForContentType(contentTypeUid: ReleaseAction['contentType']) {\n return strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: contentTypeUid,\n },\n });\n },\n});\n\nexport default createReleaseActionService;\n","import { setCreatorFields, errors } from '@strapi/utils';\n\nimport type { LoadedStrapi, EntityService, UID } from '@strapi/types';\n\nimport _ from 'lodash/fp';\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\ninterface 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 'entry.contentType.displayName';\n case 'action':\n return 'type';\n case 'locale':\n return _.getOr('No locale', 'entry.locale.name');\n default:\n return 'entry.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 return strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\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 findManyForContentTypeEntry(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'],\n {\n hasEntryAttached,\n }: { hasEntryAttached?: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] } = {\n hasEntryAttached: false,\n }\n ) {\n const whereActions = hasEntryAttached\n ? {\n // Find all Releases where the content type entry is present\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n }\n : {\n // Find all Releases where the content type entry is not present\n $or: [\n {\n $not: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n {\n actions: null,\n },\n ],\n };\n const populateAttachedAction = hasEntryAttached\n ? {\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 const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n ...whereActions,\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n ...populateAttachedAction,\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: true,\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 allLocales: Locale[] = await strapi.plugin('i18n').service('locales').find();\n const allLocalesDictionary = allLocales.reduce<LocaleDictionary>((acc, locale) => {\n acc[locale.code] = { name: locale.name, code: locale.code };\n\n return acc;\n }, {});\n\n const formattedData = actions.map((action: ReleaseAction) => {\n const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];\n\n return {\n ...action,\n entry: {\n id: action.entry.id,\n contentType: {\n displayName,\n mainFieldValue: action.entry[mainField],\n },\n locale: action.locale ? allLocalesDictionary[action.locale] : null,\n status: action.entry.publishedAt ? 'published' : 'draft',\n },\n };\n });\n\n const groupName = getGroupName(groupBy);\n return _.groupBy(groupName)(formattedData);\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 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: true,\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 group by content type\n */\n const actions: {\n [key: UID.ContentType]: {\n publish: ReleaseAction['entry'][];\n unpublish: ReleaseAction['entry'][];\n };\n } = {};\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (!actions[contentTypeUid]) {\n actions[contentTypeUid] = {\n publish: [],\n unpublish: [],\n };\n }\n\n if (action.type === 'publish') {\n actions[contentTypeUid].publish.push(action.entry);\n } else {\n actions[contentTypeUid].unpublish.push(action.entry);\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\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 for (const contentTypeUid of Object.keys(actions)) {\n const { publish, unpublish } = actions[contentTypeUid as UID.ContentType];\n\n if (publish.length > 0) {\n await entityManagerService.publishMany(publish, contentTypeUid);\n }\n\n if (unpublish.length > 0) {\n await entityManagerService.unpublishMany(unpublish, 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 type { Release } 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});\n\nexport default createReleaseValidationService;\n","interface ReleaseEventServiceState {\n destroyListenerCallbacks: (() => void)[];\n}\n\nconst createEventManagerService = () => {\n const state: ReleaseEventServiceState = {\n destroyListenerCallbacks: [],\n };\n\n return {\n addDestroyListenerCallback(destroyListenerCallback: () => void) {\n state.destroyListenerCallbacks.push(destroyListenerCallback);\n },\n\n destroyAllListeners() {\n if (!state.destroyListenerCallbacks.length) {\n return;\n }\n\n state.destroyListenerCallbacks.forEach((destroyListenerCallback) => {\n destroyListenerCallback();\n });\n },\n };\n};\n\nexport default createEventManagerService;\n","import releaseAction from './release-action';\nimport release from './release';\nimport releaseValidation from './validation';\nimport eventManager from './event-manager';\n\nexport const services = {\n release,\n 'release-action': releaseAction,\n 'release-validation': releaseValidation,\n 'event-manager': eventManager,\n};\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\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 = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, {\n hasEntryAttached,\n });\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\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n const sanitizedRelease = await permissionsManager.sanitizeOutput(release);\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\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 ctx.body = {\n data: release,\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 {\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 const groupedData = await releaseService.groupActions(results, query.groupBy);\n\n ctx.body = {\n data: groupedData,\n meta: {\n pagination,\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';\nimport { getService } from './utils';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n return {\n register,\n bootstrap,\n contentTypes,\n services,\n controllers,\n routes,\n destroy() {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n getService('event-manager').destroyAllListeners();\n }\n },\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":["strapi","features","release","schema","releaseAction","_","setCreatorFields","errors","releaseValidation","eventManager","yup","validateYupSchema"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../server/src/constants.ts","../../server/src/utils/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/services/release-action.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/event-manager.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","export const getService = (\n name: 'release' | 'release-validation' | '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 } from '@strapi/types';\nimport { ACTIONS } from './constants';\n\nimport { getService } from './utils';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n\n const releaseActionService = getService('release-action', { strapi });\n const eventManager = getService('event-manager', { strapi });\n // Clean up release-actions when draft and publish is disabled\n const destroyContentTypeUpdateListener = strapi.eventHub.on(\n 'content-type.update',\n async ({ contentType }) => {\n if (contentType.schema.options.draftAndPublish === false) {\n await releaseActionService.deleteManyForContentType(contentType.uid);\n }\n }\n );\n eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);\n // Clean up release-actions when a content-type is deleted\n const destroyContentTypeDeleteListener = strapi.eventHub.on(\n 'content-type.delete',\n async ({ contentType }) => {\n await releaseActionService.deleteManyForContentType(contentType.uid);\n }\n );\n eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);\n }\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';\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 (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\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\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\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 /**\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\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\n const entriesToDelete = await strapi.db\n .query(model.uid)\n .findMany({ select: ['id'], where });\n\n event.state.entriesToDelete = entriesToDelete;\n }\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\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 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 type { LoadedStrapi } from '@strapi/types';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\nimport type { ReleaseAction } from '../../../shared/contracts/release-actions';\n\nconst createReleaseActionService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async deleteManyForContentType(contentTypeUid: ReleaseAction['contentType']) {\n return strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n target_type: contentTypeUid,\n },\n });\n },\n});\n\nexport default createReleaseActionService;\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\ninterface 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 await getService('release-validation', { strapi }).validatePendingReleasesLimit();\n\n return strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\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 findManyForContentTypeEntry(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'],\n {\n hasEntryAttached,\n }: { hasEntryAttached?: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] } = {\n hasEntryAttached: false,\n }\n ) {\n const whereActions = hasEntryAttached\n ? {\n // Find all Releases where the content type entry is present\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n }\n : {\n // Find all Releases where the content type entry is not present\n $or: [\n {\n $not: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n {\n actions: null,\n },\n ],\n };\n const populateAttachedAction = hasEntryAttached\n ? {\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 const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n ...whereActions,\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n ...populateAttachedAction,\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: true,\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 group by content type\n */\n const actions: {\n [key: UID.ContentType]: {\n publish: ReleaseAction['entry'][];\n unpublish: ReleaseAction['entry'][];\n };\n } = {};\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (!actions[contentTypeUid]) {\n actions[contentTypeUid] = {\n publish: [],\n unpublish: [],\n };\n }\n\n if (action.type === 'publish') {\n actions[contentTypeUid].publish.push(action.entry);\n } else {\n actions[contentTypeUid].unpublish.push(action.entry);\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\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 for (const contentTypeUid of Object.keys(actions)) {\n const { publish, unpublish } = actions[contentTypeUid as UID.ContentType];\n\n if (publish.length > 0) {\n await entityManagerService.publishMany(publish, contentTypeUid);\n }\n\n if (unpublish.length > 0) {\n await entityManagerService.unpublishMany(unpublish, 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 } 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});\n\nexport default createReleaseValidationService;\n","interface ReleaseEventServiceState {\n destroyListenerCallbacks: (() => void)[];\n}\n\nconst createEventManagerService = () => {\n const state: ReleaseEventServiceState = {\n destroyListenerCallbacks: [],\n };\n\n return {\n addDestroyListenerCallback(destroyListenerCallback: () => void) {\n state.destroyListenerCallbacks.push(destroyListenerCallback);\n },\n\n destroyAllListeners() {\n if (!state.destroyListenerCallbacks.length) {\n return;\n }\n\n state.destroyListenerCallbacks.forEach((destroyListenerCallback) => {\n destroyListenerCallback();\n });\n },\n };\n};\n\nexport default createEventManagerService;\n","import releaseAction from './release-action';\nimport release from './release';\nimport releaseValidation from './validation';\nimport eventManager from './event-manager';\n\nexport const services = {\n release,\n 'release-action': releaseAction,\n 'release-validation': releaseValidation,\n 'event-manager': eventManager,\n};\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\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 = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, {\n hasEntryAttached,\n });\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\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n const sanitizedRelease = await permissionsManager.sanitizeOutput(release);\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\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 ctx.body = {\n data: release,\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';\nimport { getService } from './utils';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n return {\n register,\n bootstrap,\n contentTypes,\n services,\n controllers,\n routes,\n destroy() {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n getService('event-manager').destroyAllListeners();\n }\n },\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":["strapi","features","release","schema","releaseAction","_","setCreatorFields","errors","EE","releaseValidation","eventManager","yup","validateYupSchema","mapAsync","contentTypes"],"mappings":"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"}
|
package/dist/server/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { setCreatorFields, errors, validateYupSchema, yup as yup$1 } from "@strapi/utils";
|
|
1
|
+
import { setCreatorFields, errors, validateYupSchema, yup as yup$1, mapAsync } from "@strapi/utils";
|
|
2
2
|
import _ from "lodash/fp";
|
|
3
|
+
import EE from "@strapi/strapi/dist/utils/ee";
|
|
3
4
|
import * as yup from "yup";
|
|
4
5
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
5
6
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -223,18 +224,19 @@ const createReleaseActionService = ({ strapi: strapi2 }) => ({
|
|
|
223
224
|
const getGroupName = (queryValue) => {
|
|
224
225
|
switch (queryValue) {
|
|
225
226
|
case "contentType":
|
|
226
|
-
return "
|
|
227
|
+
return "contentType.displayName";
|
|
227
228
|
case "action":
|
|
228
229
|
return "type";
|
|
229
230
|
case "locale":
|
|
230
|
-
return _.getOr("No locale", "
|
|
231
|
+
return _.getOr("No locale", "locale.name");
|
|
231
232
|
default:
|
|
232
|
-
return "
|
|
233
|
+
return "contentType.displayName";
|
|
233
234
|
}
|
|
234
235
|
};
|
|
235
236
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
236
237
|
async create(releaseData, { user }) {
|
|
237
238
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
239
|
+
await getService("release-validation", { strapi: strapi2 }).validatePendingReleasesLimit();
|
|
238
240
|
return strapi2.entityService.create(RELEASE_MODEL_UID, {
|
|
239
241
|
data: releaseWithCreatorFields
|
|
240
242
|
});
|
|
@@ -375,7 +377,9 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
375
377
|
return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
|
|
376
378
|
...query,
|
|
377
379
|
populate: {
|
|
378
|
-
entry:
|
|
380
|
+
entry: {
|
|
381
|
+
populate: "*"
|
|
382
|
+
}
|
|
379
383
|
},
|
|
380
384
|
filters: {
|
|
381
385
|
release: releaseId
|
|
@@ -395,29 +399,32 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
395
399
|
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
396
400
|
contentTypeUids
|
|
397
401
|
);
|
|
398
|
-
const
|
|
399
|
-
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
400
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
401
|
-
return acc;
|
|
402
|
-
}, {});
|
|
402
|
+
const allLocalesDictionary = await this.getLocalesDataForActions();
|
|
403
403
|
const formattedData = actions.map((action) => {
|
|
404
404
|
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
405
405
|
return {
|
|
406
406
|
...action,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
},
|
|
413
|
-
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
414
|
-
status: action.entry.publishedAt ? "published" : "draft"
|
|
407
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
408
|
+
contentType: {
|
|
409
|
+
displayName,
|
|
410
|
+
mainFieldValue: action.entry[mainField],
|
|
411
|
+
uid: action.contentType
|
|
415
412
|
}
|
|
416
413
|
};
|
|
417
414
|
});
|
|
418
415
|
const groupName = getGroupName(groupBy);
|
|
419
416
|
return _.groupBy(groupName)(formattedData);
|
|
420
417
|
},
|
|
418
|
+
async getLocalesDataForActions() {
|
|
419
|
+
if (!strapi2.plugin("i18n")) {
|
|
420
|
+
return {};
|
|
421
|
+
}
|
|
422
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find() || [];
|
|
423
|
+
return allLocales.reduce((acc, locale) => {
|
|
424
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
425
|
+
return acc;
|
|
426
|
+
}, {});
|
|
427
|
+
},
|
|
421
428
|
async getContentTypesDataForActions(contentTypesUids) {
|
|
422
429
|
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
423
430
|
const contentTypesData = {};
|
|
@@ -432,6 +439,34 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
432
439
|
}
|
|
433
440
|
return contentTypesData;
|
|
434
441
|
},
|
|
442
|
+
getContentTypeModelsFromActions(actions) {
|
|
443
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
444
|
+
if (!acc.includes(action.contentType)) {
|
|
445
|
+
acc.push(action.contentType);
|
|
446
|
+
}
|
|
447
|
+
return acc;
|
|
448
|
+
}, []);
|
|
449
|
+
const contentTypeModelsMap = contentTypeUids.reduce(
|
|
450
|
+
(acc, contentTypeUid) => {
|
|
451
|
+
acc[contentTypeUid] = strapi2.getModel(contentTypeUid);
|
|
452
|
+
return acc;
|
|
453
|
+
},
|
|
454
|
+
{}
|
|
455
|
+
);
|
|
456
|
+
return contentTypeModelsMap;
|
|
457
|
+
},
|
|
458
|
+
async getAllComponents() {
|
|
459
|
+
const contentManagerComponentsService = strapi2.plugin("content-manager").service("components");
|
|
460
|
+
const components = await contentManagerComponentsService.findAllComponents();
|
|
461
|
+
const componentsMap = components.reduce(
|
|
462
|
+
(acc, component) => {
|
|
463
|
+
acc[component.uid] = component;
|
|
464
|
+
return acc;
|
|
465
|
+
},
|
|
466
|
+
{}
|
|
467
|
+
);
|
|
468
|
+
return componentsMap;
|
|
469
|
+
},
|
|
435
470
|
async delete(releaseId) {
|
|
436
471
|
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
437
472
|
populate: {
|
|
@@ -586,6 +621,22 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
586
621
|
`Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`
|
|
587
622
|
);
|
|
588
623
|
}
|
|
624
|
+
},
|
|
625
|
+
async validatePendingReleasesLimit() {
|
|
626
|
+
const maximumPendingReleases = (
|
|
627
|
+
// @ts-expect-error - options is not typed into features
|
|
628
|
+
EE.features.get("cms-content-releases")?.options?.maximumReleases || 3
|
|
629
|
+
);
|
|
630
|
+
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
631
|
+
filters: {
|
|
632
|
+
releasedAt: {
|
|
633
|
+
$null: true
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
if (pendingReleasesCount >= maximumPendingReleases) {
|
|
638
|
+
throw new errors.ValidationError("You have reached the maximum number of pending releases");
|
|
639
|
+
}
|
|
589
640
|
}
|
|
590
641
|
});
|
|
591
642
|
const createEventManagerService = () => {
|
|
@@ -760,11 +811,30 @@ const releaseActionController = {
|
|
|
760
811
|
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
761
812
|
...query
|
|
762
813
|
});
|
|
763
|
-
const
|
|
814
|
+
const contentTypeOutputSanitizers = results.reduce((acc, action) => {
|
|
815
|
+
if (acc[action.contentType]) {
|
|
816
|
+
return acc;
|
|
817
|
+
}
|
|
818
|
+
const contentTypePermissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
819
|
+
ability: ctx.state.userAbility,
|
|
820
|
+
model: action.contentType
|
|
821
|
+
});
|
|
822
|
+
acc[action.contentType] = contentTypePermissionsManager.sanitizeOutput;
|
|
823
|
+
return acc;
|
|
824
|
+
}, {});
|
|
825
|
+
const sanitizedResults = await mapAsync(results, async (action) => ({
|
|
826
|
+
...action,
|
|
827
|
+
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
828
|
+
}));
|
|
829
|
+
const groupedData = await releaseService.groupActions(sanitizedResults, query.groupBy);
|
|
830
|
+
const contentTypes2 = releaseService.getContentTypeModelsFromActions(results);
|
|
831
|
+
const components = await releaseService.getAllComponents();
|
|
764
832
|
ctx.body = {
|
|
765
833
|
data: groupedData,
|
|
766
834
|
meta: {
|
|
767
|
-
pagination
|
|
835
|
+
pagination,
|
|
836
|
+
contentTypes: contentTypes2,
|
|
837
|
+
components
|
|
768
838
|
}
|
|
769
839
|
};
|
|
770
840
|
},
|