@strapi/content-manager 0.0.0-experimental.32c4b04580cc12400710050c8198e46b3644cfd4 → 0.0.0-experimental.39bf1ab0d2e327b0a192d2f5adcb4182de865411
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-CzVt9QCC.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-CzVt9QCC.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js → ComponentConfigurationPage-DYq8aqos.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-DYq8aqos.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-Xp7lun0f.js → EditConfigurationPage-C9IATpr0.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-C9IATpr0.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs → EditConfigurationPage-CLDwrUv5.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-CLDwrUv5.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-Ch-uBvbv.js} +63 -13
- package/dist/_chunks/EditViewPage-Ch-uBvbv.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-DtKM7Jgw.mjs} +63 -12
- package/dist/_chunks/EditViewPage-DtKM7Jgw.mjs.map +1 -0
- package/dist/_chunks/{Field-Bfph5SOd.js → Field-B9ADaInZ.js} +235 -164
- package/dist/_chunks/Field-B9ADaInZ.js.map +1 -0
- package/dist/_chunks/{Field-Cs7duwWd.mjs → Field-Bn1jgMeF.mjs} +232 -160
- package/dist/_chunks/Field-Bn1jgMeF.mjs.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-Dg_GS5TQ.mjs → Form-BB5i9Pxl.mjs} +37 -18
- package/dist/_chunks/Form-BB5i9Pxl.mjs.map +1 -0
- package/dist/_chunks/{Form-CPYqIWDG.js → Form-C3kjKrPw.js} +39 -21
- package/dist/_chunks/Form-C3kjKrPw.js.map +1 -0
- package/dist/_chunks/{History-DNQkXANT.js → History-AwrK0-SA.js} +42 -100
- package/dist/_chunks/History-AwrK0-SA.js.map +1 -0
- package/dist/_chunks/{History-wrnHqf09.mjs → History-Cw2Q7OQL.mjs} +43 -100
- package/dist/_chunks/History-Cw2Q7OQL.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-B47JIu1e.mjs} +19 -8
- package/dist/_chunks/ListConfigurationPage-B47JIu1e.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-CNTJ0DBm.js} +19 -9
- package/dist/_chunks/ListConfigurationPage-CNTJ0DBm.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-Be_UEBar.js} +109 -78
- package/dist/_chunks/ListViewPage-Be_UEBar.js.map +1 -0
- package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-DuvjX6ra.mjs} +106 -74
- package/dist/_chunks/ListViewPage-DuvjX6ra.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-B1J0KUCO.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-B1J0KUCO.js.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-C6M-Q0Tv.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-C6M-Q0Tv.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-CAi3zCAD.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-CAi3zCAD.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-CN34TlEE.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-CN34TlEE.js.map} +1 -1
- package/dist/_chunks/Preview-BrBRcL10.mjs +293 -0
- package/dist/_chunks/Preview-BrBRcL10.mjs.map +1 -0
- package/dist/_chunks/Preview-DOqm5jcJ.js +311 -0
- package/dist/_chunks/Preview-DOqm5jcJ.js.map +1 -0
- package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-_K-HYOiM.mjs} +76 -42
- package/dist/_chunks/Relations-_K-HYOiM.mjs.map +1 -0
- package/dist/_chunks/{Relations-CtELXYIK.js → Relations-xtKZHtTN.js} +76 -43
- package/dist/_chunks/Relations-xtKZHtTN.js.map +1 -0
- package/dist/_chunks/{en-uOUIxfcQ.js → en-BK8Xyl5I.js} +28 -15
- package/dist/_chunks/{en-uOUIxfcQ.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-BrCTWlZv.mjs → en-Dtk_ot79.mjs} +28 -15
- package/dist/_chunks/{en-BrCTWlZv.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-OerGjbAN.js → index-BlX-OdHL.js} +1092 -758
- package/dist/_chunks/index-BlX-OdHL.js.map +1 -0
- package/dist/_chunks/{index-c_5DdJi-.mjs → index-tETMKK2G.mjs} +1110 -776
- package/dist/_chunks/index-tETMKK2G.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-oPBiO7RY.mjs → layout-BaQBaz56.mjs} +23 -10
- package/dist/_chunks/layout-BaQBaz56.mjs.map +1 -0
- package/dist/_chunks/{layout-Ci7qHlFb.js → layout-D8Sz3KxF.js} +23 -11
- package/dist/_chunks/layout-D8Sz3KxF.js.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-COBpStiF.js → relations-CAbbX8Sa.js} +6 -7
- package/dist/_chunks/relations-CAbbX8Sa.js.map +1 -0
- package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-CsfmCqOU.mjs} +6 -7
- package/dist/_chunks/relations-CsfmCqOU.mjs.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 +5 -4
- package/dist/admin/src/content-manager.d.ts +3 -2
- package/dist/admin/src/exports.d.ts +1 -1
- 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/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- 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 +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- 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 +578 -271
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +578 -270
- 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/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.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/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-BLsjc5F-.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-C-ukDOB7.js.map +0 -1
- package/dist/_chunks/Field-Bfph5SOd.js.map +0 -1
- package/dist/_chunks/Field-Cs7duwWd.mjs.map +0 -1
- package/dist/_chunks/Form-CPYqIWDG.js.map +0 -1
- package/dist/_chunks/Form-Dg_GS5TQ.mjs.map +0 -1
- package/dist/_chunks/History-DNQkXANT.js.map +0 -1
- package/dist/_chunks/History-wrnHqf09.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-CUQxfpjT.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DScmJVkW.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BsLiH2-2.js.map +0 -1
- package/dist/_chunks/ListViewPage-C4IvrMgY.mjs.map +0 -1
- package/dist/_chunks/Relations-BZr8tL0R.mjs.map +0 -1
- package/dist/_chunks/Relations-CtELXYIK.js.map +0 -1
- package/dist/_chunks/index-OerGjbAN.js.map +0 -1
- package/dist/_chunks/index-c_5DdJi-.mjs.map +0 -1
- package/dist/_chunks/layout-Ci7qHlFb.js.map +0 -1
- package/dist/_chunks/layout-oPBiO7RY.mjs.map +0 -1
- package/dist/_chunks/relations-BIdWFjdq.mjs.map +0 -1
- package/dist/_chunks/relations-COBpStiF.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.js
CHANGED
@@ -10,8 +10,7 @@ const qs = require("qs");
|
|
10
10
|
const slugify = require("@sindresorhus/slugify");
|
11
11
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
12
12
|
function _interopNamespace(e) {
|
13
|
-
if (e && e.__esModule)
|
14
|
-
return e;
|
13
|
+
if (e && e.__esModule) return e;
|
15
14
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
16
15
|
if (e) {
|
17
16
|
for (const k in e) {
|
@@ -33,10 +32,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
32
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
33
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
34
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
35
|
+
const getService$2 = (name) => {
|
37
36
|
return strapi.plugin("content-manager").service(name);
|
38
37
|
};
|
39
|
-
function getService(strapi2, name) {
|
38
|
+
function getService$1(strapi2, name) {
|
40
39
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
40
|
}
|
42
41
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +71,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
71
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
72
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
73
|
}
|
75
|
-
const permissionChecker2 = getService$
|
74
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
75
|
userAbility: ctx.state.userAbility,
|
77
76
|
model: ctx.query.contentType
|
78
77
|
});
|
@@ -80,7 +79,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
79
|
return ctx.forbidden();
|
81
80
|
}
|
82
81
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
82
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
83
|
query: {
|
85
84
|
...query,
|
86
85
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +104,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
104
|
async restoreVersion(ctx) {
|
106
105
|
const request = ctx.request;
|
107
106
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
107
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
108
|
userAbility: ctx.state.userAbility,
|
110
109
|
model: request.body.contentType
|
111
110
|
});
|
112
111
|
if (permissionChecker2.cannot.update()) {
|
113
112
|
throw new strapiUtils.errors.ForbiddenError();
|
114
113
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
114
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
115
|
request.params.versionId
|
117
116
|
);
|
118
117
|
return {
|
@@ -121,7 +120,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
120
|
}
|
122
121
|
};
|
123
122
|
};
|
124
|
-
const controllers$
|
123
|
+
const controllers$2 = {
|
125
124
|
"history-version": createHistoryVersionController
|
126
125
|
/**
|
127
126
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -167,8 +166,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
167
166
|
};
|
168
167
|
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
169
168
|
if (Array.isArray(versionRelationData)) {
|
170
|
-
if (versionRelationData.length === 0)
|
171
|
-
return versionRelationData;
|
169
|
+
if (versionRelationData.length === 0) return versionRelationData;
|
172
170
|
const existingAndMissingRelations = await Promise.all(
|
173
171
|
versionRelationData.map((relation) => {
|
174
172
|
return strapi2.documents(attribute.target).findOne({
|
@@ -199,10 +197,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
197
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
198
|
};
|
201
199
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
200
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
201
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
202
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
203
|
const getLocaleDictionary = async () => {
|
204
|
-
if (!localesService)
|
205
|
-
return {};
|
204
|
+
if (!localesService) return {};
|
206
205
|
const locales = await localesService.find() || [];
|
207
206
|
return locales.reduce(
|
208
207
|
(acc, locale) => {
|
@@ -226,9 +225,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
225
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
226
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
227
|
};
|
229
|
-
const
|
228
|
+
const getComponentFields = (componentUID) => {
|
229
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
230
|
+
(fieldsAcc, [key, attribute]) => {
|
231
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
232
|
+
fieldsAcc.push(key);
|
233
|
+
}
|
234
|
+
return fieldsAcc;
|
235
|
+
},
|
236
|
+
[]
|
237
|
+
);
|
238
|
+
};
|
239
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
240
|
const model = strapi2.getModel(uid2);
|
231
241
|
const attributes = Object.entries(model.attributes);
|
242
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
243
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
244
|
switch (attribute.type) {
|
234
245
|
case "relation": {
|
@@ -238,23 +249,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
238
249
|
}
|
239
250
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
240
251
|
if (isVisible2) {
|
241
|
-
acc[attributeName] = {
|
252
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
242
253
|
}
|
243
254
|
break;
|
244
255
|
}
|
245
256
|
case "media": {
|
246
|
-
acc[attributeName] = {
|
257
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
247
258
|
break;
|
248
259
|
}
|
249
260
|
case "component": {
|
250
261
|
const populate = getDeepPopulate2(attribute.component);
|
251
|
-
acc[attributeName] = {
|
262
|
+
acc[attributeName] = {
|
263
|
+
populate,
|
264
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
265
|
+
};
|
252
266
|
break;
|
253
267
|
}
|
254
268
|
case "dynamiczone": {
|
255
269
|
const populatedComponents = (attribute.components || []).reduce(
|
256
270
|
(acc2, componentUID) => {
|
257
|
-
acc2[componentUID] = {
|
271
|
+
acc2[componentUID] = {
|
272
|
+
populate: getDeepPopulate2(componentUID),
|
273
|
+
[fieldSelector]: getComponentFields(componentUID)
|
274
|
+
};
|
258
275
|
return acc2;
|
259
276
|
},
|
260
277
|
{}
|
@@ -316,6 +333,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
316
333
|
getRelationRestoreValue,
|
317
334
|
getMediaRestoreValue,
|
318
335
|
getDefaultLocale,
|
336
|
+
isLocalizedContentType,
|
319
337
|
getLocaleDictionary,
|
320
338
|
getRetentionDays,
|
321
339
|
getVersionStatus,
|
@@ -338,7 +356,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
338
356
|
});
|
339
357
|
},
|
340
358
|
async findVersionsPage(params) {
|
341
|
-
const
|
359
|
+
const model = strapi2.getModel(params.query.contentType);
|
360
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
361
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
362
|
+
let locale = null;
|
363
|
+
if (isLocalizedContentType) {
|
364
|
+
locale = params.query.locale || defaultLocale;
|
365
|
+
}
|
342
366
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
343
367
|
query.findPage({
|
344
368
|
...params.query,
|
@@ -360,7 +384,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
360
384
|
const attributeValue = entry.data[attributeKey];
|
361
385
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
362
386
|
if (attributeSchema.type === "media") {
|
363
|
-
const permissionChecker2 = getService$
|
387
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
364
388
|
userAbility: params.state.userAbility,
|
365
389
|
model: "plugin::upload.file"
|
366
390
|
});
|
@@ -383,7 +407,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
383
407
|
if (userToPopulate == null) {
|
384
408
|
return null;
|
385
409
|
}
|
386
|
-
return strapi2.query("admin::user").findOne({
|
410
|
+
return strapi2.query("admin::user").findOne({
|
411
|
+
where: {
|
412
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
413
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
414
|
+
}
|
415
|
+
});
|
387
416
|
})
|
388
417
|
);
|
389
418
|
return {
|
@@ -396,7 +425,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
396
425
|
[attributeKey]: adminUsers
|
397
426
|
};
|
398
427
|
}
|
399
|
-
const permissionChecker2 = getService$
|
428
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
400
429
|
userAbility: params.state.userAbility,
|
401
430
|
model: attributeSchema.target
|
402
431
|
});
|
@@ -494,6 +523,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
494
523
|
}
|
495
524
|
};
|
496
525
|
};
|
526
|
+
const shouldCreateHistoryVersion = (context) => {
|
527
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
528
|
+
return false;
|
529
|
+
}
|
530
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
return true;
|
540
|
+
};
|
541
|
+
const getSchemas = (uid2) => {
|
542
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
543
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
544
|
+
(currentComponentSchemas, key) => {
|
545
|
+
const fieldSchema = attributesSchema[key];
|
546
|
+
if (fieldSchema.type === "component") {
|
547
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
548
|
+
return {
|
549
|
+
...currentComponentSchemas,
|
550
|
+
[fieldSchema.component]: componentSchema
|
551
|
+
};
|
552
|
+
}
|
553
|
+
return currentComponentSchemas;
|
554
|
+
},
|
555
|
+
{}
|
556
|
+
);
|
557
|
+
return {
|
558
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
559
|
+
componentsSchemas
|
560
|
+
};
|
561
|
+
};
|
497
562
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
498
563
|
const state = {
|
499
564
|
deleteExpiredJob: null,
|
@@ -506,76 +571,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
506
571
|
return;
|
507
572
|
}
|
508
573
|
strapi2.documents.use(async (context, next) => {
|
509
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
510
|
-
return next();
|
511
|
-
}
|
512
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
513
|
-
return next();
|
514
|
-
}
|
515
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
516
|
-
return next();
|
517
|
-
}
|
518
|
-
const contentTypeUid = context.contentType.uid;
|
519
|
-
if (!contentTypeUid.startsWith("api::")) {
|
520
|
-
return next();
|
521
|
-
}
|
522
574
|
const result = await next();
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
575
|
+
if (!shouldCreateHistoryVersion(context)) {
|
576
|
+
return result;
|
577
|
+
}
|
578
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
527
579
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
528
|
-
const
|
529
|
-
if (
|
530
|
-
|
531
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
532
|
-
);
|
533
|
-
return next();
|
580
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
581
|
+
if (!locales.length) {
|
582
|
+
return result;
|
534
583
|
}
|
535
|
-
const
|
536
|
-
|
537
|
-
|
538
|
-
|
584
|
+
const uid2 = context.contentType.uid;
|
585
|
+
const schemas = getSchemas(uid2);
|
586
|
+
const model = strapi2.getModel(uid2);
|
587
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
588
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
589
|
+
where: {
|
590
|
+
documentId,
|
591
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
592
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
593
|
+
},
|
594
|
+
populate: serviceUtils.getDeepPopulate(
|
595
|
+
uid2,
|
596
|
+
true
|
597
|
+
/* use database syntax */
|
598
|
+
)
|
539
599
|
});
|
540
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
541
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
542
|
-
const componentsSchemas = Object.keys(
|
543
|
-
attributesSchema
|
544
|
-
).reduce((currentComponentSchemas, key) => {
|
545
|
-
const fieldSchema = attributesSchema[key];
|
546
|
-
if (fieldSchema.type === "component") {
|
547
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
548
|
-
return {
|
549
|
-
...currentComponentSchemas,
|
550
|
-
[fieldSchema.component]: componentSchema
|
551
|
-
};
|
552
|
-
}
|
553
|
-
return currentComponentSchemas;
|
554
|
-
}, {});
|
555
600
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
556
|
-
onCommit(() => {
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
601
|
+
onCommit(async () => {
|
602
|
+
for (const entry of localeEntries) {
|
603
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
604
|
+
await getService$1(strapi2, "history").createVersion({
|
605
|
+
contentType: uid2,
|
606
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
607
|
+
relatedDocumentId: documentId,
|
608
|
+
locale: entry.locale,
|
609
|
+
status,
|
610
|
+
...schemas
|
611
|
+
});
|
612
|
+
}
|
566
613
|
});
|
567
614
|
});
|
568
615
|
return result;
|
569
616
|
});
|
570
|
-
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
617
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
571
618
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
572
619
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
573
620
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
574
621
|
where: {
|
575
622
|
created_at: {
|
576
|
-
$lt: expirationDate
|
623
|
+
$lt: expirationDate
|
577
624
|
}
|
578
625
|
}
|
626
|
+
}).catch((error) => {
|
627
|
+
if (error instanceof Error) {
|
628
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
629
|
+
}
|
579
630
|
});
|
580
631
|
});
|
581
632
|
state.isInitialized = true;
|
@@ -587,17 +638,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
587
638
|
}
|
588
639
|
};
|
589
640
|
};
|
590
|
-
const services$
|
641
|
+
const services$2 = {
|
591
642
|
history: createHistoryService,
|
592
643
|
lifecycles: createLifecyclesService
|
593
644
|
};
|
594
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
645
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
595
646
|
const historyVersionRouter = {
|
596
647
|
type: "admin",
|
597
648
|
routes: [
|
598
649
|
{
|
599
650
|
method: "GET",
|
600
|
-
info,
|
651
|
+
info: info$1,
|
601
652
|
path: "/history-versions",
|
602
653
|
handler: "history-version.findMany",
|
603
654
|
config: {
|
@@ -606,7 +657,7 @@ const historyVersionRouter = {
|
|
606
657
|
},
|
607
658
|
{
|
608
659
|
method: "PUT",
|
609
|
-
info,
|
660
|
+
info: info$1,
|
610
661
|
path: "/history-versions/:versionId/restore",
|
611
662
|
handler: "history-version.restoreVersion",
|
612
663
|
config: {
|
@@ -615,7 +666,7 @@ const historyVersionRouter = {
|
|
615
666
|
}
|
616
667
|
]
|
617
668
|
};
|
618
|
-
const routes$
|
669
|
+
const routes$2 = {
|
619
670
|
"history-version": historyVersionRouter
|
620
671
|
};
|
621
672
|
const historyVersion = {
|
@@ -662,21 +713,21 @@ const historyVersion = {
|
|
662
713
|
}
|
663
714
|
}
|
664
715
|
};
|
665
|
-
const getFeature = () => {
|
716
|
+
const getFeature$1 = () => {
|
666
717
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
667
718
|
return {
|
668
719
|
register({ strapi: strapi2 }) {
|
669
720
|
strapi2.get("models").add(historyVersion);
|
670
721
|
},
|
671
722
|
bootstrap({ strapi: strapi2 }) {
|
672
|
-
getService(strapi2, "lifecycles").bootstrap();
|
723
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
673
724
|
},
|
674
725
|
destroy({ strapi: strapi2 }) {
|
675
|
-
getService(strapi2, "lifecycles").destroy();
|
726
|
+
getService$1(strapi2, "lifecycles").destroy();
|
676
727
|
},
|
677
|
-
controllers: controllers$
|
678
|
-
services: services$
|
679
|
-
routes: routes$
|
728
|
+
controllers: controllers$2,
|
729
|
+
services: services$2,
|
730
|
+
routes: routes$2
|
680
731
|
};
|
681
732
|
}
|
682
733
|
return {
|
@@ -685,9 +736,205 @@ const getFeature = () => {
|
|
685
736
|
}
|
686
737
|
};
|
687
738
|
};
|
688
|
-
const history = getFeature();
|
739
|
+
const history = getFeature$1();
|
740
|
+
const FEATURE_ID = "preview";
|
741
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
742
|
+
const previewRouter = {
|
743
|
+
type: "admin",
|
744
|
+
routes: [
|
745
|
+
{
|
746
|
+
method: "GET",
|
747
|
+
info,
|
748
|
+
path: "/preview/url/:contentType",
|
749
|
+
handler: "preview.getPreviewUrl",
|
750
|
+
config: {
|
751
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
752
|
+
}
|
753
|
+
}
|
754
|
+
]
|
755
|
+
};
|
756
|
+
const routes$1 = {
|
757
|
+
preview: previewRouter
|
758
|
+
};
|
759
|
+
function getService(strapi2, name) {
|
760
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
761
|
+
}
|
762
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
763
|
+
// Will be undefined for single types
|
764
|
+
documentId: yup__namespace.string(),
|
765
|
+
locale: yup__namespace.string().nullable(),
|
766
|
+
status: yup__namespace.string()
|
767
|
+
}).required();
|
768
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
769
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
770
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
771
|
+
const model = strapi2.getModel(uid2);
|
772
|
+
if (!model || model.modelType !== "contentType") {
|
773
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
774
|
+
}
|
775
|
+
const isSingleType = model?.kind === "singleType";
|
776
|
+
if (!isSingleType && !params.documentId) {
|
777
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
778
|
+
}
|
779
|
+
if (isSingleType) {
|
780
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
781
|
+
if (!doc) {
|
782
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
783
|
+
}
|
784
|
+
newParams.documentId = doc?.documentId;
|
785
|
+
}
|
786
|
+
if (!newParams.status) {
|
787
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
788
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
789
|
+
}
|
790
|
+
return newParams;
|
791
|
+
};
|
792
|
+
const createPreviewController = () => {
|
793
|
+
return {
|
794
|
+
/**
|
795
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
796
|
+
* in the Content Manager.
|
797
|
+
*/
|
798
|
+
async getPreviewUrl(ctx) {
|
799
|
+
const uid2 = ctx.params.contentType;
|
800
|
+
const query = ctx.request.query;
|
801
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
802
|
+
const previewService = getService(strapi, "preview");
|
803
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
804
|
+
if (!url) {
|
805
|
+
ctx.status = 204;
|
806
|
+
}
|
807
|
+
return {
|
808
|
+
data: { url }
|
809
|
+
};
|
810
|
+
}
|
811
|
+
};
|
812
|
+
};
|
813
|
+
const controllers$1 = {
|
814
|
+
preview: createPreviewController
|
815
|
+
/**
|
816
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
817
|
+
* passing a controller factory as the value, instead of a controller object directly
|
818
|
+
*/
|
819
|
+
};
|
820
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
821
|
+
const config = getService(strapi2, "preview-config");
|
822
|
+
return {
|
823
|
+
async getPreviewUrl(uid2, params) {
|
824
|
+
const handler = config.getPreviewHandler();
|
825
|
+
try {
|
826
|
+
return handler(uid2, params);
|
827
|
+
} catch (error) {
|
828
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
829
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
830
|
+
}
|
831
|
+
return;
|
832
|
+
}
|
833
|
+
};
|
834
|
+
};
|
835
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
836
|
+
const middlewares = strapi.config.get("middlewares");
|
837
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
838
|
+
if (currentMiddleware === middleware.name) {
|
839
|
+
return middleware;
|
840
|
+
}
|
841
|
+
if (currentMiddleware.name === middleware.name) {
|
842
|
+
return fp.mergeWith(
|
843
|
+
(objValue, srcValue) => {
|
844
|
+
if (Array.isArray(objValue)) {
|
845
|
+
return objValue.concat(srcValue);
|
846
|
+
}
|
847
|
+
return void 0;
|
848
|
+
},
|
849
|
+
currentMiddleware,
|
850
|
+
middleware
|
851
|
+
);
|
852
|
+
}
|
853
|
+
return currentMiddleware;
|
854
|
+
});
|
855
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
856
|
+
};
|
857
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
858
|
+
return {
|
859
|
+
register() {
|
860
|
+
if (!this.isEnabled()) {
|
861
|
+
return;
|
862
|
+
}
|
863
|
+
const config = strapi2.config.get("admin.preview");
|
864
|
+
if (config.config?.allowedOrigins) {
|
865
|
+
extendMiddlewareConfiguration({
|
866
|
+
name: "strapi::security",
|
867
|
+
config: {
|
868
|
+
contentSecurityPolicy: {
|
869
|
+
directives: {
|
870
|
+
"frame-src": config.config.allowedOrigins
|
871
|
+
}
|
872
|
+
}
|
873
|
+
}
|
874
|
+
});
|
875
|
+
}
|
876
|
+
},
|
877
|
+
isEnabled() {
|
878
|
+
const config = strapi2.config.get("admin.preview");
|
879
|
+
if (!config) {
|
880
|
+
return false;
|
881
|
+
}
|
882
|
+
return config?.enabled ?? true;
|
883
|
+
},
|
884
|
+
/**
|
885
|
+
* Validate if the configuration is valid
|
886
|
+
*/
|
887
|
+
validate() {
|
888
|
+
if (!this.isEnabled()) {
|
889
|
+
return;
|
890
|
+
}
|
891
|
+
const handler = this.getPreviewHandler();
|
892
|
+
if (typeof handler !== "function") {
|
893
|
+
throw new strapiUtils.errors.ValidationError(
|
894
|
+
"Preview configuration is invalid. Handler must be a function"
|
895
|
+
);
|
896
|
+
}
|
897
|
+
},
|
898
|
+
/**
|
899
|
+
* Utility to get the preview handler from the configuration
|
900
|
+
*/
|
901
|
+
getPreviewHandler() {
|
902
|
+
const config = strapi2.config.get("admin.preview");
|
903
|
+
const emptyHandler = () => {
|
904
|
+
return void 0;
|
905
|
+
};
|
906
|
+
if (!this.isEnabled()) {
|
907
|
+
return emptyHandler;
|
908
|
+
}
|
909
|
+
return config?.config?.handler || emptyHandler;
|
910
|
+
}
|
911
|
+
};
|
912
|
+
};
|
913
|
+
const services$1 = {
|
914
|
+
preview: createPreviewService,
|
915
|
+
"preview-config": createPreviewConfigService
|
916
|
+
};
|
917
|
+
const getFeature = () => {
|
918
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
919
|
+
return {};
|
920
|
+
}
|
921
|
+
return {
|
922
|
+
register() {
|
923
|
+
const config = getService(strapi, "preview-config");
|
924
|
+
config.validate();
|
925
|
+
config.register();
|
926
|
+
},
|
927
|
+
bootstrap() {
|
928
|
+
},
|
929
|
+
routes: routes$1,
|
930
|
+
controllers: controllers$1,
|
931
|
+
services: services$1
|
932
|
+
};
|
933
|
+
};
|
934
|
+
const preview = getFeature();
|
689
935
|
const register = async ({ strapi: strapi2 }) => {
|
690
936
|
await history.register?.({ strapi: strapi2 });
|
937
|
+
await preview.register?.({ strapi: strapi2 });
|
691
938
|
};
|
692
939
|
const ALLOWED_WEBHOOK_EVENTS = {
|
693
940
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -697,11 +944,12 @@ const bootstrap = async () => {
|
|
697
944
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
698
945
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
699
946
|
});
|
700
|
-
getService$
|
701
|
-
await getService$
|
702
|
-
await getService$
|
703
|
-
await getService$
|
947
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
948
|
+
await getService$2("components").syncConfigurations();
|
949
|
+
await getService$2("content-types").syncConfigurations();
|
950
|
+
await getService$2("permission").registerPermissions();
|
704
951
|
await history.bootstrap?.({ strapi });
|
952
|
+
await preview.bootstrap?.({ strapi });
|
705
953
|
};
|
706
954
|
const destroy = async ({ strapi: strapi2 }) => {
|
707
955
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1191,7 +1439,8 @@ const admin = {
|
|
1191
1439
|
};
|
1192
1440
|
const routes = {
|
1193
1441
|
admin,
|
1194
|
-
...history.routes ? history.routes : {}
|
1442
|
+
...history.routes ? history.routes : {},
|
1443
|
+
...preview.routes ? preview.routes : {}
|
1195
1444
|
};
|
1196
1445
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1197
1446
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1202,6 +1451,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1202
1451
|
const hasPermissions = createPolicy({
|
1203
1452
|
name: "plugin::content-manager.hasPermissions",
|
1204
1453
|
validator: validateHasPermissionsInput,
|
1454
|
+
/**
|
1455
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1456
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1457
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1458
|
+
*/
|
1205
1459
|
handler(ctx, config = {}) {
|
1206
1460
|
const { actions = [], hasAtLeastOne = false } = config;
|
1207
1461
|
const { userAbility } = ctx.state;
|
@@ -1249,8 +1503,7 @@ const isSortable = (schema, name) => {
|
|
1249
1503
|
if (!___default.default.has(schema.attributes, name)) {
|
1250
1504
|
return false;
|
1251
1505
|
}
|
1252
|
-
if (schema.modelType === "component" && name === "id")
|
1253
|
-
return false;
|
1506
|
+
if (schema.modelType === "component" && name === "id") return false;
|
1254
1507
|
const attribute = schema.attributes[name];
|
1255
1508
|
if (NON_SORTABLES.includes(attribute.type)) {
|
1256
1509
|
return false;
|
@@ -1395,8 +1648,7 @@ const createDefaultSettings = async (schema) => {
|
|
1395
1648
|
};
|
1396
1649
|
};
|
1397
1650
|
const syncSettings = async (configuration, schema) => {
|
1398
|
-
if (fp.isEmpty(configuration.settings))
|
1399
|
-
return createDefaultSettings(schema);
|
1651
|
+
if (fp.isEmpty(configuration.settings)) return createDefaultSettings(schema);
|
1400
1652
|
const defaultField = getDefaultMainField(schema);
|
1401
1653
|
const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
|
1402
1654
|
return {
|
@@ -1443,7 +1695,7 @@ const createMetadasSchema = (schema) => {
|
|
1443
1695
|
if (!value) {
|
1444
1696
|
return strapiUtils.yup.string();
|
1445
1697
|
}
|
1446
|
-
const targetSchema = getService$
|
1698
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1447
1699
|
schema.attributes[key].targetModel
|
1448
1700
|
);
|
1449
1701
|
if (!targetSchema) {
|
@@ -1572,8 +1824,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1572
1824
|
}
|
1573
1825
|
switch (attribute.type) {
|
1574
1826
|
case "relation": {
|
1575
|
-
if (canCreate(attributePath))
|
1576
|
-
return body2;
|
1827
|
+
if (canCreate(attributePath)) return body2;
|
1577
1828
|
return fp.set(attributePath, { set: [] }, body2);
|
1578
1829
|
}
|
1579
1830
|
case "component": {
|
@@ -1583,8 +1834,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1583
1834
|
]);
|
1584
1835
|
}
|
1585
1836
|
default: {
|
1586
|
-
if (canCreate(attributePath))
|
1587
|
-
return body2;
|
1837
|
+
if (canCreate(attributePath)) return body2;
|
1588
1838
|
return fp.set(attributePath, null, body2);
|
1589
1839
|
}
|
1590
1840
|
}
|
@@ -1612,7 +1862,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
|
|
1612
1862
|
}
|
1613
1863
|
};
|
1614
1864
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1615
|
-
const documentMetadata2 = getService$
|
1865
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1616
1866
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1617
1867
|
let {
|
1618
1868
|
meta: { availableLocales, availableStatus }
|
@@ -1638,8 +1888,8 @@ const createDocument = async (ctx, opts) => {
|
|
1638
1888
|
const { userAbility, user } = ctx.state;
|
1639
1889
|
const { model } = ctx.params;
|
1640
1890
|
const { body } = ctx.request;
|
1641
|
-
const documentManager2 = getService$
|
1642
|
-
const permissionChecker2 = getService$
|
1891
|
+
const documentManager2 = getService$2("document-manager");
|
1892
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1643
1893
|
if (permissionChecker2.cannot.create()) {
|
1644
1894
|
throw new strapiUtils.errors.ForbiddenError();
|
1645
1895
|
}
|
@@ -1659,13 +1909,13 @@ const updateDocument = async (ctx, opts) => {
|
|
1659
1909
|
const { userAbility, user } = ctx.state;
|
1660
1910
|
const { id, model } = ctx.params;
|
1661
1911
|
const { body } = ctx.request;
|
1662
|
-
const documentManager2 = getService$
|
1663
|
-
const permissionChecker2 = getService$
|
1912
|
+
const documentManager2 = getService$2("document-manager");
|
1913
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1664
1914
|
if (permissionChecker2.cannot.update()) {
|
1665
1915
|
throw new strapiUtils.errors.ForbiddenError();
|
1666
1916
|
}
|
1667
1917
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1668
|
-
const populate = await getService$
|
1918
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1669
1919
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1670
1920
|
const [documentVersion, documentExists] = await Promise.all([
|
1671
1921
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
@@ -1682,7 +1932,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1682
1932
|
throw new strapiUtils.errors.ForbiddenError();
|
1683
1933
|
}
|
1684
1934
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1685
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1935
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1686
1936
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1687
1937
|
const sanitizedBody = await sanitizeFn(body);
|
1688
1938
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1696,14 +1946,14 @@ const collectionTypes = {
|
|
1696
1946
|
const { userAbility } = ctx.state;
|
1697
1947
|
const { model } = ctx.params;
|
1698
1948
|
const { query } = ctx.request;
|
1699
|
-
const documentMetadata2 = getService$
|
1700
|
-
const documentManager2 = getService$
|
1701
|
-
const permissionChecker2 = getService$
|
1949
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1950
|
+
const documentManager2 = getService$2("document-manager");
|
1951
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1702
1952
|
if (permissionChecker2.cannot.read()) {
|
1703
1953
|
return ctx.forbidden();
|
1704
1954
|
}
|
1705
1955
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1706
|
-
const populate = await getService$
|
1956
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1707
1957
|
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1708
1958
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1709
1959
|
{ ...permissionQuery, populate, locale, status },
|
@@ -1732,13 +1982,13 @@ const collectionTypes = {
|
|
1732
1982
|
async findOne(ctx) {
|
1733
1983
|
const { userAbility } = ctx.state;
|
1734
1984
|
const { model, id } = ctx.params;
|
1735
|
-
const documentManager2 = getService$
|
1736
|
-
const permissionChecker2 = getService$
|
1985
|
+
const documentManager2 = getService$2("document-manager");
|
1986
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1737
1987
|
if (permissionChecker2.cannot.read()) {
|
1738
1988
|
return ctx.forbidden();
|
1739
1989
|
}
|
1740
1990
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1741
|
-
const populate = await getService$
|
1991
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1742
1992
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1743
1993
|
const version = await documentManager2.findOne(id, model, {
|
1744
1994
|
populate,
|
@@ -1754,7 +2004,7 @@ const collectionTypes = {
|
|
1754
2004
|
permissionChecker2,
|
1755
2005
|
model,
|
1756
2006
|
// @ts-expect-error TODO: fix
|
1757
|
-
{ id, locale, publishedAt: null },
|
2007
|
+
{ documentId: id, locale, publishedAt: null },
|
1758
2008
|
{ availableLocales: true, availableStatus: false }
|
1759
2009
|
);
|
1760
2010
|
ctx.body = { data: {}, meta };
|
@@ -1769,7 +2019,7 @@ const collectionTypes = {
|
|
1769
2019
|
async create(ctx) {
|
1770
2020
|
const { userAbility } = ctx.state;
|
1771
2021
|
const { model } = ctx.params;
|
1772
|
-
const permissionChecker2 = getService$
|
2022
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1773
2023
|
const [totalEntries, document] = await Promise.all([
|
1774
2024
|
strapi.db.query(model).count(),
|
1775
2025
|
createDocument(ctx)
|
@@ -1790,7 +2040,7 @@ const collectionTypes = {
|
|
1790
2040
|
async update(ctx) {
|
1791
2041
|
const { userAbility } = ctx.state;
|
1792
2042
|
const { model } = ctx.params;
|
1793
|
-
const permissionChecker2 = getService$
|
2043
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1794
2044
|
const updatedVersion = await updateDocument(ctx);
|
1795
2045
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1796
2046
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1799,13 +2049,13 @@ const collectionTypes = {
|
|
1799
2049
|
const { userAbility, user } = ctx.state;
|
1800
2050
|
const { model, sourceId: id } = ctx.params;
|
1801
2051
|
const { body } = ctx.request;
|
1802
|
-
const documentManager2 = getService$
|
1803
|
-
const permissionChecker2 = getService$
|
2052
|
+
const documentManager2 = getService$2("document-manager");
|
2053
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1804
2054
|
if (permissionChecker2.cannot.create()) {
|
1805
2055
|
return ctx.forbidden();
|
1806
2056
|
}
|
1807
2057
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1808
|
-
const populate = await getService$
|
2058
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1809
2059
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1810
2060
|
const document = await documentManager2.findOne(id, model, {
|
1811
2061
|
populate,
|
@@ -1844,13 +2094,13 @@ const collectionTypes = {
|
|
1844
2094
|
async delete(ctx) {
|
1845
2095
|
const { userAbility } = ctx.state;
|
1846
2096
|
const { id, model } = ctx.params;
|
1847
|
-
const documentManager2 = getService$
|
1848
|
-
const permissionChecker2 = getService$
|
2097
|
+
const documentManager2 = getService$2("document-manager");
|
2098
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1849
2099
|
if (permissionChecker2.cannot.delete()) {
|
1850
2100
|
return ctx.forbidden();
|
1851
2101
|
}
|
1852
2102
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1853
|
-
const populate = await getService$
|
2103
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1854
2104
|
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1855
2105
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1856
2106
|
if (documentLocales.length === 0) {
|
@@ -1872,19 +2122,42 @@ const collectionTypes = {
|
|
1872
2122
|
const { userAbility } = ctx.state;
|
1873
2123
|
const { id, model } = ctx.params;
|
1874
2124
|
const { body } = ctx.request;
|
1875
|
-
const documentManager2 = getService$
|
1876
|
-
const permissionChecker2 = getService$
|
2125
|
+
const documentManager2 = getService$2("document-manager");
|
2126
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1877
2127
|
if (permissionChecker2.cannot.publish()) {
|
1878
2128
|
return ctx.forbidden();
|
1879
2129
|
}
|
1880
2130
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1881
2131
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1882
|
-
const populate = await getService$
|
1883
|
-
|
2132
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2133
|
+
let document;
|
2134
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2135
|
+
const isCreate = fp.isNil(id);
|
2136
|
+
if (isCreate) {
|
2137
|
+
if (permissionChecker2.cannot.create()) {
|
2138
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2139
|
+
}
|
2140
|
+
document = await createDocument(ctx, { populate });
|
2141
|
+
}
|
2142
|
+
const isUpdate = !isCreate;
|
2143
|
+
if (isUpdate) {
|
2144
|
+
const documentExists = documentManager2.exists(model, id);
|
2145
|
+
if (!documentExists) {
|
2146
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2147
|
+
}
|
2148
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2149
|
+
if (!document) {
|
2150
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2151
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2152
|
+
}
|
2153
|
+
document = await updateDocument(ctx);
|
2154
|
+
} else if (permissionChecker2.can.update(document)) {
|
2155
|
+
await updateDocument(ctx);
|
2156
|
+
}
|
2157
|
+
}
|
1884
2158
|
if (permissionChecker2.cannot.publish(document)) {
|
1885
2159
|
throw new strapiUtils.errors.ForbiddenError();
|
1886
2160
|
}
|
1887
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1888
2161
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1889
2162
|
locale
|
1890
2163
|
// TODO: Allow setting creator fields on publish
|
@@ -1904,13 +2177,13 @@ const collectionTypes = {
|
|
1904
2177
|
const { body } = ctx.request;
|
1905
2178
|
const { documentIds } = body;
|
1906
2179
|
await validateBulkActionInput(body);
|
1907
|
-
const documentManager2 = getService$
|
1908
|
-
const permissionChecker2 = getService$
|
2180
|
+
const documentManager2 = getService$2("document-manager");
|
2181
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1909
2182
|
if (permissionChecker2.cannot.publish()) {
|
1910
2183
|
return ctx.forbidden();
|
1911
2184
|
}
|
1912
2185
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1913
|
-
const populate = await getService$
|
2186
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1914
2187
|
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1915
2188
|
allowMultipleLocales: true
|
1916
2189
|
});
|
@@ -1935,12 +2208,14 @@ const collectionTypes = {
|
|
1935
2208
|
const { body } = ctx.request;
|
1936
2209
|
const { documentIds } = body;
|
1937
2210
|
await validateBulkActionInput(body);
|
1938
|
-
const documentManager2 = getService$
|
1939
|
-
const permissionChecker2 = getService$
|
2211
|
+
const documentManager2 = getService$2("document-manager");
|
2212
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1940
2213
|
if (permissionChecker2.cannot.unpublish()) {
|
1941
2214
|
return ctx.forbidden();
|
1942
2215
|
}
|
1943
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model
|
2216
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2217
|
+
allowMultipleLocales: true
|
2218
|
+
});
|
1944
2219
|
const entityPromises = documentIds.map(
|
1945
2220
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1946
2221
|
);
|
@@ -1963,8 +2238,8 @@ const collectionTypes = {
|
|
1963
2238
|
const {
|
1964
2239
|
body: { discardDraft, ...body }
|
1965
2240
|
} = ctx.request;
|
1966
|
-
const documentManager2 = getService$
|
1967
|
-
const permissionChecker2 = getService$
|
2241
|
+
const documentManager2 = getService$2("document-manager");
|
2242
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1968
2243
|
if (permissionChecker2.cannot.unpublish()) {
|
1969
2244
|
return ctx.forbidden();
|
1970
2245
|
}
|
@@ -1972,7 +2247,7 @@ const collectionTypes = {
|
|
1972
2247
|
return ctx.forbidden();
|
1973
2248
|
}
|
1974
2249
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1975
|
-
const populate = await getService$
|
2250
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1976
2251
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1977
2252
|
const document = await documentManager2.findOne(id, model, {
|
1978
2253
|
populate,
|
@@ -2003,13 +2278,13 @@ const collectionTypes = {
|
|
2003
2278
|
const { userAbility } = ctx.state;
|
2004
2279
|
const { id, model } = ctx.params;
|
2005
2280
|
const { body } = ctx.request;
|
2006
|
-
const documentManager2 = getService$
|
2007
|
-
const permissionChecker2 = getService$
|
2281
|
+
const documentManager2 = getService$2("document-manager");
|
2282
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2008
2283
|
if (permissionChecker2.cannot.discard()) {
|
2009
2284
|
return ctx.forbidden();
|
2010
2285
|
}
|
2011
2286
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2012
|
-
const populate = await getService$
|
2287
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2013
2288
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2014
2289
|
const document = await documentManager2.findOne(id, model, {
|
2015
2290
|
populate,
|
@@ -2034,13 +2309,13 @@ const collectionTypes = {
|
|
2034
2309
|
const { query, body } = ctx.request;
|
2035
2310
|
const { documentIds } = body;
|
2036
2311
|
await validateBulkActionInput(body);
|
2037
|
-
const documentManager2 = getService$
|
2038
|
-
const permissionChecker2 = getService$
|
2312
|
+
const documentManager2 = getService$2("document-manager");
|
2313
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2039
2314
|
if (permissionChecker2.cannot.delete()) {
|
2040
2315
|
return ctx.forbidden();
|
2041
2316
|
}
|
2042
2317
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2043
|
-
const populate = await getService$
|
2318
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2044
2319
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2045
2320
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2046
2321
|
populate,
|
@@ -2061,13 +2336,13 @@ const collectionTypes = {
|
|
2061
2336
|
async countDraftRelations(ctx) {
|
2062
2337
|
const { userAbility } = ctx.state;
|
2063
2338
|
const { model, id } = ctx.params;
|
2064
|
-
const documentManager2 = getService$
|
2065
|
-
const permissionChecker2 = getService$
|
2339
|
+
const documentManager2 = getService$2("document-manager");
|
2340
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2066
2341
|
if (permissionChecker2.cannot.read()) {
|
2067
2342
|
return ctx.forbidden();
|
2068
2343
|
}
|
2069
2344
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2070
|
-
const populate = await getService$
|
2345
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2071
2346
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2072
2347
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2073
2348
|
if (!entity) {
|
@@ -2086,8 +2361,8 @@ const collectionTypes = {
|
|
2086
2361
|
const ids = ctx.request.query.documentIds;
|
2087
2362
|
const locale = ctx.request.query.locale;
|
2088
2363
|
const { model } = ctx.params;
|
2089
|
-
const documentManager2 = getService$
|
2090
|
-
const permissionChecker2 = getService$
|
2364
|
+
const documentManager2 = getService$2("document-manager");
|
2365
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2091
2366
|
if (permissionChecker2.cannot.read()) {
|
2092
2367
|
return ctx.forbidden();
|
2093
2368
|
}
|
@@ -2111,13 +2386,13 @@ const collectionTypes = {
|
|
2111
2386
|
};
|
2112
2387
|
const components$1 = {
|
2113
2388
|
findComponents(ctx) {
|
2114
|
-
const components2 = getService$
|
2115
|
-
const { toDto } = getService$
|
2389
|
+
const components2 = getService$2("components").findAllComponents();
|
2390
|
+
const { toDto } = getService$2("data-mapper");
|
2116
2391
|
ctx.body = { data: components2.map(toDto) };
|
2117
2392
|
},
|
2118
2393
|
async findComponentConfiguration(ctx) {
|
2119
2394
|
const { uid: uid2 } = ctx.params;
|
2120
|
-
const componentService = getService$
|
2395
|
+
const componentService = getService$2("components");
|
2121
2396
|
const component = componentService.findComponent(uid2);
|
2122
2397
|
if (!component) {
|
2123
2398
|
return ctx.notFound("component.notFound");
|
@@ -2134,7 +2409,7 @@ const components$1 = {
|
|
2134
2409
|
async updateComponentConfiguration(ctx) {
|
2135
2410
|
const { uid: uid2 } = ctx.params;
|
2136
2411
|
const { body } = ctx.request;
|
2137
|
-
const componentService = getService$
|
2412
|
+
const componentService = getService$2("components");
|
2138
2413
|
const component = componentService.findComponent(uid2);
|
2139
2414
|
if (!component) {
|
2140
2415
|
return ctx.notFound("component.notFound");
|
@@ -2168,12 +2443,12 @@ const contentTypes = {
|
|
2168
2443
|
} catch (error) {
|
2169
2444
|
return ctx.send({ error }, 400);
|
2170
2445
|
}
|
2171
|
-
const contentTypes2 = getService$
|
2172
|
-
const { toDto } = getService$
|
2446
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2447
|
+
const { toDto } = getService$2("data-mapper");
|
2173
2448
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2174
2449
|
},
|
2175
2450
|
async findContentTypesSettings(ctx) {
|
2176
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2451
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2177
2452
|
const contentTypes2 = await findAllContentTypes();
|
2178
2453
|
const configurations = await Promise.all(
|
2179
2454
|
contentTypes2.map(async (contentType) => {
|
@@ -2187,7 +2462,7 @@ const contentTypes = {
|
|
2187
2462
|
},
|
2188
2463
|
async findContentTypeConfiguration(ctx) {
|
2189
2464
|
const { uid: uid2 } = ctx.params;
|
2190
|
-
const contentTypeService = getService$
|
2465
|
+
const contentTypeService = getService$2("content-types");
|
2191
2466
|
const contentType = await contentTypeService.findContentType(uid2);
|
2192
2467
|
if (!contentType) {
|
2193
2468
|
return ctx.notFound("contentType.notFound");
|
@@ -2209,13 +2484,13 @@ const contentTypes = {
|
|
2209
2484
|
const { userAbility } = ctx.state;
|
2210
2485
|
const { uid: uid2 } = ctx.params;
|
2211
2486
|
const { body } = ctx.request;
|
2212
|
-
const contentTypeService = getService$
|
2213
|
-
const metricsService = getService$
|
2487
|
+
const contentTypeService = getService$2("content-types");
|
2488
|
+
const metricsService = getService$2("metrics");
|
2214
2489
|
const contentType = await contentTypeService.findContentType(uid2);
|
2215
2490
|
if (!contentType) {
|
2216
2491
|
return ctx.notFound("contentType.notFound");
|
2217
2492
|
}
|
2218
|
-
if (!getService$
|
2493
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2219
2494
|
return ctx.forbidden();
|
2220
2495
|
}
|
2221
2496
|
let input;
|
@@ -2248,10 +2523,10 @@ const contentTypes = {
|
|
2248
2523
|
};
|
2249
2524
|
const init = {
|
2250
2525
|
getInitData(ctx) {
|
2251
|
-
const { toDto } = getService$
|
2252
|
-
const { findAllComponents } = getService$
|
2253
|
-
const { getAllFieldSizes } = getService$
|
2254
|
-
const { findAllContentTypes } = getService$
|
2526
|
+
const { toDto } = getService$2("data-mapper");
|
2527
|
+
const { findAllComponents } = getService$2("components");
|
2528
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2529
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2255
2530
|
ctx.body = {
|
2256
2531
|
data: {
|
2257
2532
|
fieldSizes: getAllFieldSizes(),
|
@@ -2287,36 +2562,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2287
2562
|
params.filters.$and.push(filtersClause);
|
2288
2563
|
};
|
2289
2564
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2290
|
-
const permissionChecker2 = getService$
|
2565
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2291
2566
|
userAbility,
|
2292
2567
|
model: model.uid
|
2293
2568
|
});
|
2294
|
-
|
2569
|
+
const isMainFieldListable = isListable(model, mainField);
|
2570
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2571
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2295
2572
|
return "id";
|
2296
2573
|
}
|
2297
|
-
if (
|
2298
|
-
|
2299
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2300
|
-
userAbility,
|
2301
|
-
model: "plugin::users-permissions.user"
|
2302
|
-
});
|
2303
|
-
if (userPermissionChecker.can.read()) {
|
2304
|
-
return "name";
|
2305
|
-
}
|
2306
|
-
}
|
2307
|
-
return "id";
|
2574
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2575
|
+
return "name";
|
2308
2576
|
}
|
2309
2577
|
return mainField;
|
2310
2578
|
};
|
2311
|
-
const addStatusToRelations = async (
|
2312
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2579
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2580
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2581
|
+
return relations2;
|
2582
|
+
}
|
2583
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2584
|
+
if (!relations2.length) {
|
2313
2585
|
return relations2;
|
2314
2586
|
}
|
2315
|
-
const
|
2316
|
-
const
|
2587
|
+
const firstRelation = relations2[0];
|
2588
|
+
const filters = {
|
2589
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2590
|
+
// NOTE: find the "opposite" status
|
2591
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2592
|
+
};
|
2593
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2594
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2595
|
+
filters
|
2596
|
+
});
|
2317
2597
|
return relations2.map((relation) => {
|
2318
|
-
const availableStatuses =
|
2319
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2598
|
+
const availableStatuses = availableStatus.filter(
|
2599
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2320
2600
|
);
|
2321
2601
|
return {
|
2322
2602
|
...relation,
|
@@ -2337,11 +2617,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2337
2617
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2338
2618
|
const isSourceLocalized = isLocalized(sourceModel);
|
2339
2619
|
const isTargetLocalized = isLocalized(targetModel);
|
2340
|
-
let validatedLocale = locale;
|
2341
|
-
if (!targetModel || !isTargetLocalized)
|
2342
|
-
validatedLocale = void 0;
|
2343
2620
|
return {
|
2344
|
-
locale
|
2621
|
+
locale,
|
2345
2622
|
isSourceLocalized,
|
2346
2623
|
isTargetLocalized
|
2347
2624
|
};
|
@@ -2350,8 +2627,7 @@ const validateStatus = (sourceUid, status) => {
|
|
2350
2627
|
const sourceModel = strapi.getModel(sourceUid);
|
2351
2628
|
const isDP = strapiUtils.contentTypes.hasDraftAndPublish;
|
2352
2629
|
const isSourceDP = isDP(sourceModel);
|
2353
|
-
if (!isSourceDP)
|
2354
|
-
return { status: void 0 };
|
2630
|
+
if (!isSourceDP) return { status: void 0 };
|
2355
2631
|
switch (status) {
|
2356
2632
|
case "published":
|
2357
2633
|
return { status: "published" };
|
@@ -2381,7 +2657,7 @@ const relations = {
|
|
2381
2657
|
ctx.request?.query?.locale
|
2382
2658
|
);
|
2383
2659
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2384
|
-
const permissionChecker2 = getService$
|
2660
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2385
2661
|
userAbility,
|
2386
2662
|
model
|
2387
2663
|
});
|
@@ -2406,7 +2682,7 @@ const relations = {
|
|
2406
2682
|
where.id = id;
|
2407
2683
|
}
|
2408
2684
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2409
|
-
const populate = await getService$
|
2685
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2410
2686
|
const currentEntity = await strapi.db.query(model).findOne({
|
2411
2687
|
where,
|
2412
2688
|
populate
|
@@ -2421,7 +2697,7 @@ const relations = {
|
|
2421
2697
|
}
|
2422
2698
|
entryId = currentEntity.id;
|
2423
2699
|
}
|
2424
|
-
const modelConfig = isComponent2 ? await getService$
|
2700
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2425
2701
|
const targetSchema = strapi.getModel(targetUid);
|
2426
2702
|
const mainField = fp.flow(
|
2427
2703
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2444,7 +2720,7 @@ const relations = {
|
|
2444
2720
|
attribute,
|
2445
2721
|
fieldsToSelect,
|
2446
2722
|
mainField,
|
2447
|
-
source: { schema: sourceSchema },
|
2723
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2448
2724
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2449
2725
|
sourceSchema,
|
2450
2726
|
targetSchema,
|
@@ -2466,7 +2742,8 @@ const relations = {
|
|
2466
2742
|
fieldsToSelect,
|
2467
2743
|
mainField,
|
2468
2744
|
source: {
|
2469
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2745
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2746
|
+
isLocalized: isSourceLocalized
|
2470
2747
|
},
|
2471
2748
|
target: {
|
2472
2749
|
schema: { uid: targetUid },
|
@@ -2474,7 +2751,7 @@ const relations = {
|
|
2474
2751
|
}
|
2475
2752
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2476
2753
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2477
|
-
const permissionChecker2 = getService$
|
2754
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2478
2755
|
userAbility: ctx.state.userAbility,
|
2479
2756
|
model: targetUid
|
2480
2757
|
});
|
@@ -2504,12 +2781,16 @@ const relations = {
|
|
2504
2781
|
} else {
|
2505
2782
|
where.id = id;
|
2506
2783
|
}
|
2507
|
-
|
2508
|
-
|
2784
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2785
|
+
if (!fp.isEmpty(publishedAt)) {
|
2786
|
+
where[`${alias}.published_at`] = publishedAt;
|
2509
2787
|
}
|
2510
|
-
if (
|
2788
|
+
if (isTargetLocalized && locale) {
|
2511
2789
|
where[`${alias}.locale`] = locale;
|
2512
2790
|
}
|
2791
|
+
if (isSourceLocalized && locale) {
|
2792
|
+
where.locale = locale;
|
2793
|
+
}
|
2513
2794
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2514
2795
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2515
2796
|
}
|
@@ -2527,7 +2808,8 @@ const relations = {
|
|
2527
2808
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2528
2809
|
});
|
2529
2810
|
}
|
2530
|
-
const
|
2811
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2812
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2531
2813
|
ctx.body = {
|
2532
2814
|
...res,
|
2533
2815
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2542,29 +2824,39 @@ const relations = {
|
|
2542
2824
|
attribute,
|
2543
2825
|
targetField,
|
2544
2826
|
fieldsToSelect,
|
2545
|
-
|
2546
|
-
|
2547
|
-
}
|
2548
|
-
target: {
|
2549
|
-
schema: { uid: targetUid }
|
2550
|
-
}
|
2827
|
+
status,
|
2828
|
+
source: { schema: sourceSchema },
|
2829
|
+
target: { schema: targetSchema }
|
2551
2830
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2552
|
-
const
|
2831
|
+
const { uid: sourceUid } = sourceSchema;
|
2832
|
+
const { uid: targetUid } = targetSchema;
|
2833
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2553
2834
|
const dbQuery = strapi.db.query(sourceUid);
|
2554
2835
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2836
|
+
const filters = {};
|
2837
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2838
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2839
|
+
if (status === "published") {
|
2840
|
+
filters.publishedAt = { $notNull: true };
|
2841
|
+
} else {
|
2842
|
+
filters.publishedAt = { $null: true };
|
2843
|
+
}
|
2844
|
+
}
|
2845
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2846
|
+
filters.publishedAt = { $null: true };
|
2847
|
+
}
|
2555
2848
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2556
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2849
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2557
2850
|
ordering: "desc",
|
2558
2851
|
page: ctx.request.query.page,
|
2559
|
-
pageSize: ctx.request.query.pageSize
|
2852
|
+
pageSize: ctx.request.query.pageSize,
|
2853
|
+
filters
|
2560
2854
|
});
|
2561
2855
|
const loadedIds = res.results.map((item) => item.id);
|
2562
2856
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2563
2857
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2564
2858
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2565
|
-
ordering: "desc"
|
2566
|
-
page: ctx.request.query.page,
|
2567
|
-
pageSize: ctx.request.query.pageSize
|
2859
|
+
ordering: "desc"
|
2568
2860
|
});
|
2569
2861
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2570
2862
|
ctx.body = {
|
@@ -2579,10 +2871,10 @@ const relations = {
|
|
2579
2871
|
}
|
2580
2872
|
};
|
2581
2873
|
const buildPopulateFromQuery = async (query, model) => {
|
2582
|
-
return getService$
|
2874
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2583
2875
|
};
|
2584
2876
|
const findDocument = async (query, uid2, opts = {}) => {
|
2585
|
-
const documentManager2 = getService$
|
2877
|
+
const documentManager2 = getService$2("document-manager");
|
2586
2878
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2587
2879
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2588
2880
|
};
|
@@ -2590,8 +2882,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2590
2882
|
const { user, userAbility } = ctx.state;
|
2591
2883
|
const { model } = ctx.params;
|
2592
2884
|
const { body, query } = ctx.request;
|
2593
|
-
const documentManager2 = getService$
|
2594
|
-
const permissionChecker2 = getService$
|
2885
|
+
const documentManager2 = getService$2("document-manager");
|
2886
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2595
2887
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2596
2888
|
throw new strapiUtils.errors.ForbiddenError();
|
2597
2889
|
}
|
@@ -2632,7 +2924,7 @@ const singleTypes = {
|
|
2632
2924
|
const { userAbility } = ctx.state;
|
2633
2925
|
const { model } = ctx.params;
|
2634
2926
|
const { query = {} } = ctx.request;
|
2635
|
-
const permissionChecker2 = getService$
|
2927
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2636
2928
|
if (permissionChecker2.cannot.read()) {
|
2637
2929
|
return ctx.forbidden();
|
2638
2930
|
}
|
@@ -2651,7 +2943,7 @@ const singleTypes = {
|
|
2651
2943
|
permissionChecker2,
|
2652
2944
|
model,
|
2653
2945
|
// @ts-expect-error - fix types
|
2654
|
-
{
|
2946
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2655
2947
|
{ availableLocales: true, availableStatus: false }
|
2656
2948
|
);
|
2657
2949
|
ctx.body = { data: {}, meta };
|
@@ -2666,7 +2958,7 @@ const singleTypes = {
|
|
2666
2958
|
async createOrUpdate(ctx) {
|
2667
2959
|
const { userAbility } = ctx.state;
|
2668
2960
|
const { model } = ctx.params;
|
2669
|
-
const permissionChecker2 = getService$
|
2961
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2670
2962
|
const document = await createOrUpdateDocument(ctx);
|
2671
2963
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2672
2964
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2675,8 +2967,8 @@ const singleTypes = {
|
|
2675
2967
|
const { userAbility } = ctx.state;
|
2676
2968
|
const { model } = ctx.params;
|
2677
2969
|
const { query = {} } = ctx.request;
|
2678
|
-
const documentManager2 = getService$
|
2679
|
-
const permissionChecker2 = getService$
|
2970
|
+
const documentManager2 = getService$2("document-manager");
|
2971
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2680
2972
|
if (permissionChecker2.cannot.delete()) {
|
2681
2973
|
return ctx.forbidden();
|
2682
2974
|
}
|
@@ -2704,8 +2996,8 @@ const singleTypes = {
|
|
2704
2996
|
const { userAbility } = ctx.state;
|
2705
2997
|
const { model } = ctx.params;
|
2706
2998
|
const { query = {} } = ctx.request;
|
2707
|
-
const documentManager2 = getService$
|
2708
|
-
const permissionChecker2 = getService$
|
2999
|
+
const documentManager2 = getService$2("document-manager");
|
3000
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2709
3001
|
if (permissionChecker2.cannot.publish()) {
|
2710
3002
|
return ctx.forbidden();
|
2711
3003
|
}
|
@@ -2733,8 +3025,8 @@ const singleTypes = {
|
|
2733
3025
|
body: { discardDraft, ...body },
|
2734
3026
|
query = {}
|
2735
3027
|
} = ctx.request;
|
2736
|
-
const documentManager2 = getService$
|
2737
|
-
const permissionChecker2 = getService$
|
3028
|
+
const documentManager2 = getService$2("document-manager");
|
3029
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2738
3030
|
if (permissionChecker2.cannot.unpublish()) {
|
2739
3031
|
return ctx.forbidden();
|
2740
3032
|
}
|
@@ -2768,8 +3060,8 @@ const singleTypes = {
|
|
2768
3060
|
const { userAbility } = ctx.state;
|
2769
3061
|
const { model } = ctx.params;
|
2770
3062
|
const { body, query = {} } = ctx.request;
|
2771
|
-
const documentManager2 = getService$
|
2772
|
-
const permissionChecker2 = getService$
|
3063
|
+
const documentManager2 = getService$2("document-manager");
|
3064
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2773
3065
|
if (permissionChecker2.cannot.discard()) {
|
2774
3066
|
return ctx.forbidden();
|
2775
3067
|
}
|
@@ -2792,8 +3084,8 @@ const singleTypes = {
|
|
2792
3084
|
const { userAbility } = ctx.state;
|
2793
3085
|
const { model } = ctx.params;
|
2794
3086
|
const { query } = ctx.request;
|
2795
|
-
const documentManager2 = getService$
|
2796
|
-
const permissionChecker2 = getService$
|
3087
|
+
const documentManager2 = getService$2("document-manager");
|
3088
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2797
3089
|
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2798
3090
|
if (permissionChecker2.cannot.read()) {
|
2799
3091
|
return ctx.forbidden();
|
@@ -2817,7 +3109,7 @@ const uid$1 = {
|
|
2817
3109
|
const { query = {} } = ctx.request;
|
2818
3110
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2819
3111
|
await validateUIDField(contentTypeUID, field);
|
2820
|
-
const uidService = getService$
|
3112
|
+
const uidService = getService$2("uid");
|
2821
3113
|
ctx.body = {
|
2822
3114
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2823
3115
|
};
|
@@ -2829,7 +3121,7 @@ const uid$1 = {
|
|
2829
3121
|
const { query = {} } = ctx.request;
|
2830
3122
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2831
3123
|
await validateUIDField(contentTypeUID, field);
|
2832
|
-
const uidService = getService$
|
3124
|
+
const uidService = getService$2("uid");
|
2833
3125
|
const isAvailable = await uidService.checkUIDAvailability({
|
2834
3126
|
contentTypeUID,
|
2835
3127
|
field,
|
@@ -2850,7 +3142,8 @@ const controllers = {
|
|
2850
3142
|
relations,
|
2851
3143
|
"single-types": singleTypes,
|
2852
3144
|
uid: uid$1,
|
2853
|
-
...history.controllers ? history.controllers : {}
|
3145
|
+
...history.controllers ? history.controllers : {},
|
3146
|
+
...preview.controllers ? preview.controllers : {}
|
2854
3147
|
};
|
2855
3148
|
const keys = {
|
2856
3149
|
CONFIGURATION: "configuration"
|
@@ -2979,18 +3272,15 @@ async function syncMetadatas(configuration, schema) {
|
|
2979
3272
|
___default.default.set(updatedMeta, ["list", "searchable"], false);
|
2980
3273
|
___default.default.set(acc, [key], updatedMeta);
|
2981
3274
|
}
|
2982
|
-
if (!___default.default.has(edit, "mainField"))
|
2983
|
-
return acc;
|
3275
|
+
if (!___default.default.has(edit, "mainField")) return acc;
|
2984
3276
|
if (!isRelation$1(attr)) {
|
2985
3277
|
___default.default.set(updatedMeta, "edit", ___default.default.omit(edit, ["mainField"]));
|
2986
3278
|
___default.default.set(acc, [key], updatedMeta);
|
2987
3279
|
return acc;
|
2988
3280
|
}
|
2989
|
-
if (edit.mainField === "id")
|
2990
|
-
return acc;
|
3281
|
+
if (edit.mainField === "id") return acc;
|
2991
3282
|
const targetSchema = getTargetSchema(attr.targetModel);
|
2992
|
-
if (!targetSchema)
|
2993
|
-
return acc;
|
3283
|
+
if (!targetSchema) return acc;
|
2994
3284
|
if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
|
2995
3285
|
___default.default.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
|
2996
3286
|
___default.default.set(acc, [key], updatedMeta);
|
@@ -3001,12 +3291,12 @@ async function syncMetadatas(configuration, schema) {
|
|
3001
3291
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
3002
3292
|
}
|
3003
3293
|
const getTargetSchema = (targetModel) => {
|
3004
|
-
return getService$
|
3294
|
+
return getService$2("content-types").findContentType(targetModel);
|
3005
3295
|
};
|
3006
3296
|
const DEFAULT_LIST_LENGTH = 4;
|
3007
3297
|
const MAX_ROW_SIZE = 12;
|
3008
3298
|
const isAllowedFieldSize = (type, size) => {
|
3009
|
-
const { getFieldSize } = getService$
|
3299
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3010
3300
|
const fieldSize = getFieldSize(type);
|
3011
3301
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3012
3302
|
return false;
|
@@ -3014,7 +3304,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3014
3304
|
return size <= MAX_ROW_SIZE;
|
3015
3305
|
};
|
3016
3306
|
const getDefaultFieldSize = (attribute) => {
|
3017
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3307
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3018
3308
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3019
3309
|
};
|
3020
3310
|
async function createDefaultLayouts(schema) {
|
@@ -3035,8 +3325,7 @@ function createDefaultEditLayout(schema) {
|
|
3035
3325
|
return appendToEditLayout([], keys2, schema);
|
3036
3326
|
}
|
3037
3327
|
function syncLayouts(configuration, schema) {
|
3038
|
-
if (___default.default.isEmpty(configuration.layouts))
|
3039
|
-
return createDefaultLayouts(schema);
|
3328
|
+
if (___default.default.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
3040
3329
|
const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
|
3041
3330
|
let cleanList = list.filter((attr) => isListable(schema, attr));
|
3042
3331
|
const cleanEditRelations = editRelations.filter(
|
@@ -3047,9 +3336,8 @@ function syncLayouts(configuration, schema) {
|
|
3047
3336
|
for (const row of edit) {
|
3048
3337
|
const newRow = [];
|
3049
3338
|
for (const el of row) {
|
3050
|
-
if (!hasEditableAttribute(schema, el.name))
|
3051
|
-
|
3052
|
-
const { hasFieldSize } = getService$1("field-sizes");
|
3339
|
+
if (!hasEditableAttribute(schema, el.name)) continue;
|
3340
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3053
3341
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3054
3342
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3055
3343
|
elementsToReAppend.push(el.name);
|
@@ -3079,8 +3367,7 @@ function syncLayouts(configuration, schema) {
|
|
3079
3367
|
};
|
3080
3368
|
}
|
3081
3369
|
const appendToEditLayout = (layout = [], keysToAppend, schema) => {
|
3082
|
-
if (keysToAppend.length === 0)
|
3083
|
-
return layout;
|
3370
|
+
if (keysToAppend.length === 0) return layout;
|
3084
3371
|
let currentRowIndex = Math.max(layout.length - 1, 0);
|
3085
3372
|
if (!layout[currentRowIndex]) {
|
3086
3373
|
layout[currentRowIndex] = [];
|
@@ -3189,17 +3476,17 @@ const configurationService$1 = createConfigurationService({
|
|
3189
3476
|
isComponent: true,
|
3190
3477
|
prefix: STORE_KEY_PREFIX,
|
3191
3478
|
getModels() {
|
3192
|
-
const { toContentManagerModel } = getService$
|
3479
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3193
3480
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3194
3481
|
}
|
3195
3482
|
});
|
3196
3483
|
const components = ({ strapi: strapi2 }) => ({
|
3197
3484
|
findAllComponents() {
|
3198
|
-
const { toContentManagerModel } = getService$
|
3485
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3199
3486
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3200
3487
|
},
|
3201
3488
|
findComponent(uid2) {
|
3202
|
-
const { toContentManagerModel } = getService$
|
3489
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3203
3490
|
const component = strapi2.components[uid2];
|
3204
3491
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3205
3492
|
},
|
@@ -3250,17 +3537,17 @@ const configurationService = createConfigurationService({
|
|
3250
3537
|
storeUtils,
|
3251
3538
|
prefix: "content_types",
|
3252
3539
|
getModels() {
|
3253
|
-
const { toContentManagerModel } = getService$
|
3540
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3254
3541
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3255
3542
|
}
|
3256
3543
|
});
|
3257
3544
|
const service = ({ strapi: strapi2 }) => ({
|
3258
3545
|
findAllContentTypes() {
|
3259
|
-
const { toContentManagerModel } = getService$
|
3546
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3260
3547
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3261
3548
|
},
|
3262
3549
|
findContentType(uid2) {
|
3263
|
-
const { toContentManagerModel } = getService$
|
3550
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3264
3551
|
const contentType = strapi2.contentTypes[uid2];
|
3265
3552
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3266
3553
|
},
|
@@ -3289,7 +3576,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3289
3576
|
return this.findConfiguration(contentType);
|
3290
3577
|
},
|
3291
3578
|
findComponentsConfigurations(contentType) {
|
3292
|
-
return getService$
|
3579
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3293
3580
|
},
|
3294
3581
|
syncConfigurations() {
|
3295
3582
|
return configurationService.syncConfigurations();
|
@@ -3470,12 +3757,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3470
3757
|
ability: userAbility,
|
3471
3758
|
model
|
3472
3759
|
});
|
3473
|
-
const
|
3760
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3761
|
+
const toSubject = (entity) => {
|
3762
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3763
|
+
};
|
3474
3764
|
const can = (action, entity, field) => {
|
3475
|
-
|
3765
|
+
const subject = toSubject(entity);
|
3766
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3767
|
+
return (
|
3768
|
+
// Test the original action to see if it passes
|
3769
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3770
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3771
|
+
);
|
3476
3772
|
};
|
3477
3773
|
const cannot = (action, entity, field) => {
|
3478
|
-
|
3774
|
+
const subject = toSubject(entity);
|
3775
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3776
|
+
return (
|
3777
|
+
// Test both the original action
|
3778
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3779
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3780
|
+
);
|
3479
3781
|
};
|
3480
3782
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3481
3783
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3546,7 +3848,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3546
3848
|
return userAbility.can(action);
|
3547
3849
|
},
|
3548
3850
|
async registerPermissions() {
|
3549
|
-
const displayedContentTypes = getService$
|
3851
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3550
3852
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3551
3853
|
const actions = [
|
3552
3854
|
{
|
@@ -3822,7 +4124,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3822
4124
|
return populateQuery;
|
3823
4125
|
};
|
3824
4126
|
const buildDeepPopulate = (uid2) => {
|
3825
|
-
return getService$
|
4127
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3826
4128
|
};
|
3827
4129
|
const populateBuilder = (uid2) => {
|
3828
4130
|
let getInitialPopulate = async () => {
|
@@ -4007,7 +4309,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4007
4309
|
*/
|
4008
4310
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
4009
4311
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
4010
|
-
|
4312
|
+
if (version.locale) {
|
4313
|
+
delete versionsByLocale[version.locale];
|
4314
|
+
}
|
4011
4315
|
const model = strapi2.getModel(uid2);
|
4012
4316
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4013
4317
|
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
@@ -4054,8 +4358,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4054
4358
|
const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
|
4055
4359
|
return matchLocale && matchStatus;
|
4056
4360
|
});
|
4057
|
-
if (!availableStatus)
|
4058
|
-
return availableStatus;
|
4361
|
+
if (!availableStatus) return availableStatus;
|
4059
4362
|
return fp.pick(AVAILABLE_STATUS_FIELDS, availableStatus);
|
4060
4363
|
},
|
4061
4364
|
/**
|
@@ -4065,8 +4368,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4065
4368
|
* @returns
|
4066
4369
|
*/
|
4067
4370
|
async getManyAvailableStatus(uid2, documents) {
|
4068
|
-
if (!documents.length)
|
4069
|
-
return [];
|
4371
|
+
if (!documents.length) return [];
|
4070
4372
|
const status = documents[0].publishedAt !== null ? "published" : "draft";
|
4071
4373
|
const locale = documents[0]?.locale;
|
4072
4374
|
const otherStatus = status === "published" ? "draft" : "published";
|
@@ -4093,10 +4395,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4093
4395
|
} else if (otherVersion) {
|
4094
4396
|
draftVersion = otherVersion;
|
4095
4397
|
}
|
4096
|
-
if (!draftVersion)
|
4097
|
-
|
4098
|
-
if (!publishedVersion)
|
4099
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
4398
|
+
if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4399
|
+
if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
|
4100
4400
|
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4101
4401
|
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
4102
4402
|
},
|
@@ -4133,7 +4433,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4133
4433
|
*/
|
4134
4434
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4135
4435
|
if (!document) {
|
4136
|
-
return
|
4436
|
+
return {
|
4437
|
+
data: document,
|
4438
|
+
meta: {
|
4439
|
+
availableLocales: [],
|
4440
|
+
availableStatus: []
|
4441
|
+
}
|
4442
|
+
};
|
4137
4443
|
}
|
4138
4444
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4139
4445
|
if (!hasDraftAndPublish) {
|
@@ -4357,7 +4663,8 @@ const services = {
|
|
4357
4663
|
permission,
|
4358
4664
|
"populate-builder": populateBuilder$1,
|
4359
4665
|
uid,
|
4360
|
-
...history.services ? history.services : {}
|
4666
|
+
...history.services ? history.services : {},
|
4667
|
+
...preview.services ? preview.services : {}
|
4361
4668
|
};
|
4362
4669
|
const index = () => {
|
4363
4670
|
return {
|