@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.8c83c87960f2f5ddf95ae2f0acf849052f4a9ab4
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/LICENSE +18 -3
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-BgCLcjXO.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-BgCLcjXO.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage-DywpTZeV.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-DywpTZeV.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-BNjOAHNS.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-BNjOAHNS.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-CxRlP5if.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-CxRlP5if.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-BRewdTqE.js} +101 -51
- package/dist/_chunks/EditViewPage-BRewdTqE.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-CD_hqc1J.mjs} +102 -51
- package/dist/_chunks/EditViewPage-CD_hqc1J.mjs.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-BPkQ-3Ku.mjs} +631 -279
- package/dist/_chunks/Field-BPkQ-3Ku.mjs.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-DwvmENVf.js} +634 -283
- package/dist/_chunks/Field-DwvmENVf.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-Bpig5rch.js → Form-C_Gwv8P_.js} +55 -38
- package/dist/_chunks/Form-C_Gwv8P_.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-Czi0cf_2.mjs} +55 -37
- package/dist/_chunks/Form-Czi0cf_2.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-C1TKAig-.js} +175 -129
- package/dist/_chunks/History-C1TKAig-.js.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-CIQHyi4T.mjs} +176 -129
- package/dist/_chunks/History-CIQHyi4T.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-D-NGRLYu.js} +62 -51
- package/dist/_chunks/ListConfigurationPage-D-NGRLYu.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-DcZsfyEL.mjs} +63 -52
- package/dist/_chunks/ListConfigurationPage-DcZsfyEL.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-C10McTK1.mjs} +152 -128
- package/dist/_chunks/ListViewPage-C10McTK1.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-xv5IQoZp.js} +155 -132
- package/dist/_chunks/ListViewPage-xv5IQoZp.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-CPc0Cd3S.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-CPc0Cd3S.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-Dzw5Yj5u.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-Dzw5Yj5u.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-DAe5CDCC.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-DAe5CDCC.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-wfPBh2_0.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-wfPBh2_0.mjs.map} +1 -1
- package/dist/_chunks/Preview-B7LyGT_b.js +290 -0
- package/dist/_chunks/Preview-B7LyGT_b.js.map +1 -0
- package/dist/_chunks/Preview-BVFFm7uB.mjs +272 -0
- package/dist/_chunks/Preview-BVFFm7uB.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-BmYR1AjY.js} +76 -43
- package/dist/_chunks/Relations-BmYR1AjY.js.map +1 -0
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-JPhWxk-s.mjs} +76 -42
- package/dist/_chunks/Relations-JPhWxk-s.mjs.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-BK8Xyl5I.js} +35 -18
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-Dtk_ot79.mjs} +35 -18
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-Dtk_ot79.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-DzN3kBgx.js → index-C2Q_PLWj.js} +1165 -880
- package/dist/_chunks/index-C2Q_PLWj.js.map +1 -0
- package/dist/_chunks/{index-VHviNMeW.mjs → index-DLIkNVnQ.mjs} +1185 -900
- package/dist/_chunks/index-DLIkNVnQ.mjs.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-b91XRlD2.js → layout-7AsWJzZJ.js} +41 -24
- package/dist/_chunks/layout-7AsWJzZJ.js.map +1 -0
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-qE8qkNH_.mjs} +42 -24
- package/dist/_chunks/layout-qE8qkNH_.mjs.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-BsqxS6tR.mjs → relations-BjHH_1Am.mjs} +6 -7
- package/dist/_chunks/relations-BjHH_1Am.mjs.map +1 -0
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-EifVzf_2.js} +6 -7
- package/dist/_chunks/relations-EifVzf_2.js.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -20
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +616 -299
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +616 -298
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +15 -15
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
- package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
- package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -141,8 +141,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
141
141
|
};
|
142
142
|
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
143
143
|
if (Array.isArray(versionRelationData)) {
|
144
|
-
if (versionRelationData.length === 0)
|
145
|
-
return versionRelationData;
|
144
|
+
if (versionRelationData.length === 0) return versionRelationData;
|
146
145
|
const existingAndMissingRelations = await Promise.all(
|
147
146
|
versionRelationData.map((relation) => {
|
148
147
|
return strapi2.documents(attribute.target).findOne({
|
@@ -173,10 +172,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
172
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
173
|
};
|
175
174
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
175
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
176
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
177
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
178
|
const getLocaleDictionary = async () => {
|
178
|
-
if (!localesService)
|
179
|
-
return {};
|
179
|
+
if (!localesService) return {};
|
180
180
|
const locales = await localesService.find() || [];
|
181
181
|
return locales.reduce(
|
182
182
|
(acc, locale) => {
|
@@ -200,31 +200,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
200
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
201
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
202
|
};
|
203
|
-
const
|
203
|
+
const getComponentFields = (componentUID) => {
|
204
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
205
|
+
(fieldsAcc, [key, attribute]) => {
|
206
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
207
|
+
fieldsAcc.push(key);
|
208
|
+
}
|
209
|
+
return fieldsAcc;
|
210
|
+
},
|
211
|
+
[]
|
212
|
+
);
|
213
|
+
};
|
214
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
215
|
const model = strapi2.getModel(uid2);
|
205
216
|
const attributes = Object.entries(model.attributes);
|
217
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
218
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
219
|
switch (attribute.type) {
|
208
220
|
case "relation": {
|
221
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
222
|
+
if (isMorphRelation) {
|
223
|
+
break;
|
224
|
+
}
|
209
225
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
226
|
if (isVisible2) {
|
211
|
-
acc[attributeName] = {
|
227
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
212
228
|
}
|
213
229
|
break;
|
214
230
|
}
|
215
231
|
case "media": {
|
216
|
-
acc[attributeName] = {
|
232
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
217
233
|
break;
|
218
234
|
}
|
219
235
|
case "component": {
|
220
236
|
const populate = getDeepPopulate2(attribute.component);
|
221
|
-
acc[attributeName] = {
|
237
|
+
acc[attributeName] = {
|
238
|
+
populate,
|
239
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
240
|
+
};
|
222
241
|
break;
|
223
242
|
}
|
224
243
|
case "dynamiczone": {
|
225
244
|
const populatedComponents = (attribute.components || []).reduce(
|
226
245
|
(acc2, componentUID) => {
|
227
|
-
acc2[componentUID] = {
|
246
|
+
acc2[componentUID] = {
|
247
|
+
populate: getDeepPopulate2(componentUID),
|
248
|
+
[fieldSelector]: getComponentFields(componentUID)
|
249
|
+
};
|
228
250
|
return acc2;
|
229
251
|
},
|
230
252
|
{}
|
@@ -286,6 +308,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
286
308
|
getRelationRestoreValue,
|
287
309
|
getMediaRestoreValue,
|
288
310
|
getDefaultLocale,
|
311
|
+
isLocalizedContentType,
|
289
312
|
getLocaleDictionary,
|
290
313
|
getRetentionDays,
|
291
314
|
getVersionStatus,
|
@@ -308,7 +331,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
308
331
|
});
|
309
332
|
},
|
310
333
|
async findVersionsPage(params) {
|
311
|
-
const
|
334
|
+
const model = strapi2.getModel(params.query.contentType);
|
335
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
336
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
337
|
+
let locale = null;
|
338
|
+
if (isLocalizedContentType) {
|
339
|
+
locale = params.query.locale || defaultLocale;
|
340
|
+
}
|
312
341
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
342
|
query.findPage({
|
314
343
|
...params.query,
|
@@ -330,7 +359,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
330
359
|
const attributeValue = entry.data[attributeKey];
|
331
360
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
332
361
|
if (attributeSchema.type === "media") {
|
333
|
-
const permissionChecker2 = getService$
|
362
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
334
363
|
userAbility: params.state.userAbility,
|
335
364
|
model: "plugin::upload.file"
|
336
365
|
});
|
@@ -353,7 +382,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
353
382
|
if (userToPopulate == null) {
|
354
383
|
return null;
|
355
384
|
}
|
356
|
-
return strapi2.query("admin::user").findOne({
|
385
|
+
return strapi2.query("admin::user").findOne({
|
386
|
+
where: {
|
387
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
388
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
389
|
+
}
|
390
|
+
});
|
357
391
|
})
|
358
392
|
);
|
359
393
|
return {
|
@@ -366,7 +400,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
366
400
|
[attributeKey]: adminUsers
|
367
401
|
};
|
368
402
|
}
|
369
|
-
const permissionChecker2 = getService$
|
403
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
370
404
|
userAbility: params.state.userAbility,
|
371
405
|
model: attributeSchema.target
|
372
406
|
});
|
@@ -464,13 +498,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
464
498
|
}
|
465
499
|
};
|
466
500
|
};
|
501
|
+
const shouldCreateHistoryVersion = (context) => {
|
502
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
503
|
+
return false;
|
504
|
+
}
|
505
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
506
|
+
return false;
|
507
|
+
}
|
508
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
509
|
+
return false;
|
510
|
+
}
|
511
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
512
|
+
return false;
|
513
|
+
}
|
514
|
+
return true;
|
515
|
+
};
|
516
|
+
const getSchemas = (uid2) => {
|
517
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
518
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
519
|
+
(currentComponentSchemas, key) => {
|
520
|
+
const fieldSchema = attributesSchema[key];
|
521
|
+
if (fieldSchema.type === "component") {
|
522
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
523
|
+
return {
|
524
|
+
...currentComponentSchemas,
|
525
|
+
[fieldSchema.component]: componentSchema
|
526
|
+
};
|
527
|
+
}
|
528
|
+
return currentComponentSchemas;
|
529
|
+
},
|
530
|
+
{}
|
531
|
+
);
|
532
|
+
return {
|
533
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
534
|
+
componentsSchemas
|
535
|
+
};
|
536
|
+
};
|
467
537
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
538
|
const state = {
|
469
539
|
deleteExpiredJob: null,
|
470
540
|
isInitialized: false
|
471
541
|
};
|
472
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
473
|
-
const historyService = getService(strapi2, "history");
|
474
542
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
475
543
|
return {
|
476
544
|
async bootstrap() {
|
@@ -478,73 +546,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
478
546
|
return;
|
479
547
|
}
|
480
548
|
strapi2.documents.use(async (context, next) => {
|
481
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
|
-
return next();
|
483
|
-
}
|
484
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
485
|
-
return next();
|
486
|
-
}
|
487
|
-
const contentTypeUid = context.contentType.uid;
|
488
|
-
if (!contentTypeUid.startsWith("api::")) {
|
489
|
-
return next();
|
490
|
-
}
|
491
549
|
const result = await next();
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
550
|
+
if (!shouldCreateHistoryVersion(context)) {
|
551
|
+
return result;
|
552
|
+
}
|
553
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
496
554
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
497
|
-
const
|
498
|
-
if (
|
499
|
-
|
500
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
501
|
-
);
|
502
|
-
return next();
|
555
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
556
|
+
if (!locales.length) {
|
557
|
+
return result;
|
503
558
|
}
|
504
|
-
const
|
505
|
-
|
506
|
-
|
507
|
-
|
559
|
+
const uid2 = context.contentType.uid;
|
560
|
+
const schemas = getSchemas(uid2);
|
561
|
+
const model = strapi2.getModel(uid2);
|
562
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
563
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
564
|
+
where: {
|
565
|
+
documentId,
|
566
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
567
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
568
|
+
},
|
569
|
+
populate: serviceUtils.getDeepPopulate(
|
570
|
+
uid2,
|
571
|
+
true
|
572
|
+
/* use database syntax */
|
573
|
+
)
|
508
574
|
});
|
509
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
510
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
511
|
-
const componentsSchemas = Object.keys(
|
512
|
-
attributesSchema
|
513
|
-
).reduce((currentComponentSchemas, key) => {
|
514
|
-
const fieldSchema = attributesSchema[key];
|
515
|
-
if (fieldSchema.type === "component") {
|
516
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
517
|
-
return {
|
518
|
-
...currentComponentSchemas,
|
519
|
-
[fieldSchema.component]: componentSchema
|
520
|
-
};
|
521
|
-
}
|
522
|
-
return currentComponentSchemas;
|
523
|
-
}, {});
|
524
575
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
525
|
-
onCommit(() => {
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
576
|
+
onCommit(async () => {
|
577
|
+
for (const entry of localeEntries) {
|
578
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
579
|
+
await getService$1(strapi2, "history").createVersion({
|
580
|
+
contentType: uid2,
|
581
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
582
|
+
relatedDocumentId: documentId,
|
583
|
+
locale: entry.locale,
|
584
|
+
status,
|
585
|
+
...schemas
|
586
|
+
});
|
587
|
+
}
|
535
588
|
});
|
536
589
|
});
|
537
590
|
return result;
|
538
591
|
});
|
539
|
-
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
592
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
540
593
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
541
594
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
542
|
-
query.deleteMany({
|
595
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
543
596
|
where: {
|
544
597
|
created_at: {
|
545
|
-
$lt: expirationDate
|
598
|
+
$lt: expirationDate
|
546
599
|
}
|
547
600
|
}
|
601
|
+
}).catch((error) => {
|
602
|
+
if (error instanceof Error) {
|
603
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
604
|
+
}
|
548
605
|
});
|
549
606
|
});
|
550
607
|
state.isInitialized = true;
|
@@ -556,17 +613,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
556
613
|
}
|
557
614
|
};
|
558
615
|
};
|
559
|
-
const services$
|
616
|
+
const services$2 = {
|
560
617
|
history: createHistoryService,
|
561
618
|
lifecycles: createLifecyclesService
|
562
619
|
};
|
563
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
620
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
564
621
|
const historyVersionRouter = {
|
565
622
|
type: "admin",
|
566
623
|
routes: [
|
567
624
|
{
|
568
625
|
method: "GET",
|
569
|
-
info,
|
626
|
+
info: info$1,
|
570
627
|
path: "/history-versions",
|
571
628
|
handler: "history-version.findMany",
|
572
629
|
config: {
|
@@ -575,7 +632,7 @@ const historyVersionRouter = {
|
|
575
632
|
},
|
576
633
|
{
|
577
634
|
method: "PUT",
|
578
|
-
info,
|
635
|
+
info: info$1,
|
579
636
|
path: "/history-versions/:versionId/restore",
|
580
637
|
handler: "history-version.restoreVersion",
|
581
638
|
config: {
|
@@ -584,7 +641,7 @@ const historyVersionRouter = {
|
|
584
641
|
}
|
585
642
|
]
|
586
643
|
};
|
587
|
-
const routes$
|
644
|
+
const routes$2 = {
|
588
645
|
"history-version": historyVersionRouter
|
589
646
|
};
|
590
647
|
const historyVersion = {
|
@@ -631,21 +688,21 @@ const historyVersion = {
|
|
631
688
|
}
|
632
689
|
}
|
633
690
|
};
|
634
|
-
const getFeature = () => {
|
691
|
+
const getFeature$1 = () => {
|
635
692
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
636
693
|
return {
|
637
694
|
register({ strapi: strapi2 }) {
|
638
695
|
strapi2.get("models").add(historyVersion);
|
639
696
|
},
|
640
697
|
bootstrap({ strapi: strapi2 }) {
|
641
|
-
getService(strapi2, "lifecycles").bootstrap();
|
698
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
642
699
|
},
|
643
700
|
destroy({ strapi: strapi2 }) {
|
644
|
-
getService(strapi2, "lifecycles").destroy();
|
701
|
+
getService$1(strapi2, "lifecycles").destroy();
|
645
702
|
},
|
646
|
-
controllers: controllers$
|
647
|
-
services: services$
|
648
|
-
routes: routes$
|
703
|
+
controllers: controllers$2,
|
704
|
+
services: services$2,
|
705
|
+
routes: routes$2
|
649
706
|
};
|
650
707
|
}
|
651
708
|
return {
|
@@ -654,9 +711,205 @@ const getFeature = () => {
|
|
654
711
|
}
|
655
712
|
};
|
656
713
|
};
|
657
|
-
const history = getFeature();
|
714
|
+
const history = getFeature$1();
|
715
|
+
const FEATURE_ID = "preview";
|
716
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
717
|
+
const previewRouter = {
|
718
|
+
type: "admin",
|
719
|
+
routes: [
|
720
|
+
{
|
721
|
+
method: "GET",
|
722
|
+
info,
|
723
|
+
path: "/preview/url/:contentType",
|
724
|
+
handler: "preview.getPreviewUrl",
|
725
|
+
config: {
|
726
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
727
|
+
}
|
728
|
+
}
|
729
|
+
]
|
730
|
+
};
|
731
|
+
const routes$1 = {
|
732
|
+
preview: previewRouter
|
733
|
+
};
|
734
|
+
function getService(strapi2, name) {
|
735
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
736
|
+
}
|
737
|
+
const getPreviewUrlSchema = yup.object().shape({
|
738
|
+
// Will be undefined for single types
|
739
|
+
documentId: yup.string(),
|
740
|
+
locale: yup.string().nullable(),
|
741
|
+
status: yup.string()
|
742
|
+
}).required();
|
743
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
744
|
+
await validateYupSchema(getPreviewUrlSchema)(params);
|
745
|
+
const newParams = pick(["documentId", "locale", "status"], params);
|
746
|
+
const model = strapi2.getModel(uid2);
|
747
|
+
if (!model || model.modelType !== "contentType") {
|
748
|
+
throw new errors.ValidationError("Invalid content type");
|
749
|
+
}
|
750
|
+
const isSingleType = model?.kind === "singleType";
|
751
|
+
if (!isSingleType && !params.documentId) {
|
752
|
+
throw new errors.ValidationError("documentId is required for Collection Types");
|
753
|
+
}
|
754
|
+
if (isSingleType) {
|
755
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
756
|
+
if (!doc) {
|
757
|
+
throw new errors.NotFoundError("Document not found");
|
758
|
+
}
|
759
|
+
newParams.documentId = doc?.documentId;
|
760
|
+
}
|
761
|
+
if (!newParams.status) {
|
762
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
763
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
764
|
+
}
|
765
|
+
return newParams;
|
766
|
+
};
|
767
|
+
const createPreviewController = () => {
|
768
|
+
return {
|
769
|
+
/**
|
770
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
771
|
+
* in the Content Manager.
|
772
|
+
*/
|
773
|
+
async getPreviewUrl(ctx) {
|
774
|
+
const uid2 = ctx.params.contentType;
|
775
|
+
const query = ctx.request.query;
|
776
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
777
|
+
const previewService = getService(strapi, "preview");
|
778
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
779
|
+
if (!url) {
|
780
|
+
ctx.status = 204;
|
781
|
+
}
|
782
|
+
return {
|
783
|
+
data: { url }
|
784
|
+
};
|
785
|
+
}
|
786
|
+
};
|
787
|
+
};
|
788
|
+
const controllers$1 = {
|
789
|
+
preview: createPreviewController
|
790
|
+
/**
|
791
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
792
|
+
* passing a controller factory as the value, instead of a controller object directly
|
793
|
+
*/
|
794
|
+
};
|
795
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
796
|
+
const config = getService(strapi2, "preview-config");
|
797
|
+
return {
|
798
|
+
async getPreviewUrl(uid2, params) {
|
799
|
+
const handler = config.getPreviewHandler();
|
800
|
+
try {
|
801
|
+
return handler(uid2, params);
|
802
|
+
} catch (error) {
|
803
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
804
|
+
throw new errors.ApplicationError("Failed to get preview URL");
|
805
|
+
}
|
806
|
+
return;
|
807
|
+
}
|
808
|
+
};
|
809
|
+
};
|
810
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
811
|
+
const middlewares = strapi.config.get("middlewares");
|
812
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
813
|
+
if (currentMiddleware === middleware.name) {
|
814
|
+
return middleware;
|
815
|
+
}
|
816
|
+
if (currentMiddleware.name === middleware.name) {
|
817
|
+
return mergeWith(
|
818
|
+
(objValue, srcValue) => {
|
819
|
+
if (Array.isArray(objValue)) {
|
820
|
+
return objValue.concat(srcValue);
|
821
|
+
}
|
822
|
+
return void 0;
|
823
|
+
},
|
824
|
+
currentMiddleware,
|
825
|
+
middleware
|
826
|
+
);
|
827
|
+
}
|
828
|
+
return currentMiddleware;
|
829
|
+
});
|
830
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
831
|
+
};
|
832
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
833
|
+
return {
|
834
|
+
register() {
|
835
|
+
if (!this.isEnabled()) {
|
836
|
+
return;
|
837
|
+
}
|
838
|
+
const config = strapi2.config.get("admin.preview");
|
839
|
+
if (config.config?.allowedOrigins) {
|
840
|
+
extendMiddlewareConfiguration({
|
841
|
+
name: "strapi::security",
|
842
|
+
config: {
|
843
|
+
contentSecurityPolicy: {
|
844
|
+
directives: {
|
845
|
+
"frame-src": config.config.allowedOrigins
|
846
|
+
}
|
847
|
+
}
|
848
|
+
}
|
849
|
+
});
|
850
|
+
}
|
851
|
+
},
|
852
|
+
isEnabled() {
|
853
|
+
const config = strapi2.config.get("admin.preview");
|
854
|
+
if (!config) {
|
855
|
+
return false;
|
856
|
+
}
|
857
|
+
return config?.enabled ?? true;
|
858
|
+
},
|
859
|
+
/**
|
860
|
+
* Validate if the configuration is valid
|
861
|
+
*/
|
862
|
+
validate() {
|
863
|
+
if (!this.isEnabled()) {
|
864
|
+
return;
|
865
|
+
}
|
866
|
+
const handler = this.getPreviewHandler();
|
867
|
+
if (typeof handler !== "function") {
|
868
|
+
throw new errors.ValidationError(
|
869
|
+
"Preview configuration is invalid. Handler must be a function"
|
870
|
+
);
|
871
|
+
}
|
872
|
+
},
|
873
|
+
/**
|
874
|
+
* Utility to get the preview handler from the configuration
|
875
|
+
*/
|
876
|
+
getPreviewHandler() {
|
877
|
+
const config = strapi2.config.get("admin.preview");
|
878
|
+
const emptyHandler = () => {
|
879
|
+
return void 0;
|
880
|
+
};
|
881
|
+
if (!this.isEnabled()) {
|
882
|
+
return emptyHandler;
|
883
|
+
}
|
884
|
+
return config?.config?.handler || emptyHandler;
|
885
|
+
}
|
886
|
+
};
|
887
|
+
};
|
888
|
+
const services$1 = {
|
889
|
+
preview: createPreviewService,
|
890
|
+
"preview-config": createPreviewConfigService
|
891
|
+
};
|
892
|
+
const getFeature = () => {
|
893
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
894
|
+
return {};
|
895
|
+
}
|
896
|
+
return {
|
897
|
+
register() {
|
898
|
+
const config = getService(strapi, "preview-config");
|
899
|
+
config.validate();
|
900
|
+
config.register();
|
901
|
+
},
|
902
|
+
bootstrap() {
|
903
|
+
},
|
904
|
+
routes: routes$1,
|
905
|
+
controllers: controllers$1,
|
906
|
+
services: services$1
|
907
|
+
};
|
908
|
+
};
|
909
|
+
const preview = getFeature();
|
658
910
|
const register = async ({ strapi: strapi2 }) => {
|
659
911
|
await history.register?.({ strapi: strapi2 });
|
912
|
+
await preview.register?.({ strapi: strapi2 });
|
660
913
|
};
|
661
914
|
const ALLOWED_WEBHOOK_EVENTS = {
|
662
915
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -666,11 +919,12 @@ const bootstrap = async () => {
|
|
666
919
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
667
920
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
668
921
|
});
|
669
|
-
getService$
|
670
|
-
await getService$
|
671
|
-
await getService$
|
672
|
-
await getService$
|
922
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
923
|
+
await getService$2("components").syncConfigurations();
|
924
|
+
await getService$2("content-types").syncConfigurations();
|
925
|
+
await getService$2("permission").registerPermissions();
|
673
926
|
await history.bootstrap?.({ strapi });
|
927
|
+
await preview.bootstrap?.({ strapi });
|
674
928
|
};
|
675
929
|
const destroy = async ({ strapi: strapi2 }) => {
|
676
930
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1160,7 +1414,8 @@ const admin = {
|
|
1160
1414
|
};
|
1161
1415
|
const routes = {
|
1162
1416
|
admin,
|
1163
|
-
...history.routes ? history.routes : {}
|
1417
|
+
...history.routes ? history.routes : {},
|
1418
|
+
...preview.routes ? preview.routes : {}
|
1164
1419
|
};
|
1165
1420
|
const hasPermissionsSchema = yup$1.object({
|
1166
1421
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1171,6 +1426,11 @@ const { createPolicy } = policy;
|
|
1171
1426
|
const hasPermissions = createPolicy({
|
1172
1427
|
name: "plugin::content-manager.hasPermissions",
|
1173
1428
|
validator: validateHasPermissionsInput,
|
1429
|
+
/**
|
1430
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1431
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1432
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1433
|
+
*/
|
1174
1434
|
handler(ctx, config = {}) {
|
1175
1435
|
const { actions = [], hasAtLeastOne = false } = config;
|
1176
1436
|
const { userAbility } = ctx.state;
|
@@ -1218,8 +1478,7 @@ const isSortable = (schema, name) => {
|
|
1218
1478
|
if (!_.has(schema.attributes, name)) {
|
1219
1479
|
return false;
|
1220
1480
|
}
|
1221
|
-
if (schema.modelType === "component" && name === "id")
|
1222
|
-
return false;
|
1481
|
+
if (schema.modelType === "component" && name === "id") return false;
|
1223
1482
|
const attribute = schema.attributes[name];
|
1224
1483
|
if (NON_SORTABLES.includes(attribute.type)) {
|
1225
1484
|
return false;
|
@@ -1364,8 +1623,7 @@ const createDefaultSettings = async (schema) => {
|
|
1364
1623
|
};
|
1365
1624
|
};
|
1366
1625
|
const syncSettings = async (configuration, schema) => {
|
1367
|
-
if (isEmpty(configuration.settings))
|
1368
|
-
return createDefaultSettings(schema);
|
1626
|
+
if (isEmpty(configuration.settings)) return createDefaultSettings(schema);
|
1369
1627
|
const defaultField = getDefaultMainField(schema);
|
1370
1628
|
const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
|
1371
1629
|
return {
|
@@ -1412,7 +1670,7 @@ const createMetadasSchema = (schema) => {
|
|
1412
1670
|
if (!value) {
|
1413
1671
|
return yup$1.string();
|
1414
1672
|
}
|
1415
|
-
const targetSchema = getService$
|
1673
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1416
1674
|
schema.attributes[key].targetModel
|
1417
1675
|
);
|
1418
1676
|
if (!targetSchema) {
|
@@ -1541,8 +1799,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1541
1799
|
}
|
1542
1800
|
switch (attribute.type) {
|
1543
1801
|
case "relation": {
|
1544
|
-
if (canCreate(attributePath))
|
1545
|
-
return body2;
|
1802
|
+
if (canCreate(attributePath)) return body2;
|
1546
1803
|
return set(attributePath, { set: [] }, body2);
|
1547
1804
|
}
|
1548
1805
|
case "component": {
|
@@ -1552,8 +1809,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1552
1809
|
]);
|
1553
1810
|
}
|
1554
1811
|
default: {
|
1555
|
-
if (canCreate(attributePath))
|
1556
|
-
return body2;
|
1812
|
+
if (canCreate(attributePath)) return body2;
|
1557
1813
|
return set(attributePath, null, body2);
|
1558
1814
|
}
|
1559
1815
|
}
|
@@ -1564,9 +1820,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1564
1820
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1565
1821
|
);
|
1566
1822
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1567
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1823
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1568
1824
|
const { allowMultipleLocales } = opts;
|
1569
|
-
const { locale, status, ...rest } = request || {};
|
1825
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1826
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1827
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1570
1828
|
const schema = yup$1.object().shape({
|
1571
1829
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1572
1830
|
status: statusSchema
|
@@ -1579,7 +1837,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1579
1837
|
}
|
1580
1838
|
};
|
1581
1839
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1582
|
-
const documentMetadata2 = getService$
|
1840
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1583
1841
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1584
1842
|
let {
|
1585
1843
|
meta: { availableLocales, availableStatus }
|
@@ -1605,8 +1863,8 @@ const createDocument = async (ctx, opts) => {
|
|
1605
1863
|
const { userAbility, user } = ctx.state;
|
1606
1864
|
const { model } = ctx.params;
|
1607
1865
|
const { body } = ctx.request;
|
1608
|
-
const documentManager2 = getService$
|
1609
|
-
const permissionChecker2 = getService$
|
1866
|
+
const documentManager2 = getService$2("document-manager");
|
1867
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1610
1868
|
if (permissionChecker2.cannot.create()) {
|
1611
1869
|
throw new errors.ForbiddenError();
|
1612
1870
|
}
|
@@ -1614,7 +1872,7 @@ const createDocument = async (ctx, opts) => {
|
|
1614
1872
|
const setCreator = setCreatorFields({ user });
|
1615
1873
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1616
1874
|
const sanitizedBody = await sanitizeFn(body);
|
1617
|
-
const { locale, status
|
1875
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1618
1876
|
return documentManager2.create(model, {
|
1619
1877
|
data: sanitizedBody,
|
1620
1878
|
locale,
|
@@ -1626,14 +1884,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1626
1884
|
const { userAbility, user } = ctx.state;
|
1627
1885
|
const { id, model } = ctx.params;
|
1628
1886
|
const { body } = ctx.request;
|
1629
|
-
const documentManager2 = getService$
|
1630
|
-
const permissionChecker2 = getService$
|
1887
|
+
const documentManager2 = getService$2("document-manager");
|
1888
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1631
1889
|
if (permissionChecker2.cannot.update()) {
|
1632
1890
|
throw new errors.ForbiddenError();
|
1633
1891
|
}
|
1634
1892
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1635
|
-
const populate = await getService$
|
1636
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1893
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1894
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1637
1895
|
const [documentVersion, documentExists] = await Promise.all([
|
1638
1896
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1639
1897
|
documentManager2.exists(model, id)
|
@@ -1649,7 +1907,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1649
1907
|
throw new errors.ForbiddenError();
|
1650
1908
|
}
|
1651
1909
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1652
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1910
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1653
1911
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1654
1912
|
const sanitizedBody = await sanitizeFn(body);
|
1655
1913
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1663,15 +1921,15 @@ const collectionTypes = {
|
|
1663
1921
|
const { userAbility } = ctx.state;
|
1664
1922
|
const { model } = ctx.params;
|
1665
1923
|
const { query } = ctx.request;
|
1666
|
-
const documentMetadata2 = getService$
|
1667
|
-
const documentManager2 = getService$
|
1668
|
-
const permissionChecker2 = getService$
|
1924
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1925
|
+
const documentManager2 = getService$2("document-manager");
|
1926
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1669
1927
|
if (permissionChecker2.cannot.read()) {
|
1670
1928
|
return ctx.forbidden();
|
1671
1929
|
}
|
1672
1930
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1673
|
-
const populate = await getService$
|
1674
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1931
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1932
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1675
1933
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1676
1934
|
{ ...permissionQuery, populate, locale, status },
|
1677
1935
|
model
|
@@ -1699,14 +1957,14 @@ const collectionTypes = {
|
|
1699
1957
|
async findOne(ctx) {
|
1700
1958
|
const { userAbility } = ctx.state;
|
1701
1959
|
const { model, id } = ctx.params;
|
1702
|
-
const documentManager2 = getService$
|
1703
|
-
const permissionChecker2 = getService$
|
1960
|
+
const documentManager2 = getService$2("document-manager");
|
1961
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1704
1962
|
if (permissionChecker2.cannot.read()) {
|
1705
1963
|
return ctx.forbidden();
|
1706
1964
|
}
|
1707
1965
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1708
|
-
const populate = await getService$
|
1709
|
-
const { locale, status
|
1966
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1967
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1710
1968
|
const version = await documentManager2.findOne(id, model, {
|
1711
1969
|
populate,
|
1712
1970
|
locale,
|
@@ -1721,7 +1979,7 @@ const collectionTypes = {
|
|
1721
1979
|
permissionChecker2,
|
1722
1980
|
model,
|
1723
1981
|
// @ts-expect-error TODO: fix
|
1724
|
-
{ id, locale, publishedAt: null },
|
1982
|
+
{ documentId: id, locale, publishedAt: null },
|
1725
1983
|
{ availableLocales: true, availableStatus: false }
|
1726
1984
|
);
|
1727
1985
|
ctx.body = { data: {}, meta };
|
@@ -1736,7 +1994,7 @@ const collectionTypes = {
|
|
1736
1994
|
async create(ctx) {
|
1737
1995
|
const { userAbility } = ctx.state;
|
1738
1996
|
const { model } = ctx.params;
|
1739
|
-
const permissionChecker2 = getService$
|
1997
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1740
1998
|
const [totalEntries, document] = await Promise.all([
|
1741
1999
|
strapi.db.query(model).count(),
|
1742
2000
|
createDocument(ctx)
|
@@ -1757,7 +2015,7 @@ const collectionTypes = {
|
|
1757
2015
|
async update(ctx) {
|
1758
2016
|
const { userAbility } = ctx.state;
|
1759
2017
|
const { model } = ctx.params;
|
1760
|
-
const permissionChecker2 = getService$
|
2018
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1761
2019
|
const updatedVersion = await updateDocument(ctx);
|
1762
2020
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1763
2021
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1766,14 +2024,14 @@ const collectionTypes = {
|
|
1766
2024
|
const { userAbility, user } = ctx.state;
|
1767
2025
|
const { model, sourceId: id } = ctx.params;
|
1768
2026
|
const { body } = ctx.request;
|
1769
|
-
const documentManager2 = getService$
|
1770
|
-
const permissionChecker2 = getService$
|
2027
|
+
const documentManager2 = getService$2("document-manager");
|
2028
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1771
2029
|
if (permissionChecker2.cannot.create()) {
|
1772
2030
|
return ctx.forbidden();
|
1773
2031
|
}
|
1774
2032
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1775
|
-
const populate = await getService$
|
1776
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2033
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2034
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1777
2035
|
const document = await documentManager2.findOne(id, model, {
|
1778
2036
|
populate,
|
1779
2037
|
locale,
|
@@ -1811,14 +2069,14 @@ const collectionTypes = {
|
|
1811
2069
|
async delete(ctx) {
|
1812
2070
|
const { userAbility } = ctx.state;
|
1813
2071
|
const { id, model } = ctx.params;
|
1814
|
-
const documentManager2 = getService$
|
1815
|
-
const permissionChecker2 = getService$
|
2072
|
+
const documentManager2 = getService$2("document-manager");
|
2073
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1816
2074
|
if (permissionChecker2.cannot.delete()) {
|
1817
2075
|
return ctx.forbidden();
|
1818
2076
|
}
|
1819
2077
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1820
|
-
const populate = await getService$
|
1821
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2078
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2079
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1822
2080
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1823
2081
|
if (documentLocales.length === 0) {
|
1824
2082
|
return ctx.notFound();
|
@@ -1839,19 +2097,42 @@ const collectionTypes = {
|
|
1839
2097
|
const { userAbility } = ctx.state;
|
1840
2098
|
const { id, model } = ctx.params;
|
1841
2099
|
const { body } = ctx.request;
|
1842
|
-
const documentManager2 = getService$
|
1843
|
-
const permissionChecker2 = getService$
|
2100
|
+
const documentManager2 = getService$2("document-manager");
|
2101
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1844
2102
|
if (permissionChecker2.cannot.publish()) {
|
1845
2103
|
return ctx.forbidden();
|
1846
2104
|
}
|
1847
2105
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1848
2106
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1849
|
-
const populate = await getService$
|
1850
|
-
|
2107
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2108
|
+
let document;
|
2109
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2110
|
+
const isCreate = isNil$1(id);
|
2111
|
+
if (isCreate) {
|
2112
|
+
if (permissionChecker2.cannot.create()) {
|
2113
|
+
throw new errors.ForbiddenError();
|
2114
|
+
}
|
2115
|
+
document = await createDocument(ctx, { populate });
|
2116
|
+
}
|
2117
|
+
const isUpdate = !isCreate;
|
2118
|
+
if (isUpdate) {
|
2119
|
+
const documentExists = documentManager2.exists(model, id);
|
2120
|
+
if (!documentExists) {
|
2121
|
+
throw new errors.NotFoundError("Document not found");
|
2122
|
+
}
|
2123
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2124
|
+
if (!document) {
|
2125
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2126
|
+
throw new errors.ForbiddenError();
|
2127
|
+
}
|
2128
|
+
document = await updateDocument(ctx);
|
2129
|
+
} else if (permissionChecker2.can.update(document)) {
|
2130
|
+
await updateDocument(ctx);
|
2131
|
+
}
|
2132
|
+
}
|
1851
2133
|
if (permissionChecker2.cannot.publish(document)) {
|
1852
2134
|
throw new errors.ForbiddenError();
|
1853
2135
|
}
|
1854
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1855
2136
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1856
2137
|
locale
|
1857
2138
|
// TODO: Allow setting creator fields on publish
|
@@ -1871,14 +2152,16 @@ const collectionTypes = {
|
|
1871
2152
|
const { body } = ctx.request;
|
1872
2153
|
const { documentIds } = body;
|
1873
2154
|
await validateBulkActionInput(body);
|
1874
|
-
const documentManager2 = getService$
|
1875
|
-
const permissionChecker2 = getService$
|
2155
|
+
const documentManager2 = getService$2("document-manager");
|
2156
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1876
2157
|
if (permissionChecker2.cannot.publish()) {
|
1877
2158
|
return ctx.forbidden();
|
1878
2159
|
}
|
1879
2160
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1880
|
-
const populate = await getService$
|
1881
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2161
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2162
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2163
|
+
allowMultipleLocales: true
|
2164
|
+
});
|
1882
2165
|
const entityPromises = documentIds.map(
|
1883
2166
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1884
2167
|
);
|
@@ -1900,12 +2183,14 @@ const collectionTypes = {
|
|
1900
2183
|
const { body } = ctx.request;
|
1901
2184
|
const { documentIds } = body;
|
1902
2185
|
await validateBulkActionInput(body);
|
1903
|
-
const documentManager2 = getService$
|
1904
|
-
const permissionChecker2 = getService$
|
2186
|
+
const documentManager2 = getService$2("document-manager");
|
2187
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1905
2188
|
if (permissionChecker2.cannot.unpublish()) {
|
1906
2189
|
return ctx.forbidden();
|
1907
2190
|
}
|
1908
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2191
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2192
|
+
allowMultipleLocales: true
|
2193
|
+
});
|
1909
2194
|
const entityPromises = documentIds.map(
|
1910
2195
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1911
2196
|
);
|
@@ -1928,8 +2213,8 @@ const collectionTypes = {
|
|
1928
2213
|
const {
|
1929
2214
|
body: { discardDraft, ...body }
|
1930
2215
|
} = ctx.request;
|
1931
|
-
const documentManager2 = getService$
|
1932
|
-
const permissionChecker2 = getService$
|
2216
|
+
const documentManager2 = getService$2("document-manager");
|
2217
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1933
2218
|
if (permissionChecker2.cannot.unpublish()) {
|
1934
2219
|
return ctx.forbidden();
|
1935
2220
|
}
|
@@ -1937,8 +2222,8 @@ const collectionTypes = {
|
|
1937
2222
|
return ctx.forbidden();
|
1938
2223
|
}
|
1939
2224
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1940
|
-
const populate = await getService$
|
1941
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2225
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2226
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1942
2227
|
const document = await documentManager2.findOne(id, model, {
|
1943
2228
|
populate,
|
1944
2229
|
locale,
|
@@ -1968,14 +2253,14 @@ const collectionTypes = {
|
|
1968
2253
|
const { userAbility } = ctx.state;
|
1969
2254
|
const { id, model } = ctx.params;
|
1970
2255
|
const { body } = ctx.request;
|
1971
|
-
const documentManager2 = getService$
|
1972
|
-
const permissionChecker2 = getService$
|
2256
|
+
const documentManager2 = getService$2("document-manager");
|
2257
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1973
2258
|
if (permissionChecker2.cannot.discard()) {
|
1974
2259
|
return ctx.forbidden();
|
1975
2260
|
}
|
1976
2261
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1977
|
-
const populate = await getService$
|
1978
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2262
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2263
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1979
2264
|
const document = await documentManager2.findOne(id, model, {
|
1980
2265
|
populate,
|
1981
2266
|
locale,
|
@@ -1999,14 +2284,14 @@ const collectionTypes = {
|
|
1999
2284
|
const { query, body } = ctx.request;
|
2000
2285
|
const { documentIds } = body;
|
2001
2286
|
await validateBulkActionInput(body);
|
2002
|
-
const documentManager2 = getService$
|
2003
|
-
const permissionChecker2 = getService$
|
2287
|
+
const documentManager2 = getService$2("document-manager");
|
2288
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2004
2289
|
if (permissionChecker2.cannot.delete()) {
|
2005
2290
|
return ctx.forbidden();
|
2006
2291
|
}
|
2007
2292
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2008
|
-
const populate = await getService$
|
2009
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2293
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2294
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2010
2295
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2011
2296
|
populate,
|
2012
2297
|
locale
|
@@ -2026,14 +2311,14 @@ const collectionTypes = {
|
|
2026
2311
|
async countDraftRelations(ctx) {
|
2027
2312
|
const { userAbility } = ctx.state;
|
2028
2313
|
const { model, id } = ctx.params;
|
2029
|
-
const documentManager2 = getService$
|
2030
|
-
const permissionChecker2 = getService$
|
2314
|
+
const documentManager2 = getService$2("document-manager");
|
2315
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2031
2316
|
if (permissionChecker2.cannot.read()) {
|
2032
2317
|
return ctx.forbidden();
|
2033
2318
|
}
|
2034
2319
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2035
|
-
const populate = await getService$
|
2036
|
-
const { locale, status
|
2320
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2321
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2037
2322
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2038
2323
|
if (!entity) {
|
2039
2324
|
return ctx.notFound();
|
@@ -2051,12 +2336,12 @@ const collectionTypes = {
|
|
2051
2336
|
const ids = ctx.request.query.documentIds;
|
2052
2337
|
const locale = ctx.request.query.locale;
|
2053
2338
|
const { model } = ctx.params;
|
2054
|
-
const documentManager2 = getService$
|
2055
|
-
const permissionChecker2 = getService$
|
2339
|
+
const documentManager2 = getService$2("document-manager");
|
2340
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2056
2341
|
if (permissionChecker2.cannot.read()) {
|
2057
2342
|
return ctx.forbidden();
|
2058
2343
|
}
|
2059
|
-
const
|
2344
|
+
const documents = await documentManager2.findMany(
|
2060
2345
|
{
|
2061
2346
|
filters: {
|
2062
2347
|
documentId: ids
|
@@ -2065,7 +2350,7 @@ const collectionTypes = {
|
|
2065
2350
|
},
|
2066
2351
|
model
|
2067
2352
|
);
|
2068
|
-
if (!
|
2353
|
+
if (!documents) {
|
2069
2354
|
return ctx.notFound();
|
2070
2355
|
}
|
2071
2356
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2076,13 +2361,13 @@ const collectionTypes = {
|
|
2076
2361
|
};
|
2077
2362
|
const components$1 = {
|
2078
2363
|
findComponents(ctx) {
|
2079
|
-
const components2 = getService$
|
2080
|
-
const { toDto } = getService$
|
2364
|
+
const components2 = getService$2("components").findAllComponents();
|
2365
|
+
const { toDto } = getService$2("data-mapper");
|
2081
2366
|
ctx.body = { data: components2.map(toDto) };
|
2082
2367
|
},
|
2083
2368
|
async findComponentConfiguration(ctx) {
|
2084
2369
|
const { uid: uid2 } = ctx.params;
|
2085
|
-
const componentService = getService$
|
2370
|
+
const componentService = getService$2("components");
|
2086
2371
|
const component = componentService.findComponent(uid2);
|
2087
2372
|
if (!component) {
|
2088
2373
|
return ctx.notFound("component.notFound");
|
@@ -2099,7 +2384,7 @@ const components$1 = {
|
|
2099
2384
|
async updateComponentConfiguration(ctx) {
|
2100
2385
|
const { uid: uid2 } = ctx.params;
|
2101
2386
|
const { body } = ctx.request;
|
2102
|
-
const componentService = getService$
|
2387
|
+
const componentService = getService$2("components");
|
2103
2388
|
const component = componentService.findComponent(uid2);
|
2104
2389
|
if (!component) {
|
2105
2390
|
return ctx.notFound("component.notFound");
|
@@ -2133,12 +2418,12 @@ const contentTypes = {
|
|
2133
2418
|
} catch (error) {
|
2134
2419
|
return ctx.send({ error }, 400);
|
2135
2420
|
}
|
2136
|
-
const contentTypes2 = getService$
|
2137
|
-
const { toDto } = getService$
|
2421
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2422
|
+
const { toDto } = getService$2("data-mapper");
|
2138
2423
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2139
2424
|
},
|
2140
2425
|
async findContentTypesSettings(ctx) {
|
2141
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2426
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2142
2427
|
const contentTypes2 = await findAllContentTypes();
|
2143
2428
|
const configurations = await Promise.all(
|
2144
2429
|
contentTypes2.map(async (contentType) => {
|
@@ -2152,7 +2437,7 @@ const contentTypes = {
|
|
2152
2437
|
},
|
2153
2438
|
async findContentTypeConfiguration(ctx) {
|
2154
2439
|
const { uid: uid2 } = ctx.params;
|
2155
|
-
const contentTypeService = getService$
|
2440
|
+
const contentTypeService = getService$2("content-types");
|
2156
2441
|
const contentType = await contentTypeService.findContentType(uid2);
|
2157
2442
|
if (!contentType) {
|
2158
2443
|
return ctx.notFound("contentType.notFound");
|
@@ -2174,13 +2459,13 @@ const contentTypes = {
|
|
2174
2459
|
const { userAbility } = ctx.state;
|
2175
2460
|
const { uid: uid2 } = ctx.params;
|
2176
2461
|
const { body } = ctx.request;
|
2177
|
-
const contentTypeService = getService$
|
2178
|
-
const metricsService = getService$
|
2462
|
+
const contentTypeService = getService$2("content-types");
|
2463
|
+
const metricsService = getService$2("metrics");
|
2179
2464
|
const contentType = await contentTypeService.findContentType(uid2);
|
2180
2465
|
if (!contentType) {
|
2181
2466
|
return ctx.notFound("contentType.notFound");
|
2182
2467
|
}
|
2183
|
-
if (!getService$
|
2468
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2184
2469
|
return ctx.forbidden();
|
2185
2470
|
}
|
2186
2471
|
let input;
|
@@ -2213,10 +2498,10 @@ const contentTypes = {
|
|
2213
2498
|
};
|
2214
2499
|
const init = {
|
2215
2500
|
getInitData(ctx) {
|
2216
|
-
const { toDto } = getService$
|
2217
|
-
const { findAllComponents } = getService$
|
2218
|
-
const { getAllFieldSizes } = getService$
|
2219
|
-
const { findAllContentTypes } = getService$
|
2501
|
+
const { toDto } = getService$2("data-mapper");
|
2502
|
+
const { findAllComponents } = getService$2("components");
|
2503
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2504
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2220
2505
|
ctx.body = {
|
2221
2506
|
data: {
|
2222
2507
|
fieldSizes: getAllFieldSizes(),
|
@@ -2252,36 +2537,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2252
2537
|
params.filters.$and.push(filtersClause);
|
2253
2538
|
};
|
2254
2539
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2255
|
-
const permissionChecker2 = getService$
|
2540
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2256
2541
|
userAbility,
|
2257
2542
|
model: model.uid
|
2258
2543
|
});
|
2259
|
-
|
2544
|
+
const isMainFieldListable = isListable(model, mainField);
|
2545
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2546
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2260
2547
|
return "id";
|
2261
2548
|
}
|
2262
|
-
if (
|
2263
|
-
|
2264
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2265
|
-
userAbility,
|
2266
|
-
model: "plugin::users-permissions.user"
|
2267
|
-
});
|
2268
|
-
if (userPermissionChecker.can.read()) {
|
2269
|
-
return "name";
|
2270
|
-
}
|
2271
|
-
}
|
2272
|
-
return "id";
|
2549
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2550
|
+
return "name";
|
2273
2551
|
}
|
2274
2552
|
return mainField;
|
2275
2553
|
};
|
2276
|
-
const addStatusToRelations = async (
|
2277
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2554
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2555
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2278
2556
|
return relations2;
|
2279
2557
|
}
|
2280
|
-
const documentMetadata2 = getService$
|
2281
|
-
|
2558
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2559
|
+
if (!relations2.length) {
|
2560
|
+
return relations2;
|
2561
|
+
}
|
2562
|
+
const firstRelation = relations2[0];
|
2563
|
+
const filters = {
|
2564
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2565
|
+
// NOTE: find the "opposite" status
|
2566
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2567
|
+
};
|
2568
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2569
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2570
|
+
filters
|
2571
|
+
});
|
2282
2572
|
return relations2.map((relation) => {
|
2283
|
-
const availableStatuses =
|
2284
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2573
|
+
const availableStatuses = availableStatus.filter(
|
2574
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2285
2575
|
);
|
2286
2576
|
return {
|
2287
2577
|
...relation,
|
@@ -2302,11 +2592,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2302
2592
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2303
2593
|
const isSourceLocalized = isLocalized(sourceModel);
|
2304
2594
|
const isTargetLocalized = isLocalized(targetModel);
|
2305
|
-
let validatedLocale = locale;
|
2306
|
-
if (!targetModel || !isTargetLocalized)
|
2307
|
-
validatedLocale = void 0;
|
2308
2595
|
return {
|
2309
|
-
locale
|
2596
|
+
locale,
|
2310
2597
|
isSourceLocalized,
|
2311
2598
|
isTargetLocalized
|
2312
2599
|
};
|
@@ -2315,8 +2602,7 @@ const validateStatus = (sourceUid, status) => {
|
|
2315
2602
|
const sourceModel = strapi.getModel(sourceUid);
|
2316
2603
|
const isDP = contentTypes$1.hasDraftAndPublish;
|
2317
2604
|
const isSourceDP = isDP(sourceModel);
|
2318
|
-
if (!isSourceDP)
|
2319
|
-
return { status: void 0 };
|
2605
|
+
if (!isSourceDP) return { status: void 0 };
|
2320
2606
|
switch (status) {
|
2321
2607
|
case "published":
|
2322
2608
|
return { status: "published" };
|
@@ -2346,7 +2632,7 @@ const relations = {
|
|
2346
2632
|
ctx.request?.query?.locale
|
2347
2633
|
);
|
2348
2634
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2349
|
-
const permissionChecker2 = getService$
|
2635
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2350
2636
|
userAbility,
|
2351
2637
|
model
|
2352
2638
|
});
|
@@ -2371,7 +2657,7 @@ const relations = {
|
|
2371
2657
|
where.id = id;
|
2372
2658
|
}
|
2373
2659
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2374
|
-
const populate = await getService$
|
2660
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2375
2661
|
const currentEntity = await strapi.db.query(model).findOne({
|
2376
2662
|
where,
|
2377
2663
|
populate
|
@@ -2386,7 +2672,7 @@ const relations = {
|
|
2386
2672
|
}
|
2387
2673
|
entryId = currentEntity.id;
|
2388
2674
|
}
|
2389
|
-
const modelConfig = isComponent2 ? await getService$
|
2675
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2390
2676
|
const targetSchema = strapi.getModel(targetUid);
|
2391
2677
|
const mainField = flow(
|
2392
2678
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2409,7 +2695,7 @@ const relations = {
|
|
2409
2695
|
attribute,
|
2410
2696
|
fieldsToSelect,
|
2411
2697
|
mainField,
|
2412
|
-
source: { schema: sourceSchema },
|
2698
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2413
2699
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2414
2700
|
sourceSchema,
|
2415
2701
|
targetSchema,
|
@@ -2431,7 +2717,8 @@ const relations = {
|
|
2431
2717
|
fieldsToSelect,
|
2432
2718
|
mainField,
|
2433
2719
|
source: {
|
2434
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2720
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2721
|
+
isLocalized: isSourceLocalized
|
2435
2722
|
},
|
2436
2723
|
target: {
|
2437
2724
|
schema: { uid: targetUid },
|
@@ -2439,7 +2726,7 @@ const relations = {
|
|
2439
2726
|
}
|
2440
2727
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2441
2728
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2442
|
-
const permissionChecker2 = getService$
|
2729
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2443
2730
|
userAbility: ctx.state.userAbility,
|
2444
2731
|
model: targetUid
|
2445
2732
|
});
|
@@ -2469,12 +2756,16 @@ const relations = {
|
|
2469
2756
|
} else {
|
2470
2757
|
where.id = id;
|
2471
2758
|
}
|
2472
|
-
|
2473
|
-
|
2759
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2760
|
+
if (!isEmpty(publishedAt)) {
|
2761
|
+
where[`${alias}.published_at`] = publishedAt;
|
2474
2762
|
}
|
2475
|
-
if (
|
2763
|
+
if (isTargetLocalized && locale) {
|
2476
2764
|
where[`${alias}.locale`] = locale;
|
2477
2765
|
}
|
2766
|
+
if (isSourceLocalized && locale) {
|
2767
|
+
where.locale = locale;
|
2768
|
+
}
|
2478
2769
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2479
2770
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2480
2771
|
}
|
@@ -2492,7 +2783,8 @@ const relations = {
|
|
2492
2783
|
id: { $notIn: uniq(idsToOmit) }
|
2493
2784
|
});
|
2494
2785
|
}
|
2495
|
-
const
|
2786
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2787
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2496
2788
|
ctx.body = {
|
2497
2789
|
...res,
|
2498
2790
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2507,29 +2799,39 @@ const relations = {
|
|
2507
2799
|
attribute,
|
2508
2800
|
targetField,
|
2509
2801
|
fieldsToSelect,
|
2510
|
-
|
2511
|
-
|
2512
|
-
}
|
2513
|
-
target: {
|
2514
|
-
schema: { uid: targetUid }
|
2515
|
-
}
|
2802
|
+
status,
|
2803
|
+
source: { schema: sourceSchema },
|
2804
|
+
target: { schema: targetSchema }
|
2516
2805
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2517
|
-
const
|
2806
|
+
const { uid: sourceUid } = sourceSchema;
|
2807
|
+
const { uid: targetUid } = targetSchema;
|
2808
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2518
2809
|
const dbQuery = strapi.db.query(sourceUid);
|
2519
2810
|
const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2811
|
+
const filters = {};
|
2812
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2813
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2814
|
+
if (status === "published") {
|
2815
|
+
filters.publishedAt = { $notNull: true };
|
2816
|
+
} else {
|
2817
|
+
filters.publishedAt = { $null: true };
|
2818
|
+
}
|
2819
|
+
}
|
2820
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2821
|
+
filters.publishedAt = { $null: true };
|
2822
|
+
}
|
2520
2823
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2521
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2824
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2522
2825
|
ordering: "desc",
|
2523
2826
|
page: ctx.request.query.page,
|
2524
|
-
pageSize: ctx.request.query.pageSize
|
2827
|
+
pageSize: ctx.request.query.pageSize,
|
2828
|
+
filters
|
2525
2829
|
});
|
2526
2830
|
const loadedIds = res.results.map((item) => item.id);
|
2527
2831
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2528
2832
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2529
2833
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2530
|
-
ordering: "desc"
|
2531
|
-
page: ctx.request.query.page,
|
2532
|
-
pageSize: ctx.request.query.pageSize
|
2834
|
+
ordering: "desc"
|
2533
2835
|
});
|
2534
2836
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2535
2837
|
ctx.body = {
|
@@ -2544,10 +2846,10 @@ const relations = {
|
|
2544
2846
|
}
|
2545
2847
|
};
|
2546
2848
|
const buildPopulateFromQuery = async (query, model) => {
|
2547
|
-
return getService$
|
2849
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2548
2850
|
};
|
2549
2851
|
const findDocument = async (query, uid2, opts = {}) => {
|
2550
|
-
const documentManager2 = getService$
|
2852
|
+
const documentManager2 = getService$2("document-manager");
|
2551
2853
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2552
2854
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2553
2855
|
};
|
@@ -2555,13 +2857,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2555
2857
|
const { user, userAbility } = ctx.state;
|
2556
2858
|
const { model } = ctx.params;
|
2557
2859
|
const { body, query } = ctx.request;
|
2558
|
-
const documentManager2 = getService$
|
2559
|
-
const permissionChecker2 = getService$
|
2860
|
+
const documentManager2 = getService$2("document-manager");
|
2861
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2560
2862
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2561
2863
|
throw new errors.ForbiddenError();
|
2562
2864
|
}
|
2563
2865
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2564
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2866
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2565
2867
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2566
2868
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2567
2869
|
// Find the first document to check if it exists
|
@@ -2597,12 +2899,12 @@ const singleTypes = {
|
|
2597
2899
|
const { userAbility } = ctx.state;
|
2598
2900
|
const { model } = ctx.params;
|
2599
2901
|
const { query = {} } = ctx.request;
|
2600
|
-
const permissionChecker2 = getService$
|
2902
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2601
2903
|
if (permissionChecker2.cannot.read()) {
|
2602
2904
|
return ctx.forbidden();
|
2603
2905
|
}
|
2604
2906
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2605
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2907
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2606
2908
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2607
2909
|
if (!version) {
|
2608
2910
|
if (permissionChecker2.cannot.create()) {
|
@@ -2616,7 +2918,7 @@ const singleTypes = {
|
|
2616
2918
|
permissionChecker2,
|
2617
2919
|
model,
|
2618
2920
|
// @ts-expect-error - fix types
|
2619
|
-
{
|
2921
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2620
2922
|
{ availableLocales: true, availableStatus: false }
|
2621
2923
|
);
|
2622
2924
|
ctx.body = { data: {}, meta };
|
@@ -2631,7 +2933,7 @@ const singleTypes = {
|
|
2631
2933
|
async createOrUpdate(ctx) {
|
2632
2934
|
const { userAbility } = ctx.state;
|
2633
2935
|
const { model } = ctx.params;
|
2634
|
-
const permissionChecker2 = getService$
|
2936
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2635
2937
|
const document = await createOrUpdateDocument(ctx);
|
2636
2938
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2637
2939
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2640,14 +2942,14 @@ const singleTypes = {
|
|
2640
2942
|
const { userAbility } = ctx.state;
|
2641
2943
|
const { model } = ctx.params;
|
2642
2944
|
const { query = {} } = ctx.request;
|
2643
|
-
const documentManager2 = getService$
|
2644
|
-
const permissionChecker2 = getService$
|
2945
|
+
const documentManager2 = getService$2("document-manager");
|
2946
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2645
2947
|
if (permissionChecker2.cannot.delete()) {
|
2646
2948
|
return ctx.forbidden();
|
2647
2949
|
}
|
2648
2950
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2649
2951
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2650
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2952
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2651
2953
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2652
2954
|
populate,
|
2653
2955
|
locale
|
@@ -2669,8 +2971,8 @@ const singleTypes = {
|
|
2669
2971
|
const { userAbility } = ctx.state;
|
2670
2972
|
const { model } = ctx.params;
|
2671
2973
|
const { query = {} } = ctx.request;
|
2672
|
-
const documentManager2 = getService$
|
2673
|
-
const permissionChecker2 = getService$
|
2974
|
+
const documentManager2 = getService$2("document-manager");
|
2975
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2674
2976
|
if (permissionChecker2.cannot.publish()) {
|
2675
2977
|
return ctx.forbidden();
|
2676
2978
|
}
|
@@ -2684,7 +2986,7 @@ const singleTypes = {
|
|
2684
2986
|
if (permissionChecker2.cannot.publish(document)) {
|
2685
2987
|
throw new errors.ForbiddenError();
|
2686
2988
|
}
|
2687
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2989
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2688
2990
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2689
2991
|
return publishResult.at(0);
|
2690
2992
|
});
|
@@ -2698,8 +3000,8 @@ const singleTypes = {
|
|
2698
3000
|
body: { discardDraft, ...body },
|
2699
3001
|
query = {}
|
2700
3002
|
} = ctx.request;
|
2701
|
-
const documentManager2 = getService$
|
2702
|
-
const permissionChecker2 = getService$
|
3003
|
+
const documentManager2 = getService$2("document-manager");
|
3004
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2703
3005
|
if (permissionChecker2.cannot.unpublish()) {
|
2704
3006
|
return ctx.forbidden();
|
2705
3007
|
}
|
@@ -2707,7 +3009,7 @@ const singleTypes = {
|
|
2707
3009
|
return ctx.forbidden();
|
2708
3010
|
}
|
2709
3011
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2710
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3012
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2711
3013
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2712
3014
|
if (!document) {
|
2713
3015
|
return ctx.notFound();
|
@@ -2733,13 +3035,13 @@ const singleTypes = {
|
|
2733
3035
|
const { userAbility } = ctx.state;
|
2734
3036
|
const { model } = ctx.params;
|
2735
3037
|
const { body, query = {} } = ctx.request;
|
2736
|
-
const documentManager2 = getService$
|
2737
|
-
const permissionChecker2 = getService$
|
3038
|
+
const documentManager2 = getService$2("document-manager");
|
3039
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2738
3040
|
if (permissionChecker2.cannot.discard()) {
|
2739
3041
|
return ctx.forbidden();
|
2740
3042
|
}
|
2741
3043
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2742
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3044
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2743
3045
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2744
3046
|
if (!document) {
|
2745
3047
|
return ctx.notFound();
|
@@ -2757,9 +3059,9 @@ const singleTypes = {
|
|
2757
3059
|
const { userAbility } = ctx.state;
|
2758
3060
|
const { model } = ctx.params;
|
2759
3061
|
const { query } = ctx.request;
|
2760
|
-
const documentManager2 = getService$
|
2761
|
-
const permissionChecker2 = getService$
|
2762
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3062
|
+
const documentManager2 = getService$2("document-manager");
|
3063
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3064
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2763
3065
|
if (permissionChecker2.cannot.read()) {
|
2764
3066
|
return ctx.forbidden();
|
2765
3067
|
}
|
@@ -2780,9 +3082,9 @@ const uid$1 = {
|
|
2780
3082
|
async generateUID(ctx) {
|
2781
3083
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2782
3084
|
const { query = {} } = ctx.request;
|
2783
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3085
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2784
3086
|
await validateUIDField(contentTypeUID, field);
|
2785
|
-
const uidService = getService$
|
3087
|
+
const uidService = getService$2("uid");
|
2786
3088
|
ctx.body = {
|
2787
3089
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2788
3090
|
};
|
@@ -2792,9 +3094,9 @@ const uid$1 = {
|
|
2792
3094
|
ctx.request.body
|
2793
3095
|
);
|
2794
3096
|
const { query = {} } = ctx.request;
|
2795
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3097
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2796
3098
|
await validateUIDField(contentTypeUID, field);
|
2797
|
-
const uidService = getService$
|
3099
|
+
const uidService = getService$2("uid");
|
2798
3100
|
const isAvailable = await uidService.checkUIDAvailability({
|
2799
3101
|
contentTypeUID,
|
2800
3102
|
field,
|
@@ -2815,7 +3117,8 @@ const controllers = {
|
|
2815
3117
|
relations,
|
2816
3118
|
"single-types": singleTypes,
|
2817
3119
|
uid: uid$1,
|
2818
|
-
...history.controllers ? history.controllers : {}
|
3120
|
+
...history.controllers ? history.controllers : {},
|
3121
|
+
...preview.controllers ? preview.controllers : {}
|
2819
3122
|
};
|
2820
3123
|
const keys = {
|
2821
3124
|
CONFIGURATION: "configuration"
|
@@ -2944,18 +3247,15 @@ async function syncMetadatas(configuration, schema) {
|
|
2944
3247
|
_.set(updatedMeta, ["list", "searchable"], false);
|
2945
3248
|
_.set(acc, [key], updatedMeta);
|
2946
3249
|
}
|
2947
|
-
if (!_.has(edit, "mainField"))
|
2948
|
-
return acc;
|
3250
|
+
if (!_.has(edit, "mainField")) return acc;
|
2949
3251
|
if (!isRelation$1(attr)) {
|
2950
3252
|
_.set(updatedMeta, "edit", _.omit(edit, ["mainField"]));
|
2951
3253
|
_.set(acc, [key], updatedMeta);
|
2952
3254
|
return acc;
|
2953
3255
|
}
|
2954
|
-
if (edit.mainField === "id")
|
2955
|
-
return acc;
|
3256
|
+
if (edit.mainField === "id") return acc;
|
2956
3257
|
const targetSchema = getTargetSchema(attr.targetModel);
|
2957
|
-
if (!targetSchema)
|
2958
|
-
return acc;
|
3258
|
+
if (!targetSchema) return acc;
|
2959
3259
|
if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
|
2960
3260
|
_.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
|
2961
3261
|
_.set(acc, [key], updatedMeta);
|
@@ -2966,12 +3266,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2966
3266
|
return _.assign(metasWithDefaults, updatedMetas);
|
2967
3267
|
}
|
2968
3268
|
const getTargetSchema = (targetModel) => {
|
2969
|
-
return getService$
|
3269
|
+
return getService$2("content-types").findContentType(targetModel);
|
2970
3270
|
};
|
2971
3271
|
const DEFAULT_LIST_LENGTH = 4;
|
2972
3272
|
const MAX_ROW_SIZE = 12;
|
2973
3273
|
const isAllowedFieldSize = (type, size) => {
|
2974
|
-
const { getFieldSize } = getService$
|
3274
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2975
3275
|
const fieldSize = getFieldSize(type);
|
2976
3276
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2977
3277
|
return false;
|
@@ -2979,7 +3279,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2979
3279
|
return size <= MAX_ROW_SIZE;
|
2980
3280
|
};
|
2981
3281
|
const getDefaultFieldSize = (attribute) => {
|
2982
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3282
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2983
3283
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2984
3284
|
};
|
2985
3285
|
async function createDefaultLayouts(schema) {
|
@@ -3000,8 +3300,7 @@ function createDefaultEditLayout(schema) {
|
|
3000
3300
|
return appendToEditLayout([], keys2, schema);
|
3001
3301
|
}
|
3002
3302
|
function syncLayouts(configuration, schema) {
|
3003
|
-
if (_.isEmpty(configuration.layouts))
|
3004
|
-
return createDefaultLayouts(schema);
|
3303
|
+
if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
3005
3304
|
const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
|
3006
3305
|
let cleanList = list.filter((attr) => isListable(schema, attr));
|
3007
3306
|
const cleanEditRelations = editRelations.filter(
|
@@ -3012,9 +3311,8 @@ function syncLayouts(configuration, schema) {
|
|
3012
3311
|
for (const row of edit) {
|
3013
3312
|
const newRow = [];
|
3014
3313
|
for (const el of row) {
|
3015
|
-
if (!hasEditableAttribute(schema, el.name))
|
3016
|
-
|
3017
|
-
const { hasFieldSize } = getService$1("field-sizes");
|
3314
|
+
if (!hasEditableAttribute(schema, el.name)) continue;
|
3315
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3018
3316
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3019
3317
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3020
3318
|
elementsToReAppend.push(el.name);
|
@@ -3044,8 +3342,7 @@ function syncLayouts(configuration, schema) {
|
|
3044
3342
|
};
|
3045
3343
|
}
|
3046
3344
|
const appendToEditLayout = (layout = [], keysToAppend, schema) => {
|
3047
|
-
if (keysToAppend.length === 0)
|
3048
|
-
return layout;
|
3345
|
+
if (keysToAppend.length === 0) return layout;
|
3049
3346
|
let currentRowIndex = Math.max(layout.length - 1, 0);
|
3050
3347
|
if (!layout[currentRowIndex]) {
|
3051
3348
|
layout[currentRowIndex] = [];
|
@@ -3154,17 +3451,17 @@ const configurationService$1 = createConfigurationService({
|
|
3154
3451
|
isComponent: true,
|
3155
3452
|
prefix: STORE_KEY_PREFIX,
|
3156
3453
|
getModels() {
|
3157
|
-
const { toContentManagerModel } = getService$
|
3454
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3158
3455
|
return mapValues(toContentManagerModel, strapi.components);
|
3159
3456
|
}
|
3160
3457
|
});
|
3161
3458
|
const components = ({ strapi: strapi2 }) => ({
|
3162
3459
|
findAllComponents() {
|
3163
|
-
const { toContentManagerModel } = getService$
|
3460
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3164
3461
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3165
3462
|
},
|
3166
3463
|
findComponent(uid2) {
|
3167
|
-
const { toContentManagerModel } = getService$
|
3464
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3168
3465
|
const component = strapi2.components[uid2];
|
3169
3466
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3170
3467
|
},
|
@@ -3215,17 +3512,17 @@ const configurationService = createConfigurationService({
|
|
3215
3512
|
storeUtils,
|
3216
3513
|
prefix: "content_types",
|
3217
3514
|
getModels() {
|
3218
|
-
const { toContentManagerModel } = getService$
|
3515
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3219
3516
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3220
3517
|
}
|
3221
3518
|
});
|
3222
3519
|
const service = ({ strapi: strapi2 }) => ({
|
3223
3520
|
findAllContentTypes() {
|
3224
|
-
const { toContentManagerModel } = getService$
|
3521
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3225
3522
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3226
3523
|
},
|
3227
3524
|
findContentType(uid2) {
|
3228
|
-
const { toContentManagerModel } = getService$
|
3525
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3229
3526
|
const contentType = strapi2.contentTypes[uid2];
|
3230
3527
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3231
3528
|
},
|
@@ -3254,7 +3551,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3254
3551
|
return this.findConfiguration(contentType);
|
3255
3552
|
},
|
3256
3553
|
findComponentsConfigurations(contentType) {
|
3257
|
-
return getService$
|
3554
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3258
3555
|
},
|
3259
3556
|
syncConfigurations() {
|
3260
3557
|
return configurationService.syncConfigurations();
|
@@ -3435,12 +3732,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3435
3732
|
ability: userAbility,
|
3436
3733
|
model
|
3437
3734
|
});
|
3438
|
-
const
|
3735
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3736
|
+
const toSubject = (entity) => {
|
3737
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3738
|
+
};
|
3439
3739
|
const can = (action, entity, field) => {
|
3440
|
-
|
3740
|
+
const subject = toSubject(entity);
|
3741
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3742
|
+
return (
|
3743
|
+
// Test the original action to see if it passes
|
3744
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3745
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3746
|
+
);
|
3441
3747
|
};
|
3442
3748
|
const cannot = (action, entity, field) => {
|
3443
|
-
|
3749
|
+
const subject = toSubject(entity);
|
3750
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3751
|
+
return (
|
3752
|
+
// Test both the original action
|
3753
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3754
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3755
|
+
);
|
3444
3756
|
};
|
3445
3757
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3446
3758
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3511,7 +3823,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3511
3823
|
return userAbility.can(action);
|
3512
3824
|
},
|
3513
3825
|
async registerPermissions() {
|
3514
|
-
const displayedContentTypes = getService$
|
3826
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3515
3827
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3516
3828
|
const actions = [
|
3517
3829
|
{
|
@@ -3717,6 +4029,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3717
4029
|
const attribute = model.attributes[attributeName];
|
3718
4030
|
switch (attribute.type) {
|
3719
4031
|
case "relation": {
|
4032
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4033
|
+
if (isMorphRelation) {
|
4034
|
+
break;
|
4035
|
+
}
|
3720
4036
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3721
4037
|
populateAcc[attributeName] = {
|
3722
4038
|
count: true,
|
@@ -3783,7 +4099,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3783
4099
|
return populateQuery;
|
3784
4100
|
};
|
3785
4101
|
const buildDeepPopulate = (uid2) => {
|
3786
|
-
return getService$
|
4102
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3787
4103
|
};
|
3788
4104
|
const populateBuilder = (uid2) => {
|
3789
4105
|
let getInitialPopulate = async () => {
|
@@ -3968,7 +4284,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3968
4284
|
*/
|
3969
4285
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3970
4286
|
const versionsByLocale = groupBy("locale", allVersions);
|
3971
|
-
|
4287
|
+
if (version.locale) {
|
4288
|
+
delete versionsByLocale[version.locale];
|
4289
|
+
}
|
3972
4290
|
const model = strapi2.getModel(uid2);
|
3973
4291
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3974
4292
|
const traversalFunction = async (localeVersion) => traverseEntity(
|
@@ -4015,8 +4333,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4015
4333
|
const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
|
4016
4334
|
return matchLocale && matchStatus;
|
4017
4335
|
});
|
4018
|
-
if (!availableStatus)
|
4019
|
-
return availableStatus;
|
4336
|
+
if (!availableStatus) return availableStatus;
|
4020
4337
|
return pick(AVAILABLE_STATUS_FIELDS, availableStatus);
|
4021
4338
|
},
|
4022
4339
|
/**
|
@@ -4026,8 +4343,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4026
4343
|
* @returns
|
4027
4344
|
*/
|
4028
4345
|
async getManyAvailableStatus(uid2, documents) {
|
4029
|
-
if (!documents.length)
|
4030
|
-
return [];
|
4346
|
+
if (!documents.length) return [];
|
4031
4347
|
const status = documents[0].publishedAt !== null ? "published" : "draft";
|
4032
4348
|
const locale = documents[0]?.locale;
|
4033
4349
|
const otherStatus = status === "published" ? "draft" : "published";
|
@@ -4054,10 +4370,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4054
4370
|
} else if (otherVersion) {
|
4055
4371
|
draftVersion = otherVersion;
|
4056
4372
|
}
|
4057
|
-
if (!draftVersion)
|
4058
|
-
|
4059
|
-
if (!publishedVersion)
|
4060
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
4373
|
+
if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4374
|
+
if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
|
4061
4375
|
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4062
4376
|
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
4063
4377
|
},
|
@@ -4094,7 +4408,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4094
4408
|
*/
|
4095
4409
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4096
4410
|
if (!document) {
|
4097
|
-
return
|
4411
|
+
return {
|
4412
|
+
data: document,
|
4413
|
+
meta: {
|
4414
|
+
availableLocales: [],
|
4415
|
+
availableStatus: []
|
4416
|
+
}
|
4417
|
+
};
|
4098
4418
|
}
|
4099
4419
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4100
4420
|
if (!hasDraftAndPublish) {
|
@@ -4202,10 +4522,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4202
4522
|
async clone(id, body, uid2) {
|
4203
4523
|
const populate = await buildDeepPopulate(uid2);
|
4204
4524
|
const params = {
|
4205
|
-
data:
|
4206
|
-
...omitIdField(body),
|
4207
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4208
|
-
},
|
4525
|
+
data: omitIdField(body),
|
4209
4526
|
populate
|
4210
4527
|
};
|
4211
4528
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4321,7 +4638,8 @@ const services = {
|
|
4321
4638
|
permission,
|
4322
4639
|
"populate-builder": populateBuilder$1,
|
4323
4640
|
uid,
|
4324
|
-
...history.services ? history.services : {}
|
4641
|
+
...history.services ? history.services : {},
|
4642
|
+
...preview.services ? preview.services : {}
|
4325
4643
|
};
|
4326
4644
|
const index = () => {
|
4327
4645
|
return {
|