@strapi/content-releases 4.17.0 → 4.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-a4843fda.mjs → App-g2P5kbSm.mjs} +205 -115
- package/dist/_chunks/App-g2P5kbSm.mjs.map +1 -0
- package/dist/_chunks/{App-f2cafd81.js → App-o5_WfqR-.js} +202 -112
- package/dist/_chunks/App-o5_WfqR-.js.map +1 -0
- package/dist/_chunks/{en-13576ce2.js → en-haKSQIo8.js} +13 -4
- package/dist/_chunks/en-haKSQIo8.js.map +1 -0
- package/dist/_chunks/{en-e98d8b57.mjs → en-ngTk74JV.mjs} +13 -4
- package/dist/_chunks/en-ngTk74JV.mjs.map +1 -0
- package/dist/_chunks/{index-66d129ac.js → index-EdBmRHRU.js} +33 -22
- package/dist/_chunks/index-EdBmRHRU.js.map +1 -0
- package/dist/_chunks/{index-937f8179.mjs → index-XAQOX_IB.mjs} +36 -25
- package/dist/_chunks/index-XAQOX_IB.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/server/index.js +60 -35
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +58 -35
- package/dist/server/index.mjs.map +1 -1
- package/package.json +9 -8
- package/dist/_chunks/App-a4843fda.mjs.map +0 -1
- package/dist/_chunks/App-f2cafd81.js.map +0 -1
- package/dist/_chunks/en-13576ce2.js.map +0 -1
- package/dist/_chunks/en-e98d8b57.mjs.map +0 -1
- package/dist/_chunks/index-66d129ac.js.map +0 -1
- package/dist/_chunks/index-937f8179.mjs.map +0 -1
package/dist/admin/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { j } from "../_chunks/index-XAQOX_IB.mjs";
|
|
2
2
|
import "@strapi/helper-plugin";
|
|
3
3
|
import "@strapi/icons";
|
|
4
4
|
import "react/jsx-runtime";
|
|
@@ -14,6 +14,6 @@ import "yup";
|
|
|
14
14
|
import "@reduxjs/toolkit/query/react";
|
|
15
15
|
import "styled-components";
|
|
16
16
|
export {
|
|
17
|
-
|
|
17
|
+
j as default
|
|
18
18
|
};
|
|
19
19
|
//# sourceMappingURL=index.mjs.map
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const utils = require("@strapi/utils");
|
|
3
|
+
const _ = require("lodash/fp");
|
|
3
4
|
const yup = require("yup");
|
|
5
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
4
6
|
function _interopNamespace(e) {
|
|
5
7
|
if (e && e.__esModule)
|
|
6
8
|
return e;
|
|
@@ -19,6 +21,7 @@ function _interopNamespace(e) {
|
|
|
19
21
|
n.default = e;
|
|
20
22
|
return Object.freeze(n);
|
|
21
23
|
}
|
|
24
|
+
const ___default = /* @__PURE__ */ _interopDefault(_);
|
|
22
25
|
const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
|
|
23
26
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
24
27
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -142,6 +145,9 @@ const schema = {
|
|
|
142
145
|
type: "string",
|
|
143
146
|
required: true
|
|
144
147
|
},
|
|
148
|
+
locale: {
|
|
149
|
+
type: "string"
|
|
150
|
+
},
|
|
145
151
|
release: {
|
|
146
152
|
type: "relation",
|
|
147
153
|
relation: "manyToOne",
|
|
@@ -160,6 +166,18 @@ const contentTypes = {
|
|
|
160
166
|
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
161
167
|
return strapi2.plugin("content-releases").service(name);
|
|
162
168
|
};
|
|
169
|
+
const getGroupName = (queryValue) => {
|
|
170
|
+
switch (queryValue) {
|
|
171
|
+
case "contentType":
|
|
172
|
+
return "entry.contentType.displayName";
|
|
173
|
+
case "action":
|
|
174
|
+
return "type";
|
|
175
|
+
case "locale":
|
|
176
|
+
return ___default.default.getOr("No locale", "entry.locale.name");
|
|
177
|
+
default:
|
|
178
|
+
return "entry.contentType.displayName";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
163
181
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
164
182
|
async create(releaseData, { user }) {
|
|
165
183
|
const releaseWithCreatorFields = await utils.setCreatorFields({ user })(releaseData);
|
|
@@ -271,6 +289,7 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
271
289
|
data: {
|
|
272
290
|
type,
|
|
273
291
|
contentType: entry.contentType,
|
|
292
|
+
locale: entry.locale,
|
|
274
293
|
entry: {
|
|
275
294
|
id: entry.id,
|
|
276
295
|
__type: entry.contentType,
|
|
@@ -282,8 +301,10 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
282
301
|
});
|
|
283
302
|
},
|
|
284
303
|
async findActions(releaseId, query) {
|
|
285
|
-
const
|
|
286
|
-
|
|
304
|
+
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
305
|
+
fields: ["id"]
|
|
306
|
+
});
|
|
307
|
+
if (!release2) {
|
|
287
308
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
288
309
|
}
|
|
289
310
|
return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
|
|
@@ -299,18 +320,40 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
299
320
|
async countActions(query) {
|
|
300
321
|
return strapi2.entityService.count(RELEASE_ACTION_MODEL_UID, query);
|
|
301
322
|
},
|
|
302
|
-
async
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
323
|
+
async groupActions(actions, groupBy) {
|
|
324
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
325
|
+
if (!acc.includes(action.contentType)) {
|
|
326
|
+
acc.push(action.contentType);
|
|
327
|
+
}
|
|
328
|
+
return acc;
|
|
329
|
+
}, []);
|
|
330
|
+
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
331
|
+
contentTypeUids
|
|
332
|
+
);
|
|
333
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find();
|
|
334
|
+
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
335
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
336
|
+
return acc;
|
|
337
|
+
}, {});
|
|
338
|
+
const formattedData = actions.map((action) => {
|
|
339
|
+
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
340
|
+
return {
|
|
341
|
+
...action,
|
|
342
|
+
entry: {
|
|
343
|
+
id: action.entry.id,
|
|
344
|
+
contentType: {
|
|
345
|
+
displayName,
|
|
346
|
+
mainFieldValue: action.entry[mainField]
|
|
347
|
+
},
|
|
348
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
349
|
+
status: action.entry.publishedAt ? "published" : "draft"
|
|
307
350
|
}
|
|
308
|
-
|
|
309
|
-
})
|
|
310
|
-
|
|
351
|
+
};
|
|
352
|
+
});
|
|
353
|
+
const groupName = getGroupName(groupBy);
|
|
354
|
+
return ___default.default.groupBy(groupName)(formattedData);
|
|
311
355
|
},
|
|
312
|
-
async getContentTypesDataForActions(
|
|
313
|
-
const contentTypesUids = await this.getAllContentTypeUids(releaseId);
|
|
356
|
+
async getContentTypesDataForActions(contentTypesUids) {
|
|
314
357
|
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
315
358
|
const contentTypesData = {};
|
|
316
359
|
for (const contentTypeUid of contentTypesUids) {
|
|
@@ -615,31 +658,13 @@ const releaseActionController = {
|
|
|
615
658
|
});
|
|
616
659
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
617
660
|
const releaseService = getService("release", { strapi });
|
|
618
|
-
const { results, pagination } = await releaseService.findActions(releaseId,
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
);
|
|
622
|
-
const allLocales = await strapi.plugin("i18n").service("locales").find();
|
|
623
|
-
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
624
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
625
|
-
return acc;
|
|
626
|
-
}, {});
|
|
627
|
-
const data = results.map((action) => {
|
|
628
|
-
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
629
|
-
return {
|
|
630
|
-
...action,
|
|
631
|
-
entry: {
|
|
632
|
-
id: action.entry.id,
|
|
633
|
-
contentType: {
|
|
634
|
-
displayName,
|
|
635
|
-
mainFieldValue: action.entry[mainField]
|
|
636
|
-
},
|
|
637
|
-
locale: allLocalesDictionary[action.entry.locale]
|
|
638
|
-
}
|
|
639
|
-
};
|
|
661
|
+
const { results, pagination } = await releaseService.findActions(releaseId, {
|
|
662
|
+
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
663
|
+
...query
|
|
640
664
|
});
|
|
665
|
+
const groupedData = await releaseService.groupActions(results, query.groupBy);
|
|
641
666
|
ctx.body = {
|
|
642
|
-
data,
|
|
667
|
+
data: groupedData,
|
|
643
668
|
meta: {
|
|
644
669
|
pagination
|
|
645
670
|
}
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../server/src/constants.ts","../../server/src/register.ts","../../server/src/content-types/release/schema.ts","../../server/src/content-types/release/index.ts","../../server/src/content-types/release-action/schema.ts","../../server/src/content-types/release-action/index.ts","../../server/src/content-types/index.ts","../../server/src/utils/index.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/index.ts","../../shared/validation-schemas.ts","../../server/src/controllers/validation/release.ts","../../server/src/controllers/release.ts","../../server/src/controllers/validation/release-action.ts","../../server/src/controllers/release-action.ts","../../server/src/controllers/index.ts","../../server/src/routes/release.ts","../../server/src/routes/release-action.ts","../../server/src/routes/index.ts","../../server/src/index.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n];\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi } from '@strapi/types';\nimport { ACTIONS } from './constants';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n }\n};\n","import { RELEASE_ACTION_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_releases',\n info: {\n singularName: 'release',\n pluralName: 'releases',\n displayName: 'Release',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n required: true,\n },\n releasedAt: {\n type: 'datetime',\n },\n actions: {\n type: 'relation',\n relation: 'oneToMany',\n target: RELEASE_ACTION_MODEL_UID,\n mappedBy: 'release',\n },\n },\n};\n","import schema from './schema';\n\nexport const release = {\n schema,\n};\n","import { RELEASE_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_release_actions',\n info: {\n singularName: 'release-action',\n pluralName: 'release-actions',\n displayName: 'Release Action',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n type: {\n type: 'enumeration',\n enum: ['publish', 'unpublish'],\n required: true,\n },\n entry: {\n type: 'relation',\n relation: 'morphToOne',\n configurable: false,\n },\n contentType: {\n type: 'string',\n required: true,\n },\n release: {\n type: 'relation',\n relation: 'manyToOne',\n target: RELEASE_MODEL_UID,\n inversedBy: 'actions',\n },\n },\n};\n","import schema from './schema';\n\nexport const releaseAction = {\n schema,\n};\n","import { release } from './release';\nimport { releaseAction } from './release-action';\n\nexport const contentTypes = {\n release,\n 'release-action': releaseAction,\n};\n","export const getService = (\n name: 'release' | 'release-validation',\n { strapi } = { strapi: global.strapi }\n) => {\n return strapi.plugin('content-releases').service(name);\n};\n","import { setCreatorFields, errors } from '@strapi/utils';\nimport type { LoadedStrapi, EntityService, UID } from '@strapi/types';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport type {\n GetReleases,\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n} from '../../../shared/contracts/releases';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n ReleaseAction,\n UpdateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\nconst createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async create(releaseData: CreateRelease.Request['body'], { user }: { user: UserInfo }) {\n const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);\n\n return strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\n },\n\n async findOne(id: GetRelease.Request['params']['id'], query = {}) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id, {\n ...query,\n });\n\n return release;\n },\n\n findPage(query?: GetReleases.Request['query']) {\n return strapi.entityService.findPage(RELEASE_MODEL_UID, {\n ...query,\n populate: {\n actions: {\n // @ts-expect-error Ignore missing properties\n count: true,\n },\n },\n });\n },\n\n async findManyForContentTypeEntry(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'],\n {\n hasEntryAttached,\n }: { hasEntryAttached?: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] } = {\n hasEntryAttached: false,\n }\n ) {\n const whereActions = hasEntryAttached\n ? {\n // Find all Releases where the content type entry is present\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n }\n : {\n // Find all Releases where the content type entry is not present\n $or: [\n {\n $not: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n {\n actions: null,\n },\n ],\n };\n const populateAttachedAction = hasEntryAttached\n ? {\n // Filter the action to get only the content type entry\n actions: {\n where: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n }\n : {};\n\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n ...whereActions,\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n ...populateAttachedAction,\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async update(\n id: number,\n releaseData: UpdateRelease.Request['body'],\n { user }: { user: UserInfo }\n ) {\n const updatedRelease = await setCreatorFields({ user, isEdition: true })(releaseData);\n\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, id, {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">>\n * is not compatible with the type we are passing here: UpdateRelease.Request['body']\n */\n // @ts-expect-error see above\n data: updatedRelease,\n });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${id}`);\n }\n\n return release;\n },\n\n async createAction(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n action: Pick<CreateReleaseAction.Request['body'], 'type' | 'entry'>\n ) {\n const { validateEntryContentType, validateUniqueEntry } = getService('release-validation', {\n strapi,\n });\n\n await Promise.all([\n validateEntryContentType(action.entry.contentType),\n validateUniqueEntry(releaseId, action),\n ]);\n\n const { entry, type } = action;\n\n return strapi.entityService.create(RELEASE_ACTION_MODEL_UID, {\n data: {\n type,\n contentType: entry.contentType,\n entry: {\n id: entry.id,\n __type: entry.contentType,\n __pivot: { field: 'entry' },\n },\n release: releaseId,\n },\n populate: { release: { fields: ['id'] }, entry: { fields: ['id'] } },\n });\n },\n\n async findActions(\n releaseId: GetReleaseActions.Request['params']['releaseId'],\n query?: GetReleaseActions.Request['query']\n ) {\n const result = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId);\n\n if (!result) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n return strapi.entityService.findPage(RELEASE_ACTION_MODEL_UID, {\n ...query,\n populate: {\n entry: true,\n },\n filters: {\n release: releaseId,\n },\n });\n },\n\n async countActions(query: EntityService.Params.Pick<typeof RELEASE_ACTION_MODEL_UID, 'filters'>) {\n return strapi.entityService.count(RELEASE_ACTION_MODEL_UID, query);\n },\n\n async getAllContentTypeUids(releaseId: Release['id']) {\n const contentTypesFromReleaseActions: { contentType: UID.ContentType }[] = await strapi.db\n .queryBuilder(RELEASE_ACTION_MODEL_UID)\n .select('content_type')\n .where({\n $and: [\n {\n release: releaseId,\n },\n ],\n })\n .groupBy('content_type')\n .execute();\n\n return contentTypesFromReleaseActions.map(({ contentType: contentTypeUid }) => contentTypeUid);\n },\n\n async getContentTypesDataForActions(releaseId: Release['id']) {\n const contentTypesUids = await this.getAllContentTypeUids(releaseId);\n\n const contentManagerContentTypeService = strapi\n .plugin('content-manager')\n .service('content-types');\n\n const contentTypesData: Record<UID.ContentType, { mainField: string; displayName: string }> =\n {};\n for (const contentTypeUid of contentTypesUids) {\n const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({\n uid: contentTypeUid,\n });\n\n contentTypesData[contentTypeUid] = {\n mainField: contentTypeConfig.settings.mainField,\n displayName: strapi.getModel(contentTypeUid).info.displayName,\n };\n }\n\n return contentTypesData;\n },\n\n async delete(releaseId: DeleteRelease.Request['params']['id']) {\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: {\n actions: {\n fields: ['id'],\n },\n },\n })) as unknown as Release;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n // Only delete the release and its actions is you in fact can delete all the actions and the release\n // Otherwise, if the transaction fails it throws an error\n await strapi.db.transaction(async () => {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n id: {\n $in: release.actions.map((action) => action.id),\n },\n },\n });\n await strapi.entityService.delete(RELEASE_MODEL_UID, releaseId);\n });\n\n return release;\n },\n\n async publish(releaseId: PublishRelease.Request['params']['id']) {\n // We need to pass the type because entityService.findOne is not returning the correct type\n const releaseWithPopulatedActionEntries = (await strapi.entityService.findOne(\n RELEASE_MODEL_UID,\n releaseId,\n {\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n }\n )) as unknown as Release;\n\n if (!releaseWithPopulatedActionEntries) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (releaseWithPopulatedActionEntries.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n if (releaseWithPopulatedActionEntries.actions.length === 0) {\n throw new errors.ValidationError('No entries to publish');\n }\n\n /**\n * We separate publish and unpublish actions group by content type\n */\n const actions: {\n [key: UID.ContentType]: {\n publish: ReleaseAction['entry'][];\n unpublish: ReleaseAction['entry'][];\n };\n } = {};\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (!actions[contentTypeUid]) {\n actions[contentTypeUid] = {\n publish: [],\n unpublish: [],\n };\n }\n\n if (action.type === 'publish') {\n actions[contentTypeUid].publish.push(action.entry);\n } else {\n actions[contentTypeUid].unpublish.push(action.entry);\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\n\n // Only publish the release if all action updates are applied successfully to their entry, otherwise leave everything as is\n await strapi.db.transaction(async () => {\n for (const contentTypeUid of Object.keys(actions)) {\n const { publish, unpublish } = actions[contentTypeUid as UID.ContentType];\n\n if (publish.length > 0) {\n await entityManagerService.publishMany(publish, contentTypeUid);\n }\n\n if (unpublish.length > 0) {\n await entityManagerService.unpublishMany(unpublish, contentTypeUid);\n }\n }\n });\n\n // When the transaction fails it throws an error, when it is successful proceed to updating the release\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, releaseId, {\n data: {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">> looks like it's wrong\n */\n // @ts-expect-error see above\n releasedAt: new Date(),\n },\n });\n\n return release;\n },\n\n async updateAction(\n actionId: UpdateReleaseAction.Request['params']['actionId'],\n releaseId: UpdateReleaseAction.Request['params']['releaseId'],\n update: UpdateReleaseAction.Request['body']\n ) {\n const updatedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: actionId,\n release: releaseId,\n },\n data: update,\n });\n\n if (!updatedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId}`\n );\n }\n\n return updatedAction;\n },\n\n async deleteAction(\n actionId: DeleteReleaseAction.Request['params']['actionId'],\n releaseId: DeleteReleaseAction.Request['params']['releaseId']\n ) {\n const deletedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).delete({\n where: {\n id: actionId,\n release: releaseId,\n },\n });\n\n if (!deletedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId}`\n );\n }\n\n return deletedAction;\n },\n});\n\nexport default createReleaseService;\n","import { errors } from '@strapi/utils';\nimport { LoadedStrapi } from '@strapi/types';\nimport type { Release } from '../../../shared/contracts/releases';\nimport type { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createReleaseValidationService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async validateUniqueEntry(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n releaseActionArgs: CreateReleaseAction.Request['body']\n ) {\n /**\n * Asserting the type, otherwise TS complains: 'release.actions' is of type 'unknown', even though the types come through for non-populated fields...\n * Possibly related to the comment on GetValues: https://github.com/strapi/strapi/blob/main/packages/core/types/src/modules/entity-service/result.ts\n */\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: { actions: { populate: { entry: { fields: ['id'] } } } },\n })) as Release | null;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const isEntryInRelease = release.actions.some(\n (action) =>\n Number(action.entry.id) === Number(releaseActionArgs.entry.id) &&\n action.contentType === releaseActionArgs.entry.contentType\n );\n\n if (isEntryInRelease) {\n throw new errors.ValidationError(\n `Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`\n );\n }\n },\n validateEntryContentType(\n contentTypeUid: CreateReleaseAction.Request['body']['entry']['contentType']\n ) {\n const contentType = strapi.contentType(contentTypeUid);\n\n if (!contentType) {\n throw new errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);\n }\n\n // TODO: V5 migration - All contentType will have draftAndPublish enabled\n if (!contentType.options?.draftAndPublish) {\n throw new errors.ValidationError(\n `Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`\n );\n }\n },\n});\n\nexport default createReleaseValidationService;\n","import release from './release';\nimport releaseValidation from './validation';\n\nexport const services = { release, 'release-validation': releaseValidation };\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n })\n .required()\n .noUnknown();\n","import { validateYupSchema } from '@strapi/utils';\nimport { RELEASE_SCHEMA } from '../../../../shared/validation-schemas';\n\nexport const validateRelease = validateYupSchema(RELEASE_SCHEMA);\n","import type Koa from 'koa';\nimport { errors } from '@strapi/utils';\nimport { RELEASE_MODEL_UID } from '../constants';\nimport { validateRelease } from './validation/release';\nimport type {\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n} from '../../../shared/contracts/releases';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\ntype ReleaseWithPopulatedActions = Release & { actions: { count: number } };\n\nconst releaseController = {\n async findMany(ctx: Koa.Context) {\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n\n // Handle requests for releases filtered by content type entry\n const isFindManyForContentTypeEntry = Boolean(ctx.query?.contentTypeUid && ctx.query?.entryId);\n if (isFindManyForContentTypeEntry) {\n const query: GetContentTypeEntryReleases.Request['query'] =\n await permissionsManager.sanitizeQuery(ctx.query);\n\n const contentTypeUid = query.contentTypeUid;\n const entryId = query.entryId;\n // Parse the string value or fallback to a default\n const hasEntryAttached: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] =\n typeof query.hasEntryAttached === 'string' ? JSON.parse(query.hasEntryAttached) : false;\n\n const data = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, {\n hasEntryAttached,\n });\n\n ctx.body = { data };\n } else {\n const query: GetReleases.Request['query'] = await permissionsManager.sanitizeQuery(ctx.query);\n const { results, pagination } = await releaseService.findPage(query);\n\n const data = results.map((release: ReleaseWithPopulatedActions) => {\n const { actions, ...releaseData } = release;\n\n return {\n ...releaseData,\n actions: {\n meta: {\n count: actions.count,\n },\n },\n };\n });\n\n ctx.body = { data, meta: { pagination } };\n }\n },\n\n async findOne(ctx: Koa.Context) {\n const id: GetRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n const sanitizedRelease = await permissionsManager.sanitizeOutput(release);\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\n }\n\n // Format the data object\n const data = {\n ...sanitizedRelease,\n actions: {\n meta: {\n count,\n },\n },\n };\n\n ctx.body = { data };\n },\n\n async create(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: CreateRelease.Request['body'] = ctx.request.body;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.create(releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async update(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: UpdateRelease.Request['body'] = ctx.request.body;\n const id: UpdateRelease.Request['params']['id'] = ctx.params.id;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.update(id, releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async delete(ctx: Koa.Context) {\n const id: DeleteRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.delete(id);\n\n ctx.body = {\n data: release,\n };\n },\n\n async publish(ctx: Koa.Context) {\n const user: PublishRelease.Request['state']['user'] = ctx.state.user;\n const id: PublishRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.publish(id, { user });\n\n ctx.body = {\n data: release,\n };\n },\n};\n\nexport default releaseController;\n","import { yup, validateYupSchema } from '@strapi/utils';\n\nconst RELEASE_ACTION_SCHEMA = yup.object().shape({\n entry: yup\n .object()\n .shape({\n id: yup.strapiID().required(),\n contentType: yup.string().required(),\n })\n .required(),\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nconst RELEASE_ACTION_UPDATE_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nexport const validateReleaseAction = validateYupSchema(RELEASE_ACTION_SCHEMA);\nexport const validateReleaseActionUpdateSchema = validateYupSchema(RELEASE_ACTION_UPDATE_SCHEMA);\n","import type Koa from 'koa';\nimport { Entity } from '../../../shared/types';\n\nimport {\n validateReleaseAction,\n validateReleaseActionUpdateSchema,\n} from './validation/release-action';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n ReleaseAction,\n UpdateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { getService } from '../utils';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\ninterface Locale extends Entity {\n name: string;\n code: string;\n}\n\ntype LocaleDictionary = {\n [key: Locale['code']]: Pick<Locale, 'name' | 'code'>;\n};\n\nconst releaseActionController = {\n async create(ctx: Koa.Context) {\n const releaseId: CreateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionArgs: CreateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseAction(releaseActionArgs);\n\n const releaseService = getService('release', { strapi });\n const releaseAction = await releaseService.createAction(releaseId, releaseActionArgs);\n\n ctx.body = {\n data: releaseAction,\n };\n },\n async findMany(ctx: Koa.Context) {\n const releaseId: GetReleaseActions.Request['params']['releaseId'] = ctx.params.releaseId;\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_ACTION_MODEL_UID,\n });\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n const { results, pagination } = await releaseService.findActions(releaseId, query);\n const allReleaseContentTypesDictionary = await releaseService.getContentTypesDataForActions(\n releaseId\n );\n\n const allLocales: Locale[] = await strapi.plugin('i18n').service('locales').find();\n const allLocalesDictionary = allLocales.reduce<LocaleDictionary>((acc, locale) => {\n acc[locale.code] = { name: locale.name, code: locale.code };\n\n return acc;\n }, {});\n\n const data = results.map((action: ReleaseAction) => {\n const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];\n\n return {\n ...action,\n entry: {\n id: action.entry.id,\n contentType: {\n displayName,\n mainFieldValue: action.entry[mainField],\n },\n locale: allLocalesDictionary[action.entry.locale],\n },\n };\n });\n\n ctx.body = {\n data,\n meta: {\n pagination,\n },\n };\n },\n\n async update(ctx: Koa.Context) {\n const actionId: UpdateReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: UpdateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionUpdateArgs: UpdateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseActionUpdateSchema(releaseActionUpdateArgs);\n\n const releaseService = getService('release', { strapi });\n const updatedAction = await releaseService.updateAction(\n actionId,\n releaseId,\n releaseActionUpdateArgs\n );\n\n ctx.body = {\n data: updatedAction,\n };\n },\n\n async delete(ctx: Koa.Context) {\n const actionId: DeleteReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: DeleteReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n\n const deletedReleaseAction = await getService('release', { strapi }).deleteAction(\n actionId,\n releaseId\n );\n\n ctx.body = {\n data: deletedReleaseAction,\n };\n },\n};\n\nexport default releaseActionController;\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const controllers = { release, 'release-action': releaseAction };\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/',\n handler: 'release.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/',\n handler: 'release.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:id',\n handler: 'release.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:id',\n handler: 'release.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:id',\n handler: 'release.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/:id/publish',\n handler: 'release.publish',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.publish'],\n },\n },\n ],\n },\n },\n ],\n};\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/:releaseId/actions',\n handler: 'release-action.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create-action'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:releaseId/actions',\n handler: 'release-action.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete-action'],\n },\n },\n ],\n },\n },\n ],\n};\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const routes = {\n release,\n 'release-action': releaseAction,\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { register } from './register';\nimport { contentTypes } from './content-types';\nimport { services } from './services';\nimport { controllers } from './controllers';\nimport { routes } from './routes';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n return {\n register,\n contentTypes,\n services,\n controllers,\n routes,\n };\n }\n\n // We keep returning contentTypes to avoid lost the data if feature is disabled\n return {\n contentTypes,\n };\n};\n\nexport default getPlugin();\n"],"names":["features","strapi","release","schema","releaseAction","setCreatorFields","errors","releaseValidation","yup","validateYupSchema"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAO,MAAM,oBAAoB;AAC1B,MAAM,2BAA2B;AAEjC,MAAM,UAAU;AAAA,EACrB;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,IACL,YAAY;AAAA,EACd;AACF;AC1CA,MAAM,EAAA,UAAEA,WAAa,IAAA,QAAQ,8BAA8B;AAEpD,MAAM,WAAW,OAAO,EAAE,QAAAC,cAAuC;AAEpE,MAAAD,WAAS,UAAU,sBAAsB,KACzCC,QAAO,SAAS,OAAO,UAAU,iBAAiB,GAClD;AACA,UAAMA,QAAO,MAAM,SAAS,WAAW,eAAe,aAAa,OAAO;AAAA,EAC5E;AACF;ACXA,MAAe,WAAA;AAAA,EACb,gBAAgB;AAAA,EAChB,MAAM;AAAA,IACJ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA,EACA,SAAS;AAAA,IACP,iBAAiB;AAAA,EACnB;AAAA,EACA,eAAe;AAAA,IACb,mBAAmB;AAAA,MACjB,SAAS;AAAA,IACX;AAAA,IACA,wBAAwB;AAAA,MACtB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,YAAY;AAAA,IACV,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF;AACF;ACjCO,MAAMC,YAAU;AAAA,EAAA,QACrBC;AACF;ACFA,MAAe,SAAA;AAAA,EACb,gBAAgB;AAAA,EAChB,MAAM;AAAA,IACJ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA,EACA,SAAS;AAAA,IACP,iBAAiB;AAAA,EACnB;AAAA,EACA,eAAe;AAAA,IACb,mBAAmB;AAAA,MACjB,SAAS;AAAA,IACX;AAAA,IACA,wBAAwB;AAAA,MACtB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,YAAY;AAAA,IACV,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM,CAAC,WAAW,WAAW;AAAA,MAC7B,UAAU;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,EACF;AACF;ACxCO,MAAMC,kBAAgB;AAAA,EAC3B;AACF;ACDO,MAAM,eAAe;AAAA,EAAA,SAC1BF;AAAAA,EACA,kBAAkBE;AACpB;ACNa,MAAA,aAAa,CACxB,MACA,EAAE,QAAAH,QAAA,IAAW,EAAE,QAAQ,OAAO,aAC3B;AACH,SAAOA,QAAO,OAAO,kBAAkB,EAAE,QAAQ,IAAI;AACvD;ACkBA,MAAM,uBAAuB,CAAC,EAAE,QAAAA,eAAwC;AAAA,EACtE,MAAM,OAAO,aAA4C,EAAE,QAA4B;AACrF,UAAM,2BAA2B,MAAMI,MAAA,iBAAiB,EAAE,KAAM,CAAA,EAAE,WAAW;AAEtE,WAAAJ,QAAO,cAAc,OAAO,mBAAmB;AAAA,MACpD,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ,IAAwC,QAAQ,IAAI;AAChE,UAAMC,WAAU,MAAMD,QAAO,cAAc,QAAQ,mBAAmB,IAAI;AAAA,MACxE,GAAG;AAAA,IAAA,CACJ;AAEM,WAAAC;AAAA,EACT;AAAA,EAEA,SAAS,OAAsC;AACtC,WAAAD,QAAO,cAAc,SAAS,mBAAmB;AAAA,MACtD,GAAG;AAAA,MACH,UAAU;AAAA,QACR,SAAS;AAAA;AAAA,UAEP,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,MAAM,4BACJ,gBACA,SACA;AAAA,IACE;AAAA,EAAA,IAC2F;AAAA,IAC3F,kBAAkB;AAAA,EAAA,GAEpB;AACA,UAAM,eAAe,mBACjB;AAAA;AAAA,MAEE,SAAS;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,MACb;AAAA,IAAA,IAEF;AAAA;AAAA,MAEE,KAAK;AAAA,QACH;AAAA,UACE,MAAM;AAAA,YACJ,SAAS;AAAA,cACP,aAAa;AAAA,cACb,WAAW;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IAAA;AAEN,UAAM,yBAAyB,mBAC3B;AAAA;AAAA,MAEE,SAAS;AAAA,QACP,OAAO;AAAA,UACL,aAAa;AAAA,UACb,WAAW;AAAA,QACb;AAAA,MACF;AAAA,QAEF;AAEJ,UAAM,WAAW,MAAMA,QAAO,GAAG,MAAM,iBAAiB,EAAE,SAAS;AAAA,MACjE,OAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,UACV,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,UAAU;AAAA,QACR,GAAG;AAAA,MACL;AAAA,IAAA,CACD;AAEM,WAAA,SAAS,IAAI,CAACC,aAAY;AAC3B,UAAAA,SAAQ,SAAS,QAAQ;AACrB,cAAA,CAAC,cAAc,IAAIA,SAAQ;AAGjC,eAAOA,SAAQ;AAER,eAAA;AAAA,UACL,GAAGA;AAAA,UACH,QAAQ;AAAA,QAAA;AAAA,MAEZ;AAEO,aAAAA;AAAA,IAAA,CACR;AAAA,EACH;AAAA,EAEA,MAAM,OACJ,IACA,aACA,EAAE,QACF;AACM,UAAA,iBAAiB,MAAMG,MAAAA,iBAAiB,EAAE,MAAM,WAAW,KAAA,CAAM,EAAE,WAAW;AAEpF,UAAMH,WAAU,MAAMD,QAAO,cAAc,OAAO,mBAAmB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMvE,MAAM;AAAA,IAAA,CACP;AAED,QAAI,CAACC,UAAS;AACZ,YAAM,IAAII,MAAA,OAAO,cAAc,2BAA2B,EAAE,EAAE;AAAA,IAChE;AAEO,WAAAJ;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,WACA,QACA;AACA,UAAM,EAAE,0BAA0B,wBAAwB,WAAW,sBAAsB;AAAA,MACzF,QAAAD;AAAA,IAAA,CACD;AAED,UAAM,QAAQ,IAAI;AAAA,MAChB,yBAAyB,OAAO,MAAM,WAAW;AAAA,MACjD,oBAAoB,WAAW,MAAM;AAAA,IAAA,CACtC;AAEK,UAAA,EAAE,OAAO,KAAS,IAAA;AAEjB,WAAAA,QAAO,cAAc,OAAO,0BAA0B;AAAA,MAC3D,MAAM;AAAA,QACJ;AAAA,QACA,aAAa,MAAM;AAAA,QACnB,OAAO;AAAA,UACL,IAAI,MAAM;AAAA,UACV,QAAQ,MAAM;AAAA,UACd,SAAS,EAAE,OAAO,QAAQ;AAAA,QAC5B;AAAA,QACA,SAAS;AAAA,MACX;AAAA,MACA,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI;AAAA,IAAA,CACpE;AAAA,EACH;AAAA,EAEA,MAAM,YACJ,WACA,OACA;AACA,UAAM,SAAS,MAAMA,QAAO,cAAc,QAAQ,mBAAmB,SAAS;AAE9E,QAAI,CAAC,QAAQ;AACX,YAAM,IAAIK,MAAA,OAAO,cAAc,2BAA2B,SAAS,EAAE;AAAA,IACvE;AAEO,WAAAL,QAAO,cAAc,SAAS,0BAA0B;AAAA,MAC7D,GAAG;AAAA,MACH,UAAU;AAAA,QACR,OAAO;AAAA,MACT;AAAA,MACA,SAAS;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,OAA8E;AAC/F,WAAOA,QAAO,cAAc,MAAM,0BAA0B,KAAK;AAAA,EACnE;AAAA,EAEA,MAAM,sBAAsB,WAA0B;AAC9C,UAAA,iCAAqE,MAAMA,QAAO,GACrF,aAAa,wBAAwB,EACrC,OAAO,cAAc,EACrB,MAAM;AAAA,MACL,MAAM;AAAA,QACJ;AAAA,UACE,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACD,CAAA,EACA,QAAQ,cAAc,EACtB,QAAQ;AAEX,WAAO,+BAA+B,IAAI,CAAC,EAAE,aAAa,eAAA,MAAqB,cAAc;AAAA,EAC/F;AAAA,EAEA,MAAM,8BAA8B,WAA0B;AAC5D,UAAM,mBAAmB,MAAM,KAAK,sBAAsB,SAAS;AAEnE,UAAM,mCAAmCA,QACtC,OAAO,iBAAiB,EACxB,QAAQ,eAAe;AAE1B,UAAM,mBACJ,CAAA;AACF,eAAW,kBAAkB,kBAAkB;AACvC,YAAA,oBAAoB,MAAM,iCAAiC,kBAAkB;AAAA,QACjF,KAAK;AAAA,MAAA,CACN;AAED,uBAAiB,cAAc,IAAI;AAAA,QACjC,WAAW,kBAAkB,SAAS;AAAA,QACtC,aAAaA,QAAO,SAAS,cAAc,EAAE,KAAK;AAAA,MAAA;AAAA,IAEtD;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,WAAkD;AAC7D,UAAMC,WAAW,MAAMD,QAAO,cAAc,QAAQ,mBAAmB,WAAW;AAAA,MAChF,UAAU;AAAA,QACR,SAAS;AAAA,UACP,QAAQ,CAAC,IAAI;AAAA,QACf;AAAA,MACF;AAAA,IAAA,CACD;AAED,QAAI,CAACC,UAAS;AACZ,YAAM,IAAII,MAAA,OAAO,cAAc,2BAA2B,SAAS,EAAE;AAAA,IACvE;AAEA,QAAIJ,SAAQ,YAAY;AAChB,YAAA,IAAII,MAAO,OAAA,gBAAgB,2BAA2B;AAAA,IAC9D;AAIM,UAAAL,QAAO,GAAG,YAAY,YAAY;AACtC,YAAMA,QAAO,GAAG,MAAM,wBAAwB,EAAE,WAAW;AAAA,QACzD,OAAO;AAAA,UACL,IAAI;AAAA,YACF,KAAKC,SAAQ,QAAQ,IAAI,CAAC,WAAW,OAAO,EAAE;AAAA,UAChD;AAAA,QACF;AAAA,MAAA,CACD;AACD,YAAMD,QAAO,cAAc,OAAO,mBAAmB,SAAS;AAAA,IAAA,CAC/D;AAEM,WAAAC;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,WAAmD;AAEzD,UAAA,oCAAqC,MAAMD,QAAO,cAAc;AAAA,MACpE;AAAA,MACA;AAAA,MACA;AAAA,QACE,UAAU;AAAA,UACR,SAAS;AAAA,YACP,UAAU;AAAA,cACR,OAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IAAA;AAGF,QAAI,CAAC,mCAAmC;AACtC,YAAM,IAAIK,MAAA,OAAO,cAAc,2BAA2B,SAAS,EAAE;AAAA,IACvE;AAEA,QAAI,kCAAkC,YAAY;AAC1C,YAAA,IAAIA,MAAO,OAAA,gBAAgB,2BAA2B;AAAA,IAC9D;AAEI,QAAA,kCAAkC,QAAQ,WAAW,GAAG;AACpD,YAAA,IAAIA,MAAO,OAAA,gBAAgB,uBAAuB;AAAA,IAC1D;AAKA,UAAM,UAKF,CAAA;AACO,eAAA,UAAU,kCAAkC,SAAS;AAC9D,YAAM,iBAAiB,OAAO;AAE1B,UAAA,CAAC,QAAQ,cAAc,GAAG;AAC5B,gBAAQ,cAAc,IAAI;AAAA,UACxB,SAAS,CAAC;AAAA,UACV,WAAW,CAAC;AAAA,QAAA;AAAA,MAEhB;AAEI,UAAA,OAAO,SAAS,WAAW;AAC7B,gBAAQ,cAAc,EAAE,QAAQ,KAAK,OAAO,KAAK;AAAA,MAAA,OAC5C;AACL,gBAAQ,cAAc,EAAE,UAAU,KAAK,OAAO,KAAK;AAAA,MACrD;AAAA,IACF;AAEA,UAAM,uBAAuBL,QAAO,OAAO,iBAAiB,EAAE,QAAQ,gBAAgB;AAGhF,UAAAA,QAAO,GAAG,YAAY,YAAY;AACtC,iBAAW,kBAAkB,OAAO,KAAK,OAAO,GAAG;AACjD,cAAM,EAAE,SAAS,UAAU,IAAI,QAAQ,cAAiC;AAEpE,YAAA,QAAQ,SAAS,GAAG;AAChB,gBAAA,qBAAqB,YAAY,SAAS,cAAc;AAAA,QAChE;AAEI,YAAA,UAAU,SAAS,GAAG;AAClB,gBAAA,qBAAqB,cAAc,WAAW,cAAc;AAAA,QACpE;AAAA,MACF;AAAA,IAAA,CACD;AAGD,UAAMC,WAAU,MAAMD,QAAO,cAAc,OAAO,mBAAmB,WAAW;AAAA,MAC9E,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,QAKJ,gCAAgB,KAAK;AAAA,MACvB;AAAA,IAAA,CACD;AAEM,WAAAC;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,UACA,WACA,QACA;AACA,UAAM,gBAAgB,MAAMD,QAAO,GAAG,MAAM,wBAAwB,EAAE,OAAO;AAAA,MAC3E,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IAAA,CACP;AAED,QAAI,CAAC,eAAe;AAClB,YAAM,IAAIK,MAAO,OAAA;AAAA,QACf,kBAAkB,QAAQ,iCAAiC,SAAS;AAAA,MAAA;AAAA,IAExE;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,UACA,WACA;AACA,UAAM,gBAAgB,MAAML,QAAO,GAAG,MAAM,wBAAwB,EAAE,OAAO;AAAA,MAC3E,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,IAAA,CACD;AAED,QAAI,CAAC,eAAe;AAClB,YAAM,IAAIK,MAAO,OAAA;AAAA,QACf,kBAAkB,QAAQ,iCAAiC,SAAS;AAAA,MAAA;AAAA,IAExE;AAEO,WAAA;AAAA,EACT;AACF;AC7YA,MAAM,iCAAiC,CAAC,EAAE,QAAAL,eAAwC;AAAA,EAChF,MAAM,oBACJ,WACA,mBACA;AAKA,UAAMC,WAAW,MAAMD,QAAO,cAAc,QAAQ,mBAAmB,WAAW;AAAA,MAChF,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAA,IAAM;AAAA,IAAA,CAClE;AAED,QAAI,CAACC,UAAS;AACZ,YAAM,IAAII,MAAA,OAAO,cAAc,2BAA2B,SAAS,EAAE;AAAA,IACvE;AAEM,UAAA,mBAAmBJ,SAAQ,QAAQ;AAAA,MACvC,CAAC,WACC,OAAO,OAAO,MAAM,EAAE,MAAM,OAAO,kBAAkB,MAAM,EAAE,KAC7D,OAAO,gBAAgB,kBAAkB,MAAM;AAAA,IAAA;AAGnD,QAAI,kBAAkB;AACpB,YAAM,IAAII,MAAO,OAAA;AAAA,QACf,iBAAiB,kBAAkB,MAAM,EAAE,oBAAoB,kBAAkB,MAAM,WAAW,sCAAsC,SAAS;AAAA,MAAA;AAAA,IAErJ;AAAA,EACF;AAAA,EACA,yBACE,gBACA;AACM,UAAA,cAAcL,QAAO,YAAY,cAAc;AAErD,QAAI,CAAC,aAAa;AAChB,YAAM,IAAIK,MAAA,OAAO,cAAc,iCAAiC,cAAc,EAAE;AAAA,IAClF;AAGI,QAAA,CAAC,YAAY,SAAS,iBAAiB;AACzC,YAAM,IAAIA,MAAO,OAAA;AAAA,QACf,yBAAyB,cAAc;AAAA,MAAA;AAAA,IAE3C;AAAA,EACF;AACF;AChDO,MAAM,WAAW,EAAEJ,SAAAA,sBAAS,sBAAsBK,+BAAkB;ACDpE,MAAM,iBAAiBC,eAC3B,OAAO,EACP,MAAM;AAAA,EACL,MAAMA,eAAI,OAAS,EAAA,KAAA,EAAO,SAAS;AACrC,CAAC,EACA,SAAS,EACT,UAAU;ACLA,MAAA,kBAAkBC,wBAAkB,cAAc;ACgB/D,MAAM,oBAAoB;AAAA,EACxB,MAAM,SAAS,KAAkB;AAC/B,UAAM,qBAAqB,OAAO,MAAM,SAAS,WAAW,yBAAyB;AAAA,MACnF,SAAS,IAAI,MAAM;AAAA,MACnB,OAAO;AAAA,IAAA,CACR;AAEK,UAAA,mBAAmB,cAAc,IAAI,KAAK;AAEhD,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AAGvD,UAAM,gCAAgC,QAAQ,IAAI,OAAO,kBAAkB,IAAI,OAAO,OAAO;AAC7F,QAAI,+BAA+B;AACjC,YAAM,QACJ,MAAM,mBAAmB,cAAc,IAAI,KAAK;AAElD,YAAM,iBAAiB,MAAM;AAC7B,YAAM,UAAU,MAAM;AAEhB,YAAA,mBACJ,OAAO,MAAM,qBAAqB,WAAW,KAAK,MAAM,MAAM,gBAAgB,IAAI;AAEpF,YAAM,OAAO,MAAM,eAAe,4BAA4B,gBAAgB,SAAS;AAAA,QACrF;AAAA,MAAA,CACD;AAEG,UAAA,OAAO,EAAE;IAAK,OACb;AACL,YAAM,QAAsC,MAAM,mBAAmB,cAAc,IAAI,KAAK;AAC5F,YAAM,EAAE,SAAS,eAAe,MAAM,eAAe,SAAS,KAAK;AAEnE,YAAM,OAAO,QAAQ,IAAI,CAACP,aAAyC;AACjE,cAAM,EAAE,SAAS,GAAG,YAAA,IAAgBA;AAE7B,eAAA;AAAA,UACL,GAAG;AAAA,UACH,SAAS;AAAA,YACP,MAAM;AAAA,cACJ,OAAO,QAAQ;AAAA,YACjB;AAAA,UACF;AAAA,QAAA;AAAA,MACF,CACD;AAED,UAAI,OAAO,EAAE,MAAM,MAAM,EAAE;IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,KAAkB;AACxB,UAAA,KAAyC,IAAI,OAAO;AAE1D,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AAEjD,UAAAA,WAAU,MAAM,eAAe,QAAQ,IAAI,EAAE,UAAU,CAAC,WAAW,EAAA,CAAG;AAC5E,UAAM,qBAAqB,OAAO,MAAM,SAAS,WAAW,yBAAyB;AAAA,MACnF,SAAS,IAAI,MAAM;AAAA,MACnB,OAAO;AAAA,IAAA,CACR;AACD,UAAM,mBAAmB,MAAM,mBAAmB,eAAeA,QAAO;AAElE,UAAA,QAAQ,MAAM,eAAe,aAAa;AAAA,MAC9C,SAAS;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IAAA,CACD;AAED,QAAI,CAACA,UAAS;AACZ,YAAM,IAAII,MAAA,OAAO,cAAc,6BAA6B,EAAE,EAAE;AAAA,IAClE;AAGA,UAAM,OAAO;AAAA,MACX,GAAG;AAAA,MACH,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAAA,IAAA;AAGE,QAAA,OAAO,EAAE;EACf;AAAA,EAEA,MAAM,OAAO,KAAkB;AACvB,UAAA,OAAiB,IAAI,MAAM;AAC3B,UAAA,cAA6C,IAAI,QAAQ;AAE/D,UAAM,gBAAgB,WAAW;AAEjC,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACvD,UAAMJ,WAAU,MAAM,eAAe,OAAO,aAAa,EAAE,MAAM;AAEjE,UAAM,qBAAqB,OAAO,MAAM,SAAS,WAAW,yBAAyB;AAAA,MACnF,SAAS,IAAI,MAAM;AAAA,MACnB,OAAO;AAAA,IAAA,CACR;AAED,QAAI,OAAO;AAAA,MACT,MAAM,MAAM,mBAAmB,eAAeA,QAAO;AAAA,IAAA;AAAA,EAEzD;AAAA,EAEA,MAAM,OAAO,KAAkB;AACvB,UAAA,OAAiB,IAAI,MAAM;AAC3B,UAAA,cAA6C,IAAI,QAAQ;AACzD,UAAA,KAA4C,IAAI,OAAO;AAE7D,UAAM,gBAAgB,WAAW;AAEjC,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACjD,UAAAA,WAAU,MAAM,eAAe,OAAO,IAAI,aAAa,EAAE,MAAM;AAErE,UAAM,qBAAqB,OAAO,MAAM,SAAS,WAAW,yBAAyB;AAAA,MACnF,SAAS,IAAI,MAAM;AAAA,MACnB,OAAO;AAAA,IAAA,CACR;AAED,QAAI,OAAO;AAAA,MACT,MAAM,MAAM,mBAAmB,eAAeA,QAAO;AAAA,IAAA;AAAA,EAEzD;AAAA,EAEA,MAAM,OAAO,KAAkB;AACvB,UAAA,KAA4C,IAAI,OAAO;AAE7D,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACvD,UAAMA,WAAU,MAAM,eAAe,OAAO,EAAE;AAE9C,QAAI,OAAO;AAAA,MACT,MAAMA;AAAA,IAAA;AAAA,EAEV;AAAA,EAEA,MAAM,QAAQ,KAAkB;AACxB,UAAA,OAAgD,IAAI,MAAM;AAC1D,UAAA,KAA6C,IAAI,OAAO;AAE9D,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACvD,UAAMA,WAAU,MAAM,eAAe,QAAQ,IAAI,EAAE,MAAM;AAEzD,QAAI,OAAO;AAAA,MACT,MAAMA;AAAA,IAAA;AAAA,EAEV;AACF;AClKA,MAAM,wBAAwBM,MAAA,IAAI,OAAO,EAAE,MAAM;AAAA,EAC/C,OAAOA,MAAA,IACJ,OAAO,EACP,MAAM;AAAA,IACL,IAAIA,MAAA,IAAI,SAAS,EAAE,SAAS;AAAA,IAC5B,aAAaA,MAAA,IAAI,OAAO,EAAE,SAAS;AAAA,EACpC,CAAA,EACA,SAAS;AAAA,EACZ,MAAMA,MAAAA,IAAI,SAAS,MAAM,CAAC,WAAW,WAAW,CAAC,EAAE,SAAS;AAC9D,CAAC;AAED,MAAM,+BAA+BA,MAAA,IAAI,OAAO,EAAE,MAAM;AAAA,EACtD,MAAMA,MAAAA,IAAI,SAAS,MAAM,CAAC,WAAW,WAAW,CAAC,EAAE,SAAS;AAC9D,CAAC;AAEY,MAAA,wBAAwBC,MAAAA,kBAAkB,qBAAqB;AAC/D,MAAA,oCAAoCA,wBAAkB,4BAA4B;ACQ/F,MAAM,0BAA0B;AAAA,EAC9B,MAAM,OAAO,KAAkB;AACvB,UAAA,YAAgE,IAAI,OAAO;AAC3E,UAAA,oBAAyD,IAAI,QAAQ;AAE3E,UAAM,sBAAsB,iBAAiB;AAE7C,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACvD,UAAML,iBAAgB,MAAM,eAAe,aAAa,WAAW,iBAAiB;AAEpF,QAAI,OAAO;AAAA,MACT,MAAMA;AAAA,IAAA;AAAA,EAEV;AAAA,EACA,MAAM,SAAS,KAAkB;AACzB,UAAA,YAA8D,IAAI,OAAO;AAC/E,UAAM,qBAAqB,OAAO,MAAM,SAAS,WAAW,yBAAyB;AAAA,MACnF,SAAS,IAAI,MAAM;AAAA,MACnB,OAAO;AAAA,IAAA,CACR;AACD,UAAM,QAAQ,MAAM,mBAAmB,cAAc,IAAI,KAAK;AAE9D,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACjD,UAAA,EAAE,SAAS,eAAe,MAAM,eAAe,YAAY,WAAW,KAAK;AAC3E,UAAA,mCAAmC,MAAM,eAAe;AAAA,MAC5D;AAAA,IAAA;AAGI,UAAA,aAAuB,MAAM,OAAO,OAAO,MAAM,EAAE,QAAQ,SAAS,EAAE;AAC5E,UAAM,uBAAuB,WAAW,OAAyB,CAAC,KAAK,WAAW;AAC5E,UAAA,OAAO,IAAI,IAAI,EAAE,MAAM,OAAO,MAAM,MAAM,OAAO;AAE9C,aAAA;AAAA,IACT,GAAG,CAAE,CAAA;AAEL,UAAM,OAAO,QAAQ,IAAI,CAAC,WAA0B;AAClD,YAAM,EAAE,WAAW,YAAA,IAAgB,iCAAiC,OAAO,WAAW;AAE/E,aAAA;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,UACL,IAAI,OAAO,MAAM;AAAA,UACjB,aAAa;AAAA,YACX;AAAA,YACA,gBAAgB,OAAO,MAAM,SAAS;AAAA,UACxC;AAAA,UACA,QAAQ,qBAAqB,OAAO,MAAM,MAAM;AAAA,QAClD;AAAA,MAAA;AAAA,IACF,CACD;AAED,QAAI,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAM,OAAO,KAAkB;AACvB,UAAA,WAA8D,IAAI,OAAO;AACzE,UAAA,YAAgE,IAAI,OAAO;AAC3E,UAAA,0BAA+D,IAAI,QAAQ;AAEjF,UAAM,kCAAkC,uBAAuB;AAE/D,UAAM,iBAAiB,WAAW,WAAW,EAAE,OAAQ,CAAA;AACjD,UAAA,gBAAgB,MAAM,eAAe;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,OAAO;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EAEV;AAAA,EAEA,MAAM,OAAO,KAAkB;AACvB,UAAA,WAA8D,IAAI,OAAO;AACzE,UAAA,YAAgE,IAAI,OAAO;AAEjF,UAAM,uBAAuB,MAAM,WAAW,WAAW,EAAE,OAAQ,CAAA,EAAE;AAAA,MACnE;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,OAAO;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EAEV;AACF;AClHO,MAAM,cAAc,EAAEF,SAAAA,mBAAS,kBAAkBE,wBAAc;ACHtE,MAAe,UAAA;AAAA,EACb,MAAM;AAAA,EACN,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,iCAAiC;AAAA,YAC7C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,+BAA+B;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,+BAA+B;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,iCAAiC;AAAA,YAC7C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,iCAAiC;AAAA,YAC7C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,kCAAkC;AAAA,YAC9C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;ACpGA,MAAe,gBAAA;AAAA,EACb,MAAM;AAAA,EACN,QAAQ;AAAA,IACN;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,wCAAwC;AAAA,YACpD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,+BAA+B;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,iCAAiC;AAAA,YAC7C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN,SAAS,CAAC,wCAAwC;AAAA,YACpD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;ACjEO,MAAM,SAAS;AAAA,EACpB;AAAA,EACA,kBAAkB;AACpB;ACCA,MAAM,EAAE,SAAa,IAAA,QAAQ,8BAA8B;AAE3D,MAAM,YAAY,MAAM;AAEpB,MAAA,SAAS,UAAU,sBAAsB,KACzC,OAAO,SAAS,OAAO,UAAU,iBAAiB,GAClD;AACO,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAGO,SAAA;AAAA,IACL;AAAA,EAAA;AAEJ;AAEA,MAAA,QAAe,UAAU;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../server/src/constants.ts","../../server/src/register.ts","../../server/src/content-types/release/schema.ts","../../server/src/content-types/release/index.ts","../../server/src/content-types/release-action/schema.ts","../../server/src/content-types/release-action/index.ts","../../server/src/content-types/index.ts","../../server/src/utils/index.ts","../../server/src/services/release.ts","../../server/src/services/validation.ts","../../server/src/services/index.ts","../../shared/validation-schemas.ts","../../server/src/controllers/validation/release.ts","../../server/src/controllers/release.ts","../../server/src/controllers/validation/release-action.ts","../../server/src/controllers/release-action.ts","../../server/src/controllers/index.ts","../../server/src/routes/release.ts","../../server/src/routes/release-action.ts","../../server/src/routes/index.ts","../../server/src/index.ts"],"sourcesContent":["export const RELEASE_MODEL_UID = 'plugin::content-releases.release';\nexport const RELEASE_ACTION_MODEL_UID = 'plugin::content-releases.release-action';\n\nexport const ACTIONS = [\n {\n section: 'plugins',\n displayName: 'Read',\n uid: 'read',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Create',\n uid: 'create',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Edit',\n uid: 'update',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Delete',\n uid: 'delete',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Publish',\n uid: 'publish',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Remove an entry from a release',\n uid: 'delete-action',\n pluginName: 'content-releases',\n },\n {\n section: 'plugins',\n displayName: 'Add an entry to a release',\n uid: 'create-action',\n pluginName: 'content-releases',\n },\n];\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport type { LoadedStrapi } from '@strapi/types';\nimport { ACTIONS } from './constants';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nexport const register = async ({ strapi }: { strapi: LoadedStrapi }) => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);\n }\n};\n","import { RELEASE_ACTION_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_releases',\n info: {\n singularName: 'release',\n pluralName: 'releases',\n displayName: 'Release',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n required: true,\n },\n releasedAt: {\n type: 'datetime',\n },\n actions: {\n type: 'relation',\n relation: 'oneToMany',\n target: RELEASE_ACTION_MODEL_UID,\n mappedBy: 'release',\n },\n },\n};\n","import schema from './schema';\n\nexport const release = {\n schema,\n};\n","import { RELEASE_MODEL_UID } from '../../constants';\n\nexport default {\n collectionName: 'strapi_release_actions',\n info: {\n singularName: 'release-action',\n pluralName: 'release-actions',\n displayName: 'Release Action',\n },\n options: {\n draftAndPublish: false,\n },\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n type: {\n type: 'enumeration',\n enum: ['publish', 'unpublish'],\n required: true,\n },\n entry: {\n type: 'relation',\n relation: 'morphToOne',\n configurable: false,\n },\n contentType: {\n type: 'string',\n required: true,\n },\n locale: {\n type: 'string',\n },\n release: {\n type: 'relation',\n relation: 'manyToOne',\n target: RELEASE_MODEL_UID,\n inversedBy: 'actions',\n },\n },\n};\n","import schema from './schema';\n\nexport const releaseAction = {\n schema,\n};\n","import { release } from './release';\nimport { releaseAction } from './release-action';\n\nexport const contentTypes = {\n release,\n 'release-action': releaseAction,\n};\n","export const getService = (\n name: 'release' | 'release-validation',\n { strapi } = { strapi: global.strapi }\n) => {\n return strapi.plugin('content-releases').service(name);\n};\n","import { setCreatorFields, errors } from '@strapi/utils';\n\nimport type { LoadedStrapi, EntityService, UID } from '@strapi/types';\n\nimport _ from 'lodash/fp';\nimport { RELEASE_ACTION_MODEL_UID, RELEASE_MODEL_UID } from '../constants';\nimport type {\n GetReleases,\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n} from '../../../shared/contracts/releases';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n ReleaseAction,\n UpdateReleaseAction,\n DeleteReleaseAction,\n ReleaseActionGroupBy,\n} from '../../../shared/contracts/release-actions';\nimport type { Entity, UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\ninterface Locale extends Entity {\n name: string;\n code: string;\n}\n\ntype LocaleDictionary = {\n [key: Locale['code']]: Pick<Locale, 'name' | 'code'>;\n};\n\nconst getGroupName = (queryValue?: ReleaseActionGroupBy) => {\n switch (queryValue) {\n case 'contentType':\n return 'entry.contentType.displayName';\n case 'action':\n return 'type';\n case 'locale':\n return _.getOr('No locale', 'entry.locale.name');\n default:\n return 'entry.contentType.displayName';\n }\n};\n\nconst createReleaseService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async create(releaseData: CreateRelease.Request['body'], { user }: { user: UserInfo }) {\n const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);\n\n return strapi.entityService.create(RELEASE_MODEL_UID, {\n data: releaseWithCreatorFields,\n });\n },\n\n async findOne(id: GetRelease.Request['params']['id'], query = {}) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, id, {\n ...query,\n });\n\n return release;\n },\n\n findPage(query?: GetReleases.Request['query']) {\n return strapi.entityService.findPage(RELEASE_MODEL_UID, {\n ...query,\n populate: {\n actions: {\n // @ts-expect-error Ignore missing properties\n count: true,\n },\n },\n });\n },\n\n async findManyForContentTypeEntry(\n contentTypeUid: GetContentTypeEntryReleases.Request['query']['contentTypeUid'],\n entryId: GetContentTypeEntryReleases.Request['query']['entryId'],\n {\n hasEntryAttached,\n }: { hasEntryAttached?: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] } = {\n hasEntryAttached: false,\n }\n ) {\n const whereActions = hasEntryAttached\n ? {\n // Find all Releases where the content type entry is present\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n }\n : {\n // Find all Releases where the content type entry is not present\n $or: [\n {\n $not: {\n actions: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n },\n {\n actions: null,\n },\n ],\n };\n const populateAttachedAction = hasEntryAttached\n ? {\n // Filter the action to get only the content type entry\n actions: {\n where: {\n target_type: contentTypeUid,\n target_id: entryId,\n },\n },\n }\n : {};\n\n const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({\n where: {\n ...whereActions,\n releasedAt: {\n $null: true,\n },\n },\n populate: {\n ...populateAttachedAction,\n },\n });\n\n return releases.map((release) => {\n if (release.actions?.length) {\n const [actionForEntry] = release.actions;\n\n // Remove the actions key to replace it with an action key\n delete release.actions;\n\n return {\n ...release,\n action: actionForEntry,\n };\n }\n\n return release;\n });\n },\n\n async update(\n id: number,\n releaseData: UpdateRelease.Request['body'],\n { user }: { user: UserInfo }\n ) {\n const updatedRelease = await setCreatorFields({ user, isEdition: true })(releaseData);\n\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, id, {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">>\n * is not compatible with the type we are passing here: UpdateRelease.Request['body']\n */\n // @ts-expect-error see above\n data: updatedRelease,\n });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${id}`);\n }\n\n return release;\n },\n\n async createAction(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n action: Pick<CreateReleaseAction.Request['body'], 'type' | 'entry'>\n ) {\n const { validateEntryContentType, validateUniqueEntry } = getService('release-validation', {\n strapi,\n });\n\n await Promise.all([\n validateEntryContentType(action.entry.contentType),\n validateUniqueEntry(releaseId, action),\n ]);\n\n const { entry, type } = action;\n\n return strapi.entityService.create(RELEASE_ACTION_MODEL_UID, {\n data: {\n type,\n contentType: entry.contentType,\n locale: entry.locale,\n entry: {\n id: entry.id,\n __type: entry.contentType,\n __pivot: { field: 'entry' },\n },\n release: releaseId,\n },\n populate: { release: { fields: ['id'] }, entry: { fields: ['id'] } },\n });\n },\n\n async findActions(\n releaseId: GetReleaseActions.Request['params']['releaseId'],\n query?: GetReleaseActions.Request['query']\n ) {\n const release = await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n fields: ['id'],\n });\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n return strapi.entityService.findPage(RELEASE_ACTION_MODEL_UID, {\n ...query,\n populate: {\n entry: true,\n },\n filters: {\n release: releaseId,\n },\n });\n },\n\n async countActions(query: EntityService.Params.Pick<typeof RELEASE_ACTION_MODEL_UID, 'filters'>) {\n return strapi.entityService.count(RELEASE_ACTION_MODEL_UID, query);\n },\n\n async groupActions(actions: ReleaseAction[], groupBy: ReleaseActionGroupBy) {\n const contentTypeUids = actions.reduce<ReleaseAction['contentType'][]>((acc, action) => {\n if (!acc.includes(action.contentType)) {\n acc.push(action.contentType);\n }\n\n return acc;\n }, []);\n const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(\n contentTypeUids\n );\n const allLocales: Locale[] = await strapi.plugin('i18n').service('locales').find();\n const allLocalesDictionary = allLocales.reduce<LocaleDictionary>((acc, locale) => {\n acc[locale.code] = { name: locale.name, code: locale.code };\n\n return acc;\n }, {});\n\n const formattedData = actions.map((action: ReleaseAction) => {\n const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];\n\n return {\n ...action,\n entry: {\n id: action.entry.id,\n contentType: {\n displayName,\n mainFieldValue: action.entry[mainField],\n },\n locale: action.locale ? allLocalesDictionary[action.locale] : null,\n status: action.entry.publishedAt ? 'published' : 'draft',\n },\n };\n });\n\n const groupName = getGroupName(groupBy);\n return _.groupBy(groupName)(formattedData);\n },\n\n async getContentTypesDataForActions(contentTypesUids: ReleaseAction['contentType'][]) {\n const contentManagerContentTypeService = strapi\n .plugin('content-manager')\n .service('content-types');\n\n const contentTypesData: Record<UID.ContentType, { mainField: string; displayName: string }> =\n {};\n for (const contentTypeUid of contentTypesUids) {\n const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({\n uid: contentTypeUid,\n });\n\n contentTypesData[contentTypeUid] = {\n mainField: contentTypeConfig.settings.mainField,\n displayName: strapi.getModel(contentTypeUid).info.displayName,\n };\n }\n\n return contentTypesData;\n },\n\n async delete(releaseId: DeleteRelease.Request['params']['id']) {\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: {\n actions: {\n fields: ['id'],\n },\n },\n })) as unknown as Release;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (release.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n // Only delete the release and its actions is you in fact can delete all the actions and the release\n // Otherwise, if the transaction fails it throws an error\n await strapi.db.transaction(async () => {\n await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({\n where: {\n id: {\n $in: release.actions.map((action) => action.id),\n },\n },\n });\n await strapi.entityService.delete(RELEASE_MODEL_UID, releaseId);\n });\n\n return release;\n },\n\n async publish(releaseId: PublishRelease.Request['params']['id']) {\n // We need to pass the type because entityService.findOne is not returning the correct type\n const releaseWithPopulatedActionEntries = (await strapi.entityService.findOne(\n RELEASE_MODEL_UID,\n releaseId,\n {\n populate: {\n actions: {\n populate: {\n entry: true,\n },\n },\n },\n }\n )) as unknown as Release;\n\n if (!releaseWithPopulatedActionEntries) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n if (releaseWithPopulatedActionEntries.releasedAt) {\n throw new errors.ValidationError('Release already published');\n }\n\n if (releaseWithPopulatedActionEntries.actions.length === 0) {\n throw new errors.ValidationError('No entries to publish');\n }\n\n /**\n * We separate publish and unpublish actions group by content type\n */\n const actions: {\n [key: UID.ContentType]: {\n publish: ReleaseAction['entry'][];\n unpublish: ReleaseAction['entry'][];\n };\n } = {};\n for (const action of releaseWithPopulatedActionEntries.actions) {\n const contentTypeUid = action.contentType;\n\n if (!actions[contentTypeUid]) {\n actions[contentTypeUid] = {\n publish: [],\n unpublish: [],\n };\n }\n\n if (action.type === 'publish') {\n actions[contentTypeUid].publish.push(action.entry);\n } else {\n actions[contentTypeUid].unpublish.push(action.entry);\n }\n }\n\n const entityManagerService = strapi.plugin('content-manager').service('entity-manager');\n\n // Only publish the release if all action updates are applied successfully to their entry, otherwise leave everything as is\n await strapi.db.transaction(async () => {\n for (const contentTypeUid of Object.keys(actions)) {\n const { publish, unpublish } = actions[contentTypeUid as UID.ContentType];\n\n if (publish.length > 0) {\n await entityManagerService.publishMany(publish, contentTypeUid);\n }\n\n if (unpublish.length > 0) {\n await entityManagerService.unpublishMany(unpublish, contentTypeUid);\n }\n }\n });\n\n // When the transaction fails it throws an error, when it is successful proceed to updating the release\n const release = await strapi.entityService.update(RELEASE_MODEL_UID, releaseId, {\n data: {\n /*\n * The type returned from the entity service: Partial<Input<\"plugin::content-releases.release\">> looks like it's wrong\n */\n // @ts-expect-error see above\n releasedAt: new Date(),\n },\n });\n\n return release;\n },\n\n async updateAction(\n actionId: UpdateReleaseAction.Request['params']['actionId'],\n releaseId: UpdateReleaseAction.Request['params']['releaseId'],\n update: UpdateReleaseAction.Request['body']\n ) {\n const updatedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({\n where: {\n id: actionId,\n release: releaseId,\n },\n data: update,\n });\n\n if (!updatedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId}`\n );\n }\n\n return updatedAction;\n },\n\n async deleteAction(\n actionId: DeleteReleaseAction.Request['params']['actionId'],\n releaseId: DeleteReleaseAction.Request['params']['releaseId']\n ) {\n const deletedAction = await strapi.db.query(RELEASE_ACTION_MODEL_UID).delete({\n where: {\n id: actionId,\n release: releaseId,\n },\n });\n\n if (!deletedAction) {\n throw new errors.NotFoundError(\n `Action with id ${actionId} not found in release with id ${releaseId}`\n );\n }\n\n return deletedAction;\n },\n});\n\nexport default createReleaseService;\n","import { errors } from '@strapi/utils';\nimport { LoadedStrapi } from '@strapi/types';\nimport type { Release } from '../../../shared/contracts/releases';\nimport type { CreateReleaseAction } from '../../../shared/contracts/release-actions';\nimport { RELEASE_MODEL_UID } from '../constants';\n\nconst createReleaseValidationService = ({ strapi }: { strapi: LoadedStrapi }) => ({\n async validateUniqueEntry(\n releaseId: CreateReleaseAction.Request['params']['releaseId'],\n releaseActionArgs: CreateReleaseAction.Request['body']\n ) {\n /**\n * Asserting the type, otherwise TS complains: 'release.actions' is of type 'unknown', even though the types come through for non-populated fields...\n * Possibly related to the comment on GetValues: https://github.com/strapi/strapi/blob/main/packages/core/types/src/modules/entity-service/result.ts\n */\n const release = (await strapi.entityService.findOne(RELEASE_MODEL_UID, releaseId, {\n populate: { actions: { populate: { entry: { fields: ['id'] } } } },\n })) as Release | null;\n\n if (!release) {\n throw new errors.NotFoundError(`No release found for id ${releaseId}`);\n }\n\n const isEntryInRelease = release.actions.some(\n (action) =>\n Number(action.entry.id) === Number(releaseActionArgs.entry.id) &&\n action.contentType === releaseActionArgs.entry.contentType\n );\n\n if (isEntryInRelease) {\n throw new errors.ValidationError(\n `Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`\n );\n }\n },\n validateEntryContentType(\n contentTypeUid: CreateReleaseAction.Request['body']['entry']['contentType']\n ) {\n const contentType = strapi.contentType(contentTypeUid);\n\n if (!contentType) {\n throw new errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);\n }\n\n // TODO: V5 migration - All contentType will have draftAndPublish enabled\n if (!contentType.options?.draftAndPublish) {\n throw new errors.ValidationError(\n `Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`\n );\n }\n },\n});\n\nexport default createReleaseValidationService;\n","import release from './release';\nimport releaseValidation from './validation';\n\nexport const services = { release, 'release-validation': releaseValidation };\n","import * as yup from 'yup';\n\nexport const RELEASE_SCHEMA = yup\n .object()\n .shape({\n name: yup.string().trim().required(),\n })\n .required()\n .noUnknown();\n","import { validateYupSchema } from '@strapi/utils';\nimport { RELEASE_SCHEMA } from '../../../../shared/validation-schemas';\n\nexport const validateRelease = validateYupSchema(RELEASE_SCHEMA);\n","import type Koa from 'koa';\nimport { errors } from '@strapi/utils';\nimport { RELEASE_MODEL_UID } from '../constants';\nimport { validateRelease } from './validation/release';\nimport type {\n CreateRelease,\n UpdateRelease,\n PublishRelease,\n GetRelease,\n Release,\n DeleteRelease,\n GetContentTypeEntryReleases,\n GetReleases,\n} from '../../../shared/contracts/releases';\nimport type { UserInfo } from '../../../shared/types';\nimport { getService } from '../utils';\n\ntype ReleaseWithPopulatedActions = Release & { actions: { count: number } };\n\nconst releaseController = {\n async findMany(ctx: Koa.Context) {\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n\n // Handle requests for releases filtered by content type entry\n const isFindManyForContentTypeEntry = Boolean(ctx.query?.contentTypeUid && ctx.query?.entryId);\n if (isFindManyForContentTypeEntry) {\n const query: GetContentTypeEntryReleases.Request['query'] =\n await permissionsManager.sanitizeQuery(ctx.query);\n\n const contentTypeUid = query.contentTypeUid;\n const entryId = query.entryId;\n // Parse the string value or fallback to a default\n const hasEntryAttached: GetContentTypeEntryReleases.Request['query']['hasEntryAttached'] =\n typeof query.hasEntryAttached === 'string' ? JSON.parse(query.hasEntryAttached) : false;\n\n const data = await releaseService.findManyForContentTypeEntry(contentTypeUid, entryId, {\n hasEntryAttached,\n });\n\n ctx.body = { data };\n } else {\n const query: GetReleases.Request['query'] = await permissionsManager.sanitizeQuery(ctx.query);\n const { results, pagination } = await releaseService.findPage(query);\n\n const data = results.map((release: ReleaseWithPopulatedActions) => {\n const { actions, ...releaseData } = release;\n\n return {\n ...releaseData,\n actions: {\n meta: {\n count: actions.count,\n },\n },\n };\n });\n\n ctx.body = { data, meta: { pagination } };\n }\n },\n\n async findOne(ctx: Koa.Context) {\n const id: GetRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n\n const release = await releaseService.findOne(id, { populate: ['createdBy'] });\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n const sanitizedRelease = await permissionsManager.sanitizeOutput(release);\n\n const count = await releaseService.countActions({\n filters: {\n release: id,\n },\n });\n\n if (!release) {\n throw new errors.NotFoundError(`Release not found for id: ${id}`);\n }\n\n // Format the data object\n const data = {\n ...sanitizedRelease,\n actions: {\n meta: {\n count,\n },\n },\n };\n\n ctx.body = { data };\n },\n\n async create(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: CreateRelease.Request['body'] = ctx.request.body;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.create(releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async update(ctx: Koa.Context) {\n const user: UserInfo = ctx.state.user;\n const releaseArgs: UpdateRelease.Request['body'] = ctx.request.body;\n const id: UpdateRelease.Request['params']['id'] = ctx.params.id;\n\n await validateRelease(releaseArgs);\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.update(id, releaseArgs, { user });\n\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_MODEL_UID,\n });\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(release),\n };\n },\n\n async delete(ctx: Koa.Context) {\n const id: DeleteRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.delete(id);\n\n ctx.body = {\n data: release,\n };\n },\n\n async publish(ctx: Koa.Context) {\n const user: PublishRelease.Request['state']['user'] = ctx.state.user;\n const id: PublishRelease.Request['params']['id'] = ctx.params.id;\n\n const releaseService = getService('release', { strapi });\n const release = await releaseService.publish(id, { user });\n\n ctx.body = {\n data: release,\n };\n },\n};\n\nexport default releaseController;\n","import { yup, validateYupSchema } from '@strapi/utils';\n\nconst RELEASE_ACTION_SCHEMA = yup.object().shape({\n entry: yup\n .object()\n .shape({\n id: yup.strapiID().required(),\n contentType: yup.string().required(),\n })\n .required(),\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nconst RELEASE_ACTION_UPDATE_SCHEMA = yup.object().shape({\n type: yup.string().oneOf(['publish', 'unpublish']).required(),\n});\n\nexport const validateReleaseAction = validateYupSchema(RELEASE_ACTION_SCHEMA);\nexport const validateReleaseActionUpdateSchema = validateYupSchema(RELEASE_ACTION_UPDATE_SCHEMA);\n","import type Koa from 'koa';\n\nimport {\n validateReleaseAction,\n validateReleaseActionUpdateSchema,\n} from './validation/release-action';\nimport type {\n CreateReleaseAction,\n GetReleaseActions,\n UpdateReleaseAction,\n DeleteReleaseAction,\n} from '../../../shared/contracts/release-actions';\nimport { getService } from '../utils';\nimport { RELEASE_ACTION_MODEL_UID } from '../constants';\n\nconst releaseActionController = {\n async create(ctx: Koa.Context) {\n const releaseId: CreateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionArgs: CreateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseAction(releaseActionArgs);\n\n const releaseService = getService('release', { strapi });\n const releaseAction = await releaseService.createAction(releaseId, releaseActionArgs);\n\n ctx.body = {\n data: releaseAction,\n };\n },\n\n async findMany(ctx: Koa.Context) {\n const releaseId: GetReleaseActions.Request['params']['releaseId'] = ctx.params.releaseId;\n const permissionsManager = strapi.admin.services.permission.createPermissionsManager({\n ability: ctx.state.userAbility,\n model: RELEASE_ACTION_MODEL_UID,\n });\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const releaseService = getService('release', { strapi });\n const { results, pagination } = await releaseService.findActions(releaseId, {\n sort: query.groupBy === 'action' ? 'type' : query.groupBy,\n ...query,\n });\n const groupedData = await releaseService.groupActions(results, query.groupBy);\n\n ctx.body = {\n data: groupedData,\n meta: {\n pagination,\n },\n };\n },\n\n async update(ctx: Koa.Context) {\n const actionId: UpdateReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: UpdateReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n const releaseActionUpdateArgs: UpdateReleaseAction.Request['body'] = ctx.request.body;\n\n await validateReleaseActionUpdateSchema(releaseActionUpdateArgs);\n\n const releaseService = getService('release', { strapi });\n const updatedAction = await releaseService.updateAction(\n actionId,\n releaseId,\n releaseActionUpdateArgs\n );\n\n ctx.body = {\n data: updatedAction,\n };\n },\n\n async delete(ctx: Koa.Context) {\n const actionId: DeleteReleaseAction.Request['params']['actionId'] = ctx.params.actionId;\n const releaseId: DeleteReleaseAction.Request['params']['releaseId'] = ctx.params.releaseId;\n\n const deletedReleaseAction = await getService('release', { strapi }).deleteAction(\n actionId,\n releaseId\n );\n\n ctx.body = {\n data: deletedReleaseAction,\n };\n },\n};\n\nexport default releaseActionController;\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const controllers = { release, 'release-action': releaseAction };\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/',\n handler: 'release.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/',\n handler: 'release.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:id',\n handler: 'release.findOne',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:id',\n handler: 'release.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:id',\n handler: 'release.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete'],\n },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/:id/publish',\n handler: 'release.publish',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.publish'],\n },\n },\n ],\n },\n },\n ],\n};\n","export default {\n type: 'admin',\n routes: [\n {\n method: 'POST',\n path: '/:releaseId/actions',\n handler: 'release-action.create',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.create-action'],\n },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/:releaseId/actions',\n handler: 'release-action.findMany',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.read'],\n },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.update',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.update'],\n },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/:releaseId/actions/:actionId',\n handler: 'release-action.delete',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'admin::hasPermissions',\n config: {\n actions: ['plugin::content-releases.delete-action'],\n },\n },\n ],\n },\n },\n ],\n};\n","import release from './release';\nimport releaseAction from './release-action';\n\nexport const routes = {\n release,\n 'release-action': releaseAction,\n};\n","/* eslint-disable @typescript-eslint/no-var-requires */\nimport { register } from './register';\nimport { contentTypes } from './content-types';\nimport { services } from './services';\nimport { controllers } from './controllers';\nimport { routes } from './routes';\n\nconst { features } = require('@strapi/strapi/dist/utils/ee');\n\nconst getPlugin = () => {\n if (\n features.isEnabled('cms-content-releases') &&\n strapi.features.future.isEnabled('contentReleases')\n ) {\n return {\n register,\n contentTypes,\n services,\n controllers,\n routes,\n };\n }\n\n // We keep returning contentTypes to avoid lost the data if feature is disabled\n return {\n contentTypes,\n };\n};\n\nexport default getPlugin();\n"],"names":["features","strapi","release","schema","releaseAction","_","setCreatorFields","errors","releaseValidation","yup","validateYupSchema"],"mappings":"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"}
|
package/dist/server/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { setCreatorFields, errors, validateYupSchema, yup as yup$1 } from "@strapi/utils";
|
|
2
|
+
import _ from "lodash/fp";
|
|
2
3
|
import * as yup from "yup";
|
|
3
4
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
4
5
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -122,6 +123,9 @@ const schema = {
|
|
|
122
123
|
type: "string",
|
|
123
124
|
required: true
|
|
124
125
|
},
|
|
126
|
+
locale: {
|
|
127
|
+
type: "string"
|
|
128
|
+
},
|
|
125
129
|
release: {
|
|
126
130
|
type: "relation",
|
|
127
131
|
relation: "manyToOne",
|
|
@@ -140,6 +144,18 @@ const contentTypes = {
|
|
|
140
144
|
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
141
145
|
return strapi2.plugin("content-releases").service(name);
|
|
142
146
|
};
|
|
147
|
+
const getGroupName = (queryValue) => {
|
|
148
|
+
switch (queryValue) {
|
|
149
|
+
case "contentType":
|
|
150
|
+
return "entry.contentType.displayName";
|
|
151
|
+
case "action":
|
|
152
|
+
return "type";
|
|
153
|
+
case "locale":
|
|
154
|
+
return _.getOr("No locale", "entry.locale.name");
|
|
155
|
+
default:
|
|
156
|
+
return "entry.contentType.displayName";
|
|
157
|
+
}
|
|
158
|
+
};
|
|
143
159
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
144
160
|
async create(releaseData, { user }) {
|
|
145
161
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
@@ -251,6 +267,7 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
251
267
|
data: {
|
|
252
268
|
type,
|
|
253
269
|
contentType: entry.contentType,
|
|
270
|
+
locale: entry.locale,
|
|
254
271
|
entry: {
|
|
255
272
|
id: entry.id,
|
|
256
273
|
__type: entry.contentType,
|
|
@@ -262,8 +279,10 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
262
279
|
});
|
|
263
280
|
},
|
|
264
281
|
async findActions(releaseId, query) {
|
|
265
|
-
const
|
|
266
|
-
|
|
282
|
+
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
283
|
+
fields: ["id"]
|
|
284
|
+
});
|
|
285
|
+
if (!release2) {
|
|
267
286
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
268
287
|
}
|
|
269
288
|
return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
|
|
@@ -279,18 +298,40 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
279
298
|
async countActions(query) {
|
|
280
299
|
return strapi2.entityService.count(RELEASE_ACTION_MODEL_UID, query);
|
|
281
300
|
},
|
|
282
|
-
async
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
301
|
+
async groupActions(actions, groupBy) {
|
|
302
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
303
|
+
if (!acc.includes(action.contentType)) {
|
|
304
|
+
acc.push(action.contentType);
|
|
305
|
+
}
|
|
306
|
+
return acc;
|
|
307
|
+
}, []);
|
|
308
|
+
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
309
|
+
contentTypeUids
|
|
310
|
+
);
|
|
311
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find();
|
|
312
|
+
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
313
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
314
|
+
return acc;
|
|
315
|
+
}, {});
|
|
316
|
+
const formattedData = actions.map((action) => {
|
|
317
|
+
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
318
|
+
return {
|
|
319
|
+
...action,
|
|
320
|
+
entry: {
|
|
321
|
+
id: action.entry.id,
|
|
322
|
+
contentType: {
|
|
323
|
+
displayName,
|
|
324
|
+
mainFieldValue: action.entry[mainField]
|
|
325
|
+
},
|
|
326
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
327
|
+
status: action.entry.publishedAt ? "published" : "draft"
|
|
287
328
|
}
|
|
288
|
-
|
|
289
|
-
})
|
|
290
|
-
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
const groupName = getGroupName(groupBy);
|
|
332
|
+
return _.groupBy(groupName)(formattedData);
|
|
291
333
|
},
|
|
292
|
-
async getContentTypesDataForActions(
|
|
293
|
-
const contentTypesUids = await this.getAllContentTypeUids(releaseId);
|
|
334
|
+
async getContentTypesDataForActions(contentTypesUids) {
|
|
294
335
|
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
295
336
|
const contentTypesData = {};
|
|
296
337
|
for (const contentTypeUid of contentTypesUids) {
|
|
@@ -595,31 +636,13 @@ const releaseActionController = {
|
|
|
595
636
|
});
|
|
596
637
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
597
638
|
const releaseService = getService("release", { strapi });
|
|
598
|
-
const { results, pagination } = await releaseService.findActions(releaseId,
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
);
|
|
602
|
-
const allLocales = await strapi.plugin("i18n").service("locales").find();
|
|
603
|
-
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
604
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
605
|
-
return acc;
|
|
606
|
-
}, {});
|
|
607
|
-
const data = results.map((action) => {
|
|
608
|
-
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
609
|
-
return {
|
|
610
|
-
...action,
|
|
611
|
-
entry: {
|
|
612
|
-
id: action.entry.id,
|
|
613
|
-
contentType: {
|
|
614
|
-
displayName,
|
|
615
|
-
mainFieldValue: action.entry[mainField]
|
|
616
|
-
},
|
|
617
|
-
locale: allLocalesDictionary[action.entry.locale]
|
|
618
|
-
}
|
|
619
|
-
};
|
|
639
|
+
const { results, pagination } = await releaseService.findActions(releaseId, {
|
|
640
|
+
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
641
|
+
...query
|
|
620
642
|
});
|
|
643
|
+
const groupedData = await releaseService.groupActions(results, query.groupBy);
|
|
621
644
|
ctx.body = {
|
|
622
|
-
data,
|
|
645
|
+
data: groupedData,
|
|
623
646
|
meta: {
|
|
624
647
|
pagination
|
|
625
648
|
}
|