@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.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1,
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
1
|
+
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, pagination } from "@strapi/utils";
|
2
|
+
import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -141,8 +141,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
141
141
|
};
|
142
142
|
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
143
143
|
if (Array.isArray(versionRelationData)) {
|
144
|
-
if (versionRelationData.length === 0)
|
145
|
-
return versionRelationData;
|
144
|
+
if (versionRelationData.length === 0) return versionRelationData;
|
146
145
|
const existingAndMissingRelations = await Promise.all(
|
147
146
|
versionRelationData.map((relation) => {
|
148
147
|
return strapi2.documents(attribute.target).findOne({
|
@@ -173,10 +172,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
172
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
173
|
};
|
175
174
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
175
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
176
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
177
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
178
|
const getLocaleDictionary = async () => {
|
178
|
-
if (!localesService)
|
179
|
-
return {};
|
179
|
+
if (!localesService) return {};
|
180
180
|
const locales = await localesService.find() || [];
|
181
181
|
return locales.reduce(
|
182
182
|
(acc, locale) => {
|
@@ -200,9 +200,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
200
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
201
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
202
|
};
|
203
|
-
const
|
203
|
+
const getComponentFields = (componentUID) => {
|
204
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
205
|
+
(fieldsAcc, [key, attribute]) => {
|
206
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
207
|
+
fieldsAcc.push(key);
|
208
|
+
}
|
209
|
+
return fieldsAcc;
|
210
|
+
},
|
211
|
+
[]
|
212
|
+
);
|
213
|
+
};
|
214
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
215
|
const model = strapi2.getModel(uid2);
|
205
216
|
const attributes = Object.entries(model.attributes);
|
217
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
218
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
219
|
switch (attribute.type) {
|
208
220
|
case "relation": {
|
@@ -212,23 +224,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
212
224
|
}
|
213
225
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
214
226
|
if (isVisible2) {
|
215
|
-
acc[attributeName] = {
|
227
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
216
228
|
}
|
217
229
|
break;
|
218
230
|
}
|
219
231
|
case "media": {
|
220
|
-
acc[attributeName] = {
|
232
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
221
233
|
break;
|
222
234
|
}
|
223
235
|
case "component": {
|
224
236
|
const populate = getDeepPopulate2(attribute.component);
|
225
|
-
acc[attributeName] = {
|
237
|
+
acc[attributeName] = {
|
238
|
+
populate,
|
239
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
240
|
+
};
|
226
241
|
break;
|
227
242
|
}
|
228
243
|
case "dynamiczone": {
|
229
244
|
const populatedComponents = (attribute.components || []).reduce(
|
230
245
|
(acc2, componentUID) => {
|
231
|
-
acc2[componentUID] = {
|
246
|
+
acc2[componentUID] = {
|
247
|
+
populate: getDeepPopulate2(componentUID),
|
248
|
+
[fieldSelector]: getComponentFields(componentUID)
|
249
|
+
};
|
232
250
|
return acc2;
|
233
251
|
},
|
234
252
|
{}
|
@@ -290,6 +308,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
290
308
|
getRelationRestoreValue,
|
291
309
|
getMediaRestoreValue,
|
292
310
|
getDefaultLocale,
|
311
|
+
isLocalizedContentType,
|
293
312
|
getLocaleDictionary,
|
294
313
|
getRetentionDays,
|
295
314
|
getVersionStatus,
|
@@ -312,7 +331,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
312
331
|
});
|
313
332
|
},
|
314
333
|
async findVersionsPage(params) {
|
315
|
-
const
|
334
|
+
const model = strapi2.getModel(params.query.contentType);
|
335
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
336
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
337
|
+
let locale = null;
|
338
|
+
if (isLocalizedContentType) {
|
339
|
+
locale = params.query.locale || defaultLocale;
|
340
|
+
}
|
316
341
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
317
342
|
query.findPage({
|
318
343
|
...params.query,
|
@@ -334,7 +359,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
359
|
const attributeValue = entry.data[attributeKey];
|
335
360
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
336
361
|
if (attributeSchema.type === "media") {
|
337
|
-
const permissionChecker2 = getService$
|
362
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
338
363
|
userAbility: params.state.userAbility,
|
339
364
|
model: "plugin::upload.file"
|
340
365
|
});
|
@@ -357,7 +382,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
357
382
|
if (userToPopulate == null) {
|
358
383
|
return null;
|
359
384
|
}
|
360
|
-
return strapi2.query("admin::user").findOne({
|
385
|
+
return strapi2.query("admin::user").findOne({
|
386
|
+
where: {
|
387
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
388
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
389
|
+
}
|
390
|
+
});
|
361
391
|
})
|
362
392
|
);
|
363
393
|
return {
|
@@ -370,7 +400,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
370
400
|
[attributeKey]: adminUsers
|
371
401
|
};
|
372
402
|
}
|
373
|
-
const permissionChecker2 = getService$
|
403
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
374
404
|
userAbility: params.state.userAbility,
|
375
405
|
model: attributeSchema.target
|
376
406
|
});
|
@@ -468,6 +498,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
468
498
|
}
|
469
499
|
};
|
470
500
|
};
|
501
|
+
const shouldCreateHistoryVersion = (context) => {
|
502
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
503
|
+
return false;
|
504
|
+
}
|
505
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
506
|
+
return false;
|
507
|
+
}
|
508
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
509
|
+
return false;
|
510
|
+
}
|
511
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
512
|
+
return false;
|
513
|
+
}
|
514
|
+
return true;
|
515
|
+
};
|
516
|
+
const getSchemas = (uid2) => {
|
517
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
518
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
519
|
+
(currentComponentSchemas, key) => {
|
520
|
+
const fieldSchema = attributesSchema[key];
|
521
|
+
if (fieldSchema.type === "component") {
|
522
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
523
|
+
return {
|
524
|
+
...currentComponentSchemas,
|
525
|
+
[fieldSchema.component]: componentSchema
|
526
|
+
};
|
527
|
+
}
|
528
|
+
return currentComponentSchemas;
|
529
|
+
},
|
530
|
+
{}
|
531
|
+
);
|
532
|
+
return {
|
533
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
534
|
+
componentsSchemas
|
535
|
+
};
|
536
|
+
};
|
471
537
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
472
538
|
const state = {
|
473
539
|
deleteExpiredJob: null,
|
@@ -480,76 +546,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
480
546
|
return;
|
481
547
|
}
|
482
548
|
strapi2.documents.use(async (context, next) => {
|
483
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
484
|
-
return next();
|
485
|
-
}
|
486
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
487
|
-
return next();
|
488
|
-
}
|
489
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
490
|
-
return next();
|
491
|
-
}
|
492
|
-
const contentTypeUid = context.contentType.uid;
|
493
|
-
if (!contentTypeUid.startsWith("api::")) {
|
494
|
-
return next();
|
495
|
-
}
|
496
549
|
const result = await next();
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
550
|
+
if (!shouldCreateHistoryVersion(context)) {
|
551
|
+
return result;
|
552
|
+
}
|
553
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
501
554
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
502
|
-
const
|
503
|
-
if (
|
504
|
-
|
505
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
506
|
-
);
|
507
|
-
return next();
|
555
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
556
|
+
if (!locales.length) {
|
557
|
+
return result;
|
508
558
|
}
|
509
|
-
const
|
510
|
-
|
511
|
-
|
512
|
-
|
559
|
+
const uid2 = context.contentType.uid;
|
560
|
+
const schemas = getSchemas(uid2);
|
561
|
+
const model = strapi2.getModel(uid2);
|
562
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
563
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
564
|
+
where: {
|
565
|
+
documentId,
|
566
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
567
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
568
|
+
},
|
569
|
+
populate: serviceUtils.getDeepPopulate(
|
570
|
+
uid2,
|
571
|
+
true
|
572
|
+
/* use database syntax */
|
573
|
+
)
|
513
574
|
});
|
514
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
515
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
516
|
-
const componentsSchemas = Object.keys(
|
517
|
-
attributesSchema
|
518
|
-
).reduce((currentComponentSchemas, key) => {
|
519
|
-
const fieldSchema = attributesSchema[key];
|
520
|
-
if (fieldSchema.type === "component") {
|
521
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
522
|
-
return {
|
523
|
-
...currentComponentSchemas,
|
524
|
-
[fieldSchema.component]: componentSchema
|
525
|
-
};
|
526
|
-
}
|
527
|
-
return currentComponentSchemas;
|
528
|
-
}, {});
|
529
575
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
530
|
-
onCommit(() => {
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
576
|
+
onCommit(async () => {
|
577
|
+
for (const entry of localeEntries) {
|
578
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
579
|
+
await getService$1(strapi2, "history").createVersion({
|
580
|
+
contentType: uid2,
|
581
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
582
|
+
relatedDocumentId: documentId,
|
583
|
+
locale: entry.locale,
|
584
|
+
status,
|
585
|
+
...schemas
|
586
|
+
});
|
587
|
+
}
|
540
588
|
});
|
541
589
|
});
|
542
590
|
return result;
|
543
591
|
});
|
544
|
-
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
592
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
545
593
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
546
594
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
547
595
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
548
596
|
where: {
|
549
597
|
created_at: {
|
550
|
-
$lt: expirationDate
|
598
|
+
$lt: expirationDate
|
551
599
|
}
|
552
600
|
}
|
601
|
+
}).catch((error) => {
|
602
|
+
if (error instanceof Error) {
|
603
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
604
|
+
}
|
553
605
|
});
|
554
606
|
});
|
555
607
|
state.isInitialized = true;
|
@@ -561,17 +613,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
561
613
|
}
|
562
614
|
};
|
563
615
|
};
|
564
|
-
const services$
|
616
|
+
const services$2 = {
|
565
617
|
history: createHistoryService,
|
566
618
|
lifecycles: createLifecyclesService
|
567
619
|
};
|
568
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
620
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
569
621
|
const historyVersionRouter = {
|
570
622
|
type: "admin",
|
571
623
|
routes: [
|
572
624
|
{
|
573
625
|
method: "GET",
|
574
|
-
info,
|
626
|
+
info: info$1,
|
575
627
|
path: "/history-versions",
|
576
628
|
handler: "history-version.findMany",
|
577
629
|
config: {
|
@@ -580,7 +632,7 @@ const historyVersionRouter = {
|
|
580
632
|
},
|
581
633
|
{
|
582
634
|
method: "PUT",
|
583
|
-
info,
|
635
|
+
info: info$1,
|
584
636
|
path: "/history-versions/:versionId/restore",
|
585
637
|
handler: "history-version.restoreVersion",
|
586
638
|
config: {
|
@@ -589,7 +641,7 @@ const historyVersionRouter = {
|
|
589
641
|
}
|
590
642
|
]
|
591
643
|
};
|
592
|
-
const routes$
|
644
|
+
const routes$2 = {
|
593
645
|
"history-version": historyVersionRouter
|
594
646
|
};
|
595
647
|
const historyVersion = {
|
@@ -636,21 +688,21 @@ const historyVersion = {
|
|
636
688
|
}
|
637
689
|
}
|
638
690
|
};
|
639
|
-
const getFeature = () => {
|
691
|
+
const getFeature$1 = () => {
|
640
692
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
641
693
|
return {
|
642
694
|
register({ strapi: strapi2 }) {
|
643
695
|
strapi2.get("models").add(historyVersion);
|
644
696
|
},
|
645
697
|
bootstrap({ strapi: strapi2 }) {
|
646
|
-
getService(strapi2, "lifecycles").bootstrap();
|
698
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
647
699
|
},
|
648
700
|
destroy({ strapi: strapi2 }) {
|
649
|
-
getService(strapi2, "lifecycles").destroy();
|
701
|
+
getService$1(strapi2, "lifecycles").destroy();
|
650
702
|
},
|
651
|
-
controllers: controllers$
|
652
|
-
services: services$
|
653
|
-
routes: routes$
|
703
|
+
controllers: controllers$2,
|
704
|
+
services: services$2,
|
705
|
+
routes: routes$2
|
654
706
|
};
|
655
707
|
}
|
656
708
|
return {
|
@@ -659,9 +711,201 @@ const getFeature = () => {
|
|
659
711
|
}
|
660
712
|
};
|
661
713
|
};
|
662
|
-
const history = getFeature();
|
714
|
+
const history = getFeature$1();
|
715
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
716
|
+
const previewRouter = {
|
717
|
+
type: "admin",
|
718
|
+
routes: [
|
719
|
+
{
|
720
|
+
method: "GET",
|
721
|
+
info,
|
722
|
+
path: "/preview/url/:contentType",
|
723
|
+
handler: "preview.getPreviewUrl",
|
724
|
+
config: {
|
725
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
726
|
+
}
|
727
|
+
}
|
728
|
+
]
|
729
|
+
};
|
730
|
+
const routes$1 = {
|
731
|
+
preview: previewRouter
|
732
|
+
};
|
733
|
+
function getService(strapi2, name) {
|
734
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
735
|
+
}
|
736
|
+
const getPreviewUrlSchema = yup.object().shape({
|
737
|
+
// Will be undefined for single types
|
738
|
+
documentId: yup.string(),
|
739
|
+
locale: yup.string().nullable(),
|
740
|
+
status: yup.string()
|
741
|
+
}).required();
|
742
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
743
|
+
await validateYupSchema(getPreviewUrlSchema)(params);
|
744
|
+
const newParams = pick(["documentId", "locale", "status"], params);
|
745
|
+
const model = strapi2.getModel(uid2);
|
746
|
+
if (!model || model.modelType !== "contentType") {
|
747
|
+
throw new errors.ValidationError("Invalid content type");
|
748
|
+
}
|
749
|
+
const isSingleType = model?.kind === "singleType";
|
750
|
+
if (!isSingleType && !params.documentId) {
|
751
|
+
throw new errors.ValidationError("documentId is required for Collection Types");
|
752
|
+
}
|
753
|
+
if (isSingleType) {
|
754
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
755
|
+
if (!doc) {
|
756
|
+
throw new errors.NotFoundError("Document not found");
|
757
|
+
}
|
758
|
+
newParams.documentId = doc?.documentId;
|
759
|
+
}
|
760
|
+
if (!newParams.status) {
|
761
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
762
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
763
|
+
}
|
764
|
+
return newParams;
|
765
|
+
};
|
766
|
+
const createPreviewController = () => {
|
767
|
+
return {
|
768
|
+
/**
|
769
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
770
|
+
* in the Content Manager.
|
771
|
+
*/
|
772
|
+
async getPreviewUrl(ctx) {
|
773
|
+
const uid2 = ctx.params.contentType;
|
774
|
+
const query = ctx.request.query;
|
775
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
776
|
+
const previewService = getService(strapi, "preview");
|
777
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
778
|
+
if (!url) {
|
779
|
+
ctx.status = 204;
|
780
|
+
}
|
781
|
+
return {
|
782
|
+
data: { url }
|
783
|
+
};
|
784
|
+
}
|
785
|
+
};
|
786
|
+
};
|
787
|
+
const controllers$1 = {
|
788
|
+
preview: createPreviewController
|
789
|
+
/**
|
790
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
791
|
+
* passing a controller factory as the value, instead of a controller object directly
|
792
|
+
*/
|
793
|
+
};
|
794
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
795
|
+
const config = getService(strapi2, "preview-config");
|
796
|
+
return {
|
797
|
+
async getPreviewUrl(uid2, params) {
|
798
|
+
const handler = config.getPreviewHandler();
|
799
|
+
try {
|
800
|
+
return handler(uid2, params);
|
801
|
+
} catch (error) {
|
802
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
803
|
+
throw new errors.ApplicationError("Failed to get preview URL");
|
804
|
+
}
|
805
|
+
return;
|
806
|
+
}
|
807
|
+
};
|
808
|
+
};
|
809
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
810
|
+
const middlewares = strapi.config.get("middlewares");
|
811
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
812
|
+
if (currentMiddleware === middleware.name) {
|
813
|
+
return middleware;
|
814
|
+
}
|
815
|
+
if (currentMiddleware.name === middleware.name) {
|
816
|
+
return mergeWith(
|
817
|
+
(objValue, srcValue) => {
|
818
|
+
if (Array.isArray(objValue)) {
|
819
|
+
return objValue.concat(srcValue);
|
820
|
+
}
|
821
|
+
return void 0;
|
822
|
+
},
|
823
|
+
currentMiddleware,
|
824
|
+
middleware
|
825
|
+
);
|
826
|
+
}
|
827
|
+
return currentMiddleware;
|
828
|
+
});
|
829
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
830
|
+
};
|
831
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
832
|
+
return {
|
833
|
+
register() {
|
834
|
+
if (!this.isEnabled()) {
|
835
|
+
return;
|
836
|
+
}
|
837
|
+
const config = strapi2.config.get("admin.preview");
|
838
|
+
if (config.config?.allowedOrigins) {
|
839
|
+
extendMiddlewareConfiguration({
|
840
|
+
name: "strapi::security",
|
841
|
+
config: {
|
842
|
+
contentSecurityPolicy: {
|
843
|
+
directives: {
|
844
|
+
"frame-src": config.config.allowedOrigins
|
845
|
+
}
|
846
|
+
}
|
847
|
+
}
|
848
|
+
});
|
849
|
+
}
|
850
|
+
},
|
851
|
+
isEnabled() {
|
852
|
+
const config = strapi2.config.get("admin.preview");
|
853
|
+
if (!config) {
|
854
|
+
return false;
|
855
|
+
}
|
856
|
+
return config?.enabled ?? true;
|
857
|
+
},
|
858
|
+
/**
|
859
|
+
* Validate if the configuration is valid
|
860
|
+
*/
|
861
|
+
validate() {
|
862
|
+
if (!this.isEnabled()) {
|
863
|
+
return;
|
864
|
+
}
|
865
|
+
const handler = this.getPreviewHandler();
|
866
|
+
if (typeof handler !== "function") {
|
867
|
+
throw new errors.ValidationError(
|
868
|
+
"Preview configuration is invalid. Handler must be a function"
|
869
|
+
);
|
870
|
+
}
|
871
|
+
},
|
872
|
+
/**
|
873
|
+
* Utility to get the preview handler from the configuration
|
874
|
+
*/
|
875
|
+
getPreviewHandler() {
|
876
|
+
const config = strapi2.config.get("admin.preview");
|
877
|
+
const emptyHandler = () => {
|
878
|
+
return void 0;
|
879
|
+
};
|
880
|
+
if (!this.isEnabled()) {
|
881
|
+
return emptyHandler;
|
882
|
+
}
|
883
|
+
return config?.config?.handler || emptyHandler;
|
884
|
+
}
|
885
|
+
};
|
886
|
+
};
|
887
|
+
const services$1 = {
|
888
|
+
preview: createPreviewService,
|
889
|
+
"preview-config": createPreviewConfigService
|
890
|
+
};
|
891
|
+
const getFeature = () => {
|
892
|
+
return {
|
893
|
+
register() {
|
894
|
+
const config = getService(strapi, "preview-config");
|
895
|
+
config.validate();
|
896
|
+
config.register();
|
897
|
+
},
|
898
|
+
bootstrap() {
|
899
|
+
},
|
900
|
+
routes: routes$1,
|
901
|
+
controllers: controllers$1,
|
902
|
+
services: services$1
|
903
|
+
};
|
904
|
+
};
|
905
|
+
const preview = getFeature();
|
663
906
|
const register = async ({ strapi: strapi2 }) => {
|
664
907
|
await history.register?.({ strapi: strapi2 });
|
908
|
+
await preview.register?.({ strapi: strapi2 });
|
665
909
|
};
|
666
910
|
const ALLOWED_WEBHOOK_EVENTS = {
|
667
911
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -671,11 +915,12 @@ const bootstrap = async () => {
|
|
671
915
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
672
916
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
673
917
|
});
|
674
|
-
getService$
|
675
|
-
await getService$
|
676
|
-
await getService$
|
677
|
-
await getService$
|
918
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
919
|
+
await getService$2("components").syncConfigurations();
|
920
|
+
await getService$2("content-types").syncConfigurations();
|
921
|
+
await getService$2("permission").registerPermissions();
|
678
922
|
await history.bootstrap?.({ strapi });
|
923
|
+
await preview.bootstrap?.({ strapi });
|
679
924
|
};
|
680
925
|
const destroy = async ({ strapi: strapi2 }) => {
|
681
926
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1165,7 +1410,8 @@ const admin = {
|
|
1165
1410
|
};
|
1166
1411
|
const routes = {
|
1167
1412
|
admin,
|
1168
|
-
...history.routes ? history.routes : {}
|
1413
|
+
...history.routes ? history.routes : {},
|
1414
|
+
...preview.routes ? preview.routes : {}
|
1169
1415
|
};
|
1170
1416
|
const hasPermissionsSchema = yup$1.object({
|
1171
1417
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1176,6 +1422,11 @@ const { createPolicy } = policy;
|
|
1176
1422
|
const hasPermissions = createPolicy({
|
1177
1423
|
name: "plugin::content-manager.hasPermissions",
|
1178
1424
|
validator: validateHasPermissionsInput,
|
1425
|
+
/**
|
1426
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1427
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1428
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1429
|
+
*/
|
1179
1430
|
handler(ctx, config = {}) {
|
1180
1431
|
const { actions = [], hasAtLeastOne = false } = config;
|
1181
1432
|
const { userAbility } = ctx.state;
|
@@ -1223,8 +1474,7 @@ const isSortable = (schema, name) => {
|
|
1223
1474
|
if (!_.has(schema.attributes, name)) {
|
1224
1475
|
return false;
|
1225
1476
|
}
|
1226
|
-
if (schema.modelType === "component" && name === "id")
|
1227
|
-
return false;
|
1477
|
+
if (schema.modelType === "component" && name === "id") return false;
|
1228
1478
|
const attribute = schema.attributes[name];
|
1229
1479
|
if (NON_SORTABLES.includes(attribute.type)) {
|
1230
1480
|
return false;
|
@@ -1369,8 +1619,7 @@ const createDefaultSettings = async (schema) => {
|
|
1369
1619
|
};
|
1370
1620
|
};
|
1371
1621
|
const syncSettings = async (configuration, schema) => {
|
1372
|
-
if (isEmpty(configuration.settings))
|
1373
|
-
return createDefaultSettings(schema);
|
1622
|
+
if (isEmpty(configuration.settings)) return createDefaultSettings(schema);
|
1374
1623
|
const defaultField = getDefaultMainField(schema);
|
1375
1624
|
const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
|
1376
1625
|
return {
|
@@ -1417,7 +1666,7 @@ const createMetadasSchema = (schema) => {
|
|
1417
1666
|
if (!value) {
|
1418
1667
|
return yup$1.string();
|
1419
1668
|
}
|
1420
|
-
const targetSchema = getService$
|
1669
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1421
1670
|
schema.attributes[key].targetModel
|
1422
1671
|
);
|
1423
1672
|
if (!targetSchema) {
|
@@ -1546,8 +1795,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1546
1795
|
}
|
1547
1796
|
switch (attribute.type) {
|
1548
1797
|
case "relation": {
|
1549
|
-
if (canCreate(attributePath))
|
1550
|
-
return body2;
|
1798
|
+
if (canCreate(attributePath)) return body2;
|
1551
1799
|
return set(attributePath, { set: [] }, body2);
|
1552
1800
|
}
|
1553
1801
|
case "component": {
|
@@ -1557,8 +1805,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1557
1805
|
]);
|
1558
1806
|
}
|
1559
1807
|
default: {
|
1560
|
-
if (canCreate(attributePath))
|
1561
|
-
return body2;
|
1808
|
+
if (canCreate(attributePath)) return body2;
|
1562
1809
|
return set(attributePath, null, body2);
|
1563
1810
|
}
|
1564
1811
|
}
|
@@ -1586,7 +1833,7 @@ const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultiple
|
|
1586
1833
|
}
|
1587
1834
|
};
|
1588
1835
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1589
|
-
const documentMetadata2 = getService$
|
1836
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1590
1837
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1591
1838
|
let {
|
1592
1839
|
meta: { availableLocales, availableStatus }
|
@@ -1612,8 +1859,8 @@ const createDocument = async (ctx, opts) => {
|
|
1612
1859
|
const { userAbility, user } = ctx.state;
|
1613
1860
|
const { model } = ctx.params;
|
1614
1861
|
const { body } = ctx.request;
|
1615
|
-
const documentManager2 = getService$
|
1616
|
-
const permissionChecker2 = getService$
|
1862
|
+
const documentManager2 = getService$2("document-manager");
|
1863
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1617
1864
|
if (permissionChecker2.cannot.create()) {
|
1618
1865
|
throw new errors.ForbiddenError();
|
1619
1866
|
}
|
@@ -1633,13 +1880,13 @@ const updateDocument = async (ctx, opts) => {
|
|
1633
1880
|
const { userAbility, user } = ctx.state;
|
1634
1881
|
const { id, model } = ctx.params;
|
1635
1882
|
const { body } = ctx.request;
|
1636
|
-
const documentManager2 = getService$
|
1637
|
-
const permissionChecker2 = getService$
|
1883
|
+
const documentManager2 = getService$2("document-manager");
|
1884
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1638
1885
|
if (permissionChecker2.cannot.update()) {
|
1639
1886
|
throw new errors.ForbiddenError();
|
1640
1887
|
}
|
1641
1888
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1642
|
-
const populate = await getService$
|
1889
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1643
1890
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1644
1891
|
const [documentVersion, documentExists] = await Promise.all([
|
1645
1892
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
@@ -1656,7 +1903,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1656
1903
|
throw new errors.ForbiddenError();
|
1657
1904
|
}
|
1658
1905
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1659
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1906
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1660
1907
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1661
1908
|
const sanitizedBody = await sanitizeFn(body);
|
1662
1909
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1670,14 +1917,14 @@ const collectionTypes = {
|
|
1670
1917
|
const { userAbility } = ctx.state;
|
1671
1918
|
const { model } = ctx.params;
|
1672
1919
|
const { query } = ctx.request;
|
1673
|
-
const documentMetadata2 = getService$
|
1674
|
-
const documentManager2 = getService$
|
1675
|
-
const permissionChecker2 = getService$
|
1920
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1921
|
+
const documentManager2 = getService$2("document-manager");
|
1922
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1676
1923
|
if (permissionChecker2.cannot.read()) {
|
1677
1924
|
return ctx.forbidden();
|
1678
1925
|
}
|
1679
1926
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1680
|
-
const populate = await getService$
|
1927
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1681
1928
|
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1682
1929
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1683
1930
|
{ ...permissionQuery, populate, locale, status },
|
@@ -1706,13 +1953,13 @@ const collectionTypes = {
|
|
1706
1953
|
async findOne(ctx) {
|
1707
1954
|
const { userAbility } = ctx.state;
|
1708
1955
|
const { model, id } = ctx.params;
|
1709
|
-
const documentManager2 = getService$
|
1710
|
-
const permissionChecker2 = getService$
|
1956
|
+
const documentManager2 = getService$2("document-manager");
|
1957
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1711
1958
|
if (permissionChecker2.cannot.read()) {
|
1712
1959
|
return ctx.forbidden();
|
1713
1960
|
}
|
1714
1961
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1715
|
-
const populate = await getService$
|
1962
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1716
1963
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1717
1964
|
const version = await documentManager2.findOne(id, model, {
|
1718
1965
|
populate,
|
@@ -1728,7 +1975,7 @@ const collectionTypes = {
|
|
1728
1975
|
permissionChecker2,
|
1729
1976
|
model,
|
1730
1977
|
// @ts-expect-error TODO: fix
|
1731
|
-
{ id, locale, publishedAt: null },
|
1978
|
+
{ documentId: id, locale, publishedAt: null },
|
1732
1979
|
{ availableLocales: true, availableStatus: false }
|
1733
1980
|
);
|
1734
1981
|
ctx.body = { data: {}, meta };
|
@@ -1743,7 +1990,7 @@ const collectionTypes = {
|
|
1743
1990
|
async create(ctx) {
|
1744
1991
|
const { userAbility } = ctx.state;
|
1745
1992
|
const { model } = ctx.params;
|
1746
|
-
const permissionChecker2 = getService$
|
1993
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1747
1994
|
const [totalEntries, document] = await Promise.all([
|
1748
1995
|
strapi.db.query(model).count(),
|
1749
1996
|
createDocument(ctx)
|
@@ -1764,7 +2011,7 @@ const collectionTypes = {
|
|
1764
2011
|
async update(ctx) {
|
1765
2012
|
const { userAbility } = ctx.state;
|
1766
2013
|
const { model } = ctx.params;
|
1767
|
-
const permissionChecker2 = getService$
|
2014
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1768
2015
|
const updatedVersion = await updateDocument(ctx);
|
1769
2016
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1770
2017
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1773,13 +2020,13 @@ const collectionTypes = {
|
|
1773
2020
|
const { userAbility, user } = ctx.state;
|
1774
2021
|
const { model, sourceId: id } = ctx.params;
|
1775
2022
|
const { body } = ctx.request;
|
1776
|
-
const documentManager2 = getService$
|
1777
|
-
const permissionChecker2 = getService$
|
2023
|
+
const documentManager2 = getService$2("document-manager");
|
2024
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1778
2025
|
if (permissionChecker2.cannot.create()) {
|
1779
2026
|
return ctx.forbidden();
|
1780
2027
|
}
|
1781
2028
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1782
|
-
const populate = await getService$
|
2029
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1783
2030
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1784
2031
|
const document = await documentManager2.findOne(id, model, {
|
1785
2032
|
populate,
|
@@ -1818,13 +2065,13 @@ const collectionTypes = {
|
|
1818
2065
|
async delete(ctx) {
|
1819
2066
|
const { userAbility } = ctx.state;
|
1820
2067
|
const { id, model } = ctx.params;
|
1821
|
-
const documentManager2 = getService$
|
1822
|
-
const permissionChecker2 = getService$
|
2068
|
+
const documentManager2 = getService$2("document-manager");
|
2069
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1823
2070
|
if (permissionChecker2.cannot.delete()) {
|
1824
2071
|
return ctx.forbidden();
|
1825
2072
|
}
|
1826
2073
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1827
|
-
const populate = await getService$
|
2074
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1828
2075
|
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1829
2076
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1830
2077
|
if (documentLocales.length === 0) {
|
@@ -1846,19 +2093,42 @@ const collectionTypes = {
|
|
1846
2093
|
const { userAbility } = ctx.state;
|
1847
2094
|
const { id, model } = ctx.params;
|
1848
2095
|
const { body } = ctx.request;
|
1849
|
-
const documentManager2 = getService$
|
1850
|
-
const permissionChecker2 = getService$
|
2096
|
+
const documentManager2 = getService$2("document-manager");
|
2097
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1851
2098
|
if (permissionChecker2.cannot.publish()) {
|
1852
2099
|
return ctx.forbidden();
|
1853
2100
|
}
|
1854
2101
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1855
2102
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1856
|
-
const populate = await getService$
|
1857
|
-
|
2103
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2104
|
+
let document;
|
2105
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2106
|
+
const isCreate = isNil$1(id);
|
2107
|
+
if (isCreate) {
|
2108
|
+
if (permissionChecker2.cannot.create()) {
|
2109
|
+
throw new errors.ForbiddenError();
|
2110
|
+
}
|
2111
|
+
document = await createDocument(ctx, { populate });
|
2112
|
+
}
|
2113
|
+
const isUpdate = !isCreate;
|
2114
|
+
if (isUpdate) {
|
2115
|
+
const documentExists = documentManager2.exists(model, id);
|
2116
|
+
if (!documentExists) {
|
2117
|
+
throw new errors.NotFoundError("Document not found");
|
2118
|
+
}
|
2119
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2120
|
+
if (!document) {
|
2121
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2122
|
+
throw new errors.ForbiddenError();
|
2123
|
+
}
|
2124
|
+
document = await updateDocument(ctx);
|
2125
|
+
} else if (permissionChecker2.can.update(document)) {
|
2126
|
+
await updateDocument(ctx);
|
2127
|
+
}
|
2128
|
+
}
|
1858
2129
|
if (permissionChecker2.cannot.publish(document)) {
|
1859
2130
|
throw new errors.ForbiddenError();
|
1860
2131
|
}
|
1861
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1862
2132
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1863
2133
|
locale
|
1864
2134
|
// TODO: Allow setting creator fields on publish
|
@@ -1878,13 +2148,13 @@ const collectionTypes = {
|
|
1878
2148
|
const { body } = ctx.request;
|
1879
2149
|
const { documentIds } = body;
|
1880
2150
|
await validateBulkActionInput(body);
|
1881
|
-
const documentManager2 = getService$
|
1882
|
-
const permissionChecker2 = getService$
|
2151
|
+
const documentManager2 = getService$2("document-manager");
|
2152
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1883
2153
|
if (permissionChecker2.cannot.publish()) {
|
1884
2154
|
return ctx.forbidden();
|
1885
2155
|
}
|
1886
2156
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1887
|
-
const populate = await getService$
|
2157
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1888
2158
|
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
1889
2159
|
allowMultipleLocales: true
|
1890
2160
|
});
|
@@ -1909,12 +2179,14 @@ const collectionTypes = {
|
|
1909
2179
|
const { body } = ctx.request;
|
1910
2180
|
const { documentIds } = body;
|
1911
2181
|
await validateBulkActionInput(body);
|
1912
|
-
const documentManager2 = getService$
|
1913
|
-
const permissionChecker2 = getService$
|
2182
|
+
const documentManager2 = getService$2("document-manager");
|
2183
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1914
2184
|
if (permissionChecker2.cannot.unpublish()) {
|
1915
2185
|
return ctx.forbidden();
|
1916
2186
|
}
|
1917
|
-
const { locale } = await getDocumentLocaleAndStatus(body, model
|
2187
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2188
|
+
allowMultipleLocales: true
|
2189
|
+
});
|
1918
2190
|
const entityPromises = documentIds.map(
|
1919
2191
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1920
2192
|
);
|
@@ -1937,8 +2209,8 @@ const collectionTypes = {
|
|
1937
2209
|
const {
|
1938
2210
|
body: { discardDraft, ...body }
|
1939
2211
|
} = ctx.request;
|
1940
|
-
const documentManager2 = getService$
|
1941
|
-
const permissionChecker2 = getService$
|
2212
|
+
const documentManager2 = getService$2("document-manager");
|
2213
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1942
2214
|
if (permissionChecker2.cannot.unpublish()) {
|
1943
2215
|
return ctx.forbidden();
|
1944
2216
|
}
|
@@ -1946,7 +2218,7 @@ const collectionTypes = {
|
|
1946
2218
|
return ctx.forbidden();
|
1947
2219
|
}
|
1948
2220
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1949
|
-
const populate = await getService$
|
2221
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1950
2222
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1951
2223
|
const document = await documentManager2.findOne(id, model, {
|
1952
2224
|
populate,
|
@@ -1977,13 +2249,13 @@ const collectionTypes = {
|
|
1977
2249
|
const { userAbility } = ctx.state;
|
1978
2250
|
const { id, model } = ctx.params;
|
1979
2251
|
const { body } = ctx.request;
|
1980
|
-
const documentManager2 = getService$
|
1981
|
-
const permissionChecker2 = getService$
|
2252
|
+
const documentManager2 = getService$2("document-manager");
|
2253
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1982
2254
|
if (permissionChecker2.cannot.discard()) {
|
1983
2255
|
return ctx.forbidden();
|
1984
2256
|
}
|
1985
2257
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1986
|
-
const populate = await getService$
|
2258
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1987
2259
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1988
2260
|
const document = await documentManager2.findOne(id, model, {
|
1989
2261
|
populate,
|
@@ -2008,13 +2280,13 @@ const collectionTypes = {
|
|
2008
2280
|
const { query, body } = ctx.request;
|
2009
2281
|
const { documentIds } = body;
|
2010
2282
|
await validateBulkActionInput(body);
|
2011
|
-
const documentManager2 = getService$
|
2012
|
-
const permissionChecker2 = getService$
|
2283
|
+
const documentManager2 = getService$2("document-manager");
|
2284
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2013
2285
|
if (permissionChecker2.cannot.delete()) {
|
2014
2286
|
return ctx.forbidden();
|
2015
2287
|
}
|
2016
2288
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2017
|
-
const populate = await getService$
|
2289
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2018
2290
|
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2019
2291
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2020
2292
|
populate,
|
@@ -2035,13 +2307,13 @@ const collectionTypes = {
|
|
2035
2307
|
async countDraftRelations(ctx) {
|
2036
2308
|
const { userAbility } = ctx.state;
|
2037
2309
|
const { model, id } = ctx.params;
|
2038
|
-
const documentManager2 = getService$
|
2039
|
-
const permissionChecker2 = getService$
|
2310
|
+
const documentManager2 = getService$2("document-manager");
|
2311
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2040
2312
|
if (permissionChecker2.cannot.read()) {
|
2041
2313
|
return ctx.forbidden();
|
2042
2314
|
}
|
2043
2315
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2044
|
-
const populate = await getService$
|
2316
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2045
2317
|
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2046
2318
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2047
2319
|
if (!entity) {
|
@@ -2060,8 +2332,8 @@ const collectionTypes = {
|
|
2060
2332
|
const ids = ctx.request.query.documentIds;
|
2061
2333
|
const locale = ctx.request.query.locale;
|
2062
2334
|
const { model } = ctx.params;
|
2063
|
-
const documentManager2 = getService$
|
2064
|
-
const permissionChecker2 = getService$
|
2335
|
+
const documentManager2 = getService$2("document-manager");
|
2336
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2065
2337
|
if (permissionChecker2.cannot.read()) {
|
2066
2338
|
return ctx.forbidden();
|
2067
2339
|
}
|
@@ -2085,13 +2357,13 @@ const collectionTypes = {
|
|
2085
2357
|
};
|
2086
2358
|
const components$1 = {
|
2087
2359
|
findComponents(ctx) {
|
2088
|
-
const components2 = getService$
|
2089
|
-
const { toDto } = getService$
|
2360
|
+
const components2 = getService$2("components").findAllComponents();
|
2361
|
+
const { toDto } = getService$2("data-mapper");
|
2090
2362
|
ctx.body = { data: components2.map(toDto) };
|
2091
2363
|
},
|
2092
2364
|
async findComponentConfiguration(ctx) {
|
2093
2365
|
const { uid: uid2 } = ctx.params;
|
2094
|
-
const componentService = getService$
|
2366
|
+
const componentService = getService$2("components");
|
2095
2367
|
const component = componentService.findComponent(uid2);
|
2096
2368
|
if (!component) {
|
2097
2369
|
return ctx.notFound("component.notFound");
|
@@ -2108,7 +2380,7 @@ const components$1 = {
|
|
2108
2380
|
async updateComponentConfiguration(ctx) {
|
2109
2381
|
const { uid: uid2 } = ctx.params;
|
2110
2382
|
const { body } = ctx.request;
|
2111
|
-
const componentService = getService$
|
2383
|
+
const componentService = getService$2("components");
|
2112
2384
|
const component = componentService.findComponent(uid2);
|
2113
2385
|
if (!component) {
|
2114
2386
|
return ctx.notFound("component.notFound");
|
@@ -2142,12 +2414,12 @@ const contentTypes = {
|
|
2142
2414
|
} catch (error) {
|
2143
2415
|
return ctx.send({ error }, 400);
|
2144
2416
|
}
|
2145
|
-
const contentTypes2 = getService$
|
2146
|
-
const { toDto } = getService$
|
2417
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2418
|
+
const { toDto } = getService$2("data-mapper");
|
2147
2419
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2148
2420
|
},
|
2149
2421
|
async findContentTypesSettings(ctx) {
|
2150
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2422
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2151
2423
|
const contentTypes2 = await findAllContentTypes();
|
2152
2424
|
const configurations = await Promise.all(
|
2153
2425
|
contentTypes2.map(async (contentType) => {
|
@@ -2161,7 +2433,7 @@ const contentTypes = {
|
|
2161
2433
|
},
|
2162
2434
|
async findContentTypeConfiguration(ctx) {
|
2163
2435
|
const { uid: uid2 } = ctx.params;
|
2164
|
-
const contentTypeService = getService$
|
2436
|
+
const contentTypeService = getService$2("content-types");
|
2165
2437
|
const contentType = await contentTypeService.findContentType(uid2);
|
2166
2438
|
if (!contentType) {
|
2167
2439
|
return ctx.notFound("contentType.notFound");
|
@@ -2183,13 +2455,13 @@ const contentTypes = {
|
|
2183
2455
|
const { userAbility } = ctx.state;
|
2184
2456
|
const { uid: uid2 } = ctx.params;
|
2185
2457
|
const { body } = ctx.request;
|
2186
|
-
const contentTypeService = getService$
|
2187
|
-
const metricsService = getService$
|
2458
|
+
const contentTypeService = getService$2("content-types");
|
2459
|
+
const metricsService = getService$2("metrics");
|
2188
2460
|
const contentType = await contentTypeService.findContentType(uid2);
|
2189
2461
|
if (!contentType) {
|
2190
2462
|
return ctx.notFound("contentType.notFound");
|
2191
2463
|
}
|
2192
|
-
if (!getService$
|
2464
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2193
2465
|
return ctx.forbidden();
|
2194
2466
|
}
|
2195
2467
|
let input;
|
@@ -2222,10 +2494,10 @@ const contentTypes = {
|
|
2222
2494
|
};
|
2223
2495
|
const init = {
|
2224
2496
|
getInitData(ctx) {
|
2225
|
-
const { toDto } = getService$
|
2226
|
-
const { findAllComponents } = getService$
|
2227
|
-
const { getAllFieldSizes } = getService$
|
2228
|
-
const { findAllContentTypes } = getService$
|
2497
|
+
const { toDto } = getService$2("data-mapper");
|
2498
|
+
const { findAllComponents } = getService$2("components");
|
2499
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2500
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2229
2501
|
ctx.body = {
|
2230
2502
|
data: {
|
2231
2503
|
fieldSizes: getAllFieldSizes(),
|
@@ -2261,36 +2533,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2261
2533
|
params.filters.$and.push(filtersClause);
|
2262
2534
|
};
|
2263
2535
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2264
|
-
const permissionChecker2 = getService$
|
2536
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2265
2537
|
userAbility,
|
2266
2538
|
model: model.uid
|
2267
2539
|
});
|
2268
|
-
|
2540
|
+
const isMainFieldListable = isListable(model, mainField);
|
2541
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2542
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2269
2543
|
return "id";
|
2270
2544
|
}
|
2271
|
-
if (
|
2272
|
-
|
2273
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2274
|
-
userAbility,
|
2275
|
-
model: "plugin::users-permissions.user"
|
2276
|
-
});
|
2277
|
-
if (userPermissionChecker.can.read()) {
|
2278
|
-
return "name";
|
2279
|
-
}
|
2280
|
-
}
|
2281
|
-
return "id";
|
2545
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2546
|
+
return "name";
|
2282
2547
|
}
|
2283
2548
|
return mainField;
|
2284
2549
|
};
|
2285
|
-
const addStatusToRelations = async (
|
2286
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2550
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2551
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2552
|
+
return relations2;
|
2553
|
+
}
|
2554
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2555
|
+
if (!relations2.length) {
|
2287
2556
|
return relations2;
|
2288
2557
|
}
|
2289
|
-
const
|
2290
|
-
const
|
2558
|
+
const firstRelation = relations2[0];
|
2559
|
+
const filters = {
|
2560
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2561
|
+
// NOTE: find the "opposite" status
|
2562
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2563
|
+
};
|
2564
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2565
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2566
|
+
filters
|
2567
|
+
});
|
2291
2568
|
return relations2.map((relation) => {
|
2292
|
-
const availableStatuses =
|
2293
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2569
|
+
const availableStatuses = availableStatus.filter(
|
2570
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2294
2571
|
);
|
2295
2572
|
return {
|
2296
2573
|
...relation,
|
@@ -2311,11 +2588,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2311
2588
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2312
2589
|
const isSourceLocalized = isLocalized(sourceModel);
|
2313
2590
|
const isTargetLocalized = isLocalized(targetModel);
|
2314
|
-
let validatedLocale = locale;
|
2315
|
-
if (!targetModel || !isTargetLocalized)
|
2316
|
-
validatedLocale = void 0;
|
2317
2591
|
return {
|
2318
|
-
locale
|
2592
|
+
locale,
|
2319
2593
|
isSourceLocalized,
|
2320
2594
|
isTargetLocalized
|
2321
2595
|
};
|
@@ -2324,8 +2598,7 @@ const validateStatus = (sourceUid, status) => {
|
|
2324
2598
|
const sourceModel = strapi.getModel(sourceUid);
|
2325
2599
|
const isDP = contentTypes$1.hasDraftAndPublish;
|
2326
2600
|
const isSourceDP = isDP(sourceModel);
|
2327
|
-
if (!isSourceDP)
|
2328
|
-
return { status: void 0 };
|
2601
|
+
if (!isSourceDP) return { status: void 0 };
|
2329
2602
|
switch (status) {
|
2330
2603
|
case "published":
|
2331
2604
|
return { status: "published" };
|
@@ -2355,7 +2628,7 @@ const relations = {
|
|
2355
2628
|
ctx.request?.query?.locale
|
2356
2629
|
);
|
2357
2630
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2358
|
-
const permissionChecker2 = getService$
|
2631
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2359
2632
|
userAbility,
|
2360
2633
|
model
|
2361
2634
|
});
|
@@ -2380,7 +2653,7 @@ const relations = {
|
|
2380
2653
|
where.id = id;
|
2381
2654
|
}
|
2382
2655
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2383
|
-
const populate = await getService$
|
2656
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2384
2657
|
const currentEntity = await strapi.db.query(model).findOne({
|
2385
2658
|
where,
|
2386
2659
|
populate
|
@@ -2395,7 +2668,7 @@ const relations = {
|
|
2395
2668
|
}
|
2396
2669
|
entryId = currentEntity.id;
|
2397
2670
|
}
|
2398
|
-
const modelConfig = isComponent2 ? await getService$
|
2671
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2399
2672
|
const targetSchema = strapi.getModel(targetUid);
|
2400
2673
|
const mainField = flow(
|
2401
2674
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2418,7 +2691,7 @@ const relations = {
|
|
2418
2691
|
attribute,
|
2419
2692
|
fieldsToSelect,
|
2420
2693
|
mainField,
|
2421
|
-
source: { schema: sourceSchema },
|
2694
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2422
2695
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2423
2696
|
sourceSchema,
|
2424
2697
|
targetSchema,
|
@@ -2440,7 +2713,8 @@ const relations = {
|
|
2440
2713
|
fieldsToSelect,
|
2441
2714
|
mainField,
|
2442
2715
|
source: {
|
2443
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2716
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2717
|
+
isLocalized: isSourceLocalized
|
2444
2718
|
},
|
2445
2719
|
target: {
|
2446
2720
|
schema: { uid: targetUid },
|
@@ -2448,7 +2722,7 @@ const relations = {
|
|
2448
2722
|
}
|
2449
2723
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2450
2724
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2451
|
-
const permissionChecker2 = getService$
|
2725
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2452
2726
|
userAbility: ctx.state.userAbility,
|
2453
2727
|
model: targetUid
|
2454
2728
|
});
|
@@ -2478,12 +2752,16 @@ const relations = {
|
|
2478
2752
|
} else {
|
2479
2753
|
where.id = id;
|
2480
2754
|
}
|
2481
|
-
|
2482
|
-
|
2755
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2756
|
+
if (!isEmpty(publishedAt)) {
|
2757
|
+
where[`${alias}.published_at`] = publishedAt;
|
2483
2758
|
}
|
2484
|
-
if (
|
2759
|
+
if (isTargetLocalized && locale) {
|
2485
2760
|
where[`${alias}.locale`] = locale;
|
2486
2761
|
}
|
2762
|
+
if (isSourceLocalized && locale) {
|
2763
|
+
where.locale = locale;
|
2764
|
+
}
|
2487
2765
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2488
2766
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2489
2767
|
}
|
@@ -2501,7 +2779,8 @@ const relations = {
|
|
2501
2779
|
id: { $notIn: uniq(idsToOmit) }
|
2502
2780
|
});
|
2503
2781
|
}
|
2504
|
-
const
|
2782
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2783
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2505
2784
|
ctx.body = {
|
2506
2785
|
...res,
|
2507
2786
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2516,29 +2795,39 @@ const relations = {
|
|
2516
2795
|
attribute,
|
2517
2796
|
targetField,
|
2518
2797
|
fieldsToSelect,
|
2519
|
-
|
2520
|
-
|
2521
|
-
}
|
2522
|
-
target: {
|
2523
|
-
schema: { uid: targetUid }
|
2524
|
-
}
|
2798
|
+
status,
|
2799
|
+
source: { schema: sourceSchema },
|
2800
|
+
target: { schema: targetSchema }
|
2525
2801
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2526
|
-
const
|
2802
|
+
const { uid: sourceUid } = sourceSchema;
|
2803
|
+
const { uid: targetUid } = targetSchema;
|
2804
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2527
2805
|
const dbQuery = strapi.db.query(sourceUid);
|
2528
2806
|
const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2807
|
+
const filters = {};
|
2808
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2809
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2810
|
+
if (status === "published") {
|
2811
|
+
filters.publishedAt = { $notNull: true };
|
2812
|
+
} else {
|
2813
|
+
filters.publishedAt = { $null: true };
|
2814
|
+
}
|
2815
|
+
}
|
2816
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2817
|
+
filters.publishedAt = { $null: true };
|
2818
|
+
}
|
2529
2819
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2530
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2820
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2531
2821
|
ordering: "desc",
|
2532
2822
|
page: ctx.request.query.page,
|
2533
|
-
pageSize: ctx.request.query.pageSize
|
2823
|
+
pageSize: ctx.request.query.pageSize,
|
2824
|
+
filters
|
2534
2825
|
});
|
2535
2826
|
const loadedIds = res.results.map((item) => item.id);
|
2536
2827
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2537
2828
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2538
2829
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2539
|
-
ordering: "desc"
|
2540
|
-
page: ctx.request.query.page,
|
2541
|
-
pageSize: ctx.request.query.pageSize
|
2830
|
+
ordering: "desc"
|
2542
2831
|
});
|
2543
2832
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2544
2833
|
ctx.body = {
|
@@ -2553,10 +2842,10 @@ const relations = {
|
|
2553
2842
|
}
|
2554
2843
|
};
|
2555
2844
|
const buildPopulateFromQuery = async (query, model) => {
|
2556
|
-
return getService$
|
2845
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2557
2846
|
};
|
2558
2847
|
const findDocument = async (query, uid2, opts = {}) => {
|
2559
|
-
const documentManager2 = getService$
|
2848
|
+
const documentManager2 = getService$2("document-manager");
|
2560
2849
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2561
2850
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2562
2851
|
};
|
@@ -2564,8 +2853,8 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2564
2853
|
const { user, userAbility } = ctx.state;
|
2565
2854
|
const { model } = ctx.params;
|
2566
2855
|
const { body, query } = ctx.request;
|
2567
|
-
const documentManager2 = getService$
|
2568
|
-
const permissionChecker2 = getService$
|
2856
|
+
const documentManager2 = getService$2("document-manager");
|
2857
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2569
2858
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2570
2859
|
throw new errors.ForbiddenError();
|
2571
2860
|
}
|
@@ -2606,7 +2895,7 @@ const singleTypes = {
|
|
2606
2895
|
const { userAbility } = ctx.state;
|
2607
2896
|
const { model } = ctx.params;
|
2608
2897
|
const { query = {} } = ctx.request;
|
2609
|
-
const permissionChecker2 = getService$
|
2898
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2610
2899
|
if (permissionChecker2.cannot.read()) {
|
2611
2900
|
return ctx.forbidden();
|
2612
2901
|
}
|
@@ -2625,7 +2914,7 @@ const singleTypes = {
|
|
2625
2914
|
permissionChecker2,
|
2626
2915
|
model,
|
2627
2916
|
// @ts-expect-error - fix types
|
2628
|
-
{
|
2917
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2629
2918
|
{ availableLocales: true, availableStatus: false }
|
2630
2919
|
);
|
2631
2920
|
ctx.body = { data: {}, meta };
|
@@ -2640,7 +2929,7 @@ const singleTypes = {
|
|
2640
2929
|
async createOrUpdate(ctx) {
|
2641
2930
|
const { userAbility } = ctx.state;
|
2642
2931
|
const { model } = ctx.params;
|
2643
|
-
const permissionChecker2 = getService$
|
2932
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2644
2933
|
const document = await createOrUpdateDocument(ctx);
|
2645
2934
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2646
2935
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2649,8 +2938,8 @@ const singleTypes = {
|
|
2649
2938
|
const { userAbility } = ctx.state;
|
2650
2939
|
const { model } = ctx.params;
|
2651
2940
|
const { query = {} } = ctx.request;
|
2652
|
-
const documentManager2 = getService$
|
2653
|
-
const permissionChecker2 = getService$
|
2941
|
+
const documentManager2 = getService$2("document-manager");
|
2942
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2654
2943
|
if (permissionChecker2.cannot.delete()) {
|
2655
2944
|
return ctx.forbidden();
|
2656
2945
|
}
|
@@ -2678,8 +2967,8 @@ const singleTypes = {
|
|
2678
2967
|
const { userAbility } = ctx.state;
|
2679
2968
|
const { model } = ctx.params;
|
2680
2969
|
const { query = {} } = ctx.request;
|
2681
|
-
const documentManager2 = getService$
|
2682
|
-
const permissionChecker2 = getService$
|
2970
|
+
const documentManager2 = getService$2("document-manager");
|
2971
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2683
2972
|
if (permissionChecker2.cannot.publish()) {
|
2684
2973
|
return ctx.forbidden();
|
2685
2974
|
}
|
@@ -2707,8 +2996,8 @@ const singleTypes = {
|
|
2707
2996
|
body: { discardDraft, ...body },
|
2708
2997
|
query = {}
|
2709
2998
|
} = ctx.request;
|
2710
|
-
const documentManager2 = getService$
|
2711
|
-
const permissionChecker2 = getService$
|
2999
|
+
const documentManager2 = getService$2("document-manager");
|
3000
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2712
3001
|
if (permissionChecker2.cannot.unpublish()) {
|
2713
3002
|
return ctx.forbidden();
|
2714
3003
|
}
|
@@ -2742,8 +3031,8 @@ const singleTypes = {
|
|
2742
3031
|
const { userAbility } = ctx.state;
|
2743
3032
|
const { model } = ctx.params;
|
2744
3033
|
const { body, query = {} } = ctx.request;
|
2745
|
-
const documentManager2 = getService$
|
2746
|
-
const permissionChecker2 = getService$
|
3034
|
+
const documentManager2 = getService$2("document-manager");
|
3035
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2747
3036
|
if (permissionChecker2.cannot.discard()) {
|
2748
3037
|
return ctx.forbidden();
|
2749
3038
|
}
|
@@ -2766,8 +3055,8 @@ const singleTypes = {
|
|
2766
3055
|
const { userAbility } = ctx.state;
|
2767
3056
|
const { model } = ctx.params;
|
2768
3057
|
const { query } = ctx.request;
|
2769
|
-
const documentManager2 = getService$
|
2770
|
-
const permissionChecker2 = getService$
|
3058
|
+
const documentManager2 = getService$2("document-manager");
|
3059
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2771
3060
|
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2772
3061
|
if (permissionChecker2.cannot.read()) {
|
2773
3062
|
return ctx.forbidden();
|
@@ -2791,7 +3080,7 @@ const uid$1 = {
|
|
2791
3080
|
const { query = {} } = ctx.request;
|
2792
3081
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2793
3082
|
await validateUIDField(contentTypeUID, field);
|
2794
|
-
const uidService = getService$
|
3083
|
+
const uidService = getService$2("uid");
|
2795
3084
|
ctx.body = {
|
2796
3085
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2797
3086
|
};
|
@@ -2803,7 +3092,7 @@ const uid$1 = {
|
|
2803
3092
|
const { query = {} } = ctx.request;
|
2804
3093
|
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2805
3094
|
await validateUIDField(contentTypeUID, field);
|
2806
|
-
const uidService = getService$
|
3095
|
+
const uidService = getService$2("uid");
|
2807
3096
|
const isAvailable = await uidService.checkUIDAvailability({
|
2808
3097
|
contentTypeUID,
|
2809
3098
|
field,
|
@@ -2824,7 +3113,8 @@ const controllers = {
|
|
2824
3113
|
relations,
|
2825
3114
|
"single-types": singleTypes,
|
2826
3115
|
uid: uid$1,
|
2827
|
-
...history.controllers ? history.controllers : {}
|
3116
|
+
...history.controllers ? history.controllers : {},
|
3117
|
+
...preview.controllers ? preview.controllers : {}
|
2828
3118
|
};
|
2829
3119
|
const keys = {
|
2830
3120
|
CONFIGURATION: "configuration"
|
@@ -2953,18 +3243,15 @@ async function syncMetadatas(configuration, schema) {
|
|
2953
3243
|
_.set(updatedMeta, ["list", "searchable"], false);
|
2954
3244
|
_.set(acc, [key], updatedMeta);
|
2955
3245
|
}
|
2956
|
-
if (!_.has(edit, "mainField"))
|
2957
|
-
return acc;
|
3246
|
+
if (!_.has(edit, "mainField")) return acc;
|
2958
3247
|
if (!isRelation$1(attr)) {
|
2959
3248
|
_.set(updatedMeta, "edit", _.omit(edit, ["mainField"]));
|
2960
3249
|
_.set(acc, [key], updatedMeta);
|
2961
3250
|
return acc;
|
2962
3251
|
}
|
2963
|
-
if (edit.mainField === "id")
|
2964
|
-
return acc;
|
3252
|
+
if (edit.mainField === "id") return acc;
|
2965
3253
|
const targetSchema = getTargetSchema(attr.targetModel);
|
2966
|
-
if (!targetSchema)
|
2967
|
-
return acc;
|
3254
|
+
if (!targetSchema) return acc;
|
2968
3255
|
if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
|
2969
3256
|
_.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
|
2970
3257
|
_.set(acc, [key], updatedMeta);
|
@@ -2975,12 +3262,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2975
3262
|
return _.assign(metasWithDefaults, updatedMetas);
|
2976
3263
|
}
|
2977
3264
|
const getTargetSchema = (targetModel) => {
|
2978
|
-
return getService$
|
3265
|
+
return getService$2("content-types").findContentType(targetModel);
|
2979
3266
|
};
|
2980
3267
|
const DEFAULT_LIST_LENGTH = 4;
|
2981
3268
|
const MAX_ROW_SIZE = 12;
|
2982
3269
|
const isAllowedFieldSize = (type, size) => {
|
2983
|
-
const { getFieldSize } = getService$
|
3270
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2984
3271
|
const fieldSize = getFieldSize(type);
|
2985
3272
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2986
3273
|
return false;
|
@@ -2988,7 +3275,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2988
3275
|
return size <= MAX_ROW_SIZE;
|
2989
3276
|
};
|
2990
3277
|
const getDefaultFieldSize = (attribute) => {
|
2991
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3278
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2992
3279
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2993
3280
|
};
|
2994
3281
|
async function createDefaultLayouts(schema) {
|
@@ -3009,8 +3296,7 @@ function createDefaultEditLayout(schema) {
|
|
3009
3296
|
return appendToEditLayout([], keys2, schema);
|
3010
3297
|
}
|
3011
3298
|
function syncLayouts(configuration, schema) {
|
3012
|
-
if (_.isEmpty(configuration.layouts))
|
3013
|
-
return createDefaultLayouts(schema);
|
3299
|
+
if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
3014
3300
|
const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
|
3015
3301
|
let cleanList = list.filter((attr) => isListable(schema, attr));
|
3016
3302
|
const cleanEditRelations = editRelations.filter(
|
@@ -3021,9 +3307,8 @@ function syncLayouts(configuration, schema) {
|
|
3021
3307
|
for (const row of edit) {
|
3022
3308
|
const newRow = [];
|
3023
3309
|
for (const el of row) {
|
3024
|
-
if (!hasEditableAttribute(schema, el.name))
|
3025
|
-
|
3026
|
-
const { hasFieldSize } = getService$1("field-sizes");
|
3310
|
+
if (!hasEditableAttribute(schema, el.name)) continue;
|
3311
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3027
3312
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3028
3313
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3029
3314
|
elementsToReAppend.push(el.name);
|
@@ -3053,8 +3338,7 @@ function syncLayouts(configuration, schema) {
|
|
3053
3338
|
};
|
3054
3339
|
}
|
3055
3340
|
const appendToEditLayout = (layout = [], keysToAppend, schema) => {
|
3056
|
-
if (keysToAppend.length === 0)
|
3057
|
-
return layout;
|
3341
|
+
if (keysToAppend.length === 0) return layout;
|
3058
3342
|
let currentRowIndex = Math.max(layout.length - 1, 0);
|
3059
3343
|
if (!layout[currentRowIndex]) {
|
3060
3344
|
layout[currentRowIndex] = [];
|
@@ -3163,17 +3447,17 @@ const configurationService$1 = createConfigurationService({
|
|
3163
3447
|
isComponent: true,
|
3164
3448
|
prefix: STORE_KEY_PREFIX,
|
3165
3449
|
getModels() {
|
3166
|
-
const { toContentManagerModel } = getService$
|
3450
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3167
3451
|
return mapValues(toContentManagerModel, strapi.components);
|
3168
3452
|
}
|
3169
3453
|
});
|
3170
3454
|
const components = ({ strapi: strapi2 }) => ({
|
3171
3455
|
findAllComponents() {
|
3172
|
-
const { toContentManagerModel } = getService$
|
3456
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3173
3457
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3174
3458
|
},
|
3175
3459
|
findComponent(uid2) {
|
3176
|
-
const { toContentManagerModel } = getService$
|
3460
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3177
3461
|
const component = strapi2.components[uid2];
|
3178
3462
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3179
3463
|
},
|
@@ -3224,17 +3508,17 @@ const configurationService = createConfigurationService({
|
|
3224
3508
|
storeUtils,
|
3225
3509
|
prefix: "content_types",
|
3226
3510
|
getModels() {
|
3227
|
-
const { toContentManagerModel } = getService$
|
3511
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3228
3512
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3229
3513
|
}
|
3230
3514
|
});
|
3231
3515
|
const service = ({ strapi: strapi2 }) => ({
|
3232
3516
|
findAllContentTypes() {
|
3233
|
-
const { toContentManagerModel } = getService$
|
3517
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3234
3518
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3235
3519
|
},
|
3236
3520
|
findContentType(uid2) {
|
3237
|
-
const { toContentManagerModel } = getService$
|
3521
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3238
3522
|
const contentType = strapi2.contentTypes[uid2];
|
3239
3523
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3240
3524
|
},
|
@@ -3263,7 +3547,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3263
3547
|
return this.findConfiguration(contentType);
|
3264
3548
|
},
|
3265
3549
|
findComponentsConfigurations(contentType) {
|
3266
|
-
return getService$
|
3550
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3267
3551
|
},
|
3268
3552
|
syncConfigurations() {
|
3269
3553
|
return configurationService.syncConfigurations();
|
@@ -3444,12 +3728,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3444
3728
|
ability: userAbility,
|
3445
3729
|
model
|
3446
3730
|
});
|
3447
|
-
const
|
3731
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3732
|
+
const toSubject = (entity) => {
|
3733
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3734
|
+
};
|
3448
3735
|
const can = (action, entity, field) => {
|
3449
|
-
|
3736
|
+
const subject = toSubject(entity);
|
3737
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3738
|
+
return (
|
3739
|
+
// Test the original action to see if it passes
|
3740
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3741
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3742
|
+
);
|
3450
3743
|
};
|
3451
3744
|
const cannot = (action, entity, field) => {
|
3452
|
-
|
3745
|
+
const subject = toSubject(entity);
|
3746
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3747
|
+
return (
|
3748
|
+
// Test both the original action
|
3749
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3750
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3751
|
+
);
|
3453
3752
|
};
|
3454
3753
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3455
3754
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3520,7 +3819,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3520
3819
|
return userAbility.can(action);
|
3521
3820
|
},
|
3522
3821
|
async registerPermissions() {
|
3523
|
-
const displayedContentTypes = getService$
|
3822
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3524
3823
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3525
3824
|
const actions = [
|
3526
3825
|
{
|
@@ -3605,6 +3904,12 @@ function getPopulateForRelation(attribute, model, attributeName, { countMany, co
|
|
3605
3904
|
if (initialPopulate) {
|
3606
3905
|
return initialPopulate;
|
3607
3906
|
}
|
3907
|
+
if (attributeName === "localizations") {
|
3908
|
+
const validationPopulate = getPopulateForValidation(model.uid);
|
3909
|
+
return {
|
3910
|
+
populate: validationPopulate.populate
|
3911
|
+
};
|
3912
|
+
}
|
3608
3913
|
if (!isVisibleAttribute$1(model, attributeName)) {
|
3609
3914
|
return true;
|
3610
3915
|
}
|
@@ -3664,6 +3969,9 @@ const getDeepPopulate = (uid2, {
|
|
3664
3969
|
return {};
|
3665
3970
|
}
|
3666
3971
|
const model = strapi.getModel(uid2);
|
3972
|
+
if (!model) {
|
3973
|
+
return {};
|
3974
|
+
}
|
3667
3975
|
return Object.keys(model.attributes).reduce(
|
3668
3976
|
(populateAcc, attributeName) => merge(
|
3669
3977
|
populateAcc,
|
@@ -3683,40 +3991,46 @@ const getDeepPopulate = (uid2, {
|
|
3683
3991
|
{}
|
3684
3992
|
);
|
3685
3993
|
};
|
3686
|
-
const
|
3687
|
-
|
3688
|
-
|
3689
|
-
countOne = false,
|
3690
|
-
maxLevel = Infinity
|
3691
|
-
} = {}, level = 1) => {
|
3692
|
-
if (level > maxLevel) {
|
3994
|
+
const getPopulateForValidation = (uid2) => {
|
3995
|
+
const model = strapi.getModel(uid2);
|
3996
|
+
if (!model) {
|
3693
3997
|
return {};
|
3694
3998
|
}
|
3695
|
-
const model = strapi.getModel(uid2);
|
3696
3999
|
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
3697
|
-
if (
|
4000
|
+
if (isScalarAttribute(attribute)) {
|
4001
|
+
if (getDoesAttributeRequireValidation(attribute)) {
|
4002
|
+
populateAcc.fields = populateAcc.fields || [];
|
4003
|
+
populateAcc.fields.push(attributeName);
|
4004
|
+
}
|
3698
4005
|
return populateAcc;
|
3699
4006
|
}
|
3700
|
-
if (
|
3701
|
-
|
3702
|
-
|
3703
|
-
|
4007
|
+
if (isComponent(attribute)) {
|
4008
|
+
const component = attribute.component;
|
4009
|
+
const componentResult = getPopulateForValidation(component);
|
4010
|
+
if (Object.keys(componentResult).length > 0) {
|
4011
|
+
populateAcc.populate = populateAcc.populate || {};
|
4012
|
+
populateAcc.populate[attributeName] = componentResult;
|
4013
|
+
}
|
4014
|
+
return populateAcc;
|
3704
4015
|
}
|
3705
|
-
|
3706
|
-
|
3707
|
-
|
3708
|
-
|
3709
|
-
|
3710
|
-
|
3711
|
-
|
3712
|
-
|
3713
|
-
|
3714
|
-
countOne,
|
3715
|
-
maxLevel
|
4016
|
+
if (isDynamicZone(attribute)) {
|
4017
|
+
const components2 = attribute.components;
|
4018
|
+
const componentsResult = (components2 || []).reduce(
|
4019
|
+
(acc, componentUID) => {
|
4020
|
+
const componentResult = getPopulateForValidation(componentUID);
|
4021
|
+
if (Object.keys(componentResult).length > 0) {
|
4022
|
+
acc[componentUID] = componentResult;
|
4023
|
+
}
|
4024
|
+
return acc;
|
3716
4025
|
},
|
3717
|
-
|
3718
|
-
)
|
3719
|
-
|
4026
|
+
{}
|
4027
|
+
);
|
4028
|
+
if (Object.keys(componentsResult).length > 0) {
|
4029
|
+
populateAcc.populate = populateAcc.populate || {};
|
4030
|
+
populateAcc.populate[attributeName] = { on: componentsResult };
|
4031
|
+
}
|
4032
|
+
}
|
4033
|
+
return populateAcc;
|
3720
4034
|
}, {});
|
3721
4035
|
};
|
3722
4036
|
const getDeepPopulateDraftCount = (uid2) => {
|
@@ -3796,7 +4110,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3796
4110
|
return populateQuery;
|
3797
4111
|
};
|
3798
4112
|
const buildDeepPopulate = (uid2) => {
|
3799
|
-
return getService$
|
4113
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3800
4114
|
};
|
3801
4115
|
const populateBuilder = (uid2) => {
|
3802
4116
|
let getInitialPopulate = async () => {
|
@@ -3958,7 +4272,6 @@ const AVAILABLE_LOCALES_FIELDS = [
|
|
3958
4272
|
"locale",
|
3959
4273
|
"updatedAt",
|
3960
4274
|
"createdAt",
|
3961
|
-
"status",
|
3962
4275
|
"publishedAt",
|
3963
4276
|
"documentId"
|
3964
4277
|
];
|
@@ -3979,34 +4292,20 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3979
4292
|
/**
|
3980
4293
|
* Returns available locales of a document for the current status
|
3981
4294
|
*/
|
3982
|
-
async getAvailableLocales(uid2, version, allVersions
|
4295
|
+
async getAvailableLocales(uid2, version, allVersions) {
|
3983
4296
|
const versionsByLocale = groupBy("locale", allVersions);
|
3984
|
-
|
4297
|
+
if (version.locale) {
|
4298
|
+
delete versionsByLocale[version.locale];
|
4299
|
+
}
|
3985
4300
|
const model = strapi2.getModel(uid2);
|
3986
|
-
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3987
|
-
const traversalFunction = async (localeVersion) => traverseEntity(
|
3988
|
-
({ key }, { remove }) => {
|
3989
|
-
if (keysToKeep.includes(key)) {
|
3990
|
-
return;
|
3991
|
-
}
|
3992
|
-
remove(key);
|
3993
|
-
},
|
3994
|
-
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
3995
|
-
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
3996
|
-
localeVersion
|
3997
|
-
);
|
3998
4301
|
const mappingResult = await async.map(
|
3999
4302
|
Object.values(versionsByLocale),
|
4000
4303
|
async (localeVersions) => {
|
4001
|
-
const mappedLocaleVersions = await async.map(
|
4002
|
-
localeVersions,
|
4003
|
-
traversalFunction
|
4004
|
-
);
|
4005
4304
|
if (!contentTypes$1.hasDraftAndPublish(model)) {
|
4006
|
-
return
|
4305
|
+
return localeVersions[0];
|
4007
4306
|
}
|
4008
|
-
const draftVersion =
|
4009
|
-
const otherVersions =
|
4307
|
+
const draftVersion = localeVersions.find((v) => v.publishedAt === null);
|
4308
|
+
const otherVersions = localeVersions.filter((v) => v.id !== draftVersion?.id);
|
4010
4309
|
if (!draftVersion) {
|
4011
4310
|
return;
|
4012
4311
|
}
|
@@ -4028,8 +4327,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4028
4327
|
const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
|
4029
4328
|
return matchLocale && matchStatus;
|
4030
4329
|
});
|
4031
|
-
if (!availableStatus)
|
4032
|
-
return availableStatus;
|
4330
|
+
if (!availableStatus) return availableStatus;
|
4033
4331
|
return pick(AVAILABLE_STATUS_FIELDS, availableStatus);
|
4034
4332
|
},
|
4035
4333
|
/**
|
@@ -4039,18 +4337,17 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4039
4337
|
* @returns
|
4040
4338
|
*/
|
4041
4339
|
async getManyAvailableStatus(uid2, documents) {
|
4042
|
-
if (!documents.length)
|
4043
|
-
return [];
|
4340
|
+
if (!documents.length) return [];
|
4044
4341
|
const status = documents[0].publishedAt !== null ? "published" : "draft";
|
4045
|
-
const
|
4046
|
-
|
4047
|
-
|
4048
|
-
|
4049
|
-
|
4342
|
+
const locales = documents.map((d) => d.locale).filter(Boolean);
|
4343
|
+
return strapi2.query(uid2).findMany({
|
4344
|
+
where: {
|
4345
|
+
documentId: { $in: documents.map((d) => d.documentId).filter(Boolean) },
|
4346
|
+
// NOTE: find the "opposite" status
|
4347
|
+
publishedAt: { $null: status === "published" },
|
4348
|
+
locale: { $in: locales }
|
4050
4349
|
},
|
4051
|
-
|
4052
|
-
locale,
|
4053
|
-
fields: ["documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
|
4350
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"]
|
4054
4351
|
});
|
4055
4352
|
},
|
4056
4353
|
getStatus(version, otherDocumentStatuses) {
|
@@ -4067,10 +4364,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4067
4364
|
} else if (otherVersion) {
|
4068
4365
|
draftVersion = otherVersion;
|
4069
4366
|
}
|
4070
|
-
if (!draftVersion)
|
4071
|
-
|
4072
|
-
if (!publishedVersion)
|
4073
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
4367
|
+
if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4368
|
+
if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
|
4074
4369
|
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4075
4370
|
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
4076
4371
|
},
|
@@ -4078,11 +4373,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4078
4373
|
// We could refactor this so the locales are only loaded when they're
|
4079
4374
|
// needed. e.g. in the bulk locale action modal.
|
4080
4375
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4081
|
-
const populate =
|
4082
|
-
const
|
4083
|
-
where: { documentId: version.documentId },
|
4376
|
+
const { populate = {}, fields = [] } = getPopulateForValidation(uid2);
|
4377
|
+
const params = {
|
4084
4378
|
populate: {
|
4085
|
-
// Populate only fields that require validation for bulk locale actions
|
4086
4379
|
...populate,
|
4087
4380
|
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
4088
4381
|
createdBy: {
|
@@ -4091,9 +4384,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4091
4384
|
updatedBy: {
|
4092
4385
|
select: ["id", "firstname", "lastname", "email"]
|
4093
4386
|
}
|
4387
|
+
},
|
4388
|
+
fields: uniq([...AVAILABLE_LOCALES_FIELDS, ...fields]),
|
4389
|
+
filters: {
|
4390
|
+
documentId: version.documentId
|
4094
4391
|
}
|
4095
|
-
}
|
4096
|
-
const
|
4392
|
+
};
|
4393
|
+
const dbParams = strapi2.get("query-params").transform(uid2, params);
|
4394
|
+
const versions = await strapi2.db.query(uid2).findMany(dbParams);
|
4395
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions) : [];
|
4097
4396
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
4098
4397
|
return {
|
4099
4398
|
availableLocales: availableLocalesResult,
|
@@ -4107,13 +4406,29 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4107
4406
|
*/
|
4108
4407
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4109
4408
|
if (!document) {
|
4110
|
-
return
|
4409
|
+
return {
|
4410
|
+
data: document,
|
4411
|
+
meta: {
|
4412
|
+
availableLocales: [],
|
4413
|
+
availableStatus: []
|
4414
|
+
}
|
4415
|
+
};
|
4111
4416
|
}
|
4112
4417
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4113
4418
|
if (!hasDraftAndPublish) {
|
4114
4419
|
opts.availableStatus = false;
|
4115
4420
|
}
|
4116
4421
|
const meta = await this.getMetadata(uid2, document, opts);
|
4422
|
+
if (document.localizations) {
|
4423
|
+
const otherStatus = await this.getManyAvailableStatus(uid2, document.localizations);
|
4424
|
+
document.localizations = document.localizations.map((d) => {
|
4425
|
+
const status = otherStatus.find((s) => s.documentId === d.documentId);
|
4426
|
+
return {
|
4427
|
+
...d,
|
4428
|
+
status: this.getStatus(d, status ? [status] : [])
|
4429
|
+
};
|
4430
|
+
});
|
4431
|
+
}
|
4117
4432
|
return {
|
4118
4433
|
data: {
|
4119
4434
|
...document,
|
@@ -4331,7 +4646,8 @@ const services = {
|
|
4331
4646
|
permission,
|
4332
4647
|
"populate-builder": populateBuilder$1,
|
4333
4648
|
uid,
|
4334
|
-
...history.services ? history.services : {}
|
4649
|
+
...history.services ? history.services : {},
|
4650
|
+
...preview.services ? preview.services : {}
|
4335
4651
|
};
|
4336
4652
|
const index = () => {
|
4337
4653
|
return {
|