@strapi/content-manager 0.0.0-experimental.bd712ad3930045f4a5d2144c119e0b7856e97fc4 → 0.0.0-experimental.bec5a58066c034a7ebf5b14df62560e68a456fa3
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/{ComponentConfigurationPage-C7ImeKGM.mjs → ComponentConfigurationPage-BaJMOQyq.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-C7ImeKGM.mjs.map → ComponentConfigurationPage-BaJMOQyq.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js → ComponentConfigurationPage-N-CTtgQa.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js.map → ComponentConfigurationPage-N-CTtgQa.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js → EditConfigurationPage-BHkjAbxH.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js.map → EditConfigurationPage-BHkjAbxH.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs → EditConfigurationPage-CKK-5LfX.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs.map → EditConfigurationPage-CKK-5LfX.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DhmAg0NK.mjs → EditViewPage-B11aeMcf.mjs} +63 -12
- package/dist/_chunks/EditViewPage-B11aeMcf.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CmMi2Xsn.js → EditViewPage-QPUftxUd.js} +62 -11
- package/dist/_chunks/EditViewPage-QPUftxUd.js.map +1 -0
- package/dist/_chunks/{Field-Cs62u5pl.mjs → Field-Bj_RgtGo.mjs} +215 -124
- package/dist/_chunks/Field-Bj_RgtGo.mjs.map +1 -0
- package/dist/_chunks/{Field-1DLtcLAI.js → Field-DUK83cfh.js} +216 -125
- package/dist/_chunks/Field-DUK83cfh.js.map +1 -0
- package/dist/_chunks/{Form-CqFA7F_V.js → Form-DHmBRlHd.js} +36 -17
- package/dist/_chunks/Form-DHmBRlHd.js.map +1 -0
- package/dist/_chunks/{Form-zYHtzGUX.mjs → Form-DLMSoXV7.mjs} +36 -17
- package/dist/_chunks/Form-DLMSoXV7.mjs.map +1 -0
- package/dist/_chunks/{History-DalgFQ3D.mjs → History-CfCSNlG9.mjs} +59 -106
- package/dist/_chunks/History-CfCSNlG9.mjs.map +1 -0
- package/dist/_chunks/{History-BblwXv7-.js → History-Di3zm4HT.js} +57 -104
- package/dist/_chunks/History-Di3zm4HT.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DWy-vRzs.mjs → ListConfigurationPage-0mtv_iqk.mjs} +18 -7
- package/dist/_chunks/ListConfigurationPage-0mtv_iqk.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Cpy4QqNd.js → ListConfigurationPage-Cq361KIt.js} +17 -6
- package/dist/_chunks/ListConfigurationPage-Cq361KIt.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BkAwIW9s.mjs → ListViewPage-BxLVROX8.mjs} +106 -74
- package/dist/_chunks/ListViewPage-BxLVROX8.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-DFjn1DNW.js → ListViewPage-DFDcG8gM.js} +108 -76
- package/dist/_chunks/ListViewPage-DFDcG8gM.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs → NoContentTypePage-BRfDd67_.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs.map → NoContentTypePage-BRfDd67_.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js → NoContentTypePage-BSyvnDZZ.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js.map → NoContentTypePage-BSyvnDZZ.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs → NoPermissionsPage-CV9V8KWa.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs.map → NoPermissionsPage-CV9V8KWa.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js → NoPermissionsPage-DyLphsn_.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js.map → NoPermissionsPage-DyLphsn_.js.map} +1 -1
- package/dist/_chunks/Preview-C_B1nx3g.mjs +272 -0
- package/dist/_chunks/Preview-C_B1nx3g.mjs.map +1 -0
- package/dist/_chunks/Preview-D_3aO6Ly.js +291 -0
- package/dist/_chunks/Preview-D_3aO6Ly.js.map +1 -0
- package/dist/_chunks/{Relations-CJmTbZ8T.mjs → Relations-C6pwmDXh.mjs} +73 -37
- package/dist/_chunks/Relations-C6pwmDXh.mjs.map +1 -0
- package/dist/_chunks/{Relations-CrxfoH2n.js → Relations-Cne2AlrL.js} +72 -36
- package/dist/_chunks/Relations-Cne2AlrL.js.map +1 -0
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-DhFUjrNW.mjs} +31 -18
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-DhFUjrNW.mjs.map} +1 -1
- package/dist/_chunks/{en-fbKQxLGn.js → en-Ic0kXjxB.js} +31 -18
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-Ic0kXjxB.js.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/{index-D1344xdw.mjs → index-BpxR3En4.mjs} +1092 -721
- package/dist/_chunks/index-BpxR3En4.mjs.map +1 -0
- package/dist/_chunks/{index-Buwn78Rt.js → index-T-aWjbj2.js} +1073 -701
- package/dist/_chunks/index-T-aWjbj2.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-DRuJUpas.js → layout-BEuNwv-F.js} +21 -8
- package/dist/_chunks/layout-BEuNwv-F.js.map +1 -0
- package/dist/_chunks/{layout-ChVuUpa1.mjs → layout-DhMZ_lDx.mjs} +22 -9
- package/dist/_chunks/layout-DhMZ_lDx.mjs.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-B-deMCy4.mjs → relations-BdnxoX6f.mjs} +6 -7
- package/dist/_chunks/relations-BdnxoX6f.mjs.map +1 -0
- package/dist/_chunks/{relations-DuoUwyJr.js → relations-kLcuobLk.js} +6 -7
- package/dist/_chunks/relations-kLcuobLk.js.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -20
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +591 -261
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +592 -262
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +14 -14
- package/dist/_chunks/EditViewPage-CmMi2Xsn.js.map +0 -1
- package/dist/_chunks/EditViewPage-DhmAg0NK.mjs.map +0 -1
- package/dist/_chunks/Field-1DLtcLAI.js.map +0 -1
- package/dist/_chunks/Field-Cs62u5pl.mjs.map +0 -1
- package/dist/_chunks/Form-CqFA7F_V.js.map +0 -1
- package/dist/_chunks/Form-zYHtzGUX.mjs.map +0 -1
- package/dist/_chunks/History-BblwXv7-.js.map +0 -1
- package/dist/_chunks/History-DalgFQ3D.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Cpy4QqNd.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DWy-vRzs.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BkAwIW9s.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-DFjn1DNW.js.map +0 -1
- package/dist/_chunks/Relations-CJmTbZ8T.mjs.map +0 -1
- package/dist/_chunks/Relations-CrxfoH2n.js.map +0 -1
- package/dist/_chunks/index-Buwn78Rt.js.map +0 -1
- package/dist/_chunks/index-D1344xdw.mjs.map +0 -1
- package/dist/_chunks/layout-ChVuUpa1.mjs.map +0 -1
- package/dist/_chunks/layout-DRuJUpas.js.map +0 -1
- package/dist/_chunks/relations-B-deMCy4.mjs.map +0 -1
- package/dist/_chunks/relations-DuoUwyJr.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,9 +202,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const
|
205
|
+
const getComponentFields = (componentUID) => {
|
206
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
207
|
+
(fieldsAcc, [key, attribute]) => {
|
208
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
209
|
+
fieldsAcc.push(key);
|
210
|
+
}
|
211
|
+
return fieldsAcc;
|
212
|
+
},
|
213
|
+
[]
|
214
|
+
);
|
215
|
+
};
|
216
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
217
|
const model = strapi2.getModel(uid2);
|
205
218
|
const attributes = Object.entries(model.attributes);
|
219
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
220
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
221
|
switch (attribute.type) {
|
208
222
|
case "relation": {
|
@@ -212,23 +226,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
212
226
|
}
|
213
227
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
214
228
|
if (isVisible2) {
|
215
|
-
acc[attributeName] = {
|
229
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
216
230
|
}
|
217
231
|
break;
|
218
232
|
}
|
219
233
|
case "media": {
|
220
|
-
acc[attributeName] = {
|
234
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
221
235
|
break;
|
222
236
|
}
|
223
237
|
case "component": {
|
224
238
|
const populate = getDeepPopulate2(attribute.component);
|
225
|
-
acc[attributeName] = {
|
239
|
+
acc[attributeName] = {
|
240
|
+
populate,
|
241
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
242
|
+
};
|
226
243
|
break;
|
227
244
|
}
|
228
245
|
case "dynamiczone": {
|
229
246
|
const populatedComponents = (attribute.components || []).reduce(
|
230
247
|
(acc2, componentUID) => {
|
231
|
-
acc2[componentUID] = {
|
248
|
+
acc2[componentUID] = {
|
249
|
+
populate: getDeepPopulate2(componentUID),
|
250
|
+
[fieldSelector]: getComponentFields(componentUID)
|
251
|
+
};
|
232
252
|
return acc2;
|
233
253
|
},
|
234
254
|
{}
|
@@ -290,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
290
310
|
getRelationRestoreValue,
|
291
311
|
getMediaRestoreValue,
|
292
312
|
getDefaultLocale,
|
313
|
+
isLocalizedContentType,
|
293
314
|
getLocaleDictionary,
|
294
315
|
getRetentionDays,
|
295
316
|
getVersionStatus,
|
@@ -312,7 +333,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
312
333
|
});
|
313
334
|
},
|
314
335
|
async findVersionsPage(params) {
|
315
|
-
const
|
336
|
+
const model = strapi2.getModel(params.query.contentType);
|
337
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
338
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
339
|
+
let locale = null;
|
340
|
+
if (isLocalizedContentType) {
|
341
|
+
locale = params.query.locale || defaultLocale;
|
342
|
+
}
|
316
343
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
317
344
|
query.findPage({
|
318
345
|
...params.query,
|
@@ -334,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
361
|
const attributeValue = entry.data[attributeKey];
|
335
362
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
336
363
|
if (attributeSchema.type === "media") {
|
337
|
-
const permissionChecker2 = getService$
|
364
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
338
365
|
userAbility: params.state.userAbility,
|
339
366
|
model: "plugin::upload.file"
|
340
367
|
});
|
@@ -357,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
357
384
|
if (userToPopulate == null) {
|
358
385
|
return null;
|
359
386
|
}
|
360
|
-
return strapi2.query("admin::user").findOne({
|
387
|
+
return strapi2.query("admin::user").findOne({
|
388
|
+
where: {
|
389
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
390
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
391
|
+
}
|
392
|
+
});
|
361
393
|
})
|
362
394
|
);
|
363
395
|
return {
|
@@ -370,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
370
402
|
[attributeKey]: adminUsers
|
371
403
|
};
|
372
404
|
}
|
373
|
-
const permissionChecker2 = getService$
|
405
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
374
406
|
userAbility: params.state.userAbility,
|
375
407
|
model: attributeSchema.target
|
376
408
|
});
|
@@ -468,6 +500,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
468
500
|
}
|
469
501
|
};
|
470
502
|
};
|
503
|
+
const shouldCreateHistoryVersion = (context) => {
|
504
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
508
|
+
return false;
|
509
|
+
}
|
510
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
511
|
+
return false;
|
512
|
+
}
|
513
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
514
|
+
return false;
|
515
|
+
}
|
516
|
+
return true;
|
517
|
+
};
|
518
|
+
const getSchemas = (uid2) => {
|
519
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
520
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
521
|
+
(currentComponentSchemas, key) => {
|
522
|
+
const fieldSchema = attributesSchema[key];
|
523
|
+
if (fieldSchema.type === "component") {
|
524
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
525
|
+
return {
|
526
|
+
...currentComponentSchemas,
|
527
|
+
[fieldSchema.component]: componentSchema
|
528
|
+
};
|
529
|
+
}
|
530
|
+
return currentComponentSchemas;
|
531
|
+
},
|
532
|
+
{}
|
533
|
+
);
|
534
|
+
return {
|
535
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
536
|
+
componentsSchemas
|
537
|
+
};
|
538
|
+
};
|
471
539
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
472
540
|
const state = {
|
473
541
|
deleteExpiredJob: null,
|
@@ -480,76 +548,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
480
548
|
return;
|
481
549
|
}
|
482
550
|
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
551
|
const result = await next();
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
552
|
+
if (!shouldCreateHistoryVersion(context)) {
|
553
|
+
return result;
|
554
|
+
}
|
555
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
501
556
|
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();
|
557
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
558
|
+
if (!locales.length) {
|
559
|
+
return result;
|
508
560
|
}
|
509
|
-
const
|
510
|
-
|
511
|
-
|
512
|
-
|
561
|
+
const uid2 = context.contentType.uid;
|
562
|
+
const schemas = getSchemas(uid2);
|
563
|
+
const model = strapi2.getModel(uid2);
|
564
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
565
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
566
|
+
where: {
|
567
|
+
documentId,
|
568
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
569
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
570
|
+
},
|
571
|
+
populate: serviceUtils.getDeepPopulate(
|
572
|
+
uid2,
|
573
|
+
true
|
574
|
+
/* use database syntax */
|
575
|
+
)
|
513
576
|
});
|
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
577
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
530
|
-
onCommit(() => {
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
578
|
+
onCommit(async () => {
|
579
|
+
for (const entry of localeEntries) {
|
580
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
581
|
+
await getService$1(strapi2, "history").createVersion({
|
582
|
+
contentType: uid2,
|
583
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
584
|
+
relatedDocumentId: documentId,
|
585
|
+
locale: entry.locale,
|
586
|
+
status,
|
587
|
+
...schemas
|
588
|
+
});
|
589
|
+
}
|
540
590
|
});
|
541
591
|
});
|
542
592
|
return result;
|
543
593
|
});
|
544
|
-
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
594
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
545
595
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
546
596
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
547
597
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
548
598
|
where: {
|
549
599
|
created_at: {
|
550
|
-
$lt: expirationDate
|
600
|
+
$lt: expirationDate
|
551
601
|
}
|
552
602
|
}
|
603
|
+
}).catch((error) => {
|
604
|
+
if (error instanceof Error) {
|
605
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
606
|
+
}
|
553
607
|
});
|
554
608
|
});
|
555
609
|
state.isInitialized = true;
|
@@ -561,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
561
615
|
}
|
562
616
|
};
|
563
617
|
};
|
564
|
-
const services$
|
618
|
+
const services$2 = {
|
565
619
|
history: createHistoryService,
|
566
620
|
lifecycles: createLifecyclesService
|
567
621
|
};
|
568
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
622
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
569
623
|
const historyVersionRouter = {
|
570
624
|
type: "admin",
|
571
625
|
routes: [
|
572
626
|
{
|
573
627
|
method: "GET",
|
574
|
-
info,
|
628
|
+
info: info$1,
|
575
629
|
path: "/history-versions",
|
576
630
|
handler: "history-version.findMany",
|
577
631
|
config: {
|
@@ -580,7 +634,7 @@ const historyVersionRouter = {
|
|
580
634
|
},
|
581
635
|
{
|
582
636
|
method: "PUT",
|
583
|
-
info,
|
637
|
+
info: info$1,
|
584
638
|
path: "/history-versions/:versionId/restore",
|
585
639
|
handler: "history-version.restoreVersion",
|
586
640
|
config: {
|
@@ -589,7 +643,7 @@ const historyVersionRouter = {
|
|
589
643
|
}
|
590
644
|
]
|
591
645
|
};
|
592
|
-
const routes$
|
646
|
+
const routes$2 = {
|
593
647
|
"history-version": historyVersionRouter
|
594
648
|
};
|
595
649
|
const historyVersion = {
|
@@ -636,21 +690,21 @@ const historyVersion = {
|
|
636
690
|
}
|
637
691
|
}
|
638
692
|
};
|
639
|
-
const getFeature = () => {
|
693
|
+
const getFeature$1 = () => {
|
640
694
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
641
695
|
return {
|
642
696
|
register({ strapi: strapi2 }) {
|
643
697
|
strapi2.get("models").add(historyVersion);
|
644
698
|
},
|
645
699
|
bootstrap({ strapi: strapi2 }) {
|
646
|
-
getService(strapi2, "lifecycles").bootstrap();
|
700
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
647
701
|
},
|
648
702
|
destroy({ strapi: strapi2 }) {
|
649
|
-
getService(strapi2, "lifecycles").destroy();
|
703
|
+
getService$1(strapi2, "lifecycles").destroy();
|
650
704
|
},
|
651
|
-
controllers: controllers$
|
652
|
-
services: services$
|
653
|
-
routes: routes$
|
705
|
+
controllers: controllers$2,
|
706
|
+
services: services$2,
|
707
|
+
routes: routes$2
|
654
708
|
};
|
655
709
|
}
|
656
710
|
return {
|
@@ -659,9 +713,205 @@ const getFeature = () => {
|
|
659
713
|
}
|
660
714
|
};
|
661
715
|
};
|
662
|
-
const history = getFeature();
|
716
|
+
const history = getFeature$1();
|
717
|
+
const FEATURE_ID = "preview";
|
718
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
719
|
+
const previewRouter = {
|
720
|
+
type: "admin",
|
721
|
+
routes: [
|
722
|
+
{
|
723
|
+
method: "GET",
|
724
|
+
info,
|
725
|
+
path: "/preview/url/:contentType",
|
726
|
+
handler: "preview.getPreviewUrl",
|
727
|
+
config: {
|
728
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
729
|
+
}
|
730
|
+
}
|
731
|
+
]
|
732
|
+
};
|
733
|
+
const routes$1 = {
|
734
|
+
preview: previewRouter
|
735
|
+
};
|
736
|
+
function getService(strapi2, name) {
|
737
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
738
|
+
}
|
739
|
+
const getPreviewUrlSchema = yup.object().shape({
|
740
|
+
// Will be undefined for single types
|
741
|
+
documentId: yup.string(),
|
742
|
+
locale: yup.string().nullable(),
|
743
|
+
status: yup.string()
|
744
|
+
}).required();
|
745
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
746
|
+
await validateYupSchema(getPreviewUrlSchema)(params);
|
747
|
+
const newParams = pick(["documentId", "locale", "status"], params);
|
748
|
+
const model = strapi2.getModel(uid2);
|
749
|
+
if (!model || model.modelType !== "contentType") {
|
750
|
+
throw new errors.ValidationError("Invalid content type");
|
751
|
+
}
|
752
|
+
const isSingleType = model?.kind === "singleType";
|
753
|
+
if (!isSingleType && !params.documentId) {
|
754
|
+
throw new errors.ValidationError("documentId is required for Collection Types");
|
755
|
+
}
|
756
|
+
if (isSingleType) {
|
757
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
758
|
+
if (!doc) {
|
759
|
+
throw new errors.NotFoundError("Document not found");
|
760
|
+
}
|
761
|
+
newParams.documentId = doc?.documentId;
|
762
|
+
}
|
763
|
+
if (!newParams.status) {
|
764
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
765
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
766
|
+
}
|
767
|
+
return newParams;
|
768
|
+
};
|
769
|
+
const createPreviewController = () => {
|
770
|
+
return {
|
771
|
+
/**
|
772
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
773
|
+
* in the Content Manager.
|
774
|
+
*/
|
775
|
+
async getPreviewUrl(ctx) {
|
776
|
+
const uid2 = ctx.params.contentType;
|
777
|
+
const query = ctx.request.query;
|
778
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
779
|
+
const previewService = getService(strapi, "preview");
|
780
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
781
|
+
if (!url) {
|
782
|
+
ctx.status = 204;
|
783
|
+
}
|
784
|
+
return {
|
785
|
+
data: { url }
|
786
|
+
};
|
787
|
+
}
|
788
|
+
};
|
789
|
+
};
|
790
|
+
const controllers$1 = {
|
791
|
+
preview: createPreviewController
|
792
|
+
/**
|
793
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
794
|
+
* passing a controller factory as the value, instead of a controller object directly
|
795
|
+
*/
|
796
|
+
};
|
797
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
798
|
+
const config = getService(strapi2, "preview-config");
|
799
|
+
return {
|
800
|
+
async getPreviewUrl(uid2, params) {
|
801
|
+
const handler = config.getPreviewHandler();
|
802
|
+
try {
|
803
|
+
return handler(uid2, params);
|
804
|
+
} catch (error) {
|
805
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
806
|
+
throw new errors.ApplicationError("Failed to get preview URL");
|
807
|
+
}
|
808
|
+
return;
|
809
|
+
}
|
810
|
+
};
|
811
|
+
};
|
812
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
813
|
+
const middlewares = strapi.config.get("middlewares");
|
814
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
815
|
+
if (currentMiddleware === middleware.name) {
|
816
|
+
return middleware;
|
817
|
+
}
|
818
|
+
if (currentMiddleware.name === middleware.name) {
|
819
|
+
return mergeWith(
|
820
|
+
(objValue, srcValue) => {
|
821
|
+
if (Array.isArray(objValue)) {
|
822
|
+
return objValue.concat(srcValue);
|
823
|
+
}
|
824
|
+
return void 0;
|
825
|
+
},
|
826
|
+
currentMiddleware,
|
827
|
+
middleware
|
828
|
+
);
|
829
|
+
}
|
830
|
+
return currentMiddleware;
|
831
|
+
});
|
832
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
833
|
+
};
|
834
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
835
|
+
return {
|
836
|
+
register() {
|
837
|
+
if (!this.isEnabled()) {
|
838
|
+
return;
|
839
|
+
}
|
840
|
+
const config = strapi2.config.get("admin.preview");
|
841
|
+
if (config.config?.allowedOrigins) {
|
842
|
+
extendMiddlewareConfiguration({
|
843
|
+
name: "strapi::security",
|
844
|
+
config: {
|
845
|
+
contentSecurityPolicy: {
|
846
|
+
directives: {
|
847
|
+
"frame-src": config.config.allowedOrigins
|
848
|
+
}
|
849
|
+
}
|
850
|
+
}
|
851
|
+
});
|
852
|
+
}
|
853
|
+
},
|
854
|
+
isEnabled() {
|
855
|
+
const config = strapi2.config.get("admin.preview");
|
856
|
+
if (!config) {
|
857
|
+
return false;
|
858
|
+
}
|
859
|
+
return config?.enabled ?? true;
|
860
|
+
},
|
861
|
+
/**
|
862
|
+
* Validate if the configuration is valid
|
863
|
+
*/
|
864
|
+
validate() {
|
865
|
+
if (!this.isEnabled()) {
|
866
|
+
return;
|
867
|
+
}
|
868
|
+
const handler = this.getPreviewHandler();
|
869
|
+
if (typeof handler !== "function") {
|
870
|
+
throw new errors.ValidationError(
|
871
|
+
"Preview configuration is invalid. Handler must be a function"
|
872
|
+
);
|
873
|
+
}
|
874
|
+
},
|
875
|
+
/**
|
876
|
+
* Utility to get the preview handler from the configuration
|
877
|
+
*/
|
878
|
+
getPreviewHandler() {
|
879
|
+
const config = strapi2.config.get("admin.preview");
|
880
|
+
const emptyHandler = () => {
|
881
|
+
return void 0;
|
882
|
+
};
|
883
|
+
if (!this.isEnabled()) {
|
884
|
+
return emptyHandler;
|
885
|
+
}
|
886
|
+
return config?.config?.handler || emptyHandler;
|
887
|
+
}
|
888
|
+
};
|
889
|
+
};
|
890
|
+
const services$1 = {
|
891
|
+
preview: createPreviewService,
|
892
|
+
"preview-config": createPreviewConfigService
|
893
|
+
};
|
894
|
+
const getFeature = () => {
|
895
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
896
|
+
return {};
|
897
|
+
}
|
898
|
+
return {
|
899
|
+
register() {
|
900
|
+
const config = getService(strapi, "preview-config");
|
901
|
+
config.validate();
|
902
|
+
config.register();
|
903
|
+
},
|
904
|
+
bootstrap() {
|
905
|
+
},
|
906
|
+
routes: routes$1,
|
907
|
+
controllers: controllers$1,
|
908
|
+
services: services$1
|
909
|
+
};
|
910
|
+
};
|
911
|
+
const preview = getFeature();
|
663
912
|
const register = async ({ strapi: strapi2 }) => {
|
664
913
|
await history.register?.({ strapi: strapi2 });
|
914
|
+
await preview.register?.({ strapi: strapi2 });
|
665
915
|
};
|
666
916
|
const ALLOWED_WEBHOOK_EVENTS = {
|
667
917
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -671,11 +921,12 @@ const bootstrap = async () => {
|
|
671
921
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
672
922
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
673
923
|
});
|
674
|
-
getService$
|
675
|
-
await getService$
|
676
|
-
await getService$
|
677
|
-
await getService$
|
924
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
925
|
+
await getService$2("components").syncConfigurations();
|
926
|
+
await getService$2("content-types").syncConfigurations();
|
927
|
+
await getService$2("permission").registerPermissions();
|
678
928
|
await history.bootstrap?.({ strapi });
|
929
|
+
await preview.bootstrap?.({ strapi });
|
679
930
|
};
|
680
931
|
const destroy = async ({ strapi: strapi2 }) => {
|
681
932
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1165,7 +1416,8 @@ const admin = {
|
|
1165
1416
|
};
|
1166
1417
|
const routes = {
|
1167
1418
|
admin,
|
1168
|
-
...history.routes ? history.routes : {}
|
1419
|
+
...history.routes ? history.routes : {},
|
1420
|
+
...preview.routes ? preview.routes : {}
|
1169
1421
|
};
|
1170
1422
|
const hasPermissionsSchema = yup$1.object({
|
1171
1423
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1176,6 +1428,11 @@ const { createPolicy } = policy;
|
|
1176
1428
|
const hasPermissions = createPolicy({
|
1177
1429
|
name: "plugin::content-manager.hasPermissions",
|
1178
1430
|
validator: validateHasPermissionsInput,
|
1431
|
+
/**
|
1432
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1433
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1434
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1435
|
+
*/
|
1179
1436
|
handler(ctx, config = {}) {
|
1180
1437
|
const { actions = [], hasAtLeastOne = false } = config;
|
1181
1438
|
const { userAbility } = ctx.state;
|
@@ -1417,7 +1674,7 @@ const createMetadasSchema = (schema) => {
|
|
1417
1674
|
if (!value) {
|
1418
1675
|
return yup$1.string();
|
1419
1676
|
}
|
1420
|
-
const targetSchema = getService$
|
1677
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1421
1678
|
schema.attributes[key].targetModel
|
1422
1679
|
);
|
1423
1680
|
if (!targetSchema) {
|
@@ -1569,9 +1826,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1569
1826
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1570
1827
|
);
|
1571
1828
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1572
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1829
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1573
1830
|
const { allowMultipleLocales } = opts;
|
1574
|
-
const { locale, status, ...rest } = request || {};
|
1831
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1832
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1833
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1575
1834
|
const schema = yup$1.object().shape({
|
1576
1835
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1577
1836
|
status: statusSchema
|
@@ -1584,7 +1843,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1584
1843
|
}
|
1585
1844
|
};
|
1586
1845
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1587
|
-
const documentMetadata2 = getService$
|
1846
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1588
1847
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1589
1848
|
let {
|
1590
1849
|
meta: { availableLocales, availableStatus }
|
@@ -1610,8 +1869,8 @@ const createDocument = async (ctx, opts) => {
|
|
1610
1869
|
const { userAbility, user } = ctx.state;
|
1611
1870
|
const { model } = ctx.params;
|
1612
1871
|
const { body } = ctx.request;
|
1613
|
-
const documentManager2 = getService$
|
1614
|
-
const permissionChecker2 = getService$
|
1872
|
+
const documentManager2 = getService$2("document-manager");
|
1873
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1615
1874
|
if (permissionChecker2.cannot.create()) {
|
1616
1875
|
throw new errors.ForbiddenError();
|
1617
1876
|
}
|
@@ -1619,7 +1878,7 @@ const createDocument = async (ctx, opts) => {
|
|
1619
1878
|
const setCreator = setCreatorFields({ user });
|
1620
1879
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1621
1880
|
const sanitizedBody = await sanitizeFn(body);
|
1622
|
-
const { locale, status
|
1881
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1623
1882
|
return documentManager2.create(model, {
|
1624
1883
|
data: sanitizedBody,
|
1625
1884
|
locale,
|
@@ -1631,14 +1890,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1631
1890
|
const { userAbility, user } = ctx.state;
|
1632
1891
|
const { id, model } = ctx.params;
|
1633
1892
|
const { body } = ctx.request;
|
1634
|
-
const documentManager2 = getService$
|
1635
|
-
const permissionChecker2 = getService$
|
1893
|
+
const documentManager2 = getService$2("document-manager");
|
1894
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1636
1895
|
if (permissionChecker2.cannot.update()) {
|
1637
1896
|
throw new errors.ForbiddenError();
|
1638
1897
|
}
|
1639
1898
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1640
|
-
const populate = await getService$
|
1641
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1899
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1900
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1642
1901
|
const [documentVersion, documentExists] = await Promise.all([
|
1643
1902
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1644
1903
|
documentManager2.exists(model, id)
|
@@ -1654,7 +1913,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1654
1913
|
throw new errors.ForbiddenError();
|
1655
1914
|
}
|
1656
1915
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1657
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1916
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1658
1917
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1659
1918
|
const sanitizedBody = await sanitizeFn(body);
|
1660
1919
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1668,15 +1927,15 @@ const collectionTypes = {
|
|
1668
1927
|
const { userAbility } = ctx.state;
|
1669
1928
|
const { model } = ctx.params;
|
1670
1929
|
const { query } = ctx.request;
|
1671
|
-
const documentMetadata2 = getService$
|
1672
|
-
const documentManager2 = getService$
|
1673
|
-
const permissionChecker2 = getService$
|
1930
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1931
|
+
const documentManager2 = getService$2("document-manager");
|
1932
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1674
1933
|
if (permissionChecker2.cannot.read()) {
|
1675
1934
|
return ctx.forbidden();
|
1676
1935
|
}
|
1677
1936
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1678
|
-
const populate = await getService$
|
1679
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1937
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1938
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1680
1939
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1681
1940
|
{ ...permissionQuery, populate, locale, status },
|
1682
1941
|
model
|
@@ -1704,14 +1963,14 @@ const collectionTypes = {
|
|
1704
1963
|
async findOne(ctx) {
|
1705
1964
|
const { userAbility } = ctx.state;
|
1706
1965
|
const { model, id } = ctx.params;
|
1707
|
-
const documentManager2 = getService$
|
1708
|
-
const permissionChecker2 = getService$
|
1966
|
+
const documentManager2 = getService$2("document-manager");
|
1967
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1709
1968
|
if (permissionChecker2.cannot.read()) {
|
1710
1969
|
return ctx.forbidden();
|
1711
1970
|
}
|
1712
1971
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1713
|
-
const populate = await getService$
|
1714
|
-
const { locale, status
|
1972
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1973
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1715
1974
|
const version = await documentManager2.findOne(id, model, {
|
1716
1975
|
populate,
|
1717
1976
|
locale,
|
@@ -1726,7 +1985,7 @@ const collectionTypes = {
|
|
1726
1985
|
permissionChecker2,
|
1727
1986
|
model,
|
1728
1987
|
// @ts-expect-error TODO: fix
|
1729
|
-
{ id, locale, publishedAt: null },
|
1988
|
+
{ documentId: id, locale, publishedAt: null },
|
1730
1989
|
{ availableLocales: true, availableStatus: false }
|
1731
1990
|
);
|
1732
1991
|
ctx.body = { data: {}, meta };
|
@@ -1741,7 +2000,7 @@ const collectionTypes = {
|
|
1741
2000
|
async create(ctx) {
|
1742
2001
|
const { userAbility } = ctx.state;
|
1743
2002
|
const { model } = ctx.params;
|
1744
|
-
const permissionChecker2 = getService$
|
2003
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1745
2004
|
const [totalEntries, document] = await Promise.all([
|
1746
2005
|
strapi.db.query(model).count(),
|
1747
2006
|
createDocument(ctx)
|
@@ -1762,7 +2021,7 @@ const collectionTypes = {
|
|
1762
2021
|
async update(ctx) {
|
1763
2022
|
const { userAbility } = ctx.state;
|
1764
2023
|
const { model } = ctx.params;
|
1765
|
-
const permissionChecker2 = getService$
|
2024
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1766
2025
|
const updatedVersion = await updateDocument(ctx);
|
1767
2026
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1768
2027
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1771,14 +2030,14 @@ const collectionTypes = {
|
|
1771
2030
|
const { userAbility, user } = ctx.state;
|
1772
2031
|
const { model, sourceId: id } = ctx.params;
|
1773
2032
|
const { body } = ctx.request;
|
1774
|
-
const documentManager2 = getService$
|
1775
|
-
const permissionChecker2 = getService$
|
2033
|
+
const documentManager2 = getService$2("document-manager");
|
2034
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1776
2035
|
if (permissionChecker2.cannot.create()) {
|
1777
2036
|
return ctx.forbidden();
|
1778
2037
|
}
|
1779
2038
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1780
|
-
const populate = await getService$
|
1781
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2039
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2040
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1782
2041
|
const document = await documentManager2.findOne(id, model, {
|
1783
2042
|
populate,
|
1784
2043
|
locale,
|
@@ -1816,14 +2075,14 @@ const collectionTypes = {
|
|
1816
2075
|
async delete(ctx) {
|
1817
2076
|
const { userAbility } = ctx.state;
|
1818
2077
|
const { id, model } = ctx.params;
|
1819
|
-
const documentManager2 = getService$
|
1820
|
-
const permissionChecker2 = getService$
|
2078
|
+
const documentManager2 = getService$2("document-manager");
|
2079
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1821
2080
|
if (permissionChecker2.cannot.delete()) {
|
1822
2081
|
return ctx.forbidden();
|
1823
2082
|
}
|
1824
2083
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1825
|
-
const populate = await getService$
|
1826
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2084
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2085
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1827
2086
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1828
2087
|
if (documentLocales.length === 0) {
|
1829
2088
|
return ctx.notFound();
|
@@ -1844,19 +2103,42 @@ const collectionTypes = {
|
|
1844
2103
|
const { userAbility } = ctx.state;
|
1845
2104
|
const { id, model } = ctx.params;
|
1846
2105
|
const { body } = ctx.request;
|
1847
|
-
const documentManager2 = getService$
|
1848
|
-
const permissionChecker2 = getService$
|
2106
|
+
const documentManager2 = getService$2("document-manager");
|
2107
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1849
2108
|
if (permissionChecker2.cannot.publish()) {
|
1850
2109
|
return ctx.forbidden();
|
1851
2110
|
}
|
1852
2111
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1853
2112
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1854
|
-
const populate = await getService$
|
1855
|
-
|
2113
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2114
|
+
let document;
|
2115
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2116
|
+
const isCreate = isNil$1(id);
|
2117
|
+
if (isCreate) {
|
2118
|
+
if (permissionChecker2.cannot.create()) {
|
2119
|
+
throw new errors.ForbiddenError();
|
2120
|
+
}
|
2121
|
+
document = await createDocument(ctx, { populate });
|
2122
|
+
}
|
2123
|
+
const isUpdate = !isCreate;
|
2124
|
+
if (isUpdate) {
|
2125
|
+
const documentExists = documentManager2.exists(model, id);
|
2126
|
+
if (!documentExists) {
|
2127
|
+
throw new errors.NotFoundError("Document not found");
|
2128
|
+
}
|
2129
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2130
|
+
if (!document) {
|
2131
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2132
|
+
throw new errors.ForbiddenError();
|
2133
|
+
}
|
2134
|
+
document = await updateDocument(ctx);
|
2135
|
+
} else if (permissionChecker2.can.update(document)) {
|
2136
|
+
await updateDocument(ctx);
|
2137
|
+
}
|
2138
|
+
}
|
1856
2139
|
if (permissionChecker2.cannot.publish(document)) {
|
1857
2140
|
throw new errors.ForbiddenError();
|
1858
2141
|
}
|
1859
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1860
2142
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1861
2143
|
locale
|
1862
2144
|
// TODO: Allow setting creator fields on publish
|
@@ -1876,14 +2158,16 @@ const collectionTypes = {
|
|
1876
2158
|
const { body } = ctx.request;
|
1877
2159
|
const { documentIds } = body;
|
1878
2160
|
await validateBulkActionInput(body);
|
1879
|
-
const documentManager2 = getService$
|
1880
|
-
const permissionChecker2 = getService$
|
2161
|
+
const documentManager2 = getService$2("document-manager");
|
2162
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1881
2163
|
if (permissionChecker2.cannot.publish()) {
|
1882
2164
|
return ctx.forbidden();
|
1883
2165
|
}
|
1884
2166
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1885
|
-
const populate = await getService$
|
1886
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2167
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2168
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2169
|
+
allowMultipleLocales: true
|
2170
|
+
});
|
1887
2171
|
const entityPromises = documentIds.map(
|
1888
2172
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1889
2173
|
);
|
@@ -1905,12 +2189,14 @@ const collectionTypes = {
|
|
1905
2189
|
const { body } = ctx.request;
|
1906
2190
|
const { documentIds } = body;
|
1907
2191
|
await validateBulkActionInput(body);
|
1908
|
-
const documentManager2 = getService$
|
1909
|
-
const permissionChecker2 = getService$
|
2192
|
+
const documentManager2 = getService$2("document-manager");
|
2193
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1910
2194
|
if (permissionChecker2.cannot.unpublish()) {
|
1911
2195
|
return ctx.forbidden();
|
1912
2196
|
}
|
1913
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2197
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2198
|
+
allowMultipleLocales: true
|
2199
|
+
});
|
1914
2200
|
const entityPromises = documentIds.map(
|
1915
2201
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1916
2202
|
);
|
@@ -1933,8 +2219,8 @@ const collectionTypes = {
|
|
1933
2219
|
const {
|
1934
2220
|
body: { discardDraft, ...body }
|
1935
2221
|
} = ctx.request;
|
1936
|
-
const documentManager2 = getService$
|
1937
|
-
const permissionChecker2 = getService$
|
2222
|
+
const documentManager2 = getService$2("document-manager");
|
2223
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1938
2224
|
if (permissionChecker2.cannot.unpublish()) {
|
1939
2225
|
return ctx.forbidden();
|
1940
2226
|
}
|
@@ -1942,8 +2228,8 @@ const collectionTypes = {
|
|
1942
2228
|
return ctx.forbidden();
|
1943
2229
|
}
|
1944
2230
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1945
|
-
const populate = await getService$
|
1946
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2231
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2232
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1947
2233
|
const document = await documentManager2.findOne(id, model, {
|
1948
2234
|
populate,
|
1949
2235
|
locale,
|
@@ -1973,14 +2259,14 @@ const collectionTypes = {
|
|
1973
2259
|
const { userAbility } = ctx.state;
|
1974
2260
|
const { id, model } = ctx.params;
|
1975
2261
|
const { body } = ctx.request;
|
1976
|
-
const documentManager2 = getService$
|
1977
|
-
const permissionChecker2 = getService$
|
2262
|
+
const documentManager2 = getService$2("document-manager");
|
2263
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1978
2264
|
if (permissionChecker2.cannot.discard()) {
|
1979
2265
|
return ctx.forbidden();
|
1980
2266
|
}
|
1981
2267
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1982
|
-
const populate = await getService$
|
1983
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2268
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2269
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1984
2270
|
const document = await documentManager2.findOne(id, model, {
|
1985
2271
|
populate,
|
1986
2272
|
locale,
|
@@ -2004,14 +2290,14 @@ const collectionTypes = {
|
|
2004
2290
|
const { query, body } = ctx.request;
|
2005
2291
|
const { documentIds } = body;
|
2006
2292
|
await validateBulkActionInput(body);
|
2007
|
-
const documentManager2 = getService$
|
2008
|
-
const permissionChecker2 = getService$
|
2293
|
+
const documentManager2 = getService$2("document-manager");
|
2294
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2009
2295
|
if (permissionChecker2.cannot.delete()) {
|
2010
2296
|
return ctx.forbidden();
|
2011
2297
|
}
|
2012
2298
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2013
|
-
const populate = await getService$
|
2014
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2299
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2300
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2015
2301
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2016
2302
|
populate,
|
2017
2303
|
locale
|
@@ -2031,14 +2317,14 @@ const collectionTypes = {
|
|
2031
2317
|
async countDraftRelations(ctx) {
|
2032
2318
|
const { userAbility } = ctx.state;
|
2033
2319
|
const { model, id } = ctx.params;
|
2034
|
-
const documentManager2 = getService$
|
2035
|
-
const permissionChecker2 = getService$
|
2320
|
+
const documentManager2 = getService$2("document-manager");
|
2321
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2036
2322
|
if (permissionChecker2.cannot.read()) {
|
2037
2323
|
return ctx.forbidden();
|
2038
2324
|
}
|
2039
2325
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2040
|
-
const populate = await getService$
|
2041
|
-
const { locale, status
|
2326
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2327
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2042
2328
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2043
2329
|
if (!entity) {
|
2044
2330
|
return ctx.notFound();
|
@@ -2056,8 +2342,8 @@ const collectionTypes = {
|
|
2056
2342
|
const ids = ctx.request.query.documentIds;
|
2057
2343
|
const locale = ctx.request.query.locale;
|
2058
2344
|
const { model } = ctx.params;
|
2059
|
-
const documentManager2 = getService$
|
2060
|
-
const permissionChecker2 = getService$
|
2345
|
+
const documentManager2 = getService$2("document-manager");
|
2346
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2061
2347
|
if (permissionChecker2.cannot.read()) {
|
2062
2348
|
return ctx.forbidden();
|
2063
2349
|
}
|
@@ -2081,13 +2367,13 @@ const collectionTypes = {
|
|
2081
2367
|
};
|
2082
2368
|
const components$1 = {
|
2083
2369
|
findComponents(ctx) {
|
2084
|
-
const components2 = getService$
|
2085
|
-
const { toDto } = getService$
|
2370
|
+
const components2 = getService$2("components").findAllComponents();
|
2371
|
+
const { toDto } = getService$2("data-mapper");
|
2086
2372
|
ctx.body = { data: components2.map(toDto) };
|
2087
2373
|
},
|
2088
2374
|
async findComponentConfiguration(ctx) {
|
2089
2375
|
const { uid: uid2 } = ctx.params;
|
2090
|
-
const componentService = getService$
|
2376
|
+
const componentService = getService$2("components");
|
2091
2377
|
const component = componentService.findComponent(uid2);
|
2092
2378
|
if (!component) {
|
2093
2379
|
return ctx.notFound("component.notFound");
|
@@ -2104,7 +2390,7 @@ const components$1 = {
|
|
2104
2390
|
async updateComponentConfiguration(ctx) {
|
2105
2391
|
const { uid: uid2 } = ctx.params;
|
2106
2392
|
const { body } = ctx.request;
|
2107
|
-
const componentService = getService$
|
2393
|
+
const componentService = getService$2("components");
|
2108
2394
|
const component = componentService.findComponent(uid2);
|
2109
2395
|
if (!component) {
|
2110
2396
|
return ctx.notFound("component.notFound");
|
@@ -2138,12 +2424,12 @@ const contentTypes = {
|
|
2138
2424
|
} catch (error) {
|
2139
2425
|
return ctx.send({ error }, 400);
|
2140
2426
|
}
|
2141
|
-
const contentTypes2 = getService$
|
2142
|
-
const { toDto } = getService$
|
2427
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2428
|
+
const { toDto } = getService$2("data-mapper");
|
2143
2429
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2144
2430
|
},
|
2145
2431
|
async findContentTypesSettings(ctx) {
|
2146
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2432
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2147
2433
|
const contentTypes2 = await findAllContentTypes();
|
2148
2434
|
const configurations = await Promise.all(
|
2149
2435
|
contentTypes2.map(async (contentType) => {
|
@@ -2157,7 +2443,7 @@ const contentTypes = {
|
|
2157
2443
|
},
|
2158
2444
|
async findContentTypeConfiguration(ctx) {
|
2159
2445
|
const { uid: uid2 } = ctx.params;
|
2160
|
-
const contentTypeService = getService$
|
2446
|
+
const contentTypeService = getService$2("content-types");
|
2161
2447
|
const contentType = await contentTypeService.findContentType(uid2);
|
2162
2448
|
if (!contentType) {
|
2163
2449
|
return ctx.notFound("contentType.notFound");
|
@@ -2179,13 +2465,13 @@ const contentTypes = {
|
|
2179
2465
|
const { userAbility } = ctx.state;
|
2180
2466
|
const { uid: uid2 } = ctx.params;
|
2181
2467
|
const { body } = ctx.request;
|
2182
|
-
const contentTypeService = getService$
|
2183
|
-
const metricsService = getService$
|
2468
|
+
const contentTypeService = getService$2("content-types");
|
2469
|
+
const metricsService = getService$2("metrics");
|
2184
2470
|
const contentType = await contentTypeService.findContentType(uid2);
|
2185
2471
|
if (!contentType) {
|
2186
2472
|
return ctx.notFound("contentType.notFound");
|
2187
2473
|
}
|
2188
|
-
if (!getService$
|
2474
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2189
2475
|
return ctx.forbidden();
|
2190
2476
|
}
|
2191
2477
|
let input;
|
@@ -2218,10 +2504,10 @@ const contentTypes = {
|
|
2218
2504
|
};
|
2219
2505
|
const init = {
|
2220
2506
|
getInitData(ctx) {
|
2221
|
-
const { toDto } = getService$
|
2222
|
-
const { findAllComponents } = getService$
|
2223
|
-
const { getAllFieldSizes } = getService$
|
2224
|
-
const { findAllContentTypes } = getService$
|
2507
|
+
const { toDto } = getService$2("data-mapper");
|
2508
|
+
const { findAllComponents } = getService$2("components");
|
2509
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2510
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2225
2511
|
ctx.body = {
|
2226
2512
|
data: {
|
2227
2513
|
fieldSizes: getAllFieldSizes(),
|
@@ -2257,36 +2543,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2257
2543
|
params.filters.$and.push(filtersClause);
|
2258
2544
|
};
|
2259
2545
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2260
|
-
const permissionChecker2 = getService$
|
2546
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2261
2547
|
userAbility,
|
2262
2548
|
model: model.uid
|
2263
2549
|
});
|
2264
|
-
|
2550
|
+
const isMainFieldListable = isListable(model, mainField);
|
2551
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2552
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2265
2553
|
return "id";
|
2266
2554
|
}
|
2267
|
-
if (
|
2268
|
-
|
2269
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2270
|
-
userAbility,
|
2271
|
-
model: "plugin::users-permissions.user"
|
2272
|
-
});
|
2273
|
-
if (userPermissionChecker.can.read()) {
|
2274
|
-
return "name";
|
2275
|
-
}
|
2276
|
-
}
|
2277
|
-
return "id";
|
2555
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2556
|
+
return "name";
|
2278
2557
|
}
|
2279
2558
|
return mainField;
|
2280
2559
|
};
|
2281
|
-
const addStatusToRelations = async (
|
2282
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2560
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2561
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2562
|
+
return relations2;
|
2563
|
+
}
|
2564
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2565
|
+
if (!relations2.length) {
|
2283
2566
|
return relations2;
|
2284
2567
|
}
|
2285
|
-
const
|
2286
|
-
const
|
2568
|
+
const firstRelation = relations2[0];
|
2569
|
+
const filters = {
|
2570
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2571
|
+
// NOTE: find the "opposite" status
|
2572
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2573
|
+
};
|
2574
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2575
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2576
|
+
filters
|
2577
|
+
});
|
2287
2578
|
return relations2.map((relation) => {
|
2288
|
-
const availableStatuses =
|
2289
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2579
|
+
const availableStatuses = availableStatus.filter(
|
2580
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2290
2581
|
);
|
2291
2582
|
return {
|
2292
2583
|
...relation,
|
@@ -2307,11 +2598,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2307
2598
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2308
2599
|
const isSourceLocalized = isLocalized(sourceModel);
|
2309
2600
|
const isTargetLocalized = isLocalized(targetModel);
|
2310
|
-
let validatedLocale = locale;
|
2311
|
-
if (!targetModel || !isTargetLocalized)
|
2312
|
-
validatedLocale = void 0;
|
2313
2601
|
return {
|
2314
|
-
locale
|
2602
|
+
locale,
|
2315
2603
|
isSourceLocalized,
|
2316
2604
|
isTargetLocalized
|
2317
2605
|
};
|
@@ -2351,7 +2639,7 @@ const relations = {
|
|
2351
2639
|
ctx.request?.query?.locale
|
2352
2640
|
);
|
2353
2641
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2354
|
-
const permissionChecker2 = getService$
|
2642
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2355
2643
|
userAbility,
|
2356
2644
|
model
|
2357
2645
|
});
|
@@ -2376,7 +2664,7 @@ const relations = {
|
|
2376
2664
|
where.id = id;
|
2377
2665
|
}
|
2378
2666
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2379
|
-
const populate = await getService$
|
2667
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2380
2668
|
const currentEntity = await strapi.db.query(model).findOne({
|
2381
2669
|
where,
|
2382
2670
|
populate
|
@@ -2391,7 +2679,7 @@ const relations = {
|
|
2391
2679
|
}
|
2392
2680
|
entryId = currentEntity.id;
|
2393
2681
|
}
|
2394
|
-
const modelConfig = isComponent2 ? await getService$
|
2682
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2395
2683
|
const targetSchema = strapi.getModel(targetUid);
|
2396
2684
|
const mainField = flow(
|
2397
2685
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2414,7 +2702,7 @@ const relations = {
|
|
2414
2702
|
attribute,
|
2415
2703
|
fieldsToSelect,
|
2416
2704
|
mainField,
|
2417
|
-
source: { schema: sourceSchema },
|
2705
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2418
2706
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2419
2707
|
sourceSchema,
|
2420
2708
|
targetSchema,
|
@@ -2436,7 +2724,8 @@ const relations = {
|
|
2436
2724
|
fieldsToSelect,
|
2437
2725
|
mainField,
|
2438
2726
|
source: {
|
2439
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2727
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2728
|
+
isLocalized: isSourceLocalized
|
2440
2729
|
},
|
2441
2730
|
target: {
|
2442
2731
|
schema: { uid: targetUid },
|
@@ -2444,7 +2733,7 @@ const relations = {
|
|
2444
2733
|
}
|
2445
2734
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2446
2735
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2447
|
-
const permissionChecker2 = getService$
|
2736
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2448
2737
|
userAbility: ctx.state.userAbility,
|
2449
2738
|
model: targetUid
|
2450
2739
|
});
|
@@ -2474,12 +2763,16 @@ const relations = {
|
|
2474
2763
|
} else {
|
2475
2764
|
where.id = id;
|
2476
2765
|
}
|
2477
|
-
|
2478
|
-
|
2766
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2767
|
+
if (!isEmpty(publishedAt)) {
|
2768
|
+
where[`${alias}.published_at`] = publishedAt;
|
2479
2769
|
}
|
2480
|
-
if (
|
2770
|
+
if (isTargetLocalized && locale) {
|
2481
2771
|
where[`${alias}.locale`] = locale;
|
2482
2772
|
}
|
2773
|
+
if (isSourceLocalized && locale) {
|
2774
|
+
where.locale = locale;
|
2775
|
+
}
|
2483
2776
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2484
2777
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2485
2778
|
}
|
@@ -2497,7 +2790,8 @@ const relations = {
|
|
2497
2790
|
id: { $notIn: uniq(idsToOmit) }
|
2498
2791
|
});
|
2499
2792
|
}
|
2500
|
-
const
|
2793
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2794
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2501
2795
|
ctx.body = {
|
2502
2796
|
...res,
|
2503
2797
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2512,29 +2806,39 @@ const relations = {
|
|
2512
2806
|
attribute,
|
2513
2807
|
targetField,
|
2514
2808
|
fieldsToSelect,
|
2515
|
-
|
2516
|
-
|
2517
|
-
}
|
2518
|
-
target: {
|
2519
|
-
schema: { uid: targetUid }
|
2520
|
-
}
|
2809
|
+
status,
|
2810
|
+
source: { schema: sourceSchema },
|
2811
|
+
target: { schema: targetSchema }
|
2521
2812
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2522
|
-
const
|
2813
|
+
const { uid: sourceUid } = sourceSchema;
|
2814
|
+
const { uid: targetUid } = targetSchema;
|
2815
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2523
2816
|
const dbQuery = strapi.db.query(sourceUid);
|
2524
2817
|
const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2818
|
+
const filters = {};
|
2819
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2820
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2821
|
+
if (status === "published") {
|
2822
|
+
filters.publishedAt = { $notNull: true };
|
2823
|
+
} else {
|
2824
|
+
filters.publishedAt = { $null: true };
|
2825
|
+
}
|
2826
|
+
}
|
2827
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2828
|
+
filters.publishedAt = { $null: true };
|
2829
|
+
}
|
2525
2830
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2526
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2831
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2527
2832
|
ordering: "desc",
|
2528
2833
|
page: ctx.request.query.page,
|
2529
|
-
pageSize: ctx.request.query.pageSize
|
2834
|
+
pageSize: ctx.request.query.pageSize,
|
2835
|
+
filters
|
2530
2836
|
});
|
2531
2837
|
const loadedIds = res.results.map((item) => item.id);
|
2532
2838
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2533
2839
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2534
2840
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2535
|
-
ordering: "desc"
|
2536
|
-
page: ctx.request.query.page,
|
2537
|
-
pageSize: ctx.request.query.pageSize
|
2841
|
+
ordering: "desc"
|
2538
2842
|
});
|
2539
2843
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2540
2844
|
ctx.body = {
|
@@ -2549,10 +2853,10 @@ const relations = {
|
|
2549
2853
|
}
|
2550
2854
|
};
|
2551
2855
|
const buildPopulateFromQuery = async (query, model) => {
|
2552
|
-
return getService$
|
2856
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2553
2857
|
};
|
2554
2858
|
const findDocument = async (query, uid2, opts = {}) => {
|
2555
|
-
const documentManager2 = getService$
|
2859
|
+
const documentManager2 = getService$2("document-manager");
|
2556
2860
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2557
2861
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2558
2862
|
};
|
@@ -2560,13 +2864,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2560
2864
|
const { user, userAbility } = ctx.state;
|
2561
2865
|
const { model } = ctx.params;
|
2562
2866
|
const { body, query } = ctx.request;
|
2563
|
-
const documentManager2 = getService$
|
2564
|
-
const permissionChecker2 = getService$
|
2867
|
+
const documentManager2 = getService$2("document-manager");
|
2868
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2565
2869
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2566
2870
|
throw new errors.ForbiddenError();
|
2567
2871
|
}
|
2568
2872
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2569
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2873
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2570
2874
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2571
2875
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2572
2876
|
// Find the first document to check if it exists
|
@@ -2602,12 +2906,12 @@ const singleTypes = {
|
|
2602
2906
|
const { userAbility } = ctx.state;
|
2603
2907
|
const { model } = ctx.params;
|
2604
2908
|
const { query = {} } = ctx.request;
|
2605
|
-
const permissionChecker2 = getService$
|
2909
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2606
2910
|
if (permissionChecker2.cannot.read()) {
|
2607
2911
|
return ctx.forbidden();
|
2608
2912
|
}
|
2609
2913
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2610
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2914
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2611
2915
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2612
2916
|
if (!version) {
|
2613
2917
|
if (permissionChecker2.cannot.create()) {
|
@@ -2621,7 +2925,7 @@ const singleTypes = {
|
|
2621
2925
|
permissionChecker2,
|
2622
2926
|
model,
|
2623
2927
|
// @ts-expect-error - fix types
|
2624
|
-
{
|
2928
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2625
2929
|
{ availableLocales: true, availableStatus: false }
|
2626
2930
|
);
|
2627
2931
|
ctx.body = { data: {}, meta };
|
@@ -2636,7 +2940,7 @@ const singleTypes = {
|
|
2636
2940
|
async createOrUpdate(ctx) {
|
2637
2941
|
const { userAbility } = ctx.state;
|
2638
2942
|
const { model } = ctx.params;
|
2639
|
-
const permissionChecker2 = getService$
|
2943
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2640
2944
|
const document = await createOrUpdateDocument(ctx);
|
2641
2945
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2642
2946
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2645,14 +2949,14 @@ const singleTypes = {
|
|
2645
2949
|
const { userAbility } = ctx.state;
|
2646
2950
|
const { model } = ctx.params;
|
2647
2951
|
const { query = {} } = ctx.request;
|
2648
|
-
const documentManager2 = getService$
|
2649
|
-
const permissionChecker2 = getService$
|
2952
|
+
const documentManager2 = getService$2("document-manager");
|
2953
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2650
2954
|
if (permissionChecker2.cannot.delete()) {
|
2651
2955
|
return ctx.forbidden();
|
2652
2956
|
}
|
2653
2957
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2654
2958
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2655
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2959
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2656
2960
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2657
2961
|
populate,
|
2658
2962
|
locale
|
@@ -2674,8 +2978,8 @@ const singleTypes = {
|
|
2674
2978
|
const { userAbility } = ctx.state;
|
2675
2979
|
const { model } = ctx.params;
|
2676
2980
|
const { query = {} } = ctx.request;
|
2677
|
-
const documentManager2 = getService$
|
2678
|
-
const permissionChecker2 = getService$
|
2981
|
+
const documentManager2 = getService$2("document-manager");
|
2982
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2679
2983
|
if (permissionChecker2.cannot.publish()) {
|
2680
2984
|
return ctx.forbidden();
|
2681
2985
|
}
|
@@ -2689,7 +2993,7 @@ const singleTypes = {
|
|
2689
2993
|
if (permissionChecker2.cannot.publish(document)) {
|
2690
2994
|
throw new errors.ForbiddenError();
|
2691
2995
|
}
|
2692
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2996
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2693
2997
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2694
2998
|
return publishResult.at(0);
|
2695
2999
|
});
|
@@ -2703,8 +3007,8 @@ const singleTypes = {
|
|
2703
3007
|
body: { discardDraft, ...body },
|
2704
3008
|
query = {}
|
2705
3009
|
} = ctx.request;
|
2706
|
-
const documentManager2 = getService$
|
2707
|
-
const permissionChecker2 = getService$
|
3010
|
+
const documentManager2 = getService$2("document-manager");
|
3011
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2708
3012
|
if (permissionChecker2.cannot.unpublish()) {
|
2709
3013
|
return ctx.forbidden();
|
2710
3014
|
}
|
@@ -2712,7 +3016,7 @@ const singleTypes = {
|
|
2712
3016
|
return ctx.forbidden();
|
2713
3017
|
}
|
2714
3018
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2715
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3019
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2716
3020
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2717
3021
|
if (!document) {
|
2718
3022
|
return ctx.notFound();
|
@@ -2738,13 +3042,13 @@ const singleTypes = {
|
|
2738
3042
|
const { userAbility } = ctx.state;
|
2739
3043
|
const { model } = ctx.params;
|
2740
3044
|
const { body, query = {} } = ctx.request;
|
2741
|
-
const documentManager2 = getService$
|
2742
|
-
const permissionChecker2 = getService$
|
3045
|
+
const documentManager2 = getService$2("document-manager");
|
3046
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2743
3047
|
if (permissionChecker2.cannot.discard()) {
|
2744
3048
|
return ctx.forbidden();
|
2745
3049
|
}
|
2746
3050
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2747
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3051
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2748
3052
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2749
3053
|
if (!document) {
|
2750
3054
|
return ctx.notFound();
|
@@ -2762,9 +3066,9 @@ const singleTypes = {
|
|
2762
3066
|
const { userAbility } = ctx.state;
|
2763
3067
|
const { model } = ctx.params;
|
2764
3068
|
const { query } = ctx.request;
|
2765
|
-
const documentManager2 = getService$
|
2766
|
-
const permissionChecker2 = getService$
|
2767
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3069
|
+
const documentManager2 = getService$2("document-manager");
|
3070
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3071
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2768
3072
|
if (permissionChecker2.cannot.read()) {
|
2769
3073
|
return ctx.forbidden();
|
2770
3074
|
}
|
@@ -2785,9 +3089,9 @@ const uid$1 = {
|
|
2785
3089
|
async generateUID(ctx) {
|
2786
3090
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2787
3091
|
const { query = {} } = ctx.request;
|
2788
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3092
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2789
3093
|
await validateUIDField(contentTypeUID, field);
|
2790
|
-
const uidService = getService$
|
3094
|
+
const uidService = getService$2("uid");
|
2791
3095
|
ctx.body = {
|
2792
3096
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2793
3097
|
};
|
@@ -2797,9 +3101,9 @@ const uid$1 = {
|
|
2797
3101
|
ctx.request.body
|
2798
3102
|
);
|
2799
3103
|
const { query = {} } = ctx.request;
|
2800
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3104
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2801
3105
|
await validateUIDField(contentTypeUID, field);
|
2802
|
-
const uidService = getService$
|
3106
|
+
const uidService = getService$2("uid");
|
2803
3107
|
const isAvailable = await uidService.checkUIDAvailability({
|
2804
3108
|
contentTypeUID,
|
2805
3109
|
field,
|
@@ -2820,7 +3124,8 @@ const controllers = {
|
|
2820
3124
|
relations,
|
2821
3125
|
"single-types": singleTypes,
|
2822
3126
|
uid: uid$1,
|
2823
|
-
...history.controllers ? history.controllers : {}
|
3127
|
+
...history.controllers ? history.controllers : {},
|
3128
|
+
...preview.controllers ? preview.controllers : {}
|
2824
3129
|
};
|
2825
3130
|
const keys = {
|
2826
3131
|
CONFIGURATION: "configuration"
|
@@ -2971,12 +3276,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2971
3276
|
return _.assign(metasWithDefaults, updatedMetas);
|
2972
3277
|
}
|
2973
3278
|
const getTargetSchema = (targetModel) => {
|
2974
|
-
return getService$
|
3279
|
+
return getService$2("content-types").findContentType(targetModel);
|
2975
3280
|
};
|
2976
3281
|
const DEFAULT_LIST_LENGTH = 4;
|
2977
3282
|
const MAX_ROW_SIZE = 12;
|
2978
3283
|
const isAllowedFieldSize = (type, size) => {
|
2979
|
-
const { getFieldSize } = getService$
|
3284
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2980
3285
|
const fieldSize = getFieldSize(type);
|
2981
3286
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2982
3287
|
return false;
|
@@ -2984,7 +3289,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2984
3289
|
return size <= MAX_ROW_SIZE;
|
2985
3290
|
};
|
2986
3291
|
const getDefaultFieldSize = (attribute) => {
|
2987
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3292
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2988
3293
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2989
3294
|
};
|
2990
3295
|
async function createDefaultLayouts(schema) {
|
@@ -3019,7 +3324,7 @@ function syncLayouts(configuration, schema) {
|
|
3019
3324
|
for (const el of row) {
|
3020
3325
|
if (!hasEditableAttribute(schema, el.name))
|
3021
3326
|
continue;
|
3022
|
-
const { hasFieldSize } = getService$
|
3327
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3023
3328
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3024
3329
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3025
3330
|
elementsToReAppend.push(el.name);
|
@@ -3159,17 +3464,17 @@ const configurationService$1 = createConfigurationService({
|
|
3159
3464
|
isComponent: true,
|
3160
3465
|
prefix: STORE_KEY_PREFIX,
|
3161
3466
|
getModels() {
|
3162
|
-
const { toContentManagerModel } = getService$
|
3467
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3163
3468
|
return mapValues(toContentManagerModel, strapi.components);
|
3164
3469
|
}
|
3165
3470
|
});
|
3166
3471
|
const components = ({ strapi: strapi2 }) => ({
|
3167
3472
|
findAllComponents() {
|
3168
|
-
const { toContentManagerModel } = getService$
|
3473
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3169
3474
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3170
3475
|
},
|
3171
3476
|
findComponent(uid2) {
|
3172
|
-
const { toContentManagerModel } = getService$
|
3477
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3173
3478
|
const component = strapi2.components[uid2];
|
3174
3479
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3175
3480
|
},
|
@@ -3220,17 +3525,17 @@ const configurationService = createConfigurationService({
|
|
3220
3525
|
storeUtils,
|
3221
3526
|
prefix: "content_types",
|
3222
3527
|
getModels() {
|
3223
|
-
const { toContentManagerModel } = getService$
|
3528
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3224
3529
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3225
3530
|
}
|
3226
3531
|
});
|
3227
3532
|
const service = ({ strapi: strapi2 }) => ({
|
3228
3533
|
findAllContentTypes() {
|
3229
|
-
const { toContentManagerModel } = getService$
|
3534
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3230
3535
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3231
3536
|
},
|
3232
3537
|
findContentType(uid2) {
|
3233
|
-
const { toContentManagerModel } = getService$
|
3538
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3234
3539
|
const contentType = strapi2.contentTypes[uid2];
|
3235
3540
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3236
3541
|
},
|
@@ -3259,7 +3564,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3259
3564
|
return this.findConfiguration(contentType);
|
3260
3565
|
},
|
3261
3566
|
findComponentsConfigurations(contentType) {
|
3262
|
-
return getService$
|
3567
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3263
3568
|
},
|
3264
3569
|
syncConfigurations() {
|
3265
3570
|
return configurationService.syncConfigurations();
|
@@ -3440,12 +3745,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3440
3745
|
ability: userAbility,
|
3441
3746
|
model
|
3442
3747
|
});
|
3443
|
-
const
|
3748
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3749
|
+
const toSubject = (entity) => {
|
3750
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3751
|
+
};
|
3444
3752
|
const can = (action, entity, field) => {
|
3445
|
-
|
3753
|
+
const subject = toSubject(entity);
|
3754
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3755
|
+
return (
|
3756
|
+
// Test the original action to see if it passes
|
3757
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3758
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3759
|
+
);
|
3446
3760
|
};
|
3447
3761
|
const cannot = (action, entity, field) => {
|
3448
|
-
|
3762
|
+
const subject = toSubject(entity);
|
3763
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3764
|
+
return (
|
3765
|
+
// Test both the original action
|
3766
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3767
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3768
|
+
);
|
3449
3769
|
};
|
3450
3770
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3451
3771
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3516,7 +3836,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3516
3836
|
return userAbility.can(action);
|
3517
3837
|
},
|
3518
3838
|
async registerPermissions() {
|
3519
|
-
const displayedContentTypes = getService$
|
3839
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3520
3840
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3521
3841
|
const actions = [
|
3522
3842
|
{
|
@@ -3722,6 +4042,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3722
4042
|
const attribute = model.attributes[attributeName];
|
3723
4043
|
switch (attribute.type) {
|
3724
4044
|
case "relation": {
|
4045
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4046
|
+
if (isMorphRelation) {
|
4047
|
+
break;
|
4048
|
+
}
|
3725
4049
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3726
4050
|
populateAcc[attributeName] = {
|
3727
4051
|
count: true,
|
@@ -3788,7 +4112,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3788
4112
|
return populateQuery;
|
3789
4113
|
};
|
3790
4114
|
const buildDeepPopulate = (uid2) => {
|
3791
|
-
return getService$
|
4115
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3792
4116
|
};
|
3793
4117
|
const populateBuilder = (uid2) => {
|
3794
4118
|
let getInitialPopulate = async () => {
|
@@ -3973,7 +4297,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3973
4297
|
*/
|
3974
4298
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3975
4299
|
const versionsByLocale = groupBy("locale", allVersions);
|
3976
|
-
|
4300
|
+
if (version.locale) {
|
4301
|
+
delete versionsByLocale[version.locale];
|
4302
|
+
}
|
3977
4303
|
const model = strapi2.getModel(uid2);
|
3978
4304
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3979
4305
|
const traversalFunction = async (localeVersion) => traverseEntity(
|
@@ -4099,7 +4425,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4099
4425
|
*/
|
4100
4426
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4101
4427
|
if (!document) {
|
4102
|
-
return
|
4428
|
+
return {
|
4429
|
+
data: document,
|
4430
|
+
meta: {
|
4431
|
+
availableLocales: [],
|
4432
|
+
availableStatus: []
|
4433
|
+
}
|
4434
|
+
};
|
4103
4435
|
}
|
4104
4436
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4105
4437
|
if (!hasDraftAndPublish) {
|
@@ -4207,10 +4539,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4207
4539
|
async clone(id, body, uid2) {
|
4208
4540
|
const populate = await buildDeepPopulate(uid2);
|
4209
4541
|
const params = {
|
4210
|
-
data:
|
4211
|
-
...omitIdField(body),
|
4212
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4213
|
-
},
|
4542
|
+
data: omitIdField(body),
|
4214
4543
|
populate
|
4215
4544
|
};
|
4216
4545
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4326,7 +4655,8 @@ const services = {
|
|
4326
4655
|
permission,
|
4327
4656
|
"populate-builder": populateBuilder$1,
|
4328
4657
|
uid,
|
4329
|
-
...history.services ? history.services : {}
|
4658
|
+
...history.services ? history.services : {},
|
4659
|
+
...preview.services ? preview.services : {}
|
4330
4660
|
};
|
4331
4661
|
const index = () => {
|
4332
4662
|
return {
|