{"version":3,"file":"stages.mjs","sources":["../../../server/src/services/stages.ts"],"sourcesContent":["import type { Core, UID } from '@strapi/types';\nimport type { StagePermission } from '../../../shared/contracts/review-workflows';\nimport { async, errors } from '@strapi/utils';\nimport { map, pick, isEqual } from 'lodash/fp';\nimport { STAGE_MODEL_UID, ENTITY_STAGE_ATTRIBUTE, ERRORS } from '../constants/workflows';\nimport { WORKFLOW_UPDATE_STAGE } from '../constants/webhook-events';\nimport { getService } from '../utils';\n\ninterface PopulatedPermission {\n  role: number | { id: number };\n  action: string;\n  actionParameters?: { from?: number; to?: number };\n}\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizedStageFields = ['id', 'name', 'workflow', 'color'];\nconst sanitizeStageFields = pick(sanitizedStageFields);\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => {\n  const metrics = getService('workflow-metrics', { strapi });\n  const stagePermissionsService = getService('stage-permissions', { strapi });\n  const workflowValidator = getService('validation', { strapi });\n\n  return {\n    find({ workflowId, populate }: any) {\n      return strapi.db.query(STAGE_MODEL_UID).findMany({\n        where: { workflow: workflowId },\n        populate,\n      });\n    },\n\n    findById(id: string | number, { populate }: any = {}) {\n      return strapi.db.query(STAGE_MODEL_UID).findOne({\n        where: { id },\n        populate,\n      });\n    },\n\n    async createMany(stagesList: any, { fields }: any = {}) {\n      const params = { select: fields ?? '*' };\n\n      const stages = await Promise.all(\n        stagesList.map((stage: any) =>\n          strapi.db.query(STAGE_MODEL_UID).create({\n            data: sanitizeStageFields(stage),\n            ...params,\n          })\n        )\n      );\n\n      await async.reduce(stagesList)(async (_, stage, idx) => {\n        const stageId = stages[idx].id;\n        const allPermissionIds: number[] = [];\n\n        // Register \"from\" permissions\n        if (stage.fromPermissions && stage.fromPermissions.length > 0) {\n          const fromPermissions = await async.map(\n            stage.fromPermissions,\n            (permission: StagePermission) =>\n              stagePermissionsService.register({\n                roleId: permission.role,\n                action: permission.action,\n                fromStage: stageId,\n              })\n          );\n          allPermissionIds.push(...fromPermissions.flat().map((p: { id: number }) => p.id));\n        }\n\n        // Register \"to\" permissions\n        if (stage.toPermissions && stage.toPermissions.length > 0) {\n          const toPermissions = await async.map(\n            stage.toPermissions,\n            (permission: StagePermission) =>\n              stagePermissionsService.registerTo({\n                roleId: permission.role,\n                action: permission.action,\n                toStage: stageId,\n              })\n          );\n          allPermissionIds.push(...toPermissions.flat().map((p: { id: number }) => p.id));\n        }\n\n        if (allPermissionIds.length > 0) {\n          await strapi.db.query(STAGE_MODEL_UID).update({\n            where: { id: stageId },\n            data: {\n              permissions: allPermissionIds,\n            },\n          });\n        }\n      }, []);\n\n      metrics.sendDidCreateStage();\n\n      return stages;\n    },\n\n    async update(srcStage: any, destStage: any) {\n      const stageId = destStage.id;\n      const hasPermissionChanges = destStage.fromPermissions || destStage.toPermissions;\n\n      let allPermissionIds: number[];\n\n      if (hasPermissionChanges) {\n        // Delete all old permissions (both from and to) when either type changes\n        await this.deleteStagePermissions([srcStage]);\n\n        allPermissionIds = [];\n\n        const extractRoleId = (p: PopulatedPermission): number =>\n          typeof p.role === 'object' ? p.role.id : p.role;\n\n        // Re-register \"from\" permissions (fall back to existing \"from\" entries from DB)\n        const fromPerms =\n          destStage.fromPermissions ??\n          (srcStage?.permissions ?? [])\n            .filter((p: PopulatedPermission) => p.actionParameters?.from)\n            .map((p: PopulatedPermission) => ({ role: extractRoleId(p), action: p.action }));\n\n        if (fromPerms.length > 0) {\n          const registered = await async.map(fromPerms, (permission: StagePermission) =>\n            stagePermissionsService.register({\n              roleId: permission.role,\n              action: permission.action,\n              fromStage: stageId,\n            })\n          );\n          allPermissionIds.push(...registered.flat().map((p: { id: number }) => p.id));\n        }\n\n        // Re-register \"to\" permissions (fall back to existing \"to\" entries from DB)\n        const toPerms =\n          destStage.toPermissions ??\n          (srcStage?.permissions ?? [])\n            .filter((p: PopulatedPermission) => p.actionParameters?.to)\n            .map((p: PopulatedPermission) => ({ role: extractRoleId(p), action: p.action }));\n\n        if (toPerms.length > 0) {\n          const registered = await async.map(toPerms, (permission: StagePermission) =>\n            stagePermissionsService.registerTo({\n              roleId: permission.role,\n              action: permission.action,\n              toStage: stageId,\n            })\n          );\n          allPermissionIds.push(...registered.flat().map((p: { id: number }) => p.id));\n        }\n      } else {\n        allPermissionIds = (srcStage?.permissions ?? [])\n          .map((p: { id: number }) => p.id)\n          .filter(Boolean);\n      }\n\n      const stage = await strapi.db.query(STAGE_MODEL_UID).update({\n        where: { id: stageId },\n        data: {\n          ...destStage,\n          permissions: allPermissionIds,\n        },\n      });\n\n      metrics.sendDidEditStage();\n\n      return stage;\n    },\n\n    async delete(stage: any) {\n      // Unregister all permissions related to this stage id\n      await this.deleteStagePermissions([stage]);\n\n      const deletedStage = await strapi.db.query(STAGE_MODEL_UID).delete({\n        where: { id: stage.id },\n      });\n\n      metrics.sendDidDeleteStage();\n\n      return deletedStage;\n    },\n\n    async deleteMany(stages: any) {\n      await this.deleteStagePermissions(stages);\n\n      return strapi.db.query(STAGE_MODEL_UID).deleteMany({\n        where: { id: { $in: stages.map((s: any) => s.id) } },\n      });\n    },\n\n    async deleteStagePermissions(stages: any) {\n      const permissions = stages.map((s: any) => s.permissions || []).flat();\n      await stagePermissionsService.unregister(permissions || []);\n    },\n\n    count({ workflowId }: any = {}) {\n      const opts = {} as any;\n\n      if (workflowId) {\n        opts.where = {\n          workflow: workflowId,\n        };\n      }\n\n      return strapi.db.query(STAGE_MODEL_UID).count(opts);\n    },\n\n    async replaceStages(srcStages: any, destStages: any, contentTypesToMigrate = []) {\n      const { created, updated, deleted } = getDiffBetweenStages(srcStages, destStages);\n\n      assertAtLeastOneStageRemain(srcStages || [], { created, deleted });\n\n      // Update stages and assign entity stages\n      return strapi.db.transaction(async ({ trx }) => {\n        // Create the new stages\n        const createdStages = await this.createMany(created, { fields: ['id'] });\n        // Put all the newly created stages ids\n        const createdStagesIds = map('id', createdStages);\n\n        // Update the workflow stages\n        await async.map(updated, (destStage: any) => {\n          const srcStage = srcStages.find((s: any) => s.id === destStage.id);\n\n          return this.update(srcStage, destStage);\n        });\n\n        // Delete the stages that are not in the new stages list\n        await async.map(deleted, async (stage: any) => {\n          // Find the nearest stage in the workflow and newly created stages\n          // that is not deleted, prioritizing the previous stages\n          const nearestStage = findNearestMatchingStage(\n            [...srcStages, ...createdStages],\n            srcStages.findIndex((s: any) => s.id === stage.id),\n            (targetStage: any) => {\n              return !deleted.find((s: any) => s.id === targetStage.id);\n            }\n          );\n\n          // Assign the new stage to entities that had the deleted stage\n          await async.map(contentTypesToMigrate, (contentTypeUID: any) => {\n            this.updateEntitiesStage(contentTypeUID, {\n              fromStageId: stage.id,\n              toStageId: nearestStage.id,\n              trx,\n            });\n          });\n\n          return this.delete(stage);\n        });\n\n        return destStages.map((stage: any) => ({\n          ...stage,\n          id: stage.id ?? createdStagesIds.shift(),\n        }));\n      });\n    },\n\n    /**\n     * Update the stage of an entity\n     */\n    async updateEntity(\n      entityToUpdate: {\n        id: number | string;\n        documentId: string;\n        locale: string;\n        updatedAt: string;\n      },\n      model: UID.ContentType,\n      stageId: any\n    ) {\n      const stage = await this.findById(stageId);\n      const { documentId, locale } = entityToUpdate;\n\n      await workflowValidator.validateWorkflowCount();\n\n      if (!stage) {\n        throw new ApplicationError(`Selected stage does not exist`);\n      }\n\n      const entity = await strapi.documents(model).update({\n        documentId,\n        locale,\n        // Stage doesn't have DP or i18n enabled, connecting it through the `id`\n        // will be safer than relying on the `documentId` + `locale` + `status` transformation\n        data: { [ENTITY_STAGE_ATTRIBUTE]: pick(['id'], stage) },\n        populate: [ENTITY_STAGE_ATTRIBUTE],\n      });\n\n      // Update the `updated_at` field of the entity, so that the `status` is not considered `Modified`\n      // NOTE: `updatedAt` is a protected attribute that can not be modified directly from the query layer\n      //        hence the knex query builder is used here.\n      const { tableName } = strapi.db.metadata.get(model);\n      await strapi.db\n        .connection(tableName)\n        .where({ id: entityToUpdate.id })\n        .update({\n          updated_at: new Date(entityToUpdate.updatedAt),\n        });\n\n      metrics.sendDidChangeEntryStage();\n\n      return entity;\n    },\n\n    /**\n     * Updates entity stages of a content type:\n     *  - If fromStageId is undefined, all entities with an existing stage will be assigned the new stage\n     *  - If fromStageId is null, all entities without a stage will be assigned the new stage\n     *  - If fromStageId is a number, all entities with that stage will be assigned the new stage\n     *\n     * For performance reasons we use knex queries directly.\n     *\n     * @param {string} contentTypeUID\n     * @param {number | undefined | null} fromStageId\n     * @param {number} toStageId\n     * @param {import('knex').Knex.Transaction} trx\n     * @returns\n     */\n    async updateEntitiesStage(contentTypeUID: any, { fromStageId, toStageId }: any) {\n      const { attributes, tableName } = strapi.db.metadata.get(contentTypeUID) as any;\n      const joinTable = attributes[ENTITY_STAGE_ATTRIBUTE].joinTable;\n      const joinColumn = joinTable.joinColumn.name;\n      const invJoinColumn = joinTable.inverseJoinColumn.name;\n\n      await workflowValidator.validateWorkflowCount();\n\n      return strapi.db.transaction(async ({ trx }) => {\n        // Update all already existing links to the new stage\n        if (fromStageId === undefined) {\n          return strapi.db\n            .getConnection()\n            .from(joinTable.name)\n            .update({ [invJoinColumn]: toStageId })\n            .transacting(trx);\n        }\n\n        // Update all links from the specified stage to the new stage\n        const selectStatement = strapi.db\n          .getConnection()\n          .select({ [joinColumn]: 't1.id', [invJoinColumn]: toStageId })\n          .from(`${tableName} as t1`)\n          .leftJoin(`${joinTable.name} as t2`, `t1.id`, `t2.${joinColumn}`)\n          .where(`t2.${invJoinColumn}`, fromStageId)\n          .toSQL();\n\n        // Insert rows for all entries of the content type that have the specified stage\n        return strapi.db\n          .getConnection(joinTable.name)\n          .insert(\n            strapi.db.connection.raw(\n              `(${joinColumn}, ${invJoinColumn})  ${selectStatement.sql}`,\n              selectStatement.bindings\n            )\n          )\n          .transacting(trx);\n      });\n    },\n\n    /**\n     * Deletes all entity stages of a content type\n     * @param {string} contentTypeUID\n     * @returns\n     */\n    async deleteAllEntitiesStage(contentTypeUID: any) {\n      const { attributes } = strapi.db.metadata.get(contentTypeUID) as any;\n      const joinTable = attributes[ENTITY_STAGE_ATTRIBUTE].joinTable;\n\n      // Delete all stage links for the content type\n      return strapi.db.transaction(async ({ trx }) =>\n        strapi.db.getConnection().from(joinTable.name).delete().transacting(trx)\n      );\n    },\n  };\n};\n\nconst normalizeStageForDiff = (stage: {\n  name?: string;\n  color?: string;\n  fromPermissions?: unknown[];\n  toPermissions?: unknown[];\n}) => ({\n  ...pick(['name', 'color'], stage),\n  fromPermissions: stage.fromPermissions ?? [],\n  toPermissions: stage.toPermissions ?? [],\n});\n\n/**\n * Compares two arrays of stages and returns an object indicating the differences.\n *\n * The function compares the `id` properties of each stage in `sourceStages` and `comparisonStages` to determine if the stage is present in both arrays.\n * If a stage with the same `id` is found in both arrays but the `name` property is different, the stage is considered updated.\n * If a stage with a particular `id` is only found in `comparisonStages`, it is considered created.\n * If a stage with a particular `id` is only found in `sourceStages`, it is considered deleted.\n *\n * @typedef {{id: Number, name: String, workflow: Number}} Stage\n * @typedef {{created: Stage[], updated: Stage[], deleted: Stage[]}} DiffStages\n *\n * The DiffStages object has three properties: `created`, `updated`, and `deleted`.\n * `created` is an array of stages that are in `comparisonStages` but not in `sourceStages`.\n * `updated` is an array of stages that have different names in `comparisonStages` and `sourceStages`.\n * `deleted` is an array of stages that are in `sourceStages` but not in `comparisonStages`.\n *\n * @param {Stage[]} sourceStages\n * @param {Stage[]} comparisonStages\n * @returns { DiffStages }\n */\nfunction getDiffBetweenStages(sourceStages: any, comparisonStages: any) {\n  const result = comparisonStages.reduce(\n    // ...\n\n    (acc: any, stageToCompare: any) => {\n      const srcStage = sourceStages.find((stage: any) => stage.id === stageToCompare.id);\n\n      if (!srcStage) {\n        acc.created.push(stageToCompare);\n      } else if (!isEqual(normalizeStageForDiff(srcStage), normalizeStageForDiff(stageToCompare))) {\n        acc.updated.push(stageToCompare);\n      }\n      return acc;\n    },\n    { created: [], updated: [] }\n  );\n\n  result.deleted = sourceStages.filter(\n    (srcStage: any) => !comparisonStages.some((cmpStage: any) => cmpStage.id === srcStage.id)\n  );\n\n  return result;\n}\n\n/**\n * Asserts that at least one stage remains in the workflow after applying deletions and additions.\n *\n * @param {Array} workflowStages - An array of stages in the current workflow.\n * @param {Object} diffStages - An object containing the stages to be deleted and created.\n * @param {Array} diffStages.deleted - An array of stages that are planned to be deleted from the workflow.\n * @param {Array} diffStages.created - An array of stages that are planned to be created in the workflow.\n *\n * @throws {ValidationError} If the number of remaining stages in the workflow after applying deletions and additions is less than 1.\n */\nfunction assertAtLeastOneStageRemain(workflowStages: any, diffStages: any) {\n  const remainingStagesCount =\n    workflowStages.length - diffStages.deleted.length + diffStages.created.length;\n  if (remainingStagesCount < 1) {\n    throw new ValidationError(ERRORS.WORKFLOW_WITHOUT_STAGES);\n  }\n}\n\n/**\n * Find the id of the nearest object in an array that matches a condition.\n * Used for searching for the nearest stage that is not deleted.\n * Starts by searching the elements before the index, then the remaining elements in the array.\n *\n * @param {Array} stages\n * @param {Number} startIndex the index to start searching from\n * @param {Function} condition must evaluate to true for the object to be considered a match\n * @returns {Object} stage\n */\nfunction findNearestMatchingStage(stages: any, startIndex: any, condition: any) {\n  // Start by searching the elements before the startIndex\n  for (let i = startIndex; i >= 0; i -= 1) {\n    if (condition(stages[i])) {\n      return stages[i];\n    }\n  }\n\n  // If no matching element is found before the startIndex,\n  // search the remaining elements in the array\n  const remainingArray = stages.slice(startIndex + 1);\n  const nearestObject = remainingArray.filter(condition)[0];\n  return nearestObject;\n}\n"],"names":["ApplicationError","ValidationError","errors","sanitizedStageFields","sanitizeStageFields","pick","strapi","metrics","getService","stagePermissionsService","workflowValidator","find","workflowId","populate","db","query","STAGE_MODEL_UID","findMany","where","workflow","findById","id","findOne","createMany","stagesList","fields","params","select","stages","Promise","all","map","stage","create","data","async","reduce","_","idx","stageId","allPermissionIds","fromPermissions","length","permission","register","roleId","role","action","fromStage","push","flat","p","toPermissions","registerTo","toStage","update","permissions","sendDidCreateStage","srcStage","destStage","hasPermissionChanges","deleteStagePermissions","extractRoleId","fromPerms","filter","actionParameters","from","registered","toPerms","to","Boolean","sendDidEditStage","delete","deletedStage","sendDidDeleteStage","deleteMany","$in","s","unregister","count","opts","replaceStages","srcStages","destStages","contentTypesToMigrate","created","updated","deleted","getDiffBetweenStages","assertAtLeastOneStageRemain","transaction","trx","createdStages","createdStagesIds","nearestStage","findNearestMatchingStage","findIndex","targetStage","contentTypeUID","updateEntitiesStage","fromStageId","toStageId","shift","updateEntity","entityToUpdate","model","documentId","locale","validateWorkflowCount","entity","documents","ENTITY_STAGE_ATTRIBUTE","tableName","metadata","get","connection","updated_at","Date","updatedAt","sendDidChangeEntryStage","attributes","joinTable","joinColumn","name","invJoinColumn","inverseJoinColumn","undefined","getConnection","transacting","selectStatement","leftJoin","toSQL","insert","raw","sql","bindings","deleteAllEntitiesStage","normalizeStageForDiff","sourceStages","comparisonStages","result","acc","stageToCompare","isEqual","some","cmpStage","workflowStages","diffStages","remainingStagesCount","ERRORS","WORKFLOW_WITHOUT_STAGES","startIndex","condition","i","remainingArray","slice","nearestObject"],"mappings":"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"}