@strapi/content-releases 5.46.0 → 5.46.1

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.
@@ -10,9 +10,14 @@ const createHomepageService = ({ strapi })=>{
10
10
  $notNull: false
11
11
  }
12
12
  },
13
+ // `scheduledAt` is often null; tie-break by `id` so order is stable across DBs/engines.
14
+ // (E2E and the admin widget assume a predictable first row in that case — see with-admin seed.)
13
15
  orderBy: [
14
16
  {
15
17
  scheduledAt: 'asc'
18
+ },
19
+ {
20
+ id: 'asc'
16
21
  }
17
22
  ],
18
23
  limit: MAX_DOCUMENTS
@@ -1 +1 @@
1
- {"version":3,"file":"homepage.js","sources":["../../../server/src/services/homepage.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { GetUpcomingReleases } from '../../../shared/contracts/homepage';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n return {\n async getUpcomingReleases(): Promise<GetUpcomingReleases.Response['data']> {\n const releases = await strapi.db.query('plugin::content-releases.release').findMany({\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n orderBy: [{ scheduledAt: 'asc' }],\n limit: MAX_DOCUMENTS,\n });\n\n return releases;\n },\n };\n};\n\nexport default createHomepageService;\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","getUpcomingReleases","releases","db","query","findMany","filters","releasedAt","$notNull","orderBy","scheduledAt","limit"],"mappings":";;AAIA,MAAMA,qBAAAA,GAAwB,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAChE,IAAA,MAAMC,aAAAA,GAAgB,CAAA;IAEtB,OAAO;QACL,MAAMC,mBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAMH,MAAAA,CAAOI,EAAE,CAACC,KAAK,CAAC,kCAAA,CAAA,CAAoCC,QAAQ,CAAC;gBAClFC,OAAAA,EAAS;oBACPC,UAAAA,EAAY;wBACVC,QAAAA,EAAU;AACZ;AACF,iBAAA;gBACAC,OAAAA,EAAS;AAAC,oBAAA;wBAAEC,WAAAA,EAAa;AAAM;AAAE,iBAAA;gBACjCC,KAAAA,EAAOX;AACT,aAAA,CAAA;YAEA,OAAOE,QAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"homepage.js","sources":["../../../server/src/services/homepage.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { GetUpcomingReleases } from '../../../shared/contracts/homepage';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n return {\n async getUpcomingReleases(): Promise<GetUpcomingReleases.Response['data']> {\n const releases = await strapi.db.query('plugin::content-releases.release').findMany({\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n // `scheduledAt` is often null; tie-break by `id` so order is stable across DBs/engines.\n // (E2E and the admin widget assume a predictable first row in that case — see with-admin seed.)\n orderBy: [{ scheduledAt: 'asc' }, { id: 'asc' }],\n limit: MAX_DOCUMENTS,\n });\n\n return releases;\n },\n };\n};\n\nexport default createHomepageService;\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","getUpcomingReleases","releases","db","query","findMany","filters","releasedAt","$notNull","orderBy","scheduledAt","id","limit"],"mappings":";;AAIA,MAAMA,qBAAAA,GAAwB,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAChE,IAAA,MAAMC,aAAAA,GAAgB,CAAA;IAEtB,OAAO;QACL,MAAMC,mBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAMH,MAAAA,CAAOI,EAAE,CAACC,KAAK,CAAC,kCAAA,CAAA,CAAoCC,QAAQ,CAAC;gBAClFC,OAAAA,EAAS;oBACPC,UAAAA,EAAY;wBACVC,QAAAA,EAAU;AACZ;AACF,iBAAA;;;gBAGAC,OAAAA,EAAS;AAAC,oBAAA;wBAAEC,WAAAA,EAAa;AAAM,qBAAA;AAAG,oBAAA;wBAAEC,EAAAA,EAAI;AAAM;AAAE,iBAAA;gBAChDC,KAAAA,EAAOZ;AACT,aAAA,CAAA;YAEA,OAAOE,QAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
@@ -8,9 +8,14 @@ const createHomepageService = ({ strapi })=>{
8
8
  $notNull: false
9
9
  }
10
10
  },
11
+ // `scheduledAt` is often null; tie-break by `id` so order is stable across DBs/engines.
12
+ // (E2E and the admin widget assume a predictable first row in that case — see with-admin seed.)
11
13
  orderBy: [
12
14
  {
13
15
  scheduledAt: 'asc'
16
+ },
17
+ {
18
+ id: 'asc'
14
19
  }
15
20
  ],
16
21
  limit: MAX_DOCUMENTS
@@ -1 +1 @@
1
- {"version":3,"file":"homepage.mjs","sources":["../../../server/src/services/homepage.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { GetUpcomingReleases } from '../../../shared/contracts/homepage';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n return {\n async getUpcomingReleases(): Promise<GetUpcomingReleases.Response['data']> {\n const releases = await strapi.db.query('plugin::content-releases.release').findMany({\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n orderBy: [{ scheduledAt: 'asc' }],\n limit: MAX_DOCUMENTS,\n });\n\n return releases;\n },\n };\n};\n\nexport default createHomepageService;\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","getUpcomingReleases","releases","db","query","findMany","filters","releasedAt","$notNull","orderBy","scheduledAt","limit"],"mappings":"AAIA,MAAMA,qBAAAA,GAAwB,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAChE,IAAA,MAAMC,aAAAA,GAAgB,CAAA;IAEtB,OAAO;QACL,MAAMC,mBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAMH,MAAAA,CAAOI,EAAE,CAACC,KAAK,CAAC,kCAAA,CAAA,CAAoCC,QAAQ,CAAC;gBAClFC,OAAAA,EAAS;oBACPC,UAAAA,EAAY;wBACVC,QAAAA,EAAU;AACZ;AACF,iBAAA;gBACAC,OAAAA,EAAS;AAAC,oBAAA;wBAAEC,WAAAA,EAAa;AAAM;AAAE,iBAAA;gBACjCC,KAAAA,EAAOX;AACT,aAAA,CAAA;YAEA,OAAOE,QAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"homepage.mjs","sources":["../../../server/src/services/homepage.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport type { GetUpcomingReleases } from '../../../shared/contracts/homepage';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n return {\n async getUpcomingReleases(): Promise<GetUpcomingReleases.Response['data']> {\n const releases = await strapi.db.query('plugin::content-releases.release').findMany({\n filters: {\n releasedAt: {\n $notNull: false,\n },\n },\n // `scheduledAt` is often null; tie-break by `id` so order is stable across DBs/engines.\n // (E2E and the admin widget assume a predictable first row in that case — see with-admin seed.)\n orderBy: [{ scheduledAt: 'asc' }, { id: 'asc' }],\n limit: MAX_DOCUMENTS,\n });\n\n return releases;\n },\n };\n};\n\nexport default createHomepageService;\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","getUpcomingReleases","releases","db","query","findMany","filters","releasedAt","$notNull","orderBy","scheduledAt","id","limit"],"mappings":"AAIA,MAAMA,qBAAAA,GAAwB,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAChE,IAAA,MAAMC,aAAAA,GAAgB,CAAA;IAEtB,OAAO;QACL,MAAMC,mBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAMH,MAAAA,CAAOI,EAAE,CAACC,KAAK,CAAC,kCAAA,CAAA,CAAoCC,QAAQ,CAAC;gBAClFC,OAAAA,EAAS;oBACPC,UAAAA,EAAY;wBACVC,QAAAA,EAAU;AACZ;AACF,iBAAA;;;gBAGAC,OAAAA,EAAS;AAAC,oBAAA;wBAAEC,WAAAA,EAAa;AAAM,qBAAA;AAAG,oBAAA;wBAAEC,EAAAA,EAAI;AAAM;AAAE,iBAAA;gBAChDC,KAAAA,EAAOZ;AACT,aAAA,CAAA;YAEA,OAAOE,QAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
@@ -229,10 +229,16 @@ const createReleaseService = ({ strapi })=>{
229
229
  for (const contentTypeUid of contentTypeUids){
230
230
  const contentType = contentTypeUid;
231
231
  const { publish, unpublish } = formattedActions[contentType];
232
- await Promise.all([
233
- ...publish.map((params)=>strapi.documents(contentType).publish(params)),
234
- ...unpublish.map((params)=>strapi.documents(contentType).unpublish(params))
235
- ]);
232
+ // Serialize within a content type: concurrent publishes of related documents
233
+ // can race on shared join-table state (notably self-referential relations) and
234
+ // leave inconsistent FK rows when one branch deletes a row another branch is
235
+ // about to reference.
236
+ for (const params of publish){
237
+ await strapi.documents(contentType).publish(params);
238
+ }
239
+ for (const params of unpublish){
240
+ await strapi.documents(contentType).unpublish(params);
241
+ }
236
242
  }
237
243
  });
238
244
  const release = await strapi.db.query(constants.RELEASE_MODEL_UID).update({
@@ -1 +1 @@
1
- {"version":3,"file":"release.js","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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"}
1
+ {"version":3,"file":"release.js","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 // Serialize within a content type: concurrent publishes of related documents\n // can race on shared join-table state (notably self-referential relations) and\n // leave inconsistent FK rows when one branch deletes a row another branch is\n // about to reference.\n for (const params of publish) {\n await strapi.documents(contentType).publish(params);\n }\n\n for (const params of unpublish) {\n await 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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"}
@@ -227,10 +227,16 @@ const createReleaseService = ({ strapi })=>{
227
227
  for (const contentTypeUid of contentTypeUids){
228
228
  const contentType = contentTypeUid;
229
229
  const { publish, unpublish } = formattedActions[contentType];
230
- await Promise.all([
231
- ...publish.map((params)=>strapi.documents(contentType).publish(params)),
232
- ...unpublish.map((params)=>strapi.documents(contentType).unpublish(params))
233
- ]);
230
+ // Serialize within a content type: concurrent publishes of related documents
231
+ // can race on shared join-table state (notably self-referential relations) and
232
+ // leave inconsistent FK rows when one branch deletes a row another branch is
233
+ // about to reference.
234
+ for (const params of publish){
235
+ await strapi.documents(contentType).publish(params);
236
+ }
237
+ for (const params of unpublish){
238
+ await strapi.documents(contentType).unpublish(params);
239
+ }
234
240
  }
235
241
  });
236
242
  const release = await strapi.db.query(RELEASE_MODEL_UID).update({
@@ -1 +1 @@
1
- {"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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"}
1
+ {"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 // Serialize within a content type: concurrent publishes of related documents\n // can race on shared join-table state (notably self-referential relations) and\n // leave inconsistent FK rows when one branch deletes a row another branch is\n // about to reference.\n for (const params of publish) {\n await strapi.documents(contentType).publish(params);\n }\n\n for (const params of unpublish) {\n await 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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"}
@@ -21,14 +21,9 @@ const createSchedulingService = ({ strapi })=>{
21
21
  strapi.cron.add({
22
22
  [taskName]: {
23
23
  async task () {
24
- try {
25
- await index.getService('release', {
26
- strapi
27
- }).publish(releaseId);
28
- // @TODO: Trigger webhook with success message
29
- } catch (error) {
30
- // @TODO: Trigger webhook with error message
31
- }
24
+ await index.getService('release', {
25
+ strapi
26
+ }).publish(releaseId);
32
27
  },
33
28
  options: scheduleDate
34
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scheduling.js","sources":["../../../server/src/services/scheduling.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: Core.Strapi }) => {\n const scheduledJobs = new Map<Release['id'], string>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const taskName = `publishRelease_${releaseId}`;\n\n strapi.cron.add({\n [taskName]: {\n async task() {\n try {\n await getService('release', { strapi }).publish(releaseId);\n // @TODO: Trigger webhook with success message\n } catch (error) {\n // @TODO: Trigger webhook with error message\n }\n },\n options: scheduleDate,\n },\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, taskName);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n strapi.cron.remove(scheduledJobs.get(releaseId)!);\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n\n getAll() {\n return scheduledJobs;\n },\n\n /**\n * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released\n * This is useful in case the server was restarted and the scheduled jobs were lost\n * This also could be used to sync different Strapi instances in case of a cluster\n */\n async syncFromDatabase() {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n scheduledAt: {\n $gte: new Date(),\n },\n releasedAt: null,\n },\n });\n\n for (const release of releases) {\n this.set(release.id, release.scheduledAt);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n"],"names":["createSchedulingService","strapi","scheduledJobs","Map","set","releaseId","scheduleDate","release","db","query","RELEASE_MODEL_UID","findOne","where","id","releasedAt","errors","NotFoundError","taskName","cron","add","task","getService","publish","error","options","has","cancel","remove","get","delete","getAll","syncFromDatabase","releases","findMany","scheduledAt","$gte","Date"],"mappings":";;;;;;AAOA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAClE,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;IAE1B,OAAO;QACL,MAAMC,GAAAA,CAAAA,CAAIC,SAAwB,EAAEC,YAAkB,EAAA;YACpD,MAAMC,OAAAA,GAAU,MAAMN,MAAAA,CAAOO,EAAE,CAC5BC,KAAK,CAACC,2BAAAA,CAAAA,CACNC,OAAO,CAAC;gBAAEC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA;oBAAWS,UAAAA,EAAY;AAAK;AAAE,aAAA,CAAA;AAExD,YAAA,IAAI,CAACP,OAAAA,EAAS;AACZ,gBAAA,MAAM,IAAIQ,YAAAA,CAAOC,aAAa,CAAC,CAAC,wBAAwB,EAAEX,SAAAA,CAAAA,CAAW,CAAA;AACvE,YAAA;AAEA,YAAA,MAAMY,QAAAA,GAAW,CAAC,eAAe,EAAEZ,SAAAA,CAAAA,CAAW;YAE9CJ,MAAAA,CAAOiB,IAAI,CAACC,GAAG,CAAC;AACd,gBAAA,CAACF,WAAW;oBACV,MAAMG,IAAAA,CAAAA,GAAAA;wBACJ,IAAI;AACF,4BAAA,MAAMC,iBAAW,SAAA,EAAW;AAAEpB,gCAAAA;AAAO,6BAAA,CAAA,CAAGqB,OAAO,CAACjB,SAAAA,CAAAA;;AAElD,wBAAA,CAAA,CAAE,OAAOkB,KAAAA,EAAO;;AAEhB,wBAAA;AACF,oBAAA,CAAA;oBACAC,OAAAA,EAASlB;AACX;AACF,aAAA,CAAA;YAEA,IAAIJ,aAAAA,CAAcuB,GAAG,CAACpB,SAAAA,CAAAA,EAAY;gBAChC,IAAI,CAACqB,MAAM,CAACrB,SAAAA,CAAAA;AACd,YAAA;YAEAH,aAAAA,CAAcE,GAAG,CAACC,SAAAA,EAAWY,QAAAA,CAAAA;YAE7B,OAAOf,aAAAA;AACT,QAAA,CAAA;AAEAwB,QAAAA,MAAAA,CAAAA,CAAOrB,SAAwB,EAAA;YAC7B,IAAIH,aAAAA,CAAcuB,GAAG,CAACpB,SAAAA,CAAAA,EAAY;AAChCJ,gBAAAA,MAAAA,CAAOiB,IAAI,CAACS,MAAM,CAACzB,aAAAA,CAAc0B,GAAG,CAACvB,SAAAA,CAAAA,CAAAA;AACrCH,gBAAAA,aAAAA,CAAc2B,MAAM,CAACxB,SAAAA,CAAAA;AACvB,YAAA;YAEA,OAAOH,aAAAA;AACT,QAAA,CAAA;AAEA4B,QAAAA,MAAAA,CAAAA,GAAAA;YACE,OAAO5B,aAAAA;AACT,QAAA,CAAA;AAEA;;;;AAIC,QACD,MAAM6B,gBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAM/B,MAAAA,CAAOO,EAAE,CAACC,KAAK,CAACC,2BAAAA,CAAAA,CAAmBuB,QAAQ,CAAC;gBACjErB,KAAAA,EAAO;oBACLsB,WAAAA,EAAa;AACXC,wBAAAA,IAAAA,EAAM,IAAIC,IAAAA;AACZ,qBAAA;oBACAtB,UAAAA,EAAY;AACd;AACF,aAAA,CAAA;YAEA,KAAK,MAAMP,WAAWyB,QAAAA,CAAU;AAC9B,gBAAA,IAAI,CAAC5B,GAAG,CAACG,QAAQM,EAAE,EAAEN,QAAQ2B,WAAW,CAAA;AAC1C,YAAA;YAEA,OAAOhC,aAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"scheduling.js","sources":["../../../server/src/services/scheduling.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: Core.Strapi }) => {\n const scheduledJobs = new Map<Release['id'], string>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const taskName = `publishRelease_${releaseId}`;\n\n strapi.cron.add({\n [taskName]: {\n async task() {\n await getService('release', { strapi }).publish(releaseId);\n },\n options: scheduleDate,\n },\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, taskName);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n strapi.cron.remove(scheduledJobs.get(releaseId)!);\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n\n getAll() {\n return scheduledJobs;\n },\n\n /**\n * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released\n * This is useful in case the server was restarted and the scheduled jobs were lost\n * This also could be used to sync different Strapi instances in case of a cluster\n */\n async syncFromDatabase() {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n scheduledAt: {\n $gte: new Date(),\n },\n releasedAt: null,\n },\n });\n\n for (const release of releases) {\n this.set(release.id, release.scheduledAt);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n"],"names":["createSchedulingService","strapi","scheduledJobs","Map","set","releaseId","scheduleDate","release","db","query","RELEASE_MODEL_UID","findOne","where","id","releasedAt","errors","NotFoundError","taskName","cron","add","task","getService","publish","options","has","cancel","remove","get","delete","getAll","syncFromDatabase","releases","findMany","scheduledAt","$gte","Date"],"mappings":";;;;;;AAOA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAClE,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;IAE1B,OAAO;QACL,MAAMC,GAAAA,CAAAA,CAAIC,SAAwB,EAAEC,YAAkB,EAAA;YACpD,MAAMC,OAAAA,GAAU,MAAMN,MAAAA,CAAOO,EAAE,CAC5BC,KAAK,CAACC,2BAAAA,CAAAA,CACNC,OAAO,CAAC;gBAAEC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA;oBAAWS,UAAAA,EAAY;AAAK;AAAE,aAAA,CAAA;AAExD,YAAA,IAAI,CAACP,OAAAA,EAAS;AACZ,gBAAA,MAAM,IAAIQ,YAAAA,CAAOC,aAAa,CAAC,CAAC,wBAAwB,EAAEX,SAAAA,CAAAA,CAAW,CAAA;AACvE,YAAA;AAEA,YAAA,MAAMY,QAAAA,GAAW,CAAC,eAAe,EAAEZ,SAAAA,CAAAA,CAAW;YAE9CJ,MAAAA,CAAOiB,IAAI,CAACC,GAAG,CAAC;AACd,gBAAA,CAACF,WAAW;oBACV,MAAMG,IAAAA,CAAAA,GAAAA;AACJ,wBAAA,MAAMC,iBAAW,SAAA,EAAW;AAAEpB,4BAAAA;AAAO,yBAAA,CAAA,CAAGqB,OAAO,CAACjB,SAAAA,CAAAA;AAClD,oBAAA,CAAA;oBACAkB,OAAAA,EAASjB;AACX;AACF,aAAA,CAAA;YAEA,IAAIJ,aAAAA,CAAcsB,GAAG,CAACnB,SAAAA,CAAAA,EAAY;gBAChC,IAAI,CAACoB,MAAM,CAACpB,SAAAA,CAAAA;AACd,YAAA;YAEAH,aAAAA,CAAcE,GAAG,CAACC,SAAAA,EAAWY,QAAAA,CAAAA;YAE7B,OAAOf,aAAAA;AACT,QAAA,CAAA;AAEAuB,QAAAA,MAAAA,CAAAA,CAAOpB,SAAwB,EAAA;YAC7B,IAAIH,aAAAA,CAAcsB,GAAG,CAACnB,SAAAA,CAAAA,EAAY;AAChCJ,gBAAAA,MAAAA,CAAOiB,IAAI,CAACQ,MAAM,CAACxB,aAAAA,CAAcyB,GAAG,CAACtB,SAAAA,CAAAA,CAAAA;AACrCH,gBAAAA,aAAAA,CAAc0B,MAAM,CAACvB,SAAAA,CAAAA;AACvB,YAAA;YAEA,OAAOH,aAAAA;AACT,QAAA,CAAA;AAEA2B,QAAAA,MAAAA,CAAAA,GAAAA;YACE,OAAO3B,aAAAA;AACT,QAAA,CAAA;AAEA;;;;AAIC,QACD,MAAM4B,gBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAM9B,MAAAA,CAAOO,EAAE,CAACC,KAAK,CAACC,2BAAAA,CAAAA,CAAmBsB,QAAQ,CAAC;gBACjEpB,KAAAA,EAAO;oBACLqB,WAAAA,EAAa;AACXC,wBAAAA,IAAAA,EAAM,IAAIC,IAAAA;AACZ,qBAAA;oBACArB,UAAAA,EAAY;AACd;AACF,aAAA,CAAA;YAEA,KAAK,MAAMP,WAAWwB,QAAAA,CAAU;AAC9B,gBAAA,IAAI,CAAC3B,GAAG,CAACG,QAAQM,EAAE,EAAEN,QAAQ0B,WAAW,CAAA;AAC1C,YAAA;YAEA,OAAO/B,aAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
@@ -19,14 +19,9 @@ const createSchedulingService = ({ strapi })=>{
19
19
  strapi.cron.add({
20
20
  [taskName]: {
21
21
  async task () {
22
- try {
23
- await getService('release', {
24
- strapi
25
- }).publish(releaseId);
26
- // @TODO: Trigger webhook with success message
27
- } catch (error) {
28
- // @TODO: Trigger webhook with error message
29
- }
22
+ await getService('release', {
23
+ strapi
24
+ }).publish(releaseId);
30
25
  },
31
26
  options: scheduleDate
32
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scheduling.mjs","sources":["../../../server/src/services/scheduling.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: Core.Strapi }) => {\n const scheduledJobs = new Map<Release['id'], string>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const taskName = `publishRelease_${releaseId}`;\n\n strapi.cron.add({\n [taskName]: {\n async task() {\n try {\n await getService('release', { strapi }).publish(releaseId);\n // @TODO: Trigger webhook with success message\n } catch (error) {\n // @TODO: Trigger webhook with error message\n }\n },\n options: scheduleDate,\n },\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, taskName);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n strapi.cron.remove(scheduledJobs.get(releaseId)!);\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n\n getAll() {\n return scheduledJobs;\n },\n\n /**\n * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released\n * This is useful in case the server was restarted and the scheduled jobs were lost\n * This also could be used to sync different Strapi instances in case of a cluster\n */\n async syncFromDatabase() {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n scheduledAt: {\n $gte: new Date(),\n },\n releasedAt: null,\n },\n });\n\n for (const release of releases) {\n this.set(release.id, release.scheduledAt);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n"],"names":["createSchedulingService","strapi","scheduledJobs","Map","set","releaseId","scheduleDate","release","db","query","RELEASE_MODEL_UID","findOne","where","id","releasedAt","errors","NotFoundError","taskName","cron","add","task","getService","publish","error","options","has","cancel","remove","get","delete","getAll","syncFromDatabase","releases","findMany","scheduledAt","$gte","Date"],"mappings":";;;;AAOA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAClE,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;IAE1B,OAAO;QACL,MAAMC,GAAAA,CAAAA,CAAIC,SAAwB,EAAEC,YAAkB,EAAA;YACpD,MAAMC,OAAAA,GAAU,MAAMN,MAAAA,CAAOO,EAAE,CAC5BC,KAAK,CAACC,iBAAAA,CAAAA,CACNC,OAAO,CAAC;gBAAEC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA;oBAAWS,UAAAA,EAAY;AAAK;AAAE,aAAA,CAAA;AAExD,YAAA,IAAI,CAACP,OAAAA,EAAS;AACZ,gBAAA,MAAM,IAAIQ,MAAAA,CAAOC,aAAa,CAAC,CAAC,wBAAwB,EAAEX,SAAAA,CAAAA,CAAW,CAAA;AACvE,YAAA;AAEA,YAAA,MAAMY,QAAAA,GAAW,CAAC,eAAe,EAAEZ,SAAAA,CAAAA,CAAW;YAE9CJ,MAAAA,CAAOiB,IAAI,CAACC,GAAG,CAAC;AACd,gBAAA,CAACF,WAAW;oBACV,MAAMG,IAAAA,CAAAA,GAAAA;wBACJ,IAAI;AACF,4BAAA,MAAMC,WAAW,SAAA,EAAW;AAAEpB,gCAAAA;AAAO,6BAAA,CAAA,CAAGqB,OAAO,CAACjB,SAAAA,CAAAA;;AAElD,wBAAA,CAAA,CAAE,OAAOkB,KAAAA,EAAO;;AAEhB,wBAAA;AACF,oBAAA,CAAA;oBACAC,OAAAA,EAASlB;AACX;AACF,aAAA,CAAA;YAEA,IAAIJ,aAAAA,CAAcuB,GAAG,CAACpB,SAAAA,CAAAA,EAAY;gBAChC,IAAI,CAACqB,MAAM,CAACrB,SAAAA,CAAAA;AACd,YAAA;YAEAH,aAAAA,CAAcE,GAAG,CAACC,SAAAA,EAAWY,QAAAA,CAAAA;YAE7B,OAAOf,aAAAA;AACT,QAAA,CAAA;AAEAwB,QAAAA,MAAAA,CAAAA,CAAOrB,SAAwB,EAAA;YAC7B,IAAIH,aAAAA,CAAcuB,GAAG,CAACpB,SAAAA,CAAAA,EAAY;AAChCJ,gBAAAA,MAAAA,CAAOiB,IAAI,CAACS,MAAM,CAACzB,aAAAA,CAAc0B,GAAG,CAACvB,SAAAA,CAAAA,CAAAA;AACrCH,gBAAAA,aAAAA,CAAc2B,MAAM,CAACxB,SAAAA,CAAAA;AACvB,YAAA;YAEA,OAAOH,aAAAA;AACT,QAAA,CAAA;AAEA4B,QAAAA,MAAAA,CAAAA,GAAAA;YACE,OAAO5B,aAAAA;AACT,QAAA,CAAA;AAEA;;;;AAIC,QACD,MAAM6B,gBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAM/B,MAAAA,CAAOO,EAAE,CAACC,KAAK,CAACC,iBAAAA,CAAAA,CAAmBuB,QAAQ,CAAC;gBACjErB,KAAAA,EAAO;oBACLsB,WAAAA,EAAa;AACXC,wBAAAA,IAAAA,EAAM,IAAIC,IAAAA;AACZ,qBAAA;oBACAtB,UAAAA,EAAY;AACd;AACF,aAAA,CAAA;YAEA,KAAK,MAAMP,WAAWyB,QAAAA,CAAU;AAC9B,gBAAA,IAAI,CAAC5B,GAAG,CAACG,QAAQM,EAAE,EAAEN,QAAQ2B,WAAW,CAAA;AAC1C,YAAA;YAEA,OAAOhC,aAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
1
+ {"version":3,"file":"scheduling.mjs","sources":["../../../server/src/services/scheduling.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nimport { errors } from '@strapi/utils';\nimport { Release } from '../../../shared/contracts/releases';\nimport { getService } from '../utils';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createSchedulingService = ({ strapi }: { strapi: Core.Strapi }) => {\n const scheduledJobs = new Map<Release['id'], string>();\n\n return {\n async set(releaseId: Release['id'], scheduleDate: Date) {\n const release = await strapi.db\n .query(RELEASE_MODEL_UID)\n .findOne({ where: { id: releaseId, releasedAt: null } });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const taskName = `publishRelease_${releaseId}`;\n\n strapi.cron.add({\n [taskName]: {\n async task() {\n await getService('release', { strapi }).publish(releaseId);\n },\n options: scheduleDate,\n },\n });\n\n if (scheduledJobs.has(releaseId)) {\n this.cancel(releaseId);\n }\n\n scheduledJobs.set(releaseId, taskName);\n\n return scheduledJobs;\n },\n\n cancel(releaseId: Release['id']) {\n if (scheduledJobs.has(releaseId)) {\n strapi.cron.remove(scheduledJobs.get(releaseId)!);\n scheduledJobs.delete(releaseId);\n }\n\n return scheduledJobs;\n },\n\n getAll() {\n return scheduledJobs;\n },\n\n /**\n * On bootstrap, we can use this function to make sure to sync the scheduled jobs from the database that are not yet released\n * This is useful in case the server was restarted and the scheduled jobs were lost\n * This also could be used to sync different Strapi instances in case of a cluster\n */\n async syncFromDatabase() {\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n scheduledAt: {\n $gte: new Date(),\n },\n releasedAt: null,\n },\n });\n\n for (const release of releases) {\n this.set(release.id, release.scheduledAt);\n }\n\n return scheduledJobs;\n },\n };\n};\n\nexport default createSchedulingService;\n"],"names":["createSchedulingService","strapi","scheduledJobs","Map","set","releaseId","scheduleDate","release","db","query","RELEASE_MODEL_UID","findOne","where","id","releasedAt","errors","NotFoundError","taskName","cron","add","task","getService","publish","options","has","cancel","remove","get","delete","getAll","syncFromDatabase","releases","findMany","scheduledAt","$gte","Date"],"mappings":";;;;AAOA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;AAClE,IAAA,MAAMC,gBAAgB,IAAIC,GAAAA,EAAAA;IAE1B,OAAO;QACL,MAAMC,GAAAA,CAAAA,CAAIC,SAAwB,EAAEC,YAAkB,EAAA;YACpD,MAAMC,OAAAA,GAAU,MAAMN,MAAAA,CAAOO,EAAE,CAC5BC,KAAK,CAACC,iBAAAA,CAAAA,CACNC,OAAO,CAAC;gBAAEC,KAAAA,EAAO;oBAAEC,EAAAA,EAAIR,SAAAA;oBAAWS,UAAAA,EAAY;AAAK;AAAE,aAAA,CAAA;AAExD,YAAA,IAAI,CAACP,OAAAA,EAAS;AACZ,gBAAA,MAAM,IAAIQ,MAAAA,CAAOC,aAAa,CAAC,CAAC,wBAAwB,EAAEX,SAAAA,CAAAA,CAAW,CAAA;AACvE,YAAA;AAEA,YAAA,MAAMY,QAAAA,GAAW,CAAC,eAAe,EAAEZ,SAAAA,CAAAA,CAAW;YAE9CJ,MAAAA,CAAOiB,IAAI,CAACC,GAAG,CAAC;AACd,gBAAA,CAACF,WAAW;oBACV,MAAMG,IAAAA,CAAAA,GAAAA;AACJ,wBAAA,MAAMC,WAAW,SAAA,EAAW;AAAEpB,4BAAAA;AAAO,yBAAA,CAAA,CAAGqB,OAAO,CAACjB,SAAAA,CAAAA;AAClD,oBAAA,CAAA;oBACAkB,OAAAA,EAASjB;AACX;AACF,aAAA,CAAA;YAEA,IAAIJ,aAAAA,CAAcsB,GAAG,CAACnB,SAAAA,CAAAA,EAAY;gBAChC,IAAI,CAACoB,MAAM,CAACpB,SAAAA,CAAAA;AACd,YAAA;YAEAH,aAAAA,CAAcE,GAAG,CAACC,SAAAA,EAAWY,QAAAA,CAAAA;YAE7B,OAAOf,aAAAA;AACT,QAAA,CAAA;AAEAuB,QAAAA,MAAAA,CAAAA,CAAOpB,SAAwB,EAAA;YAC7B,IAAIH,aAAAA,CAAcsB,GAAG,CAACnB,SAAAA,CAAAA,EAAY;AAChCJ,gBAAAA,MAAAA,CAAOiB,IAAI,CAACQ,MAAM,CAACxB,aAAAA,CAAcyB,GAAG,CAACtB,SAAAA,CAAAA,CAAAA;AACrCH,gBAAAA,aAAAA,CAAc0B,MAAM,CAACvB,SAAAA,CAAAA;AACvB,YAAA;YAEA,OAAOH,aAAAA;AACT,QAAA,CAAA;AAEA2B,QAAAA,MAAAA,CAAAA,GAAAA;YACE,OAAO3B,aAAAA;AACT,QAAA,CAAA;AAEA;;;;AAIC,QACD,MAAM4B,gBAAAA,CAAAA,GAAAA;YACJ,MAAMC,QAAAA,GAAW,MAAM9B,MAAAA,CAAOO,EAAE,CAACC,KAAK,CAACC,iBAAAA,CAAAA,CAAmBsB,QAAQ,CAAC;gBACjEpB,KAAAA,EAAO;oBACLqB,WAAAA,EAAa;AACXC,wBAAAA,IAAAA,EAAM,IAAIC,IAAAA;AACZ,qBAAA;oBACArB,UAAAA,EAAY;AACd;AACF,aAAA,CAAA;YAEA,KAAK,MAAMP,WAAWwB,QAAAA,CAAU;AAC9B,gBAAA,IAAI,CAAC3B,GAAG,CAACG,QAAQM,EAAE,EAAEN,QAAQ0B,WAAW,CAAA;AAC1C,YAAA;YAEA,OAAO/B,aAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"homepage.d.ts","sourceRoot":"","sources":["../../../../server/src/services/homepage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;2BAIjC,QAAQ,4BAA4B,CAAC,MAAM,CAAC,CAAC;CAc7E,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"homepage.d.ts","sourceRoot":"","sources":["../../../../server/src/services/homepage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;2BAIjC,QAAQ,4BAA4B,CAAC,MAAM,CAAC,CAAC;CAgB7E,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../../server/src/services/release.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAe,IAAI,EAAE,MAAM,eAAe,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,UAAU,EACV,OAAO,EACP,aAAa,EACd,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,QAAA,MAAM,oBAAoB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;wBA2DnC,qBAAqB,CAAC,MAAM,CAAC,YAAY;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE;gBAiCnE,kBAAkB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;qBAUnC,mBAAmB,CAAC,OAAO,CAAC;;;;;;;;;qBAa5B,GAAG;eASd,KAAK,EAAE,eACE,qBAAqB,CAAC,MAAM,CAAC,YAChC;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE;;sBAsEN,qBAAqB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;uBA8CpC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;mCA0G1B,OAAO,CAAC,IAAI,CAAC;CAiDrD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAErE,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../../server/src/services/release.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAe,IAAI,EAAE,MAAM,eAAe,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,UAAU,EACV,OAAO,EACP,aAAa,EACd,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,QAAA,MAAM,oBAAoB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;wBA2DnC,qBAAqB,CAAC,MAAM,CAAC,YAAY;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE;gBAiCnE,kBAAkB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;qBAUnC,mBAAmB,CAAC,OAAO,CAAC;;;;;;;;;qBAa5B,GAAG;eASd,KAAK,EAAE,eACE,qBAAqB,CAAC,MAAM,CAAC,YAChC;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE;;sBAsEN,qBAAqB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;uBA8CpC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;mCAiH1B,OAAO,CAAC,IAAI,CAAC;CAiDrD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAErE,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../server/src/services/scheduling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAI7D,QAAA,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;mBAI3C,OAAO,CAAC,IAAI,CAAC,gBAAgB,IAAI;sBAkCpC,OAAO,CAAC,IAAI,CAAC;;IAa/B;;;;OAIG;;CAkBN,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../server/src/services/scheduling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAI7D,QAAA,MAAM,uBAAuB,eAAgB;IAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE;mBAI3C,OAAO,CAAC,IAAI,CAAC,gBAAgB,IAAI;sBA6BpC,OAAO,CAAC,IAAI,CAAC;;IAa/B;;;;OAIG;;CAkBN,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/content-releases",
3
- "version": "5.46.0",
3
+ "version": "5.46.1",
4
4
  "description": "Strapi plugin for organizing and releasing content",
5
5
  "homepage": "https://strapi.io",
6
6
  "bugs": {
@@ -64,11 +64,11 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@reduxjs/toolkit": "1.9.7",
67
- "@strapi/database": "5.46.0",
67
+ "@strapi/database": "5.46.1",
68
68
  "@strapi/design-system": "2.2.0",
69
69
  "@strapi/icons": "2.2.0",
70
- "@strapi/types": "5.46.0",
71
- "@strapi/utils": "5.46.0",
70
+ "@strapi/types": "5.46.1",
71
+ "@strapi/utils": "5.46.1",
72
72
  "date-fns": "2.30.0",
73
73
  "date-fns-tz": "2.0.1",
74
74
  "formik": "2.4.5",
@@ -79,9 +79,9 @@
79
79
  "yup": "0.32.9"
80
80
  },
81
81
  "devDependencies": {
82
- "@strapi/admin": "5.46.0",
83
- "@strapi/admin-test-utils": "5.46.0",
84
- "@strapi/content-manager": "5.46.0",
82
+ "@strapi/admin": "5.46.1",
83
+ "@strapi/admin-test-utils": "5.46.1",
84
+ "@strapi/content-manager": "5.46.1",
85
85
  "@testing-library/dom": "10.4.1",
86
86
  "@testing-library/react": "16.3.0",
87
87
  "@testing-library/user-event": "14.6.1",
@@ -92,7 +92,7 @@
92
92
  "react-dom": "18.3.1",
93
93
  "react-query": "3.39.3",
94
94
  "react-router-dom": "6.30.3",
95
- "styled-components": "6.1.8",
95
+ "styled-components": "6.4.1",
96
96
  "typescript": "5.4.5"
97
97
  },
98
98
  "peerDependencies": {