{"version":3,"file":"stages.mjs","sources":["../../../server/src/controllers/stages.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport type { Core } from '@strapi/types';\n\nimport { async, validate } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { validateUpdateStageOnEntity, validateLocale } from '../validation/review-workflows';\nimport {\n  STAGE_MODEL_UID,\n  ENTITY_STAGE_ATTRIBUTE,\n  STAGE_TRANSITION_UID,\n} from '../constants/workflows';\n\n/**\n *\n * @param { Core.Strapi } strapi - Strapi instance\n * @param userAbility\n * @return { (Stage) => SanitizedStage }\n */\nfunction sanitizeStage({ strapi }: { strapi: Core.Strapi }, userAbility: unknown) {\n  const permissionChecker = strapi\n    .plugin('content-manager')\n    .service('permission-checker')\n    .create({ userAbility, model: STAGE_MODEL_UID });\n\n  return (entity: unknown) => permissionChecker.sanitizeOutput(entity);\n}\n\nexport default {\n  /**\n   * List all stages\n   * @param {import('koa').BaseContext} ctx - koa context\n   */\n  async find(ctx: Context) {\n    const { workflow_id: workflowId } = ctx.params;\n    const { populate } = ctx.query;\n    const stagesService = getService('stages');\n    const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n    const stages = await stagesService.find({\n      workflowId,\n      populate,\n    });\n\n    ctx.body = {\n      data: await async.map(stages, sanitizer),\n    };\n  },\n  /**\n   * Get one stage\n   * @param {import('koa').BaseContext} ctx - koa context\n   */\n  async findById(ctx: Context) {\n    const { id, workflow_id: workflowId } = ctx.params;\n    const { populate } = ctx.query;\n    const stagesService = getService('stages');\n    const sanitizer = sanitizeStage({ strapi }, ctx.state.userAbility);\n\n    const stage = await stagesService.findById(id, {\n      workflowId,\n      populate,\n    });\n\n    ctx.body = {\n      data: await sanitizer(stage),\n    };\n  },\n\n  /**\n   * Updates an entity's stage.\n   * @async\n   * @param {Object} ctx - The Koa context object.\n   * @param {Object} ctx.params - An object containing the parameters from the request URL.\n   * @param {string} ctx.params.model_uid - The model UID of the entity.\n   * @param {string} ctx.params.id - The ID of the entity to update.\n   * @param {Object} ctx.request.body.data - Optional data object containing the new stage ID for the entity.\n   * @param {string} ctx.request.body.data.id - The ID of the new stage for the entity.\n   * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n   * @throws {ValidationError} If the `data` object in the request body fails to pass validation.\n   * @returns {Promise<void>} A promise that resolves when the entity's stage has been updated.\n   */\n  async updateEntity(ctx: Context) {\n    const stagesService = getService('stages');\n    const stagePermissions = getService('stage-permissions');\n    const workflowService = getService('workflows');\n\n    const { model_uid: modelUID, id: documentId } = ctx.params;\n    const { body, query = {} } = ctx.request;\n\n    const { sanitizeOutput } = strapi\n      .plugin('content-manager')\n      .service('permission-checker')\n      .create({ userAbility: ctx.state.userAbility, model: modelUID });\n\n    // Load entity\n    const locale = await validateLocale(query?.locale);\n    const entity = await strapi.documents(modelUID).findOne({\n      documentId,\n      // @ts-expect-error - locale should be also null in the doc service types\n      locale,\n      populate: [ENTITY_STAGE_ATTRIBUTE],\n    });\n\n    if (!entity) {\n      ctx.throw(404, 'Entity not found');\n    }\n\n    // Validate if entity stage can be updated\n    const canTransition = stagePermissions.can(\n      STAGE_TRANSITION_UID,\n      entity[ENTITY_STAGE_ATTRIBUTE]?.id\n    );\n\n    if (!canTransition) {\n      ctx.throw(403, 'Forbidden stage transition');\n    }\n\n    const { id: stageId } = await validateUpdateStageOnEntity(\n      { id: Number(body?.data?.id) },\n      'You should pass an id to the body of the put request.'\n    );\n\n    const workflow = await workflowService.assertContentTypeBelongsToWorkflow(modelUID);\n    workflowService.assertStageBelongsToWorkflow(stageId, workflow);\n\n    const canTransitionTo = await stagePermissions.canTransitionToStage(stageId);\n    if (!canTransitionTo) {\n      ctx.throw(403, 'Forbidden stage transition');\n    }\n\n    const updatedEntity = await stagesService.updateEntity(entity, modelUID, stageId);\n\n    ctx.body = { data: await sanitizeOutput(updatedEntity) };\n  },\n\n  /**\n   * List all the stages that are available for a user to transition an entity to.\n   * Stages are filtered by both \"from\" permission on the current stage AND \"to\" permission on each target stage.\n   * @async\n   * @param {*} ctx\n   * @param {string} ctx.params.model_uid - The model UID of the entity.\n   * @param {string} ctx.params.id - The ID of the entity.\n   * @throws {ApplicationError} If review workflows is not activated on the specified model UID.\n   */\n  async listAvailableStages(ctx: Context) {\n    const stagePermissions = getService('stage-permissions');\n    const workflowService = getService('workflows');\n\n    const { model_uid: modelUID, id: documentId } = ctx.params;\n    const { query = {} } = ctx.request;\n\n    if (\n      strapi\n        .plugin('content-manager')\n        .service('permission-checker')\n        .create({ userAbility: ctx.state.userAbility, model: modelUID })\n        .cannot.read()\n    ) {\n      return ctx.forbidden();\n    }\n\n    // Load entity\n    const locale = (await validateLocale(query?.locale)) ?? undefined;\n    const entity = await strapi.documents(modelUID).findOne({\n      documentId,\n      locale,\n      populate: [ENTITY_STAGE_ATTRIBUTE],\n    });\n\n    if (!entity) {\n      ctx.throw(404, 'Entity not found');\n    }\n\n    const entityStageId = entity[ENTITY_STAGE_ATTRIBUTE]?.id;\n    const canTransition = stagePermissions.can(STAGE_TRANSITION_UID, entityStageId);\n\n    const [workflowCount, workflowResult] = await Promise.all([\n      workflowService.count(),\n      workflowService.getAssignedWorkflow(modelUID, {\n        populate: { stages: { populate: { permissions: { populate: ['role'] } } } },\n      }),\n    ]);\n\n    const workflowStages = workflowResult ? workflowResult.stages : [];\n\n    const meta = {\n      stageCount: workflowStages.length,\n      workflowCount,\n    };\n\n    if (!canTransition) {\n      ctx.body = {\n        data: [],\n        meta,\n      };\n\n      return;\n    }\n\n    const otherStages = workflowStages.filter(\n      (stage: { id: number; permissions?: unknown[] }) => stage.id !== entityStageId\n    );\n\n    const data = otherStages.filter((stage: { id: number; permissions?: unknown[] }) =>\n      stagePermissions.canTransitionToStageWithPermissions(stage)\n    );\n\n    ctx.body = {\n      data,\n      meta,\n    };\n  },\n};\n"],"names":["sanitizeStage","strapi","userAbility","permissionChecker","plugin","service","create","model","STAGE_MODEL_UID","entity","sanitizeOutput","find","ctx","workflow_id","workflowId","params","populate","query","stagesService","getService","sanitizer","state","stages","body","data","async","map","findById","id","stage","updateEntity","stagePermissions","workflowService","model_uid","modelUID","documentId","request","locale","validateLocale","documents","findOne","ENTITY_STAGE_ATTRIBUTE","throw","canTransition","can","STAGE_TRANSITION_UID","stageId","validateUpdateStageOnEntity","Number","workflow","assertContentTypeBelongsToWorkflow","assertStageBelongsToWorkflow","canTransitionTo","canTransitionToStage","updatedEntity","listAvailableStages","cannot","read","forbidden","undefined","entityStageId","workflowCount","workflowResult","Promise","all","count","getAssignedWorkflow","permissions","workflowStages","meta","stageCount","length","otherStages","filter","canTransitionToStageWithPermissions"],"mappings":"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"}