@strapi/content-manager 0.0.0-experimental.edc24aaa3bb5a90fa5fd4fee208167dd4e2e38d4 → 0.0.0-experimental.ee7402bacc4656d268ab76aa9c334a7b7a951201
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-5ukroXAh.js → ComponentConfigurationPage-BlzvDpbX.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-5ukroXAh.js.map → ComponentConfigurationPage-BlzvDpbX.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs → ComponentConfigurationPage-DaPOlQaD.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BAgyHiMm.mjs.map → ComponentConfigurationPage-DaPOlQaD.mjs.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-DmoXawIh.mjs → EditConfigurationPage-BZPXItXo.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmoXawIh.mjs.map → EditConfigurationPage-BZPXItXo.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js → EditConfigurationPage-uy-v43AR.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-Xp7lun0f.js.map → EditConfigurationPage-uy-v43AR.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-C-ukDOB7.js → EditViewPage-DT6A4ayX.js} +63 -13
- package/dist/_chunks/EditViewPage-DT6A4ayX.js.map +1 -0
- package/dist/_chunks/{EditViewPage-BLsjc5F-.mjs → EditViewPage-oOLeTySr.mjs} +63 -12
- package/dist/_chunks/EditViewPage-oOLeTySr.mjs.map +1 -0
- package/dist/_chunks/{Field-Cs7duwWd.mjs → Field-D7dv2aUX.mjs} +335 -211
- package/dist/_chunks/Field-D7dv2aUX.mjs.map +1 -0
- package/dist/_chunks/{Field-Bfph5SOd.js → Field-kYFVIGiP.js} +339 -215
- package/dist/_chunks/Field-kYFVIGiP.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-Dg_GS5TQ.mjs → Form-BxR6sc29.mjs} +37 -18
- package/dist/_chunks/Form-BxR6sc29.mjs.map +1 -0
- package/dist/_chunks/{Form-CPYqIWDG.js → Form-CCijSg3V.js} +39 -21
- package/dist/_chunks/Form-CCijSg3V.js.map +1 -0
- package/dist/_chunks/{History-DNQkXANT.js → History-BMndx49M.js} +42 -100
- package/dist/_chunks/History-BMndx49M.js.map +1 -0
- package/dist/_chunks/{History-wrnHqf09.mjs → History-D8F7aYQU.mjs} +43 -100
- package/dist/_chunks/History-D8F7aYQU.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-CUQxfpjT.js → ListConfigurationPage-DouY1EWM.js} +19 -9
- package/dist/_chunks/ListConfigurationPage-DouY1EWM.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DScmJVkW.mjs → ListConfigurationPage-DqAdSPwC.mjs} +19 -8
- package/dist/_chunks/ListConfigurationPage-DqAdSPwC.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-BsLiH2-2.js → ListViewPage-BPVmh9pq.js} +109 -78
- package/dist/_chunks/ListViewPage-BPVmh9pq.js.map +1 -0
- package/dist/_chunks/{ListViewPage-C4IvrMgY.mjs → ListViewPage-C73F0jPh.mjs} +106 -74
- package/dist/_chunks/ListViewPage-C73F0jPh.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs → NoContentTypePage-B5w7iJOF.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-Djg8nPlj.mjs.map → NoContentTypePage-B5w7iJOF.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js → NoContentTypePage-BwcL--4H.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-BZ-PnGAf.js.map → NoContentTypePage-BwcL--4H.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js → NoPermissionsPage-BMFKVcwJ.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-_lUqjGW3.js.map → NoPermissionsPage-BMFKVcwJ.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs → NoPermissionsPage-UnEgMGK4.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DSP7R-hv.mjs.map → NoPermissionsPage-UnEgMGK4.mjs.map} +1 -1
- package/dist/_chunks/Preview-B7PR3Ok_.js +312 -0
- package/dist/_chunks/Preview-B7PR3Ok_.js.map +1 -0
- package/dist/_chunks/Preview-DECOhK0D.mjs +294 -0
- package/dist/_chunks/Preview-DECOhK0D.mjs.map +1 -0
- package/dist/_chunks/{Relations-BZr8tL0R.mjs → Relations-DinMQJ4B.mjs} +76 -42
- package/dist/_chunks/Relations-DinMQJ4B.mjs.map +1 -0
- package/dist/_chunks/{Relations-CtELXYIK.js → Relations-lndx3aQk.js} +76 -43
- package/dist/_chunks/Relations-lndx3aQk.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-c_5DdJi-.mjs → index-C2SagWVW.mjs} +1107 -777
- package/dist/_chunks/index-C2SagWVW.mjs.map +1 -0
- package/dist/_chunks/{index-OerGjbAN.js → index-Cnw4gqee.js} +1089 -759
- package/dist/_chunks/index-Cnw4gqee.js.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-DY_D9MGA.mjs} +23 -10
- package/dist/_chunks/layout-DY_D9MGA.mjs.map +1 -0
- package/dist/_chunks/{layout-Ci7qHlFb.js → layout-ivwIVPnV.js} +23 -11
- package/dist/_chunks/layout-ivwIVPnV.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-B7C7O_Pv.js} +6 -7
- package/dist/_chunks/relations-B7C7O_Pv.js.map +1 -0
- package/dist/_chunks/{relations-BIdWFjdq.mjs → relations-Boc5Y9kX.mjs} +6 -7
- package/dist/_chunks/relations-Boc5Y9kX.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/BlocksInput/Blocks/Code.d.ts +7 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/utils/prismLanguages.d.ts +49 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +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/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 +648 -333
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +649 -333
- 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 +16 -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 +7 -6
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- 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 +12 -10
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +7 -6
- 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/populate.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +17 -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,201 @@ const getFeature = () => {
|
|
685
736
|
}
|
686
737
|
};
|
687
738
|
};
|
688
|
-
const history = getFeature();
|
739
|
+
const history = getFeature$1();
|
740
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
741
|
+
const previewRouter = {
|
742
|
+
type: "admin",
|
743
|
+
routes: [
|
744
|
+
{
|
745
|
+
method: "GET",
|
746
|
+
info,
|
747
|
+
path: "/preview/url/:contentType",
|
748
|
+
handler: "preview.getPreviewUrl",
|
749
|
+
config: {
|
750
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
751
|
+
}
|
752
|
+
}
|
753
|
+
]
|
754
|
+
};
|
755
|
+
const routes$1 = {
|
756
|
+
preview: previewRouter
|
757
|
+
};
|
758
|
+
function getService(strapi2, name) {
|
759
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
760
|
+
}
|
761
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
762
|
+
// Will be undefined for single types
|
763
|
+
documentId: yup__namespace.string(),
|
764
|
+
locale: yup__namespace.string().nullable(),
|
765
|
+
status: yup__namespace.string()
|
766
|
+
}).required();
|
767
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
768
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
769
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
770
|
+
const model = strapi2.getModel(uid2);
|
771
|
+
if (!model || model.modelType !== "contentType") {
|
772
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
773
|
+
}
|
774
|
+
const isSingleType = model?.kind === "singleType";
|
775
|
+
if (!isSingleType && !params.documentId) {
|
776
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
777
|
+
}
|
778
|
+
if (isSingleType) {
|
779
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
780
|
+
if (!doc) {
|
781
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
782
|
+
}
|
783
|
+
newParams.documentId = doc?.documentId;
|
784
|
+
}
|
785
|
+
if (!newParams.status) {
|
786
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
787
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
788
|
+
}
|
789
|
+
return newParams;
|
790
|
+
};
|
791
|
+
const createPreviewController = () => {
|
792
|
+
return {
|
793
|
+
/**
|
794
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
795
|
+
* in the Content Manager.
|
796
|
+
*/
|
797
|
+
async getPreviewUrl(ctx) {
|
798
|
+
const uid2 = ctx.params.contentType;
|
799
|
+
const query = ctx.request.query;
|
800
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
801
|
+
const previewService = getService(strapi, "preview");
|
802
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
803
|
+
if (!url) {
|
804
|
+
ctx.status = 204;
|
805
|
+
}
|
806
|
+
return {
|
807
|
+
data: { url }
|
808
|
+
};
|
809
|
+
}
|
810
|
+
};
|
811
|
+
};
|
812
|
+
const controllers$1 = {
|
813
|
+
preview: createPreviewController
|
814
|
+
/**
|
815
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
816
|
+
* passing a controller factory as the value, instead of a controller object directly
|
817
|
+
*/
|
818
|
+
};
|
819
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
820
|
+
const config = getService(strapi2, "preview-config");
|
821
|
+
return {
|
822
|
+
async getPreviewUrl(uid2, params) {
|
823
|
+
const handler = config.getPreviewHandler();
|
824
|
+
try {
|
825
|
+
return handler(uid2, params);
|
826
|
+
} catch (error) {
|
827
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
828
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
829
|
+
}
|
830
|
+
return;
|
831
|
+
}
|
832
|
+
};
|
833
|
+
};
|
834
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
835
|
+
const middlewares = strapi.config.get("middlewares");
|
836
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
837
|
+
if (currentMiddleware === middleware.name) {
|
838
|
+
return middleware;
|
839
|
+
}
|
840
|
+
if (currentMiddleware.name === middleware.name) {
|
841
|
+
return fp.mergeWith(
|
842
|
+
(objValue, srcValue) => {
|
843
|
+
if (Array.isArray(objValue)) {
|
844
|
+
return objValue.concat(srcValue);
|
845
|
+
}
|
846
|
+
return void 0;
|
847
|
+
},
|
848
|
+
currentMiddleware,
|
849
|
+
middleware
|
850
|
+
);
|
851
|
+
}
|
852
|
+
return currentMiddleware;
|
853
|
+
});
|
854
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
855
|
+
};
|
856
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
857
|
+
return {
|
858
|
+
register() {
|
859
|
+
if (!this.isEnabled()) {
|
860
|
+
return;
|
861
|
+
}
|
862
|
+
const config = strapi2.config.get("admin.preview");
|
863
|
+
if (config.config?.allowedOrigins) {
|
864
|
+
extendMiddlewareConfiguration({
|
865
|
+
name: "strapi::security",
|
866
|
+
config: {
|
867
|
+
contentSecurityPolicy: {
|
868
|
+
directives: {
|
869
|
+
"frame-src": config.config.allowedOrigins
|
870
|
+
}
|
871
|
+
}
|
872
|
+
}
|
873
|
+
});
|
874
|
+
}
|
875
|
+
},
|
876
|
+
isEnabled() {
|
877
|
+
const config = strapi2.config.get("admin.preview");
|
878
|
+
if (!config) {
|
879
|
+
return false;
|
880
|
+
}
|
881
|
+
return config?.enabled ?? true;
|
882
|
+
},
|
883
|
+
/**
|
884
|
+
* Validate if the configuration is valid
|
885
|
+
*/
|
886
|
+
validate() {
|
887
|
+
if (!this.isEnabled()) {
|
888
|
+
return;
|
889
|
+
}
|
890
|
+
const handler = this.getPreviewHandler();
|
891
|
+
if (typeof handler !== "function") {
|
892
|
+
throw new strapiUtils.errors.ValidationError(
|
893
|
+
"Preview configuration is invalid. Handler must be a function"
|
894
|
+
);
|
895
|
+
}
|
896
|
+
},
|
897
|
+
/**
|
898
|
+
* Utility to get the preview handler from the configuration
|
899
|
+
*/
|
900
|
+
getPreviewHandler() {
|
901
|
+
const config = strapi2.config.get("admin.preview");
|
902
|
+
const emptyHandler = () => {
|
903
|
+
return void 0;
|
904
|
+
};
|
905
|
+
if (!this.isEnabled()) {
|
906
|
+
return emptyHandler;
|
907
|
+
}
|
908
|
+
return config?.config?.handler || emptyHandler;
|
909
|
+
}
|
910
|
+
};
|
911
|
+
};
|
912
|
+
const services$1 = {
|
913
|
+
preview: createPreviewService,
|
914
|
+
"preview-config": createPreviewConfigService
|
915
|
+
};
|
916
|
+
const getFeature = () => {
|
917
|
+
return {
|
918
|
+
register() {
|
919
|
+
const config = getService(strapi, "preview-config");
|
920
|
+
config.validate();
|
921
|
+
config.register();
|
922
|
+
},
|
923
|
+
bootstrap() {
|
924
|
+
},
|
925
|
+
routes: routes$1,
|
926
|
+
controllers: controllers$1,
|
927
|
+
services: services$1
|
928
|
+
};
|
929
|
+
};
|
930
|
+
const preview = getFeature();
|
689
931
|
const register = async ({ strapi: strapi2 }) => {
|
690
932
|
await history.register?.({ strapi: strapi2 });
|
933
|
+
await preview.register?.({ strapi: strapi2 });
|
691
934
|
};
|
692
935
|
const ALLOWED_WEBHOOK_EVENTS = {
|
693
936
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -697,11 +940,12 @@ const bootstrap = async () => {
|
|
697
940
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
698
941
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
699
942
|
});
|
700
|
-
getService$
|
701
|
-
await getService$
|
702
|
-
await getService$
|
703
|
-
await getService$
|
943
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
944
|
+
await getService$2("components").syncConfigurations();
|
945
|
+
await getService$2("content-types").syncConfigurations();
|
946
|
+
await getService$2("permission").registerPermissions();
|
704
947
|
await history.bootstrap?.({ strapi });
|
948
|
+
await preview.bootstrap?.({ strapi });
|
705
949
|
};
|
706
950
|
const destroy = async ({ strapi: strapi2 }) => {
|
707
951
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1191,7 +1435,8 @@ const admin = {
|
|
1191
1435
|
};
|
1192
1436
|
const routes = {
|
1193
1437
|
admin,
|
1194
|
-
...history.routes ? history.routes : {}
|
1438
|
+
...history.routes ? history.routes : {},
|
1439
|
+
...preview.routes ? preview.routes : {}
|
1195
1440
|
};
|
1196
1441
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1197
1442
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1202,6 +1447,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1202
1447
|
const hasPermissions = createPolicy({
|
1203
1448
|
name: "plugin::content-manager.hasPermissions",
|
1204
1449
|
validator: validateHasPermissionsInput,
|
1450
|
+
/**
|
1451
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1452
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1453
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1454
|
+
*/
|
1205
1455
|
handler(ctx, config = {}) {
|
1206
1456
|
const { actions = [], hasAtLeastOne = false } = config;
|
1207
1457
|
const { userAbility } = ctx.state;
|
@@ -1249,8 +1499,7 @@ const isSortable = (schema, name) => {
|
|
1249
1499
|
if (!___default.default.has(schema.attributes, name)) {
|
1250
1500
|
return false;
|
1251
1501
|
}
|
1252
|
-
if (schema.modelType === "component" && name === "id")
|
1253
|
-
return false;
|
1502
|
+
if (schema.modelType === "component" && name === "id") return false;
|
1254
1503
|
const attribute = schema.attributes[name];
|
1255
1504
|
if (NON_SORTABLES.includes(attribute.type)) {
|
1256
1505
|
return false;
|
@@ -1395,8 +1644,7 @@ const createDefaultSettings = async (schema) => {
|
|
1395
1644
|
};
|
1396
1645
|
};
|
1397
1646
|
const syncSettings = async (configuration, schema) => {
|
1398
|
-
if (fp.isEmpty(configuration.settings))
|
1399
|
-
return createDefaultSettings(schema);
|
1647
|
+
if (fp.isEmpty(configuration.settings)) return createDefaultSettings(schema);
|
1400
1648
|
const defaultField = getDefaultMainField(schema);
|
1401
1649
|
const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
|
1402
1650
|
return {
|
@@ -1443,7 +1691,7 @@ const createMetadasSchema = (schema) => {
|
|
1443
1691
|
if (!value) {
|
1444
1692
|
return strapiUtils.yup.string();
|
1445
1693
|
}
|
1446
|
-
const targetSchema = getService$
|
1694
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1447
1695
|
schema.attributes[key].targetModel
|
1448
1696
|
);
|
1449
1697
|
if (!targetSchema) {
|
@@ -1572,8 +1820,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1572
1820
|
}
|
1573
1821
|
switch (attribute.type) {
|
1574
1822
|
case "relation": {
|
1575
|
-
if (canCreate(attributePath))
|
1576
|
-
return body2;
|
1823
|
+
if (canCreate(attributePath)) return body2;
|
1577
1824
|
return fp.set(attributePath, { set: [] }, body2);
|
1578
1825
|
}
|
1579
1826
|
case "component": {
|
@@ -1583,8 +1830,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1583
1830
|
]);
|
1584
1831
|
}
|
1585
1832
|
default: {
|
1586
|
-
if (canCreate(attributePath))
|
1587
|
-
return body2;
|
1833
|
+
if (canCreate(attributePath)) return body2;
|
1588
1834
|
return fp.set(attributePath, null, body2);
|
1589
1835
|
}
|
1590
1836
|
}
|
@@ -1612,7 +1858,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
|
|
1612
1858
|
}
|
1613
1859
|
};
|
1614
1860
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1615
|
-
const documentMetadata2 = getService$
|
1861
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1616
1862
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1617
1863
|
let {
|
1618
1864
|
meta: { availableLocales, availableStatus }
|
@@ -1638,8 +1884,8 @@ const createDocument = async (ctx, opts) => {
|
|
1638
1884
|
const { userAbility, user } = ctx.state;
|
1639
1885
|
const { model } = ctx.params;
|
1640
1886
|
const { body } = ctx.request;
|
1641
|
-
const documentManager2 = getService$
|
1642
|
-
const permissionChecker2 = getService$
|
1887
|
+
const documentManager2 = getService$2("document-manager");
|
1888
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1643
1889
|
if (permissionChecker2.cannot.create()) {
|
1644
1890
|
throw new strapiUtils.errors.ForbiddenError();
|
1645
1891
|
}
|
@@ -1659,13 +1905,13 @@ const updateDocument = async (ctx, opts) => {
|
|
1659
1905
|
const { userAbility, user } = ctx.state;
|
1660
1906
|
const { id, model } = ctx.params;
|
1661
1907
|
const { body } = ctx.request;
|
1662
|
-
const documentManager2 = getService$
|
1663
|
-
const permissionChecker2 = getService$
|
1908
|
+
const documentManager2 = getService$2("document-manager");
|
1909
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1664
1910
|
if (permissionChecker2.cannot.update()) {
|
1665
1911
|
throw new strapiUtils.errors.ForbiddenError();
|
1666
1912
|
}
|
1667
1913
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1668
|
-
const populate = await getService$
|
1914
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1669
1915
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1670
1916
|
const [documentVersion, documentExists] = await Promise.all([
|
1671
1917
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
@@ -1682,7 +1928,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1682
1928
|
throw new strapiUtils.errors.ForbiddenError();
|
1683
1929
|
}
|
1684
1930
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1685
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1931
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1686
1932
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1687
1933
|
const sanitizedBody = await sanitizeFn(body);
|
1688
1934
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1696,14 +1942,14 @@ const collectionTypes = {
|
|
1696
1942
|
const { userAbility } = ctx.state;
|
1697
1943
|
const { model } = ctx.params;
|
1698
1944
|
const { query } = ctx.request;
|
1699
|
-
const documentMetadata2 = getService$
|
1700
|
-
const documentManager2 = getService$
|
1701
|
-
const permissionChecker2 = getService$
|
1945
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1946
|
+
const documentManager2 = getService$2("document-manager");
|
1947
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1702
1948
|
if (permissionChecker2.cannot.read()) {
|
1703
1949
|
return ctx.forbidden();
|
1704
1950
|
}
|
1705
1951
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1706
|
-
const populate = await getService$
|
1952
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1707
1953
|
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1708
1954
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1709
1955
|
{ ...permissionQuery, populate, locale, status },
|
@@ -1732,13 +1978,13 @@ const collectionTypes = {
|
|
1732
1978
|
async findOne(ctx) {
|
1733
1979
|
const { userAbility } = ctx.state;
|
1734
1980
|
const { model, id } = ctx.params;
|
1735
|
-
const documentManager2 = getService$
|
1736
|
-
const permissionChecker2 = getService$
|
1981
|
+
const documentManager2 = getService$2("document-manager");
|
1982
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1737
1983
|
if (permissionChecker2.cannot.read()) {
|
1738
1984
|
return ctx.forbidden();
|
1739
1985
|
}
|
1740
1986
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1741
|
-
const populate = await getService$
|
1987
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1742
1988
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1743
1989
|
const version = await documentManager2.findOne(id, model, {
|
1744
1990
|
populate,
|
@@ -1754,7 +2000,7 @@ const collectionTypes = {
|
|
1754
2000
|
permissionChecker2,
|
1755
2001
|
model,
|
1756
2002
|
// @ts-expect-error TODO: fix
|
1757
|
-
{ id, locale, publishedAt: null },
|
2003
|
+
{ documentId: id, locale, publishedAt: null },
|
1758
2004
|
{ availableLocales: true, availableStatus: false }
|
1759
2005
|
);
|
1760
2006
|
ctx.body = { data: {}, meta };
|
@@ -1769,7 +2015,7 @@ const collectionTypes = {
|
|
1769
2015
|
async create(ctx) {
|
1770
2016
|
const { userAbility } = ctx.state;
|
1771
2017
|
const { model } = ctx.params;
|
1772
|
-
const permissionChecker2 = getService$
|
2018
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1773
2019
|
const [totalEntries, document] = await Promise.all([
|
1774
2020
|
strapi.db.query(model).count(),
|
1775
2021
|
createDocument(ctx)
|
@@ -1790,7 +2036,7 @@ const collectionTypes = {
|
|
1790
2036
|
async update(ctx) {
|
1791
2037
|
const { userAbility } = ctx.state;
|
1792
2038
|
const { model } = ctx.params;
|
1793
|
-
const permissionChecker2 = getService$
|
2039
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1794
2040
|
const updatedVersion = await updateDocument(ctx);
|
1795
2041
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1796
2042
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1799,13 +2045,13 @@ const collectionTypes = {
|
|
1799
2045
|
const { userAbility, user } = ctx.state;
|
1800
2046
|
const { model, sourceId: id } = ctx.params;
|
1801
2047
|
const { body } = ctx.request;
|
1802
|
-
const documentManager2 = getService$
|
1803
|
-
const permissionChecker2 = getService$
|
2048
|
+
const documentManager2 = getService$2("document-manager");
|
2049
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1804
2050
|
if (permissionChecker2.cannot.create()) {
|
1805
2051
|
return ctx.forbidden();
|
1806
2052
|
}
|
1807
2053
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1808
|
-
const populate = await getService$
|
2054
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1809
2055
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1810
2056
|
const document = await documentManager2.findOne(id, model, {
|
1811
2057
|
populate,
|
@@ -1844,13 +2090,13 @@ const collectionTypes = {
|
|
1844
2090
|
async delete(ctx) {
|
1845
2091
|
const { userAbility } = ctx.state;
|
1846
2092
|
const { id, model } = ctx.params;
|
1847
|
-
const documentManager2 = getService$
|
1848
|
-
const permissionChecker2 = getService$
|
2093
|
+
const documentManager2 = getService$2("document-manager");
|
2094
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1849
2095
|
if (permissionChecker2.cannot.delete()) {
|
1850
2096
|
return ctx.forbidden();
|
1851
2097
|
}
|
1852
2098
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1853
|
-
const populate = await getService$
|
2099
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1854
2100
|
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1855
2101
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1856
2102
|
if (documentLocales.length === 0) {
|
@@ -1872,19 +2118,42 @@ const collectionTypes = {
|
|
1872
2118
|
const { userAbility } = ctx.state;
|
1873
2119
|
const { id, model } = ctx.params;
|
1874
2120
|
const { body } = ctx.request;
|
1875
|
-
const documentManager2 = getService$
|
1876
|
-
const permissionChecker2 = getService$
|
2121
|
+
const documentManager2 = getService$2("document-manager");
|
2122
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1877
2123
|
if (permissionChecker2.cannot.publish()) {
|
1878
2124
|
return ctx.forbidden();
|
1879
2125
|
}
|
1880
2126
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1881
2127
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1882
|
-
const populate = await getService$
|
1883
|
-
|
2128
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2129
|
+
let document;
|
2130
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2131
|
+
const isCreate = fp.isNil(id);
|
2132
|
+
if (isCreate) {
|
2133
|
+
if (permissionChecker2.cannot.create()) {
|
2134
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2135
|
+
}
|
2136
|
+
document = await createDocument(ctx, { populate });
|
2137
|
+
}
|
2138
|
+
const isUpdate = !isCreate;
|
2139
|
+
if (isUpdate) {
|
2140
|
+
const documentExists = documentManager2.exists(model, id);
|
2141
|
+
if (!documentExists) {
|
2142
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2143
|
+
}
|
2144
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2145
|
+
if (!document) {
|
2146
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2147
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2148
|
+
}
|
2149
|
+
document = await updateDocument(ctx);
|
2150
|
+
} else if (permissionChecker2.can.update(document)) {
|
2151
|
+
await updateDocument(ctx);
|
2152
|
+
}
|
2153
|
+
}
|
1884
2154
|
if (permissionChecker2.cannot.publish(document)) {
|
1885
2155
|
throw new strapiUtils.errors.ForbiddenError();
|
1886
2156
|
}
|
1887
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1888
2157
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1889
2158
|
locale
|
1890
2159
|
// TODO: Allow setting creator fields on publish
|
@@ -1904,13 +2173,13 @@ const collectionTypes = {
|
|
1904
2173
|
const { body } = ctx.request;
|
1905
2174
|
const { documentIds } = body;
|
1906
2175
|
await validateBulkActionInput(body);
|
1907
|
-
const documentManager2 = getService$
|
1908
|
-
const permissionChecker2 = getService$
|
2176
|
+
const documentManager2 = getService$2("document-manager");
|
2177
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1909
2178
|
if (permissionChecker2.cannot.publish()) {
|
1910
2179
|
return ctx.forbidden();
|
1911
2180
|
}
|
1912
2181
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1913
|
-
const populate = await getService$
|
2182
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1914
2183
|
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1915
2184
|
allowMultipleLocales: true
|
1916
2185
|
});
|
@@ -1935,12 +2204,14 @@ const collectionTypes = {
|
|
1935
2204
|
const { body } = ctx.request;
|
1936
2205
|
const { documentIds } = body;
|
1937
2206
|
await validateBulkActionInput(body);
|
1938
|
-
const documentManager2 = getService$
|
1939
|
-
const permissionChecker2 = getService$
|
2207
|
+
const documentManager2 = getService$2("document-manager");
|
2208
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1940
2209
|
if (permissionChecker2.cannot.unpublish()) {
|
1941
2210
|
return ctx.forbidden();
|
1942
2211
|
}
|
1943
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model
|
2212
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2213
|
+
allowMultipleLocales: true
|
2214
|
+
});
|
1944
2215
|
const entityPromises = documentIds.map(
|
1945
2216
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1946
2217
|
);
|
@@ -1963,8 +2234,8 @@ const collectionTypes = {
|
|
1963
2234
|
const {
|
1964
2235
|
body: { discardDraft, ...body }
|
1965
2236
|
} = ctx.request;
|
1966
|
-
const documentManager2 = getService$
|
1967
|
-
const permissionChecker2 = getService$
|
2237
|
+
const documentManager2 = getService$2("document-manager");
|
2238
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1968
2239
|
if (permissionChecker2.cannot.unpublish()) {
|
1969
2240
|
return ctx.forbidden();
|
1970
2241
|
}
|
@@ -1972,7 +2243,7 @@ const collectionTypes = {
|
|
1972
2243
|
return ctx.forbidden();
|
1973
2244
|
}
|
1974
2245
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1975
|
-
const populate = await getService$
|
2246
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1976
2247
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1977
2248
|
const document = await documentManager2.findOne(id, model, {
|
1978
2249
|
populate,
|
@@ -2003,13 +2274,13 @@ const collectionTypes = {
|
|
2003
2274
|
const { userAbility } = ctx.state;
|
2004
2275
|
const { id, model } = ctx.params;
|
2005
2276
|
const { body } = ctx.request;
|
2006
|
-
const documentManager2 = getService$
|
2007
|
-
const permissionChecker2 = getService$
|
2277
|
+
const documentManager2 = getService$2("document-manager");
|
2278
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2008
2279
|
if (permissionChecker2.cannot.discard()) {
|
2009
2280
|
return ctx.forbidden();
|
2010
2281
|
}
|
2011
2282
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2012
|
-
const populate = await getService$
|
2283
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2013
2284
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2014
2285
|
const document = await documentManager2.findOne(id, model, {
|
2015
2286
|
populate,
|
@@ -2034,13 +2305,13 @@ const collectionTypes = {
|
|
2034
2305
|
const { query, body } = ctx.request;
|
2035
2306
|
const { documentIds } = body;
|
2036
2307
|
await validateBulkActionInput(body);
|
2037
|
-
const documentManager2 = getService$
|
2038
|
-
const permissionChecker2 = getService$
|
2308
|
+
const documentManager2 = getService$2("document-manager");
|
2309
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2039
2310
|
if (permissionChecker2.cannot.delete()) {
|
2040
2311
|
return ctx.forbidden();
|
2041
2312
|
}
|
2042
2313
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2043
|
-
const populate = await getService$
|
2314
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2044
2315
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2045
2316
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2046
2317
|
populate,
|
@@ -2061,13 +2332,13 @@ const collectionTypes = {
|
|
2061
2332
|
async countDraftRelations(ctx) {
|
2062
2333
|
const { userAbility } = ctx.state;
|
2063
2334
|
const { model, id } = ctx.params;
|
2064
|
-
const documentManager2 = getService$
|
2065
|
-
const permissionChecker2 = getService$
|
2335
|
+
const documentManager2 = getService$2("document-manager");
|
2336
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2066
2337
|
if (permissionChecker2.cannot.read()) {
|
2067
2338
|
return ctx.forbidden();
|
2068
2339
|
}
|
2069
2340
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2070
|
-
const populate = await getService$
|
2341
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2071
2342
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2072
2343
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2073
2344
|
if (!entity) {
|
@@ -2086,8 +2357,8 @@ const collectionTypes = {
|
|
2086
2357
|
const ids = ctx.request.query.documentIds;
|
2087
2358
|
const locale = ctx.request.query.locale;
|
2088
2359
|
const { model } = ctx.params;
|
2089
|
-
const documentManager2 = getService$
|
2090
|
-
const permissionChecker2 = getService$
|
2360
|
+
const documentManager2 = getService$2("document-manager");
|
2361
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2091
2362
|
if (permissionChecker2.cannot.read()) {
|
2092
2363
|
return ctx.forbidden();
|
2093
2364
|
}
|
@@ -2111,13 +2382,13 @@ const collectionTypes = {
|
|
2111
2382
|
};
|
2112
2383
|
const components$1 = {
|
2113
2384
|
findComponents(ctx) {
|
2114
|
-
const components2 = getService$
|
2115
|
-
const { toDto } = getService$
|
2385
|
+
const components2 = getService$2("components").findAllComponents();
|
2386
|
+
const { toDto } = getService$2("data-mapper");
|
2116
2387
|
ctx.body = { data: components2.map(toDto) };
|
2117
2388
|
},
|
2118
2389
|
async findComponentConfiguration(ctx) {
|
2119
2390
|
const { uid: uid2 } = ctx.params;
|
2120
|
-
const componentService = getService$
|
2391
|
+
const componentService = getService$2("components");
|
2121
2392
|
const component = componentService.findComponent(uid2);
|
2122
2393
|
if (!component) {
|
2123
2394
|
return ctx.notFound("component.notFound");
|
@@ -2134,7 +2405,7 @@ const components$1 = {
|
|
2134
2405
|
async updateComponentConfiguration(ctx) {
|
2135
2406
|
const { uid: uid2 } = ctx.params;
|
2136
2407
|
const { body } = ctx.request;
|
2137
|
-
const componentService = getService$
|
2408
|
+
const componentService = getService$2("components");
|
2138
2409
|
const component = componentService.findComponent(uid2);
|
2139
2410
|
if (!component) {
|
2140
2411
|
return ctx.notFound("component.notFound");
|
@@ -2168,12 +2439,12 @@ const contentTypes = {
|
|
2168
2439
|
} catch (error) {
|
2169
2440
|
return ctx.send({ error }, 400);
|
2170
2441
|
}
|
2171
|
-
const contentTypes2 = getService$
|
2172
|
-
const { toDto } = getService$
|
2442
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2443
|
+
const { toDto } = getService$2("data-mapper");
|
2173
2444
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2174
2445
|
},
|
2175
2446
|
async findContentTypesSettings(ctx) {
|
2176
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2447
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2177
2448
|
const contentTypes2 = await findAllContentTypes();
|
2178
2449
|
const configurations = await Promise.all(
|
2179
2450
|
contentTypes2.map(async (contentType) => {
|
@@ -2187,7 +2458,7 @@ const contentTypes = {
|
|
2187
2458
|
},
|
2188
2459
|
async findContentTypeConfiguration(ctx) {
|
2189
2460
|
const { uid: uid2 } = ctx.params;
|
2190
|
-
const contentTypeService = getService$
|
2461
|
+
const contentTypeService = getService$2("content-types");
|
2191
2462
|
const contentType = await contentTypeService.findContentType(uid2);
|
2192
2463
|
if (!contentType) {
|
2193
2464
|
return ctx.notFound("contentType.notFound");
|
@@ -2209,13 +2480,13 @@ const contentTypes = {
|
|
2209
2480
|
const { userAbility } = ctx.state;
|
2210
2481
|
const { uid: uid2 } = ctx.params;
|
2211
2482
|
const { body } = ctx.request;
|
2212
|
-
const contentTypeService = getService$
|
2213
|
-
const metricsService = getService$
|
2483
|
+
const contentTypeService = getService$2("content-types");
|
2484
|
+
const metricsService = getService$2("metrics");
|
2214
2485
|
const contentType = await contentTypeService.findContentType(uid2);
|
2215
2486
|
if (!contentType) {
|
2216
2487
|
return ctx.notFound("contentType.notFound");
|
2217
2488
|
}
|
2218
|
-
if (!getService$
|
2489
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2219
2490
|
return ctx.forbidden();
|
2220
2491
|
}
|
2221
2492
|
let input;
|
@@ -2248,10 +2519,10 @@ const contentTypes = {
|
|
2248
2519
|
};
|
2249
2520
|
const init = {
|
2250
2521
|
getInitData(ctx) {
|
2251
|
-
const { toDto } = getService$
|
2252
|
-
const { findAllComponents } = getService$
|
2253
|
-
const { getAllFieldSizes } = getService$
|
2254
|
-
const { findAllContentTypes } = getService$
|
2522
|
+
const { toDto } = getService$2("data-mapper");
|
2523
|
+
const { findAllComponents } = getService$2("components");
|
2524
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2525
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2255
2526
|
ctx.body = {
|
2256
2527
|
data: {
|
2257
2528
|
fieldSizes: getAllFieldSizes(),
|
@@ -2287,36 +2558,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2287
2558
|
params.filters.$and.push(filtersClause);
|
2288
2559
|
};
|
2289
2560
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2290
|
-
const permissionChecker2 = getService$
|
2561
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2291
2562
|
userAbility,
|
2292
2563
|
model: model.uid
|
2293
2564
|
});
|
2294
|
-
|
2565
|
+
const isMainFieldListable = isListable(model, mainField);
|
2566
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2567
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2295
2568
|
return "id";
|
2296
2569
|
}
|
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";
|
2570
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2571
|
+
return "name";
|
2308
2572
|
}
|
2309
2573
|
return mainField;
|
2310
2574
|
};
|
2311
|
-
const addStatusToRelations = async (
|
2312
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2575
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2576
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2577
|
+
return relations2;
|
2578
|
+
}
|
2579
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2580
|
+
if (!relations2.length) {
|
2313
2581
|
return relations2;
|
2314
2582
|
}
|
2315
|
-
const
|
2316
|
-
const
|
2583
|
+
const firstRelation = relations2[0];
|
2584
|
+
const filters = {
|
2585
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2586
|
+
// NOTE: find the "opposite" status
|
2587
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2588
|
+
};
|
2589
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2590
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2591
|
+
filters
|
2592
|
+
});
|
2317
2593
|
return relations2.map((relation) => {
|
2318
|
-
const availableStatuses =
|
2319
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2594
|
+
const availableStatuses = availableStatus.filter(
|
2595
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2320
2596
|
);
|
2321
2597
|
return {
|
2322
2598
|
...relation,
|
@@ -2337,11 +2613,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2337
2613
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2338
2614
|
const isSourceLocalized = isLocalized(sourceModel);
|
2339
2615
|
const isTargetLocalized = isLocalized(targetModel);
|
2340
|
-
let validatedLocale = locale;
|
2341
|
-
if (!targetModel || !isTargetLocalized)
|
2342
|
-
validatedLocale = void 0;
|
2343
2616
|
return {
|
2344
|
-
locale
|
2617
|
+
locale,
|
2345
2618
|
isSourceLocalized,
|
2346
2619
|
isTargetLocalized
|
2347
2620
|
};
|
@@ -2350,8 +2623,7 @@ const validateStatus = (sourceUid, status) => {
|
|
2350
2623
|
const sourceModel = strapi.getModel(sourceUid);
|
2351
2624
|
const isDP = strapiUtils.contentTypes.hasDraftAndPublish;
|
2352
2625
|
const isSourceDP = isDP(sourceModel);
|
2353
|
-
if (!isSourceDP)
|
2354
|
-
return { status: void 0 };
|
2626
|
+
if (!isSourceDP) return { status: void 0 };
|
2355
2627
|
switch (status) {
|
2356
2628
|
case "published":
|
2357
2629
|
return { status: "published" };
|
@@ -2381,7 +2653,7 @@ const relations = {
|
|
2381
2653
|
ctx.request?.query?.locale
|
2382
2654
|
);
|
2383
2655
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2384
|
-
const permissionChecker2 = getService$
|
2656
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2385
2657
|
userAbility,
|
2386
2658
|
model
|
2387
2659
|
});
|
@@ -2406,7 +2678,7 @@ const relations = {
|
|
2406
2678
|
where.id = id;
|
2407
2679
|
}
|
2408
2680
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2409
|
-
const populate = await getService$
|
2681
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2410
2682
|
const currentEntity = await strapi.db.query(model).findOne({
|
2411
2683
|
where,
|
2412
2684
|
populate
|
@@ -2421,7 +2693,7 @@ const relations = {
|
|
2421
2693
|
}
|
2422
2694
|
entryId = currentEntity.id;
|
2423
2695
|
}
|
2424
|
-
const modelConfig = isComponent2 ? await getService$
|
2696
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2425
2697
|
const targetSchema = strapi.getModel(targetUid);
|
2426
2698
|
const mainField = fp.flow(
|
2427
2699
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2444,7 +2716,7 @@ const relations = {
|
|
2444
2716
|
attribute,
|
2445
2717
|
fieldsToSelect,
|
2446
2718
|
mainField,
|
2447
|
-
source: { schema: sourceSchema },
|
2719
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2448
2720
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2449
2721
|
sourceSchema,
|
2450
2722
|
targetSchema,
|
@@ -2466,7 +2738,8 @@ const relations = {
|
|
2466
2738
|
fieldsToSelect,
|
2467
2739
|
mainField,
|
2468
2740
|
source: {
|
2469
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2741
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2742
|
+
isLocalized: isSourceLocalized
|
2470
2743
|
},
|
2471
2744
|
target: {
|
2472
2745
|
schema: { uid: targetUid },
|
@@ -2474,7 +2747,7 @@ const relations = {
|
|
2474
2747
|
}
|
2475
2748
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2476
2749
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2477
|
-
const permissionChecker2 = getService$
|
2750
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2478
2751
|
userAbility: ctx.state.userAbility,
|
2479
2752
|
model: targetUid
|
2480
2753
|
});
|
@@ -2504,12 +2777,16 @@ const relations = {
|
|
2504
2777
|
} else {
|
2505
2778
|
where.id = id;
|
2506
2779
|
}
|
2507
|
-
|
2508
|
-
|
2780
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2781
|
+
if (!fp.isEmpty(publishedAt)) {
|
2782
|
+
where[`${alias}.published_at`] = publishedAt;
|
2509
2783
|
}
|
2510
|
-
if (
|
2784
|
+
if (isTargetLocalized && locale) {
|
2511
2785
|
where[`${alias}.locale`] = locale;
|
2512
2786
|
}
|
2787
|
+
if (isSourceLocalized && locale) {
|
2788
|
+
where.locale = locale;
|
2789
|
+
}
|
2513
2790
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2514
2791
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2515
2792
|
}
|
@@ -2527,7 +2804,8 @@ const relations = {
|
|
2527
2804
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2528
2805
|
});
|
2529
2806
|
}
|
2530
|
-
const
|
2807
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2808
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2531
2809
|
ctx.body = {
|
2532
2810
|
...res,
|
2533
2811
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2542,29 +2820,39 @@ const relations = {
|
|
2542
2820
|
attribute,
|
2543
2821
|
targetField,
|
2544
2822
|
fieldsToSelect,
|
2545
|
-
|
2546
|
-
|
2547
|
-
}
|
2548
|
-
target: {
|
2549
|
-
schema: { uid: targetUid }
|
2550
|
-
}
|
2823
|
+
status,
|
2824
|
+
source: { schema: sourceSchema },
|
2825
|
+
target: { schema: targetSchema }
|
2551
2826
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2552
|
-
const
|
2827
|
+
const { uid: sourceUid } = sourceSchema;
|
2828
|
+
const { uid: targetUid } = targetSchema;
|
2829
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2553
2830
|
const dbQuery = strapi.db.query(sourceUid);
|
2554
2831
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2832
|
+
const filters = {};
|
2833
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2834
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2835
|
+
if (status === "published") {
|
2836
|
+
filters.publishedAt = { $notNull: true };
|
2837
|
+
} else {
|
2838
|
+
filters.publishedAt = { $null: true };
|
2839
|
+
}
|
2840
|
+
}
|
2841
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2842
|
+
filters.publishedAt = { $null: true };
|
2843
|
+
}
|
2555
2844
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2556
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2845
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2557
2846
|
ordering: "desc",
|
2558
2847
|
page: ctx.request.query.page,
|
2559
|
-
pageSize: ctx.request.query.pageSize
|
2848
|
+
pageSize: ctx.request.query.pageSize,
|
2849
|
+
filters
|
2560
2850
|
});
|
2561
2851
|
const loadedIds = res.results.map((item) => item.id);
|
2562
2852
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2563
2853
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2564
2854
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2565
|
-
ordering: "desc"
|
2566
|
-
page: ctx.request.query.page,
|
2567
|
-
pageSize: ctx.request.query.pageSize
|
2855
|
+
ordering: "desc"
|
2568
2856
|
});
|
2569
2857
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2570
2858
|
ctx.body = {
|
@@ -2579,10 +2867,10 @@ const relations = {
|
|
2579
2867
|
}
|
2580
2868
|
};
|
2581
2869
|
const buildPopulateFromQuery = async (query, model) => {
|
2582
|
-
return getService$
|
2870
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2583
2871
|
};
|
2584
2872
|
const findDocument = async (query, uid2, opts = {}) => {
|
2585
|
-
const documentManager2 = getService$
|
2873
|
+
const documentManager2 = getService$2("document-manager");
|
2586
2874
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2587
2875
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2588
2876
|
};
|
@@ -2590,8 +2878,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2590
2878
|
const { user, userAbility } = ctx.state;
|
2591
2879
|
const { model } = ctx.params;
|
2592
2880
|
const { body, query } = ctx.request;
|
2593
|
-
const documentManager2 = getService$
|
2594
|
-
const permissionChecker2 = getService$
|
2881
|
+
const documentManager2 = getService$2("document-manager");
|
2882
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2595
2883
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2596
2884
|
throw new strapiUtils.errors.ForbiddenError();
|
2597
2885
|
}
|
@@ -2632,7 +2920,7 @@ const singleTypes = {
|
|
2632
2920
|
const { userAbility } = ctx.state;
|
2633
2921
|
const { model } = ctx.params;
|
2634
2922
|
const { query = {} } = ctx.request;
|
2635
|
-
const permissionChecker2 = getService$
|
2923
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2636
2924
|
if (permissionChecker2.cannot.read()) {
|
2637
2925
|
return ctx.forbidden();
|
2638
2926
|
}
|
@@ -2651,7 +2939,7 @@ const singleTypes = {
|
|
2651
2939
|
permissionChecker2,
|
2652
2940
|
model,
|
2653
2941
|
// @ts-expect-error - fix types
|
2654
|
-
{
|
2942
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2655
2943
|
{ availableLocales: true, availableStatus: false }
|
2656
2944
|
);
|
2657
2945
|
ctx.body = { data: {}, meta };
|
@@ -2666,7 +2954,7 @@ const singleTypes = {
|
|
2666
2954
|
async createOrUpdate(ctx) {
|
2667
2955
|
const { userAbility } = ctx.state;
|
2668
2956
|
const { model } = ctx.params;
|
2669
|
-
const permissionChecker2 = getService$
|
2957
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2670
2958
|
const document = await createOrUpdateDocument(ctx);
|
2671
2959
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2672
2960
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2675,8 +2963,8 @@ const singleTypes = {
|
|
2675
2963
|
const { userAbility } = ctx.state;
|
2676
2964
|
const { model } = ctx.params;
|
2677
2965
|
const { query = {} } = ctx.request;
|
2678
|
-
const documentManager2 = getService$
|
2679
|
-
const permissionChecker2 = getService$
|
2966
|
+
const documentManager2 = getService$2("document-manager");
|
2967
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2680
2968
|
if (permissionChecker2.cannot.delete()) {
|
2681
2969
|
return ctx.forbidden();
|
2682
2970
|
}
|
@@ -2704,8 +2992,8 @@ const singleTypes = {
|
|
2704
2992
|
const { userAbility } = ctx.state;
|
2705
2993
|
const { model } = ctx.params;
|
2706
2994
|
const { query = {} } = ctx.request;
|
2707
|
-
const documentManager2 = getService$
|
2708
|
-
const permissionChecker2 = getService$
|
2995
|
+
const documentManager2 = getService$2("document-manager");
|
2996
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2709
2997
|
if (permissionChecker2.cannot.publish()) {
|
2710
2998
|
return ctx.forbidden();
|
2711
2999
|
}
|
@@ -2733,8 +3021,8 @@ const singleTypes = {
|
|
2733
3021
|
body: { discardDraft, ...body },
|
2734
3022
|
query = {}
|
2735
3023
|
} = ctx.request;
|
2736
|
-
const documentManager2 = getService$
|
2737
|
-
const permissionChecker2 = getService$
|
3024
|
+
const documentManager2 = getService$2("document-manager");
|
3025
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2738
3026
|
if (permissionChecker2.cannot.unpublish()) {
|
2739
3027
|
return ctx.forbidden();
|
2740
3028
|
}
|
@@ -2768,8 +3056,8 @@ const singleTypes = {
|
|
2768
3056
|
const { userAbility } = ctx.state;
|
2769
3057
|
const { model } = ctx.params;
|
2770
3058
|
const { body, query = {} } = ctx.request;
|
2771
|
-
const documentManager2 = getService$
|
2772
|
-
const permissionChecker2 = getService$
|
3059
|
+
const documentManager2 = getService$2("document-manager");
|
3060
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2773
3061
|
if (permissionChecker2.cannot.discard()) {
|
2774
3062
|
return ctx.forbidden();
|
2775
3063
|
}
|
@@ -2792,8 +3080,8 @@ const singleTypes = {
|
|
2792
3080
|
const { userAbility } = ctx.state;
|
2793
3081
|
const { model } = ctx.params;
|
2794
3082
|
const { query } = ctx.request;
|
2795
|
-
const documentManager2 = getService$
|
2796
|
-
const permissionChecker2 = getService$
|
3083
|
+
const documentManager2 = getService$2("document-manager");
|
3084
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2797
3085
|
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2798
3086
|
if (permissionChecker2.cannot.read()) {
|
2799
3087
|
return ctx.forbidden();
|
@@ -2817,7 +3105,7 @@ const uid$1 = {
|
|
2817
3105
|
const { query = {} } = ctx.request;
|
2818
3106
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2819
3107
|
await validateUIDField(contentTypeUID, field);
|
2820
|
-
const uidService = getService$
|
3108
|
+
const uidService = getService$2("uid");
|
2821
3109
|
ctx.body = {
|
2822
3110
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2823
3111
|
};
|
@@ -2829,7 +3117,7 @@ const uid$1 = {
|
|
2829
3117
|
const { query = {} } = ctx.request;
|
2830
3118
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2831
3119
|
await validateUIDField(contentTypeUID, field);
|
2832
|
-
const uidService = getService$
|
3120
|
+
const uidService = getService$2("uid");
|
2833
3121
|
const isAvailable = await uidService.checkUIDAvailability({
|
2834
3122
|
contentTypeUID,
|
2835
3123
|
field,
|
@@ -2850,7 +3138,8 @@ const controllers = {
|
|
2850
3138
|
relations,
|
2851
3139
|
"single-types": singleTypes,
|
2852
3140
|
uid: uid$1,
|
2853
|
-
...history.controllers ? history.controllers : {}
|
3141
|
+
...history.controllers ? history.controllers : {},
|
3142
|
+
...preview.controllers ? preview.controllers : {}
|
2854
3143
|
};
|
2855
3144
|
const keys = {
|
2856
3145
|
CONFIGURATION: "configuration"
|
@@ -2979,18 +3268,15 @@ async function syncMetadatas(configuration, schema) {
|
|
2979
3268
|
___default.default.set(updatedMeta, ["list", "searchable"], false);
|
2980
3269
|
___default.default.set(acc, [key], updatedMeta);
|
2981
3270
|
}
|
2982
|
-
if (!___default.default.has(edit, "mainField"))
|
2983
|
-
return acc;
|
3271
|
+
if (!___default.default.has(edit, "mainField")) return acc;
|
2984
3272
|
if (!isRelation$1(attr)) {
|
2985
3273
|
___default.default.set(updatedMeta, "edit", ___default.default.omit(edit, ["mainField"]));
|
2986
3274
|
___default.default.set(acc, [key], updatedMeta);
|
2987
3275
|
return acc;
|
2988
3276
|
}
|
2989
|
-
if (edit.mainField === "id")
|
2990
|
-
return acc;
|
3277
|
+
if (edit.mainField === "id") return acc;
|
2991
3278
|
const targetSchema = getTargetSchema(attr.targetModel);
|
2992
|
-
if (!targetSchema)
|
2993
|
-
return acc;
|
3279
|
+
if (!targetSchema) return acc;
|
2994
3280
|
if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
|
2995
3281
|
___default.default.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
|
2996
3282
|
___default.default.set(acc, [key], updatedMeta);
|
@@ -3001,12 +3287,12 @@ async function syncMetadatas(configuration, schema) {
|
|
3001
3287
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
3002
3288
|
}
|
3003
3289
|
const getTargetSchema = (targetModel) => {
|
3004
|
-
return getService$
|
3290
|
+
return getService$2("content-types").findContentType(targetModel);
|
3005
3291
|
};
|
3006
3292
|
const DEFAULT_LIST_LENGTH = 4;
|
3007
3293
|
const MAX_ROW_SIZE = 12;
|
3008
3294
|
const isAllowedFieldSize = (type, size) => {
|
3009
|
-
const { getFieldSize } = getService$
|
3295
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3010
3296
|
const fieldSize = getFieldSize(type);
|
3011
3297
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3012
3298
|
return false;
|
@@ -3014,7 +3300,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3014
3300
|
return size <= MAX_ROW_SIZE;
|
3015
3301
|
};
|
3016
3302
|
const getDefaultFieldSize = (attribute) => {
|
3017
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3303
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3018
3304
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3019
3305
|
};
|
3020
3306
|
async function createDefaultLayouts(schema) {
|
@@ -3035,8 +3321,7 @@ function createDefaultEditLayout(schema) {
|
|
3035
3321
|
return appendToEditLayout([], keys2, schema);
|
3036
3322
|
}
|
3037
3323
|
function syncLayouts(configuration, schema) {
|
3038
|
-
if (___default.default.isEmpty(configuration.layouts))
|
3039
|
-
return createDefaultLayouts(schema);
|
3324
|
+
if (___default.default.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
3040
3325
|
const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
|
3041
3326
|
let cleanList = list.filter((attr) => isListable(schema, attr));
|
3042
3327
|
const cleanEditRelations = editRelations.filter(
|
@@ -3047,9 +3332,8 @@ function syncLayouts(configuration, schema) {
|
|
3047
3332
|
for (const row of edit) {
|
3048
3333
|
const newRow = [];
|
3049
3334
|
for (const el of row) {
|
3050
|
-
if (!hasEditableAttribute(schema, el.name))
|
3051
|
-
|
3052
|
-
const { hasFieldSize } = getService$1("field-sizes");
|
3335
|
+
if (!hasEditableAttribute(schema, el.name)) continue;
|
3336
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3053
3337
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3054
3338
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3055
3339
|
elementsToReAppend.push(el.name);
|
@@ -3079,8 +3363,7 @@ function syncLayouts(configuration, schema) {
|
|
3079
3363
|
};
|
3080
3364
|
}
|
3081
3365
|
const appendToEditLayout = (layout = [], keysToAppend, schema) => {
|
3082
|
-
if (keysToAppend.length === 0)
|
3083
|
-
return layout;
|
3366
|
+
if (keysToAppend.length === 0) return layout;
|
3084
3367
|
let currentRowIndex = Math.max(layout.length - 1, 0);
|
3085
3368
|
if (!layout[currentRowIndex]) {
|
3086
3369
|
layout[currentRowIndex] = [];
|
@@ -3189,17 +3472,17 @@ const configurationService$1 = createConfigurationService({
|
|
3189
3472
|
isComponent: true,
|
3190
3473
|
prefix: STORE_KEY_PREFIX,
|
3191
3474
|
getModels() {
|
3192
|
-
const { toContentManagerModel } = getService$
|
3475
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3193
3476
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3194
3477
|
}
|
3195
3478
|
});
|
3196
3479
|
const components = ({ strapi: strapi2 }) => ({
|
3197
3480
|
findAllComponents() {
|
3198
|
-
const { toContentManagerModel } = getService$
|
3481
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3199
3482
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3200
3483
|
},
|
3201
3484
|
findComponent(uid2) {
|
3202
|
-
const { toContentManagerModel } = getService$
|
3485
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3203
3486
|
const component = strapi2.components[uid2];
|
3204
3487
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3205
3488
|
},
|
@@ -3250,17 +3533,17 @@ const configurationService = createConfigurationService({
|
|
3250
3533
|
storeUtils,
|
3251
3534
|
prefix: "content_types",
|
3252
3535
|
getModels() {
|
3253
|
-
const { toContentManagerModel } = getService$
|
3536
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3254
3537
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3255
3538
|
}
|
3256
3539
|
});
|
3257
3540
|
const service = ({ strapi: strapi2 }) => ({
|
3258
3541
|
findAllContentTypes() {
|
3259
|
-
const { toContentManagerModel } = getService$
|
3542
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3260
3543
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3261
3544
|
},
|
3262
3545
|
findContentType(uid2) {
|
3263
|
-
const { toContentManagerModel } = getService$
|
3546
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3264
3547
|
const contentType = strapi2.contentTypes[uid2];
|
3265
3548
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3266
3549
|
},
|
@@ -3289,7 +3572,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3289
3572
|
return this.findConfiguration(contentType);
|
3290
3573
|
},
|
3291
3574
|
findComponentsConfigurations(contentType) {
|
3292
|
-
return getService$
|
3575
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3293
3576
|
},
|
3294
3577
|
syncConfigurations() {
|
3295
3578
|
return configurationService.syncConfigurations();
|
@@ -3470,12 +3753,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3470
3753
|
ability: userAbility,
|
3471
3754
|
model
|
3472
3755
|
});
|
3473
|
-
const
|
3756
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3757
|
+
const toSubject = (entity) => {
|
3758
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3759
|
+
};
|
3474
3760
|
const can = (action, entity, field) => {
|
3475
|
-
|
3761
|
+
const subject = toSubject(entity);
|
3762
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3763
|
+
return (
|
3764
|
+
// Test the original action to see if it passes
|
3765
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3766
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3767
|
+
);
|
3476
3768
|
};
|
3477
3769
|
const cannot = (action, entity, field) => {
|
3478
|
-
|
3770
|
+
const subject = toSubject(entity);
|
3771
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3772
|
+
return (
|
3773
|
+
// Test both the original action
|
3774
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3775
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3776
|
+
);
|
3479
3777
|
};
|
3480
3778
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3481
3779
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3546,7 +3844,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3546
3844
|
return userAbility.can(action);
|
3547
3845
|
},
|
3548
3846
|
async registerPermissions() {
|
3549
|
-
const displayedContentTypes = getService$
|
3847
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3550
3848
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3551
3849
|
const actions = [
|
3552
3850
|
{
|
@@ -3631,6 +3929,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
|
|
3631
3929
|
if (initialPopulate) {
|
3632
3930
|
return initialPopulate;
|
3633
3931
|
}
|
3932
|
+
if (attributeName === "localizations") {
|
3933
|
+
const validationPopulate = getPopulateForValidation(model.uid);
|
3934
|
+
return {
|
3935
|
+
populate: validationPopulate.populate
|
3936
|
+
};
|
3937
|
+
}
|
3634
3938
|
if (!isVisibleAttribute$1(model, attributeName)) {
|
3635
3939
|
return true;
|
3636
3940
|
}
|
@@ -3690,6 +3994,9 @@ const getDeepPopulate = (uid2, {
|
|
3690
3994
|
return {};
|
3691
3995
|
}
|
3692
3996
|
const model = strapi.getModel(uid2);
|
3997
|
+
if (!model) {
|
3998
|
+
return {};
|
3999
|
+
}
|
3693
4000
|
return Object.keys(model.attributes).reduce(
|
3694
4001
|
(populateAcc, attributeName) => fp.merge(
|
3695
4002
|
populateAcc,
|
@@ -3709,40 +4016,46 @@ const getDeepPopulate = (uid2, {
|
|
3709
4016
|
{}
|
3710
4017
|
);
|
3711
4018
|
};
|
3712
|
-
const
|
3713
|
-
|
3714
|
-
|
3715
|
-
countOne = false,
|
3716
|
-
maxLevel = Infinity
|
3717
|
-
} = {}, level = 1) => {
|
3718
|
-
if (level > maxLevel) {
|
4019
|
+
const getPopulateForValidation = (uid2) => {
|
4020
|
+
const model = strapi.getModel(uid2);
|
4021
|
+
if (!model) {
|
3719
4022
|
return {};
|
3720
4023
|
}
|
3721
|
-
const model = strapi.getModel(uid2);
|
3722
4024
|
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
3723
|
-
if (
|
4025
|
+
if (isScalarAttribute(attribute)) {
|
4026
|
+
if (getDoesAttributeRequireValidation(attribute)) {
|
4027
|
+
populateAcc.fields = populateAcc.fields || [];
|
4028
|
+
populateAcc.fields.push(attributeName);
|
4029
|
+
}
|
3724
4030
|
return populateAcc;
|
3725
4031
|
}
|
3726
|
-
if (
|
3727
|
-
|
3728
|
-
|
3729
|
-
|
4032
|
+
if (isComponent(attribute)) {
|
4033
|
+
const component = attribute.component;
|
4034
|
+
const componentResult = getPopulateForValidation(component);
|
4035
|
+
if (Object.keys(componentResult).length > 0) {
|
4036
|
+
populateAcc.populate = populateAcc.populate || {};
|
4037
|
+
populateAcc.populate[attributeName] = componentResult;
|
4038
|
+
}
|
4039
|
+
return populateAcc;
|
3730
4040
|
}
|
3731
|
-
|
3732
|
-
|
3733
|
-
|
3734
|
-
|
3735
|
-
|
3736
|
-
|
3737
|
-
|
3738
|
-
|
3739
|
-
|
3740
|
-
countOne,
|
3741
|
-
maxLevel
|
4041
|
+
if (isDynamicZone(attribute)) {
|
4042
|
+
const components2 = attribute.components;
|
4043
|
+
const componentsResult = (components2 || []).reduce(
|
4044
|
+
(acc, componentUID) => {
|
4045
|
+
const componentResult = getPopulateForValidation(componentUID);
|
4046
|
+
if (Object.keys(componentResult).length > 0) {
|
4047
|
+
acc[componentUID] = componentResult;
|
4048
|
+
}
|
4049
|
+
return acc;
|
3742
4050
|
},
|
3743
|
-
|
3744
|
-
)
|
3745
|
-
|
4051
|
+
{}
|
4052
|
+
);
|
4053
|
+
if (Object.keys(componentsResult).length > 0) {
|
4054
|
+
populateAcc.populate = populateAcc.populate || {};
|
4055
|
+
populateAcc.populate[attributeName] = { on: componentsResult };
|
4056
|
+
}
|
4057
|
+
}
|
4058
|
+
return populateAcc;
|
3746
4059
|
}, {});
|
3747
4060
|
};
|
3748
4061
|
const getDeepPopulateDraftCount = (uid2) => {
|
@@ -3822,7 +4135,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3822
4135
|
return populateQuery;
|
3823
4136
|
};
|
3824
4137
|
const buildDeepPopulate = (uid2) => {
|
3825
|
-
return getService$
|
4138
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3826
4139
|
};
|
3827
4140
|
const populateBuilder = (uid2) => {
|
3828
4141
|
let getInitialPopulate = async () => {
|
@@ -3984,7 +4297,6 @@ const AVAILABLE_LOCALES_FIELDS = [
|
|
3984
4297
|
"locale",
|
3985
4298
|
"updatedAt",
|
3986
4299
|
"createdAt",
|
3987
|
-
"status",
|
3988
4300
|
"publishedAt",
|
3989
4301
|
"documentId"
|
3990
4302
|
];
|
@@ -4005,34 +4317,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4005
4317
|
/**
|
4006
4318
|
* Returns available locales of a document for the current status
|
4007
4319
|
*/
|
4008
|
-
async getAvailableLocales(uid2, version, allVersions
|
4320
|
+
async getAvailableLocales(uid2, version, allVersions) {
|
4009
4321
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
4010
|
-
|
4322
|
+
if (version.locale) {
|
4323
|
+
delete versionsByLocale[version.locale];
|
4324
|
+
}
|
4011
4325
|
const model = strapi2.getModel(uid2);
|
4012
|
-
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4013
|
-
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
4014
|
-
({ key }, { remove }) => {
|
4015
|
-
if (keysToKeep.includes(key)) {
|
4016
|
-
return;
|
4017
|
-
}
|
4018
|
-
remove(key);
|
4019
|
-
},
|
4020
|
-
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
4021
|
-
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
4022
|
-
localeVersion
|
4023
|
-
);
|
4024
4326
|
const mappingResult = await strapiUtils.async.map(
|
4025
4327
|
Object.values(versionsByLocale),
|
4026
4328
|
async (localeVersions) => {
|
4027
|
-
const mappedLocaleVersions = await strapiUtils.async.map(
|
4028
|
-
localeVersions,
|
4029
|
-
traversalFunction
|
4030
|
-
);
|
4031
4329
|
if (!strapiUtils.contentTypes.hasDraftAndPublish(model)) {
|
4032
|
-
return
|
4330
|
+
return localeVersions[0];
|
4033
4331
|
}
|
4034
|
-
const draftVersion =
|
4035
|
-
const otherVersions =
|
4332
|
+
const draftVersion = localeVersions.find((v) => v.publishedAt === null);
|
4333
|
+
const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);
|
4036
4334
|
if (!draftVersion) {
|
4037
4335
|
return;
|
4038
4336
|
}
|
@@ -4054,8 +4352,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4054
4352
|
const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
|
4055
4353
|
return matchLocale && matchStatus;
|
4056
4354
|
});
|
4057
|
-
if (!availableStatus)
|
4058
|
-
return availableStatus;
|
4355
|
+
if (!availableStatus) return availableStatus;
|
4059
4356
|
return fp.pick(AVAILABLE_STATUS_FIELDS, availableStatus);
|
4060
4357
|
},
|
4061
4358
|
/**
|
@@ -4065,18 +4362,17 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4065
4362
|
* @returns
|
4066
4363
|
*/
|
4067
4364
|
async getManyAvailableStatus(uid2, documents) {
|
4068
|
-
if (!documents.length)
|
4069
|
-
return [];
|
4365
|
+
if (!documents.length) return [];
|
4070
4366
|
const status = documents[0].publishedAt !== null ? "published" : "draft";
|
4071
|
-
const
|
4072
|
-
|
4073
|
-
|
4074
|
-
|
4075
|
-
|
4367
|
+
const locales = documents.map((d) => d.locale).filter(Boolean);
|
4368
|
+
return strapi2.query(uid2).findMany({
|
4369
|
+
where: {
|
4370
|
+
documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },
|
4371
|
+
// NOTE: find the "opposite" status
|
4372
|
+
publishedAt: { $null: status === "published" },
|
4373
|
+
locale: { $in: locales }
|
4076
4374
|
},
|
4077
|
-
|
4078
|
-
locale,
|
4079
|
-
fields: ["documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
|
4375
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
|
4080
4376
|
});
|
4081
4377
|
},
|
4082
4378
|
getStatus(version, otherDocumentStatuses) {
|
@@ -4093,10 +4389,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4093
4389
|
} else if (otherVersion) {
|
4094
4390
|
draftVersion = otherVersion;
|
4095
4391
|
}
|
4096
|
-
if (!draftVersion)
|
4097
|
-
|
4098
|
-
if (!publishedVersion)
|
4099
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
4392
|
+
if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4393
|
+
if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
|
4100
4394
|
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4101
4395
|
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
4102
4396
|
},
|
@@ -4104,11 +4398,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4104
4398
|
// We could refactor this so the locales are only loaded when they're
|
4105
4399
|
// needed. e.g. in the bulk locale action modal.
|
4106
4400
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4107
|
-
const populate =
|
4108
|
-
const
|
4109
|
-
where: { documentId: version.documentId },
|
4401
|
+
const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
|
4402
|
+
const params = {
|
4110
4403
|
populate: {
|
4111
|
-
// Populate only fields that require validation for bulk locale actions
|
4112
4404
|
...populate,
|
4113
4405
|
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
4114
4406
|
createdBy: {
|
@@ -4117,9 +4409,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4117
4409
|
updatedBy: {
|
4118
4410
|
select: ["id", "firstname", "lastname", "email"]
|
4119
4411
|
}
|
4412
|
+
},
|
4413
|
+
fields: fp.uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
|
4414
|
+
filters: {
|
4415
|
+
documentId: version.documentId
|
4120
4416
|
}
|
4121
|
-
}
|
4122
|
-
const
|
4417
|
+
};
|
4418
|
+
const dbParams = strapi2.get("query-params").transform(uid2, params);
|
4419
|
+
const versions = await strapi2.db.query(uid2).findMany(dbParams);
|
4420
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions) : [];
|
4123
4421
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
4124
4422
|
return {
|
4125
4423
|
availableLocales: availableLocalesResult,
|
@@ -4133,13 +4431,29 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4133
4431
|
*/
|
4134
4432
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4135
4433
|
if (!document) {
|
4136
|
-
return
|
4434
|
+
return {
|
4435
|
+
data: document,
|
4436
|
+
meta: {
|
4437
|
+
availableLocales: [],
|
4438
|
+
availableStatus: []
|
4439
|
+
}
|
4440
|
+
};
|
4137
4441
|
}
|
4138
4442
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4139
4443
|
if (!hasDraftAndPublish) {
|
4140
4444
|
opts.availableStatus = false;
|
4141
4445
|
}
|
4142
4446
|
const meta = await this.getMetadata(uid2, document, opts);
|
4447
|
+
if (document.localizations) {
|
4448
|
+
const otherStatus = await this.getManyAvailableStatus(uid2, document.localizations);
|
4449
|
+
document.localizations = document.localizations.map((d) => {
|
4450
|
+
const status = otherStatus.find((s) => s.documentId === d.documentId);
|
4451
|
+
return {
|
4452
|
+
...d,
|
4453
|
+
status: this.getStatus(d, status ? [status] : [])
|
4454
|
+
};
|
4455
|
+
});
|
4456
|
+
}
|
4143
4457
|
return {
|
4144
4458
|
data: {
|
4145
4459
|
...document,
|
@@ -4357,7 +4671,8 @@ const services = {
|
|
4357
4671
|
permission,
|
4358
4672
|
"populate-builder": populateBuilder$1,
|
4359
4673
|
uid,
|
4360
|
-
...history.services ? history.services : {}
|
4674
|
+
...history.services ? history.services : {},
|
4675
|
+
...preview.services ? preview.services : {}
|
4361
4676
|
};
|
4362
4677
|
const index = () => {
|
4363
4678
|
return {
|