{"version":3,"file":"release.mjs","sources":["../../../server/src/services/release.ts"],"sourcesContent":["import { setCreatorFields, errors } from '@strapi/utils';\n\nimport type { Core, Struct, UID, Data } from '@strapi/types';\n\nimport { ALLOWED_WEBHOOK_EVENTS, 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} from '../../../shared/contracts/releases';\nimport type { ReleaseAction } from '../../../shared/contracts/release-actions';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService, getPublishOrderForContentTypes } from '../utils';\n\nconst createReleaseService = ({ strapi }: { strapi: Core.Strapi }) => {\n  const dispatchWebhook = (\n    event: string,\n    { isPublished, release, error }: { isPublished: boolean; release?: any; error?: unknown }\n  ) => {\n    strapi.eventHub.emit(event, {\n      isPublished,\n      error,\n      release,\n    });\n  };\n\n  /**\n   * Given a release id, it returns the actions formatted ready to be used to publish them.\n   * We split them by contentType and type (publish/unpublish) and extract only the documentIds and locales.\n   */\n  const getFormattedActions = async (releaseId: Release['id']) => {\n    const actions = (await strapi.db.query(RELEASE_ACTION_MODEL_UID).findMany({\n      where: {\n        release: {\n          id: releaseId,\n        },\n      },\n    })) as ReleaseAction[];\n\n    if (actions.length === 0) {\n      throw new errors.ValidationError('No entries to publish');\n    }\n\n    /**\n     * We separate publish and unpublish actions, grouping them by contentType and extracting only their documentIds and locales.\n     */\n    const formattedActions: {\n      [key: UID.ContentType]: {\n        publish: { documentId: ReleaseAction['entryDocumentId']; locale?: string }[];\n        unpublish: { documentId: ReleaseAction['entryDocumentId']; locale?: string }[];\n      };\n    } = {};\n\n    for (const action of actions) {\n      const contentTypeUid: UID.ContentType = action.contentType;\n\n      if (!formattedActions[contentTypeUid]) {\n        formattedActions[contentTypeUid] = {\n          publish: [],\n          unpublish: [],\n        };\n      }\n\n      formattedActions[contentTypeUid][action.type].push({\n        documentId: action.entryDocumentId,\n        locale: action.locale,\n      });\n    }\n\n    return formattedActions;\n  };\n\n  return {\n    async create(releaseData: CreateRelease.Request['body'], { user }: { user: UserInfo }) {\n      const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);\n\n      const {\n        validatePendingReleasesLimit,\n        validateUniqueNameForPendingRelease,\n        validateScheduledAtIsLaterThanNow,\n      } = getService('release-validation', { strapi });\n\n      await Promise.all([\n        validatePendingReleasesLimit(),\n        validateUniqueNameForPendingRelease(releaseWithCreatorFields.name),\n        validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt),\n      ]);\n\n      const release = await strapi.db.query(RELEASE_MODEL_UID).create({\n        data: {\n          ...releaseWithCreatorFields,\n          status: 'empty',\n        },\n      });\n\n      if (releaseWithCreatorFields.scheduledAt) {\n        const schedulingService = getService('scheduling', { strapi });\n\n        await schedulingService.set(release.id, release.scheduledAt);\n      }\n\n      strapi.telemetry.send('didCreateContentRelease');\n\n      return release;\n    },\n\n    async findOne(id: GetRelease.Request['params']['id'], query = {}) {\n      const dbQuery = strapi.get('query-params').transform(RELEASE_MODEL_UID, query);\n      const release = await strapi.db.query(RELEASE_MODEL_UID).findOne({\n        ...dbQuery,\n        where: { id },\n      });\n\n      return release;\n    },\n\n    findPage(query?: GetReleases.Request['query']) {\n      const dbQuery = strapi.get('query-params').transform(RELEASE_MODEL_UID, query ?? {});\n\n      return strapi.db.query(RELEASE_MODEL_UID).findPage({\n        ...dbQuery,\n        populate: {\n          actions: {\n            count: true,\n          },\n        },\n      });\n    },\n\n    findMany(query?: any) {\n      const dbQuery = strapi.get('query-params').transform(RELEASE_MODEL_UID, query ?? {});\n\n      return strapi.db.query(RELEASE_MODEL_UID).findMany({\n        ...dbQuery,\n      });\n    },\n\n    async update(\n      id: Data.ID,\n      releaseData: UpdateRelease.Request['body'],\n      { user }: { user: UserInfo }\n    ) {\n      const releaseWithCreatorFields = await setCreatorFields({ user, isEdition: true })(\n        releaseData\n      );\n\n      const { validateUniqueNameForPendingRelease, validateScheduledAtIsLaterThanNow } = getService(\n        'release-validation',\n        { strapi }\n      );\n\n      await Promise.all([\n        validateUniqueNameForPendingRelease(releaseWithCreatorFields.name, id),\n        validateScheduledAtIsLaterThanNow(releaseWithCreatorFields.scheduledAt),\n      ]);\n\n      const release = await strapi.db.query(RELEASE_MODEL_UID).findOne({ where: { 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.db.query(RELEASE_MODEL_UID).update({\n        where: { id },\n        data: releaseWithCreatorFields,\n      });\n\n      const schedulingService = getService('scheduling', { strapi });\n\n      if (releaseData.scheduledAt) {\n        // set function always cancel the previous job if it exists, so we can call it directly\n        await schedulingService.set(id, releaseData.scheduledAt);\n      } else if (release.scheduledAt) {\n        // When user don't send a scheduledAt and we have one on the release, means that user want to unschedule it\n        schedulingService.cancel(id);\n      }\n\n      this.updateReleaseStatus(id);\n\n      strapi.telemetry.send('didUpdateContentRelease');\n\n      return updatedRelease;\n    },\n\n    async getAllComponents() {\n      const contentManagerComponentsService = strapi\n        .plugin('content-manager')\n        .service('components');\n\n      const components = await contentManagerComponentsService.findAllComponents();\n\n      const componentsMap = components.reduce(\n        (\n          acc: { [key: Struct.ComponentSchema['uid']]: Struct.ComponentSchema },\n          component: Struct.ComponentSchema\n        ) => {\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: Release = await strapi.db.query(RELEASE_MODEL_UID).findOne({\n        where: { id: releaseId },\n        populate: {\n          actions: {\n            select: ['id'],\n          },\n        },\n      });\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\n        await strapi.db.query(RELEASE_MODEL_UID).delete({\n          where: {\n            id: releaseId,\n          },\n        });\n      });\n\n      if (release.scheduledAt) {\n        const schedulingService = getService('scheduling', { strapi });\n        await schedulingService.cancel(release.id);\n      }\n\n      strapi.telemetry.send('didDeleteContentRelease');\n\n      return release;\n    },\n\n    async publish(releaseId: PublishRelease.Request['params']['id']) {\n      const {\n        release,\n        error,\n      }: { release: Pick<Release, 'id' | 'releasedAt' | 'status'> | null; error: unknown | null } =\n        await strapi.db.transaction(async ({ trx }) => {\n          /**\n           * We lock the release in this transaction, so any other process trying to publish it will wait until this transaction is finished\n           * In this transaction we don't care about rollback, becasue we want to persist the lock until the end and if it fails we want to change the release status to failed\n           */\n          const lockedRelease = (await strapi.db\n            ?.queryBuilder(RELEASE_MODEL_UID)\n            .where({ id: releaseId })\n            .select(['id', 'name', 'releasedAt', 'status'])\n            .first()\n            .transacting(trx)\n            .forUpdate()\n            .execute()) as Pick<Release, 'id' | 'name' | 'releasedAt' | 'status'> | undefined;\n\n          if (!lockedRelease) {\n            throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n          }\n\n          if (lockedRelease.releasedAt) {\n            throw new errors.ValidationError('Release already published');\n          }\n\n          if (lockedRelease.status === 'failed') {\n            throw new errors.ValidationError('Release failed to publish');\n          }\n\n          try {\n            strapi.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);\n\n            const formattedActions = await getFormattedActions(releaseId);\n\n            // Publish content types in dependency order so that when entity A has a relation\n            // to entity B, B is published first to keep this relation.\n            const contentTypeUids = getPublishOrderForContentTypes(\n              Object.keys(formattedActions) as UID.ContentType[],\n              { strapi }\n            );\n\n            await strapi.db.transaction(async () => {\n              for (const contentTypeUid of contentTypeUids) {\n                const contentType = contentTypeUid as UID.ContentType;\n                const { publish, unpublish } = formattedActions[contentType];\n\n                await Promise.all([\n                  ...publish.map((params) => strapi.documents(contentType).publish(params)),\n                  ...unpublish.map((params) => strapi.documents(contentType).unpublish(params)),\n                ]);\n              }\n            });\n\n            const release = await strapi.db.query(RELEASE_MODEL_UID).update({\n              where: {\n                id: releaseId,\n              },\n              data: {\n                status: 'done',\n                releasedAt: new Date(),\n              },\n            });\n\n            dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {\n              isPublished: true,\n              release,\n            });\n\n            strapi.telemetry.send('didPublishContentRelease');\n\n            return { release, error: null };\n          } catch (error) {\n            dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {\n              isPublished: false,\n              error,\n            });\n\n            // We need to run the update in the same transaction because the release is locked\n            await strapi.db\n              ?.queryBuilder(RELEASE_MODEL_UID)\n              .where({ id: releaseId })\n              .update({\n                status: 'failed',\n              })\n              .transacting(trx)\n              .execute();\n\n            // At this point, we don't want to throw the error because if that happen we rollback the change in the release status\n            // We want to throw the error after the transaction is finished, so we return the error\n            return {\n              release: null,\n              error,\n            };\n          }\n        });\n\n      // Now the first transaction is commited, we can safely throw the error if it exists\n      if (error instanceof Error) {\n        throw error;\n      }\n\n      return release;\n    },\n\n    async updateReleaseStatus(releaseId: Release['id']) {\n      const releaseActionService = getService('release-action', { strapi });\n\n      const [totalActions, invalidActions] = await Promise.all([\n        releaseActionService.countActions({\n          filters: {\n            release: releaseId,\n          },\n        }),\n        releaseActionService.countActions({\n          filters: {\n            release: releaseId,\n            isEntryValid: false,\n          },\n        }),\n      ]);\n\n      if (totalActions > 0) {\n        if (invalidActions > 0) {\n          return strapi.db.query(RELEASE_MODEL_UID).update({\n            where: {\n              id: releaseId,\n            },\n            data: {\n              status: 'blocked',\n            },\n          });\n        }\n\n        return strapi.db.query(RELEASE_MODEL_UID).update({\n          where: {\n            id: releaseId,\n          },\n          data: {\n            status: 'ready',\n          },\n        });\n      }\n\n      return strapi.db.query(RELEASE_MODEL_UID).update({\n        where: {\n          id: releaseId,\n        },\n        data: {\n          status: 'empty',\n        },\n      });\n    },\n  };\n};\n\nexport type ReleaseService = ReturnType<typeof createReleaseService>;\n\nexport default createReleaseService;\n"],"names":["createReleaseService","strapi","dispatchWebhook","event","isPublished","release","error","eventHub","emit","getFormattedActions","releaseId","actions","db","query","RELEASE_ACTION_MODEL_UID","findMany","where","id","length","errors","ValidationError","formattedActions","action","contentTypeUid","contentType","publish","unpublish","type","push","documentId","entryDocumentId","locale","create","releaseData","user","releaseWithCreatorFields","setCreatorFields","validatePendingReleasesLimit","validateUniqueNameForPendingRelease","validateScheduledAtIsLaterThanNow","getService","Promise","all","name","scheduledAt","RELEASE_MODEL_UID","data","status","schedulingService","set","telemetry","send","findOne","dbQuery","get","transform","findPage","populate","count","update","isEdition","NotFoundError","releasedAt","updatedRelease","cancel","updateReleaseStatus","getAllComponents","contentManagerComponentsService","plugin","service","components","findAllComponents","componentsMap","reduce","acc","component","uid","delete","select","transaction","deleteMany","$in","map","trx","lockedRelease","queryBuilder","first","transacting","forUpdate","execute","log","info","contentTypeUids","getPublishOrderForContentTypes","Object","keys","params","documents","Date","ALLOWED_WEBHOOK_EVENTS","RELEASES_PUBLISH","Error","releaseActionService","totalActions","invalidActions","countActions","filters","isEntryValid"],"mappings":"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"}