@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.js
CHANGED
@@ -33,10 +33,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
33
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
34
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
35
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
36
|
+
const getService$2 = (name) => {
|
37
37
|
return strapi.plugin("content-manager").service(name);
|
38
38
|
};
|
39
|
-
function getService(strapi2, name) {
|
39
|
+
function getService$1(strapi2, name) {
|
40
40
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
41
|
}
|
42
42
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +72,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
72
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
73
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
74
|
}
|
75
|
-
const permissionChecker2 = getService$
|
75
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
76
|
userAbility: ctx.state.userAbility,
|
77
77
|
model: ctx.query.contentType
|
78
78
|
});
|
@@ -80,7 +80,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
80
|
return ctx.forbidden();
|
81
81
|
}
|
82
82
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
83
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
84
|
query: {
|
85
85
|
...query,
|
86
86
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +105,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
105
|
async restoreVersion(ctx) {
|
106
106
|
const request = ctx.request;
|
107
107
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
108
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
109
|
userAbility: ctx.state.userAbility,
|
110
110
|
model: request.body.contentType
|
111
111
|
});
|
112
112
|
if (permissionChecker2.cannot.update()) {
|
113
113
|
throw new strapiUtils.errors.ForbiddenError();
|
114
114
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
115
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
116
|
request.params.versionId
|
117
117
|
);
|
118
118
|
return {
|
@@ -121,7 +121,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
121
|
}
|
122
122
|
};
|
123
123
|
};
|
124
|
-
const controllers$
|
124
|
+
const controllers$2 = {
|
125
125
|
"history-version": createHistoryVersionController
|
126
126
|
/**
|
127
127
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -199,7 +199,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
199
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
200
|
};
|
201
201
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
202
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
203
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
204
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
205
|
const getLocaleDictionary = async () => {
|
204
206
|
if (!localesService)
|
205
207
|
return {};
|
@@ -226,9 +228,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
228
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
229
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
230
|
};
|
229
|
-
const
|
231
|
+
const getComponentFields = (componentUID) => {
|
232
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
233
|
+
(fieldsAcc, [key, attribute]) => {
|
234
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
235
|
+
fieldsAcc.push(key);
|
236
|
+
}
|
237
|
+
return fieldsAcc;
|
238
|
+
},
|
239
|
+
[]
|
240
|
+
);
|
241
|
+
};
|
242
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
243
|
const model = strapi2.getModel(uid2);
|
231
244
|
const attributes = Object.entries(model.attributes);
|
245
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
246
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
247
|
switch (attribute.type) {
|
234
248
|
case "relation": {
|
@@ -238,23 +252,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
238
252
|
}
|
239
253
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
240
254
|
if (isVisible2) {
|
241
|
-
acc[attributeName] = {
|
255
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
242
256
|
}
|
243
257
|
break;
|
244
258
|
}
|
245
259
|
case "media": {
|
246
|
-
acc[attributeName] = {
|
260
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
247
261
|
break;
|
248
262
|
}
|
249
263
|
case "component": {
|
250
264
|
const populate = getDeepPopulate2(attribute.component);
|
251
|
-
acc[attributeName] = {
|
265
|
+
acc[attributeName] = {
|
266
|
+
populate,
|
267
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
268
|
+
};
|
252
269
|
break;
|
253
270
|
}
|
254
271
|
case "dynamiczone": {
|
255
272
|
const populatedComponents = (attribute.components || []).reduce(
|
256
273
|
(acc2, componentUID) => {
|
257
|
-
acc2[componentUID] = {
|
274
|
+
acc2[componentUID] = {
|
275
|
+
populate: getDeepPopulate2(componentUID),
|
276
|
+
[fieldSelector]: getComponentFields(componentUID)
|
277
|
+
};
|
258
278
|
return acc2;
|
259
279
|
},
|
260
280
|
{}
|
@@ -316,6 +336,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
316
336
|
getRelationRestoreValue,
|
317
337
|
getMediaRestoreValue,
|
318
338
|
getDefaultLocale,
|
339
|
+
isLocalizedContentType,
|
319
340
|
getLocaleDictionary,
|
320
341
|
getRetentionDays,
|
321
342
|
getVersionStatus,
|
@@ -338,7 +359,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
338
359
|
});
|
339
360
|
},
|
340
361
|
async findVersionsPage(params) {
|
341
|
-
const
|
362
|
+
const model = strapi2.getModel(params.query.contentType);
|
363
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
364
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
365
|
+
let locale = null;
|
366
|
+
if (isLocalizedContentType) {
|
367
|
+
locale = params.query.locale || defaultLocale;
|
368
|
+
}
|
342
369
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
343
370
|
query.findPage({
|
344
371
|
...params.query,
|
@@ -360,7 +387,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
360
387
|
const attributeValue = entry.data[attributeKey];
|
361
388
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
362
389
|
if (attributeSchema.type === "media") {
|
363
|
-
const permissionChecker2 = getService$
|
390
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
364
391
|
userAbility: params.state.userAbility,
|
365
392
|
model: "plugin::upload.file"
|
366
393
|
});
|
@@ -383,7 +410,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
383
410
|
if (userToPopulate == null) {
|
384
411
|
return null;
|
385
412
|
}
|
386
|
-
return strapi2.query("admin::user").findOne({
|
413
|
+
return strapi2.query("admin::user").findOne({
|
414
|
+
where: {
|
415
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
416
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
417
|
+
}
|
418
|
+
});
|
387
419
|
})
|
388
420
|
);
|
389
421
|
return {
|
@@ -396,7 +428,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
396
428
|
[attributeKey]: adminUsers
|
397
429
|
};
|
398
430
|
}
|
399
|
-
const permissionChecker2 = getService$
|
431
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
400
432
|
userAbility: params.state.userAbility,
|
401
433
|
model: attributeSchema.target
|
402
434
|
});
|
@@ -494,6 +526,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
494
526
|
}
|
495
527
|
};
|
496
528
|
};
|
529
|
+
const shouldCreateHistoryVersion = (context) => {
|
530
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
540
|
+
return false;
|
541
|
+
}
|
542
|
+
return true;
|
543
|
+
};
|
544
|
+
const getSchemas = (uid2) => {
|
545
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
546
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
547
|
+
(currentComponentSchemas, key) => {
|
548
|
+
const fieldSchema = attributesSchema[key];
|
549
|
+
if (fieldSchema.type === "component") {
|
550
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
551
|
+
return {
|
552
|
+
...currentComponentSchemas,
|
553
|
+
[fieldSchema.component]: componentSchema
|
554
|
+
};
|
555
|
+
}
|
556
|
+
return currentComponentSchemas;
|
557
|
+
},
|
558
|
+
{}
|
559
|
+
);
|
560
|
+
return {
|
561
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
562
|
+
componentsSchemas
|
563
|
+
};
|
564
|
+
};
|
497
565
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
498
566
|
const state = {
|
499
567
|
deleteExpiredJob: null,
|
@@ -506,76 +574,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
506
574
|
return;
|
507
575
|
}
|
508
576
|
strapi2.documents.use(async (context, next) => {
|
509
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
510
|
-
return next();
|
511
|
-
}
|
512
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
513
|
-
return next();
|
514
|
-
}
|
515
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
516
|
-
return next();
|
517
|
-
}
|
518
|
-
const contentTypeUid = context.contentType.uid;
|
519
|
-
if (!contentTypeUid.startsWith("api::")) {
|
520
|
-
return next();
|
521
|
-
}
|
522
577
|
const result = await next();
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
578
|
+
if (!shouldCreateHistoryVersion(context)) {
|
579
|
+
return result;
|
580
|
+
}
|
581
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
527
582
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
528
|
-
const
|
529
|
-
if (
|
530
|
-
|
531
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
532
|
-
);
|
533
|
-
return next();
|
583
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
584
|
+
if (!locales.length) {
|
585
|
+
return result;
|
534
586
|
}
|
535
|
-
const
|
536
|
-
|
537
|
-
|
538
|
-
|
587
|
+
const uid2 = context.contentType.uid;
|
588
|
+
const schemas = getSchemas(uid2);
|
589
|
+
const model = strapi2.getModel(uid2);
|
590
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
591
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
592
|
+
where: {
|
593
|
+
documentId,
|
594
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
595
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
596
|
+
},
|
597
|
+
populate: serviceUtils.getDeepPopulate(
|
598
|
+
uid2,
|
599
|
+
true
|
600
|
+
/* use database syntax */
|
601
|
+
)
|
539
602
|
});
|
540
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
541
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
542
|
-
const componentsSchemas = Object.keys(
|
543
|
-
attributesSchema
|
544
|
-
).reduce((currentComponentSchemas, key) => {
|
545
|
-
const fieldSchema = attributesSchema[key];
|
546
|
-
if (fieldSchema.type === "component") {
|
547
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
548
|
-
return {
|
549
|
-
...currentComponentSchemas,
|
550
|
-
[fieldSchema.component]: componentSchema
|
551
|
-
};
|
552
|
-
}
|
553
|
-
return currentComponentSchemas;
|
554
|
-
}, {});
|
555
603
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
556
|
-
onCommit(() => {
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
604
|
+
onCommit(async () => {
|
605
|
+
for (const entry of localeEntries) {
|
606
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
607
|
+
await getService$1(strapi2, "history").createVersion({
|
608
|
+
contentType: uid2,
|
609
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
610
|
+
relatedDocumentId: documentId,
|
611
|
+
locale: entry.locale,
|
612
|
+
status,
|
613
|
+
...schemas
|
614
|
+
});
|
615
|
+
}
|
566
616
|
});
|
567
617
|
});
|
568
618
|
return result;
|
569
619
|
});
|
570
|
-
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
620
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
571
621
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
572
622
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
573
623
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
574
624
|
where: {
|
575
625
|
created_at: {
|
576
|
-
$lt: expirationDate
|
626
|
+
$lt: expirationDate
|
577
627
|
}
|
578
628
|
}
|
629
|
+
}).catch((error) => {
|
630
|
+
if (error instanceof Error) {
|
631
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
632
|
+
}
|
579
633
|
});
|
580
634
|
});
|
581
635
|
state.isInitialized = true;
|
@@ -587,17 +641,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
587
641
|
}
|
588
642
|
};
|
589
643
|
};
|
590
|
-
const services$
|
644
|
+
const services$2 = {
|
591
645
|
history: createHistoryService,
|
592
646
|
lifecycles: createLifecyclesService
|
593
647
|
};
|
594
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
648
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
595
649
|
const historyVersionRouter = {
|
596
650
|
type: "admin",
|
597
651
|
routes: [
|
598
652
|
{
|
599
653
|
method: "GET",
|
600
|
-
info,
|
654
|
+
info: info$1,
|
601
655
|
path: "/history-versions",
|
602
656
|
handler: "history-version.findMany",
|
603
657
|
config: {
|
@@ -606,7 +660,7 @@ const historyVersionRouter = {
|
|
606
660
|
},
|
607
661
|
{
|
608
662
|
method: "PUT",
|
609
|
-
info,
|
663
|
+
info: info$1,
|
610
664
|
path: "/history-versions/:versionId/restore",
|
611
665
|
handler: "history-version.restoreVersion",
|
612
666
|
config: {
|
@@ -615,7 +669,7 @@ const historyVersionRouter = {
|
|
615
669
|
}
|
616
670
|
]
|
617
671
|
};
|
618
|
-
const routes$
|
672
|
+
const routes$2 = {
|
619
673
|
"history-version": historyVersionRouter
|
620
674
|
};
|
621
675
|
const historyVersion = {
|
@@ -662,21 +716,21 @@ const historyVersion = {
|
|
662
716
|
}
|
663
717
|
}
|
664
718
|
};
|
665
|
-
const getFeature = () => {
|
719
|
+
const getFeature$1 = () => {
|
666
720
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
667
721
|
return {
|
668
722
|
register({ strapi: strapi2 }) {
|
669
723
|
strapi2.get("models").add(historyVersion);
|
670
724
|
},
|
671
725
|
bootstrap({ strapi: strapi2 }) {
|
672
|
-
getService(strapi2, "lifecycles").bootstrap();
|
726
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
673
727
|
},
|
674
728
|
destroy({ strapi: strapi2 }) {
|
675
|
-
getService(strapi2, "lifecycles").destroy();
|
729
|
+
getService$1(strapi2, "lifecycles").destroy();
|
676
730
|
},
|
677
|
-
controllers: controllers$
|
678
|
-
services: services$
|
679
|
-
routes: routes$
|
731
|
+
controllers: controllers$2,
|
732
|
+
services: services$2,
|
733
|
+
routes: routes$2
|
680
734
|
};
|
681
735
|
}
|
682
736
|
return {
|
@@ -685,9 +739,205 @@ const getFeature = () => {
|
|
685
739
|
}
|
686
740
|
};
|
687
741
|
};
|
688
|
-
const history = getFeature();
|
742
|
+
const history = getFeature$1();
|
743
|
+
const FEATURE_ID = "preview";
|
744
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
745
|
+
const previewRouter = {
|
746
|
+
type: "admin",
|
747
|
+
routes: [
|
748
|
+
{
|
749
|
+
method: "GET",
|
750
|
+
info,
|
751
|
+
path: "/preview/url/:contentType",
|
752
|
+
handler: "preview.getPreviewUrl",
|
753
|
+
config: {
|
754
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
755
|
+
}
|
756
|
+
}
|
757
|
+
]
|
758
|
+
};
|
759
|
+
const routes$1 = {
|
760
|
+
preview: previewRouter
|
761
|
+
};
|
762
|
+
function getService(strapi2, name) {
|
763
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
764
|
+
}
|
765
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
766
|
+
// Will be undefined for single types
|
767
|
+
documentId: yup__namespace.string(),
|
768
|
+
locale: yup__namespace.string().nullable(),
|
769
|
+
status: yup__namespace.string()
|
770
|
+
}).required();
|
771
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
772
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
773
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
774
|
+
const model = strapi2.getModel(uid2);
|
775
|
+
if (!model || model.modelType !== "contentType") {
|
776
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
777
|
+
}
|
778
|
+
const isSingleType = model?.kind === "singleType";
|
779
|
+
if (!isSingleType && !params.documentId) {
|
780
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
781
|
+
}
|
782
|
+
if (isSingleType) {
|
783
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
784
|
+
if (!doc) {
|
785
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
786
|
+
}
|
787
|
+
newParams.documentId = doc?.documentId;
|
788
|
+
}
|
789
|
+
if (!newParams.status) {
|
790
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
791
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
792
|
+
}
|
793
|
+
return newParams;
|
794
|
+
};
|
795
|
+
const createPreviewController = () => {
|
796
|
+
return {
|
797
|
+
/**
|
798
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
799
|
+
* in the Content Manager.
|
800
|
+
*/
|
801
|
+
async getPreviewUrl(ctx) {
|
802
|
+
const uid2 = ctx.params.contentType;
|
803
|
+
const query = ctx.request.query;
|
804
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
805
|
+
const previewService = getService(strapi, "preview");
|
806
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
807
|
+
if (!url) {
|
808
|
+
ctx.status = 204;
|
809
|
+
}
|
810
|
+
return {
|
811
|
+
data: { url }
|
812
|
+
};
|
813
|
+
}
|
814
|
+
};
|
815
|
+
};
|
816
|
+
const controllers$1 = {
|
817
|
+
preview: createPreviewController
|
818
|
+
/**
|
819
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
820
|
+
* passing a controller factory as the value, instead of a controller object directly
|
821
|
+
*/
|
822
|
+
};
|
823
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
824
|
+
const config = getService(strapi2, "preview-config");
|
825
|
+
return {
|
826
|
+
async getPreviewUrl(uid2, params) {
|
827
|
+
const handler = config.getPreviewHandler();
|
828
|
+
try {
|
829
|
+
return handler(uid2, params);
|
830
|
+
} catch (error) {
|
831
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
832
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
833
|
+
}
|
834
|
+
return;
|
835
|
+
}
|
836
|
+
};
|
837
|
+
};
|
838
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
839
|
+
const middlewares = strapi.config.get("middlewares");
|
840
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
841
|
+
if (currentMiddleware === middleware.name) {
|
842
|
+
return middleware;
|
843
|
+
}
|
844
|
+
if (currentMiddleware.name === middleware.name) {
|
845
|
+
return fp.mergeWith(
|
846
|
+
(objValue, srcValue) => {
|
847
|
+
if (Array.isArray(objValue)) {
|
848
|
+
return objValue.concat(srcValue);
|
849
|
+
}
|
850
|
+
return void 0;
|
851
|
+
},
|
852
|
+
currentMiddleware,
|
853
|
+
middleware
|
854
|
+
);
|
855
|
+
}
|
856
|
+
return currentMiddleware;
|
857
|
+
});
|
858
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
859
|
+
};
|
860
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
861
|
+
return {
|
862
|
+
register() {
|
863
|
+
if (!this.isEnabled()) {
|
864
|
+
return;
|
865
|
+
}
|
866
|
+
const config = strapi2.config.get("admin.preview");
|
867
|
+
if (config.config?.allowedOrigins) {
|
868
|
+
extendMiddlewareConfiguration({
|
869
|
+
name: "strapi::security",
|
870
|
+
config: {
|
871
|
+
contentSecurityPolicy: {
|
872
|
+
directives: {
|
873
|
+
"frame-src": config.config.allowedOrigins
|
874
|
+
}
|
875
|
+
}
|
876
|
+
}
|
877
|
+
});
|
878
|
+
}
|
879
|
+
},
|
880
|
+
isEnabled() {
|
881
|
+
const config = strapi2.config.get("admin.preview");
|
882
|
+
if (!config) {
|
883
|
+
return false;
|
884
|
+
}
|
885
|
+
return config?.enabled ?? true;
|
886
|
+
},
|
887
|
+
/**
|
888
|
+
* Validate if the configuration is valid
|
889
|
+
*/
|
890
|
+
validate() {
|
891
|
+
if (!this.isEnabled()) {
|
892
|
+
return;
|
893
|
+
}
|
894
|
+
const handler = this.getPreviewHandler();
|
895
|
+
if (typeof handler !== "function") {
|
896
|
+
throw new strapiUtils.errors.ValidationError(
|
897
|
+
"Preview configuration is invalid. Handler must be a function"
|
898
|
+
);
|
899
|
+
}
|
900
|
+
},
|
901
|
+
/**
|
902
|
+
* Utility to get the preview handler from the configuration
|
903
|
+
*/
|
904
|
+
getPreviewHandler() {
|
905
|
+
const config = strapi2.config.get("admin.preview");
|
906
|
+
const emptyHandler = () => {
|
907
|
+
return void 0;
|
908
|
+
};
|
909
|
+
if (!this.isEnabled()) {
|
910
|
+
return emptyHandler;
|
911
|
+
}
|
912
|
+
return config?.config?.handler || emptyHandler;
|
913
|
+
}
|
914
|
+
};
|
915
|
+
};
|
916
|
+
const services$1 = {
|
917
|
+
preview: createPreviewService,
|
918
|
+
"preview-config": createPreviewConfigService
|
919
|
+
};
|
920
|
+
const getFeature = () => {
|
921
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
922
|
+
return {};
|
923
|
+
}
|
924
|
+
return {
|
925
|
+
register() {
|
926
|
+
const config = getService(strapi, "preview-config");
|
927
|
+
config.validate();
|
928
|
+
config.register();
|
929
|
+
},
|
930
|
+
bootstrap() {
|
931
|
+
},
|
932
|
+
routes: routes$1,
|
933
|
+
controllers: controllers$1,
|
934
|
+
services: services$1
|
935
|
+
};
|
936
|
+
};
|
937
|
+
const preview = getFeature();
|
689
938
|
const register = async ({ strapi: strapi2 }) => {
|
690
939
|
await history.register?.({ strapi: strapi2 });
|
940
|
+
await preview.register?.({ strapi: strapi2 });
|
691
941
|
};
|
692
942
|
const ALLOWED_WEBHOOK_EVENTS = {
|
693
943
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -697,11 +947,12 @@ const bootstrap = async () => {
|
|
697
947
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
698
948
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
699
949
|
});
|
700
|
-
getService$
|
701
|
-
await getService$
|
702
|
-
await getService$
|
703
|
-
await getService$
|
950
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
951
|
+
await getService$2("components").syncConfigurations();
|
952
|
+
await getService$2("content-types").syncConfigurations();
|
953
|
+
await getService$2("permission").registerPermissions();
|
704
954
|
await history.bootstrap?.({ strapi });
|
955
|
+
await preview.bootstrap?.({ strapi });
|
705
956
|
};
|
706
957
|
const destroy = async ({ strapi: strapi2 }) => {
|
707
958
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1191,7 +1442,8 @@ const admin = {
|
|
1191
1442
|
};
|
1192
1443
|
const routes = {
|
1193
1444
|
admin,
|
1194
|
-
...history.routes ? history.routes : {}
|
1445
|
+
...history.routes ? history.routes : {},
|
1446
|
+
...preview.routes ? preview.routes : {}
|
1195
1447
|
};
|
1196
1448
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1197
1449
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1202,6 +1454,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1202
1454
|
const hasPermissions = createPolicy({
|
1203
1455
|
name: "plugin::content-manager.hasPermissions",
|
1204
1456
|
validator: validateHasPermissionsInput,
|
1457
|
+
/**
|
1458
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1459
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1460
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1461
|
+
*/
|
1205
1462
|
handler(ctx, config = {}) {
|
1206
1463
|
const { actions = [], hasAtLeastOne = false } = config;
|
1207
1464
|
const { userAbility } = ctx.state;
|
@@ -1443,7 +1700,7 @@ const createMetadasSchema = (schema) => {
|
|
1443
1700
|
if (!value) {
|
1444
1701
|
return strapiUtils.yup.string();
|
1445
1702
|
}
|
1446
|
-
const targetSchema = getService$
|
1703
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1447
1704
|
schema.attributes[key].targetModel
|
1448
1705
|
);
|
1449
1706
|
if (!targetSchema) {
|
@@ -1595,9 +1852,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1595
1852
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1596
1853
|
);
|
1597
1854
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1598
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1855
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1599
1856
|
const { allowMultipleLocales } = opts;
|
1600
|
-
const { locale, status, ...rest } = request || {};
|
1857
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1858
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1859
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1601
1860
|
const schema = strapiUtils.yup.object().shape({
|
1602
1861
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1603
1862
|
status: statusSchema
|
@@ -1610,7 +1869,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1610
1869
|
}
|
1611
1870
|
};
|
1612
1871
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1613
|
-
const documentMetadata2 = getService$
|
1872
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1614
1873
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1615
1874
|
let {
|
1616
1875
|
meta: { availableLocales, availableStatus }
|
@@ -1636,8 +1895,8 @@ const createDocument = async (ctx, opts) => {
|
|
1636
1895
|
const { userAbility, user } = ctx.state;
|
1637
1896
|
const { model } = ctx.params;
|
1638
1897
|
const { body } = ctx.request;
|
1639
|
-
const documentManager2 = getService$
|
1640
|
-
const permissionChecker2 = getService$
|
1898
|
+
const documentManager2 = getService$2("document-manager");
|
1899
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1641
1900
|
if (permissionChecker2.cannot.create()) {
|
1642
1901
|
throw new strapiUtils.errors.ForbiddenError();
|
1643
1902
|
}
|
@@ -1645,7 +1904,7 @@ const createDocument = async (ctx, opts) => {
|
|
1645
1904
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1646
1905
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1647
1906
|
const sanitizedBody = await sanitizeFn(body);
|
1648
|
-
const { locale, status
|
1907
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1649
1908
|
return documentManager2.create(model, {
|
1650
1909
|
data: sanitizedBody,
|
1651
1910
|
locale,
|
@@ -1657,14 +1916,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1657
1916
|
const { userAbility, user } = ctx.state;
|
1658
1917
|
const { id, model } = ctx.params;
|
1659
1918
|
const { body } = ctx.request;
|
1660
|
-
const documentManager2 = getService$
|
1661
|
-
const permissionChecker2 = getService$
|
1919
|
+
const documentManager2 = getService$2("document-manager");
|
1920
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1662
1921
|
if (permissionChecker2.cannot.update()) {
|
1663
1922
|
throw new strapiUtils.errors.ForbiddenError();
|
1664
1923
|
}
|
1665
1924
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1666
|
-
const populate = await getService$
|
1667
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1925
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1926
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1668
1927
|
const [documentVersion, documentExists] = await Promise.all([
|
1669
1928
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1670
1929
|
documentManager2.exists(model, id)
|
@@ -1680,7 +1939,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1680
1939
|
throw new strapiUtils.errors.ForbiddenError();
|
1681
1940
|
}
|
1682
1941
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1683
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1942
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1684
1943
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1685
1944
|
const sanitizedBody = await sanitizeFn(body);
|
1686
1945
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1694,15 +1953,15 @@ const collectionTypes = {
|
|
1694
1953
|
const { userAbility } = ctx.state;
|
1695
1954
|
const { model } = ctx.params;
|
1696
1955
|
const { query } = ctx.request;
|
1697
|
-
const documentMetadata2 = getService$
|
1698
|
-
const documentManager2 = getService$
|
1699
|
-
const permissionChecker2 = getService$
|
1956
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1957
|
+
const documentManager2 = getService$2("document-manager");
|
1958
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1700
1959
|
if (permissionChecker2.cannot.read()) {
|
1701
1960
|
return ctx.forbidden();
|
1702
1961
|
}
|
1703
1962
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1704
|
-
const populate = await getService$
|
1705
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1963
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1964
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1706
1965
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1707
1966
|
{ ...permissionQuery, populate, locale, status },
|
1708
1967
|
model
|
@@ -1730,14 +1989,14 @@ const collectionTypes = {
|
|
1730
1989
|
async findOne(ctx) {
|
1731
1990
|
const { userAbility } = ctx.state;
|
1732
1991
|
const { model, id } = ctx.params;
|
1733
|
-
const documentManager2 = getService$
|
1734
|
-
const permissionChecker2 = getService$
|
1992
|
+
const documentManager2 = getService$2("document-manager");
|
1993
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1735
1994
|
if (permissionChecker2.cannot.read()) {
|
1736
1995
|
return ctx.forbidden();
|
1737
1996
|
}
|
1738
1997
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1739
|
-
const populate = await getService$
|
1740
|
-
const { locale, status
|
1998
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1999
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1741
2000
|
const version = await documentManager2.findOne(id, model, {
|
1742
2001
|
populate,
|
1743
2002
|
locale,
|
@@ -1752,7 +2011,7 @@ const collectionTypes = {
|
|
1752
2011
|
permissionChecker2,
|
1753
2012
|
model,
|
1754
2013
|
// @ts-expect-error TODO: fix
|
1755
|
-
{ id, locale, publishedAt: null },
|
2014
|
+
{ documentId: id, locale, publishedAt: null },
|
1756
2015
|
{ availableLocales: true, availableStatus: false }
|
1757
2016
|
);
|
1758
2017
|
ctx.body = { data: {}, meta };
|
@@ -1767,7 +2026,7 @@ const collectionTypes = {
|
|
1767
2026
|
async create(ctx) {
|
1768
2027
|
const { userAbility } = ctx.state;
|
1769
2028
|
const { model } = ctx.params;
|
1770
|
-
const permissionChecker2 = getService$
|
2029
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1771
2030
|
const [totalEntries, document] = await Promise.all([
|
1772
2031
|
strapi.db.query(model).count(),
|
1773
2032
|
createDocument(ctx)
|
@@ -1788,7 +2047,7 @@ const collectionTypes = {
|
|
1788
2047
|
async update(ctx) {
|
1789
2048
|
const { userAbility } = ctx.state;
|
1790
2049
|
const { model } = ctx.params;
|
1791
|
-
const permissionChecker2 = getService$
|
2050
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1792
2051
|
const updatedVersion = await updateDocument(ctx);
|
1793
2052
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1794
2053
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1797,14 +2056,14 @@ const collectionTypes = {
|
|
1797
2056
|
const { userAbility, user } = ctx.state;
|
1798
2057
|
const { model, sourceId: id } = ctx.params;
|
1799
2058
|
const { body } = ctx.request;
|
1800
|
-
const documentManager2 = getService$
|
1801
|
-
const permissionChecker2 = getService$
|
2059
|
+
const documentManager2 = getService$2("document-manager");
|
2060
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1802
2061
|
if (permissionChecker2.cannot.create()) {
|
1803
2062
|
return ctx.forbidden();
|
1804
2063
|
}
|
1805
2064
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1806
|
-
const populate = await getService$
|
1807
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2065
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2066
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1808
2067
|
const document = await documentManager2.findOne(id, model, {
|
1809
2068
|
populate,
|
1810
2069
|
locale,
|
@@ -1842,14 +2101,14 @@ const collectionTypes = {
|
|
1842
2101
|
async delete(ctx) {
|
1843
2102
|
const { userAbility } = ctx.state;
|
1844
2103
|
const { id, model } = ctx.params;
|
1845
|
-
const documentManager2 = getService$
|
1846
|
-
const permissionChecker2 = getService$
|
2104
|
+
const documentManager2 = getService$2("document-manager");
|
2105
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1847
2106
|
if (permissionChecker2.cannot.delete()) {
|
1848
2107
|
return ctx.forbidden();
|
1849
2108
|
}
|
1850
2109
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1851
|
-
const populate = await getService$
|
1852
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2110
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2111
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1853
2112
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1854
2113
|
if (documentLocales.length === 0) {
|
1855
2114
|
return ctx.notFound();
|
@@ -1870,19 +2129,42 @@ const collectionTypes = {
|
|
1870
2129
|
const { userAbility } = ctx.state;
|
1871
2130
|
const { id, model } = ctx.params;
|
1872
2131
|
const { body } = ctx.request;
|
1873
|
-
const documentManager2 = getService$
|
1874
|
-
const permissionChecker2 = getService$
|
2132
|
+
const documentManager2 = getService$2("document-manager");
|
2133
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1875
2134
|
if (permissionChecker2.cannot.publish()) {
|
1876
2135
|
return ctx.forbidden();
|
1877
2136
|
}
|
1878
2137
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1879
2138
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1880
|
-
const populate = await getService$
|
1881
|
-
|
2139
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2140
|
+
let document;
|
2141
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2142
|
+
const isCreate = fp.isNil(id);
|
2143
|
+
if (isCreate) {
|
2144
|
+
if (permissionChecker2.cannot.create()) {
|
2145
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2146
|
+
}
|
2147
|
+
document = await createDocument(ctx, { populate });
|
2148
|
+
}
|
2149
|
+
const isUpdate = !isCreate;
|
2150
|
+
if (isUpdate) {
|
2151
|
+
const documentExists = documentManager2.exists(model, id);
|
2152
|
+
if (!documentExists) {
|
2153
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2154
|
+
}
|
2155
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2156
|
+
if (!document) {
|
2157
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2158
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2159
|
+
}
|
2160
|
+
document = await updateDocument(ctx);
|
2161
|
+
} else if (permissionChecker2.can.update(document)) {
|
2162
|
+
await updateDocument(ctx);
|
2163
|
+
}
|
2164
|
+
}
|
1882
2165
|
if (permissionChecker2.cannot.publish(document)) {
|
1883
2166
|
throw new strapiUtils.errors.ForbiddenError();
|
1884
2167
|
}
|
1885
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1886
2168
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1887
2169
|
locale
|
1888
2170
|
// TODO: Allow setting creator fields on publish
|
@@ -1902,14 +2184,16 @@ const collectionTypes = {
|
|
1902
2184
|
const { body } = ctx.request;
|
1903
2185
|
const { documentIds } = body;
|
1904
2186
|
await validateBulkActionInput(body);
|
1905
|
-
const documentManager2 = getService$
|
1906
|
-
const permissionChecker2 = getService$
|
2187
|
+
const documentManager2 = getService$2("document-manager");
|
2188
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1907
2189
|
if (permissionChecker2.cannot.publish()) {
|
1908
2190
|
return ctx.forbidden();
|
1909
2191
|
}
|
1910
2192
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1911
|
-
const populate = await getService$
|
1912
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2193
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2194
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2195
|
+
allowMultipleLocales: true
|
2196
|
+
});
|
1913
2197
|
const entityPromises = documentIds.map(
|
1914
2198
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1915
2199
|
);
|
@@ -1931,12 +2215,14 @@ const collectionTypes = {
|
|
1931
2215
|
const { body } = ctx.request;
|
1932
2216
|
const { documentIds } = body;
|
1933
2217
|
await validateBulkActionInput(body);
|
1934
|
-
const documentManager2 = getService$
|
1935
|
-
const permissionChecker2 = getService$
|
2218
|
+
const documentManager2 = getService$2("document-manager");
|
2219
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1936
2220
|
if (permissionChecker2.cannot.unpublish()) {
|
1937
2221
|
return ctx.forbidden();
|
1938
2222
|
}
|
1939
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2223
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2224
|
+
allowMultipleLocales: true
|
2225
|
+
});
|
1940
2226
|
const entityPromises = documentIds.map(
|
1941
2227
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1942
2228
|
);
|
@@ -1959,8 +2245,8 @@ const collectionTypes = {
|
|
1959
2245
|
const {
|
1960
2246
|
body: { discardDraft, ...body }
|
1961
2247
|
} = ctx.request;
|
1962
|
-
const documentManager2 = getService$
|
1963
|
-
const permissionChecker2 = getService$
|
2248
|
+
const documentManager2 = getService$2("document-manager");
|
2249
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1964
2250
|
if (permissionChecker2.cannot.unpublish()) {
|
1965
2251
|
return ctx.forbidden();
|
1966
2252
|
}
|
@@ -1968,8 +2254,8 @@ const collectionTypes = {
|
|
1968
2254
|
return ctx.forbidden();
|
1969
2255
|
}
|
1970
2256
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1971
|
-
const populate = await getService$
|
1972
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2257
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2258
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1973
2259
|
const document = await documentManager2.findOne(id, model, {
|
1974
2260
|
populate,
|
1975
2261
|
locale,
|
@@ -1999,14 +2285,14 @@ const collectionTypes = {
|
|
1999
2285
|
const { userAbility } = ctx.state;
|
2000
2286
|
const { id, model } = ctx.params;
|
2001
2287
|
const { body } = ctx.request;
|
2002
|
-
const documentManager2 = getService$
|
2003
|
-
const permissionChecker2 = getService$
|
2288
|
+
const documentManager2 = getService$2("document-manager");
|
2289
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2004
2290
|
if (permissionChecker2.cannot.discard()) {
|
2005
2291
|
return ctx.forbidden();
|
2006
2292
|
}
|
2007
2293
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2008
|
-
const populate = await getService$
|
2009
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2294
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2295
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2010
2296
|
const document = await documentManager2.findOne(id, model, {
|
2011
2297
|
populate,
|
2012
2298
|
locale,
|
@@ -2030,14 +2316,14 @@ const collectionTypes = {
|
|
2030
2316
|
const { query, body } = ctx.request;
|
2031
2317
|
const { documentIds } = body;
|
2032
2318
|
await validateBulkActionInput(body);
|
2033
|
-
const documentManager2 = getService$
|
2034
|
-
const permissionChecker2 = getService$
|
2319
|
+
const documentManager2 = getService$2("document-manager");
|
2320
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2035
2321
|
if (permissionChecker2.cannot.delete()) {
|
2036
2322
|
return ctx.forbidden();
|
2037
2323
|
}
|
2038
2324
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2039
|
-
const populate = await getService$
|
2040
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2325
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2326
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2041
2327
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2042
2328
|
populate,
|
2043
2329
|
locale
|
@@ -2057,14 +2343,14 @@ const collectionTypes = {
|
|
2057
2343
|
async countDraftRelations(ctx) {
|
2058
2344
|
const { userAbility } = ctx.state;
|
2059
2345
|
const { model, id } = ctx.params;
|
2060
|
-
const documentManager2 = getService$
|
2061
|
-
const permissionChecker2 = getService$
|
2346
|
+
const documentManager2 = getService$2("document-manager");
|
2347
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2062
2348
|
if (permissionChecker2.cannot.read()) {
|
2063
2349
|
return ctx.forbidden();
|
2064
2350
|
}
|
2065
2351
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2066
|
-
const populate = await getService$
|
2067
|
-
const { locale, status
|
2352
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2353
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2068
2354
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2069
2355
|
if (!entity) {
|
2070
2356
|
return ctx.notFound();
|
@@ -2082,8 +2368,8 @@ const collectionTypes = {
|
|
2082
2368
|
const ids = ctx.request.query.documentIds;
|
2083
2369
|
const locale = ctx.request.query.locale;
|
2084
2370
|
const { model } = ctx.params;
|
2085
|
-
const documentManager2 = getService$
|
2086
|
-
const permissionChecker2 = getService$
|
2371
|
+
const documentManager2 = getService$2("document-manager");
|
2372
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2087
2373
|
if (permissionChecker2.cannot.read()) {
|
2088
2374
|
return ctx.forbidden();
|
2089
2375
|
}
|
@@ -2107,13 +2393,13 @@ const collectionTypes = {
|
|
2107
2393
|
};
|
2108
2394
|
const components$1 = {
|
2109
2395
|
findComponents(ctx) {
|
2110
|
-
const components2 = getService$
|
2111
|
-
const { toDto } = getService$
|
2396
|
+
const components2 = getService$2("components").findAllComponents();
|
2397
|
+
const { toDto } = getService$2("data-mapper");
|
2112
2398
|
ctx.body = { data: components2.map(toDto) };
|
2113
2399
|
},
|
2114
2400
|
async findComponentConfiguration(ctx) {
|
2115
2401
|
const { uid: uid2 } = ctx.params;
|
2116
|
-
const componentService = getService$
|
2402
|
+
const componentService = getService$2("components");
|
2117
2403
|
const component = componentService.findComponent(uid2);
|
2118
2404
|
if (!component) {
|
2119
2405
|
return ctx.notFound("component.notFound");
|
@@ -2130,7 +2416,7 @@ const components$1 = {
|
|
2130
2416
|
async updateComponentConfiguration(ctx) {
|
2131
2417
|
const { uid: uid2 } = ctx.params;
|
2132
2418
|
const { body } = ctx.request;
|
2133
|
-
const componentService = getService$
|
2419
|
+
const componentService = getService$2("components");
|
2134
2420
|
const component = componentService.findComponent(uid2);
|
2135
2421
|
if (!component) {
|
2136
2422
|
return ctx.notFound("component.notFound");
|
@@ -2164,12 +2450,12 @@ const contentTypes = {
|
|
2164
2450
|
} catch (error) {
|
2165
2451
|
return ctx.send({ error }, 400);
|
2166
2452
|
}
|
2167
|
-
const contentTypes2 = getService$
|
2168
|
-
const { toDto } = getService$
|
2453
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2454
|
+
const { toDto } = getService$2("data-mapper");
|
2169
2455
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2170
2456
|
},
|
2171
2457
|
async findContentTypesSettings(ctx) {
|
2172
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2458
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2173
2459
|
const contentTypes2 = await findAllContentTypes();
|
2174
2460
|
const configurations = await Promise.all(
|
2175
2461
|
contentTypes2.map(async (contentType) => {
|
@@ -2183,7 +2469,7 @@ const contentTypes = {
|
|
2183
2469
|
},
|
2184
2470
|
async findContentTypeConfiguration(ctx) {
|
2185
2471
|
const { uid: uid2 } = ctx.params;
|
2186
|
-
const contentTypeService = getService$
|
2472
|
+
const contentTypeService = getService$2("content-types");
|
2187
2473
|
const contentType = await contentTypeService.findContentType(uid2);
|
2188
2474
|
if (!contentType) {
|
2189
2475
|
return ctx.notFound("contentType.notFound");
|
@@ -2205,13 +2491,13 @@ const contentTypes = {
|
|
2205
2491
|
const { userAbility } = ctx.state;
|
2206
2492
|
const { uid: uid2 } = ctx.params;
|
2207
2493
|
const { body } = ctx.request;
|
2208
|
-
const contentTypeService = getService$
|
2209
|
-
const metricsService = getService$
|
2494
|
+
const contentTypeService = getService$2("content-types");
|
2495
|
+
const metricsService = getService$2("metrics");
|
2210
2496
|
const contentType = await contentTypeService.findContentType(uid2);
|
2211
2497
|
if (!contentType) {
|
2212
2498
|
return ctx.notFound("contentType.notFound");
|
2213
2499
|
}
|
2214
|
-
if (!getService$
|
2500
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2215
2501
|
return ctx.forbidden();
|
2216
2502
|
}
|
2217
2503
|
let input;
|
@@ -2244,10 +2530,10 @@ const contentTypes = {
|
|
2244
2530
|
};
|
2245
2531
|
const init = {
|
2246
2532
|
getInitData(ctx) {
|
2247
|
-
const { toDto } = getService$
|
2248
|
-
const { findAllComponents } = getService$
|
2249
|
-
const { getAllFieldSizes } = getService$
|
2250
|
-
const { findAllContentTypes } = getService$
|
2533
|
+
const { toDto } = getService$2("data-mapper");
|
2534
|
+
const { findAllComponents } = getService$2("components");
|
2535
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2536
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2251
2537
|
ctx.body = {
|
2252
2538
|
data: {
|
2253
2539
|
fieldSizes: getAllFieldSizes(),
|
@@ -2283,36 +2569,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2283
2569
|
params.filters.$and.push(filtersClause);
|
2284
2570
|
};
|
2285
2571
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2286
|
-
const permissionChecker2 = getService$
|
2572
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2287
2573
|
userAbility,
|
2288
2574
|
model: model.uid
|
2289
2575
|
});
|
2290
|
-
|
2576
|
+
const isMainFieldListable = isListable(model, mainField);
|
2577
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2578
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2291
2579
|
return "id";
|
2292
2580
|
}
|
2293
|
-
if (
|
2294
|
-
|
2295
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2296
|
-
userAbility,
|
2297
|
-
model: "plugin::users-permissions.user"
|
2298
|
-
});
|
2299
|
-
if (userPermissionChecker.can.read()) {
|
2300
|
-
return "name";
|
2301
|
-
}
|
2302
|
-
}
|
2303
|
-
return "id";
|
2581
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2582
|
+
return "name";
|
2304
2583
|
}
|
2305
2584
|
return mainField;
|
2306
2585
|
};
|
2307
|
-
const addStatusToRelations = async (
|
2308
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2586
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2587
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2588
|
+
return relations2;
|
2589
|
+
}
|
2590
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2591
|
+
if (!relations2.length) {
|
2309
2592
|
return relations2;
|
2310
2593
|
}
|
2311
|
-
const
|
2312
|
-
const
|
2594
|
+
const firstRelation = relations2[0];
|
2595
|
+
const filters = {
|
2596
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2597
|
+
// NOTE: find the "opposite" status
|
2598
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2599
|
+
};
|
2600
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2601
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2602
|
+
filters
|
2603
|
+
});
|
2313
2604
|
return relations2.map((relation) => {
|
2314
|
-
const availableStatuses =
|
2315
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2605
|
+
const availableStatuses = availableStatus.filter(
|
2606
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2316
2607
|
);
|
2317
2608
|
return {
|
2318
2609
|
...relation,
|
@@ -2333,11 +2624,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2333
2624
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2334
2625
|
const isSourceLocalized = isLocalized(sourceModel);
|
2335
2626
|
const isTargetLocalized = isLocalized(targetModel);
|
2336
|
-
let validatedLocale = locale;
|
2337
|
-
if (!targetModel || !isTargetLocalized)
|
2338
|
-
validatedLocale = void 0;
|
2339
2627
|
return {
|
2340
|
-
locale
|
2628
|
+
locale,
|
2341
2629
|
isSourceLocalized,
|
2342
2630
|
isTargetLocalized
|
2343
2631
|
};
|
@@ -2377,7 +2665,7 @@ const relations = {
|
|
2377
2665
|
ctx.request?.query?.locale
|
2378
2666
|
);
|
2379
2667
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2380
|
-
const permissionChecker2 = getService$
|
2668
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2381
2669
|
userAbility,
|
2382
2670
|
model
|
2383
2671
|
});
|
@@ -2402,7 +2690,7 @@ const relations = {
|
|
2402
2690
|
where.id = id;
|
2403
2691
|
}
|
2404
2692
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2405
|
-
const populate = await getService$
|
2693
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2406
2694
|
const currentEntity = await strapi.db.query(model).findOne({
|
2407
2695
|
where,
|
2408
2696
|
populate
|
@@ -2417,7 +2705,7 @@ const relations = {
|
|
2417
2705
|
}
|
2418
2706
|
entryId = currentEntity.id;
|
2419
2707
|
}
|
2420
|
-
const modelConfig = isComponent2 ? await getService$
|
2708
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2421
2709
|
const targetSchema = strapi.getModel(targetUid);
|
2422
2710
|
const mainField = fp.flow(
|
2423
2711
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2440,7 +2728,7 @@ const relations = {
|
|
2440
2728
|
attribute,
|
2441
2729
|
fieldsToSelect,
|
2442
2730
|
mainField,
|
2443
|
-
source: { schema: sourceSchema },
|
2731
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2444
2732
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2445
2733
|
sourceSchema,
|
2446
2734
|
targetSchema,
|
@@ -2462,7 +2750,8 @@ const relations = {
|
|
2462
2750
|
fieldsToSelect,
|
2463
2751
|
mainField,
|
2464
2752
|
source: {
|
2465
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2753
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2754
|
+
isLocalized: isSourceLocalized
|
2466
2755
|
},
|
2467
2756
|
target: {
|
2468
2757
|
schema: { uid: targetUid },
|
@@ -2470,7 +2759,7 @@ const relations = {
|
|
2470
2759
|
}
|
2471
2760
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2472
2761
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2473
|
-
const permissionChecker2 = getService$
|
2762
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2474
2763
|
userAbility: ctx.state.userAbility,
|
2475
2764
|
model: targetUid
|
2476
2765
|
});
|
@@ -2500,12 +2789,16 @@ const relations = {
|
|
2500
2789
|
} else {
|
2501
2790
|
where.id = id;
|
2502
2791
|
}
|
2503
|
-
|
2504
|
-
|
2792
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2793
|
+
if (!fp.isEmpty(publishedAt)) {
|
2794
|
+
where[`${alias}.published_at`] = publishedAt;
|
2505
2795
|
}
|
2506
|
-
if (
|
2796
|
+
if (isTargetLocalized && locale) {
|
2507
2797
|
where[`${alias}.locale`] = locale;
|
2508
2798
|
}
|
2799
|
+
if (isSourceLocalized && locale) {
|
2800
|
+
where.locale = locale;
|
2801
|
+
}
|
2509
2802
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2510
2803
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2511
2804
|
}
|
@@ -2523,7 +2816,8 @@ const relations = {
|
|
2523
2816
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2524
2817
|
});
|
2525
2818
|
}
|
2526
|
-
const
|
2819
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2820
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2527
2821
|
ctx.body = {
|
2528
2822
|
...res,
|
2529
2823
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2538,29 +2832,39 @@ const relations = {
|
|
2538
2832
|
attribute,
|
2539
2833
|
targetField,
|
2540
2834
|
fieldsToSelect,
|
2541
|
-
|
2542
|
-
|
2543
|
-
}
|
2544
|
-
target: {
|
2545
|
-
schema: { uid: targetUid }
|
2546
|
-
}
|
2835
|
+
status,
|
2836
|
+
source: { schema: sourceSchema },
|
2837
|
+
target: { schema: targetSchema }
|
2547
2838
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2548
|
-
const
|
2839
|
+
const { uid: sourceUid } = sourceSchema;
|
2840
|
+
const { uid: targetUid } = targetSchema;
|
2841
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2549
2842
|
const dbQuery = strapi.db.query(sourceUid);
|
2550
2843
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2844
|
+
const filters = {};
|
2845
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2846
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2847
|
+
if (status === "published") {
|
2848
|
+
filters.publishedAt = { $notNull: true };
|
2849
|
+
} else {
|
2850
|
+
filters.publishedAt = { $null: true };
|
2851
|
+
}
|
2852
|
+
}
|
2853
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2854
|
+
filters.publishedAt = { $null: true };
|
2855
|
+
}
|
2551
2856
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2552
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2857
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2553
2858
|
ordering: "desc",
|
2554
2859
|
page: ctx.request.query.page,
|
2555
|
-
pageSize: ctx.request.query.pageSize
|
2860
|
+
pageSize: ctx.request.query.pageSize,
|
2861
|
+
filters
|
2556
2862
|
});
|
2557
2863
|
const loadedIds = res.results.map((item) => item.id);
|
2558
2864
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2559
2865
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2560
2866
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2561
|
-
ordering: "desc"
|
2562
|
-
page: ctx.request.query.page,
|
2563
|
-
pageSize: ctx.request.query.pageSize
|
2867
|
+
ordering: "desc"
|
2564
2868
|
});
|
2565
2869
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2566
2870
|
ctx.body = {
|
@@ -2575,10 +2879,10 @@ const relations = {
|
|
2575
2879
|
}
|
2576
2880
|
};
|
2577
2881
|
const buildPopulateFromQuery = async (query, model) => {
|
2578
|
-
return getService$
|
2882
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2579
2883
|
};
|
2580
2884
|
const findDocument = async (query, uid2, opts = {}) => {
|
2581
|
-
const documentManager2 = getService$
|
2885
|
+
const documentManager2 = getService$2("document-manager");
|
2582
2886
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2583
2887
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2584
2888
|
};
|
@@ -2586,13 +2890,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2586
2890
|
const { user, userAbility } = ctx.state;
|
2587
2891
|
const { model } = ctx.params;
|
2588
2892
|
const { body, query } = ctx.request;
|
2589
|
-
const documentManager2 = getService$
|
2590
|
-
const permissionChecker2 = getService$
|
2893
|
+
const documentManager2 = getService$2("document-manager");
|
2894
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2591
2895
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2592
2896
|
throw new strapiUtils.errors.ForbiddenError();
|
2593
2897
|
}
|
2594
2898
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2595
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2899
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2596
2900
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2597
2901
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2598
2902
|
// Find the first document to check if it exists
|
@@ -2628,12 +2932,12 @@ const singleTypes = {
|
|
2628
2932
|
const { userAbility } = ctx.state;
|
2629
2933
|
const { model } = ctx.params;
|
2630
2934
|
const { query = {} } = ctx.request;
|
2631
|
-
const permissionChecker2 = getService$
|
2935
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2632
2936
|
if (permissionChecker2.cannot.read()) {
|
2633
2937
|
return ctx.forbidden();
|
2634
2938
|
}
|
2635
2939
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2636
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2940
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2637
2941
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2638
2942
|
if (!version) {
|
2639
2943
|
if (permissionChecker2.cannot.create()) {
|
@@ -2647,7 +2951,7 @@ const singleTypes = {
|
|
2647
2951
|
permissionChecker2,
|
2648
2952
|
model,
|
2649
2953
|
// @ts-expect-error - fix types
|
2650
|
-
{
|
2954
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2651
2955
|
{ availableLocales: true, availableStatus: false }
|
2652
2956
|
);
|
2653
2957
|
ctx.body = { data: {}, meta };
|
@@ -2662,7 +2966,7 @@ const singleTypes = {
|
|
2662
2966
|
async createOrUpdate(ctx) {
|
2663
2967
|
const { userAbility } = ctx.state;
|
2664
2968
|
const { model } = ctx.params;
|
2665
|
-
const permissionChecker2 = getService$
|
2969
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2666
2970
|
const document = await createOrUpdateDocument(ctx);
|
2667
2971
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2668
2972
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2671,14 +2975,14 @@ const singleTypes = {
|
|
2671
2975
|
const { userAbility } = ctx.state;
|
2672
2976
|
const { model } = ctx.params;
|
2673
2977
|
const { query = {} } = ctx.request;
|
2674
|
-
const documentManager2 = getService$
|
2675
|
-
const permissionChecker2 = getService$
|
2978
|
+
const documentManager2 = getService$2("document-manager");
|
2979
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2676
2980
|
if (permissionChecker2.cannot.delete()) {
|
2677
2981
|
return ctx.forbidden();
|
2678
2982
|
}
|
2679
2983
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2680
2984
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2681
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2985
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2682
2986
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2683
2987
|
populate,
|
2684
2988
|
locale
|
@@ -2700,8 +3004,8 @@ const singleTypes = {
|
|
2700
3004
|
const { userAbility } = ctx.state;
|
2701
3005
|
const { model } = ctx.params;
|
2702
3006
|
const { query = {} } = ctx.request;
|
2703
|
-
const documentManager2 = getService$
|
2704
|
-
const permissionChecker2 = getService$
|
3007
|
+
const documentManager2 = getService$2("document-manager");
|
3008
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2705
3009
|
if (permissionChecker2.cannot.publish()) {
|
2706
3010
|
return ctx.forbidden();
|
2707
3011
|
}
|
@@ -2715,7 +3019,7 @@ const singleTypes = {
|
|
2715
3019
|
if (permissionChecker2.cannot.publish(document)) {
|
2716
3020
|
throw new strapiUtils.errors.ForbiddenError();
|
2717
3021
|
}
|
2718
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
3022
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2719
3023
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2720
3024
|
return publishResult.at(0);
|
2721
3025
|
});
|
@@ -2729,8 +3033,8 @@ const singleTypes = {
|
|
2729
3033
|
body: { discardDraft, ...body },
|
2730
3034
|
query = {}
|
2731
3035
|
} = ctx.request;
|
2732
|
-
const documentManager2 = getService$
|
2733
|
-
const permissionChecker2 = getService$
|
3036
|
+
const documentManager2 = getService$2("document-manager");
|
3037
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2734
3038
|
if (permissionChecker2.cannot.unpublish()) {
|
2735
3039
|
return ctx.forbidden();
|
2736
3040
|
}
|
@@ -2738,7 +3042,7 @@ const singleTypes = {
|
|
2738
3042
|
return ctx.forbidden();
|
2739
3043
|
}
|
2740
3044
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2741
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3045
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2742
3046
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2743
3047
|
if (!document) {
|
2744
3048
|
return ctx.notFound();
|
@@ -2764,13 +3068,13 @@ const singleTypes = {
|
|
2764
3068
|
const { userAbility } = ctx.state;
|
2765
3069
|
const { model } = ctx.params;
|
2766
3070
|
const { body, query = {} } = ctx.request;
|
2767
|
-
const documentManager2 = getService$
|
2768
|
-
const permissionChecker2 = getService$
|
3071
|
+
const documentManager2 = getService$2("document-manager");
|
3072
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2769
3073
|
if (permissionChecker2.cannot.discard()) {
|
2770
3074
|
return ctx.forbidden();
|
2771
3075
|
}
|
2772
3076
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2773
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3077
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2774
3078
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2775
3079
|
if (!document) {
|
2776
3080
|
return ctx.notFound();
|
@@ -2788,9 +3092,9 @@ const singleTypes = {
|
|
2788
3092
|
const { userAbility } = ctx.state;
|
2789
3093
|
const { model } = ctx.params;
|
2790
3094
|
const { query } = ctx.request;
|
2791
|
-
const documentManager2 = getService$
|
2792
|
-
const permissionChecker2 = getService$
|
2793
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3095
|
+
const documentManager2 = getService$2("document-manager");
|
3096
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3097
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2794
3098
|
if (permissionChecker2.cannot.read()) {
|
2795
3099
|
return ctx.forbidden();
|
2796
3100
|
}
|
@@ -2811,9 +3115,9 @@ const uid$1 = {
|
|
2811
3115
|
async generateUID(ctx) {
|
2812
3116
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2813
3117
|
const { query = {} } = ctx.request;
|
2814
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3118
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2815
3119
|
await validateUIDField(contentTypeUID, field);
|
2816
|
-
const uidService = getService$
|
3120
|
+
const uidService = getService$2("uid");
|
2817
3121
|
ctx.body = {
|
2818
3122
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2819
3123
|
};
|
@@ -2823,9 +3127,9 @@ const uid$1 = {
|
|
2823
3127
|
ctx.request.body
|
2824
3128
|
);
|
2825
3129
|
const { query = {} } = ctx.request;
|
2826
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3130
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2827
3131
|
await validateUIDField(contentTypeUID, field);
|
2828
|
-
const uidService = getService$
|
3132
|
+
const uidService = getService$2("uid");
|
2829
3133
|
const isAvailable = await uidService.checkUIDAvailability({
|
2830
3134
|
contentTypeUID,
|
2831
3135
|
field,
|
@@ -2846,7 +3150,8 @@ const controllers = {
|
|
2846
3150
|
relations,
|
2847
3151
|
"single-types": singleTypes,
|
2848
3152
|
uid: uid$1,
|
2849
|
-
...history.controllers ? history.controllers : {}
|
3153
|
+
...history.controllers ? history.controllers : {},
|
3154
|
+
...preview.controllers ? preview.controllers : {}
|
2850
3155
|
};
|
2851
3156
|
const keys = {
|
2852
3157
|
CONFIGURATION: "configuration"
|
@@ -2997,12 +3302,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2997
3302
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
2998
3303
|
}
|
2999
3304
|
const getTargetSchema = (targetModel) => {
|
3000
|
-
return getService$
|
3305
|
+
return getService$2("content-types").findContentType(targetModel);
|
3001
3306
|
};
|
3002
3307
|
const DEFAULT_LIST_LENGTH = 4;
|
3003
3308
|
const MAX_ROW_SIZE = 12;
|
3004
3309
|
const isAllowedFieldSize = (type, size) => {
|
3005
|
-
const { getFieldSize } = getService$
|
3310
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3006
3311
|
const fieldSize = getFieldSize(type);
|
3007
3312
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3008
3313
|
return false;
|
@@ -3010,7 +3315,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3010
3315
|
return size <= MAX_ROW_SIZE;
|
3011
3316
|
};
|
3012
3317
|
const getDefaultFieldSize = (attribute) => {
|
3013
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3318
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3014
3319
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3015
3320
|
};
|
3016
3321
|
async function createDefaultLayouts(schema) {
|
@@ -3045,7 +3350,7 @@ function syncLayouts(configuration, schema) {
|
|
3045
3350
|
for (const el of row) {
|
3046
3351
|
if (!hasEditableAttribute(schema, el.name))
|
3047
3352
|
continue;
|
3048
|
-
const { hasFieldSize } = getService$
|
3353
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3049
3354
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3050
3355
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3051
3356
|
elementsToReAppend.push(el.name);
|
@@ -3185,17 +3490,17 @@ const configurationService$1 = createConfigurationService({
|
|
3185
3490
|
isComponent: true,
|
3186
3491
|
prefix: STORE_KEY_PREFIX,
|
3187
3492
|
getModels() {
|
3188
|
-
const { toContentManagerModel } = getService$
|
3493
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3189
3494
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3190
3495
|
}
|
3191
3496
|
});
|
3192
3497
|
const components = ({ strapi: strapi2 }) => ({
|
3193
3498
|
findAllComponents() {
|
3194
|
-
const { toContentManagerModel } = getService$
|
3499
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3195
3500
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3196
3501
|
},
|
3197
3502
|
findComponent(uid2) {
|
3198
|
-
const { toContentManagerModel } = getService$
|
3503
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3199
3504
|
const component = strapi2.components[uid2];
|
3200
3505
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3201
3506
|
},
|
@@ -3246,17 +3551,17 @@ const configurationService = createConfigurationService({
|
|
3246
3551
|
storeUtils,
|
3247
3552
|
prefix: "content_types",
|
3248
3553
|
getModels() {
|
3249
|
-
const { toContentManagerModel } = getService$
|
3554
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3250
3555
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3251
3556
|
}
|
3252
3557
|
});
|
3253
3558
|
const service = ({ strapi: strapi2 }) => ({
|
3254
3559
|
findAllContentTypes() {
|
3255
|
-
const { toContentManagerModel } = getService$
|
3560
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3256
3561
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3257
3562
|
},
|
3258
3563
|
findContentType(uid2) {
|
3259
|
-
const { toContentManagerModel } = getService$
|
3564
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3260
3565
|
const contentType = strapi2.contentTypes[uid2];
|
3261
3566
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3262
3567
|
},
|
@@ -3285,7 +3590,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3285
3590
|
return this.findConfiguration(contentType);
|
3286
3591
|
},
|
3287
3592
|
findComponentsConfigurations(contentType) {
|
3288
|
-
return getService$
|
3593
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3289
3594
|
},
|
3290
3595
|
syncConfigurations() {
|
3291
3596
|
return configurationService.syncConfigurations();
|
@@ -3466,12 +3771,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3466
3771
|
ability: userAbility,
|
3467
3772
|
model
|
3468
3773
|
});
|
3469
|
-
const
|
3774
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3775
|
+
const toSubject = (entity) => {
|
3776
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3777
|
+
};
|
3470
3778
|
const can = (action, entity, field) => {
|
3471
|
-
|
3779
|
+
const subject = toSubject(entity);
|
3780
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3781
|
+
return (
|
3782
|
+
// Test the original action to see if it passes
|
3783
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3784
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3785
|
+
);
|
3472
3786
|
};
|
3473
3787
|
const cannot = (action, entity, field) => {
|
3474
|
-
|
3788
|
+
const subject = toSubject(entity);
|
3789
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3790
|
+
return (
|
3791
|
+
// Test both the original action
|
3792
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3793
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3794
|
+
);
|
3475
3795
|
};
|
3476
3796
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3477
3797
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3542,7 +3862,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3542
3862
|
return userAbility.can(action);
|
3543
3863
|
},
|
3544
3864
|
async registerPermissions() {
|
3545
|
-
const displayedContentTypes = getService$
|
3865
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3546
3866
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3547
3867
|
const actions = [
|
3548
3868
|
{
|
@@ -3748,6 +4068,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3748
4068
|
const attribute = model.attributes[attributeName];
|
3749
4069
|
switch (attribute.type) {
|
3750
4070
|
case "relation": {
|
4071
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4072
|
+
if (isMorphRelation) {
|
4073
|
+
break;
|
4074
|
+
}
|
3751
4075
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3752
4076
|
populateAcc[attributeName] = {
|
3753
4077
|
count: true,
|
@@ -3814,7 +4138,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3814
4138
|
return populateQuery;
|
3815
4139
|
};
|
3816
4140
|
const buildDeepPopulate = (uid2) => {
|
3817
|
-
return getService$
|
4141
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3818
4142
|
};
|
3819
4143
|
const populateBuilder = (uid2) => {
|
3820
4144
|
let getInitialPopulate = async () => {
|
@@ -3999,7 +4323,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3999
4323
|
*/
|
4000
4324
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
4001
4325
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
4002
|
-
|
4326
|
+
if (version.locale) {
|
4327
|
+
delete versionsByLocale[version.locale];
|
4328
|
+
}
|
4003
4329
|
const model = strapi2.getModel(uid2);
|
4004
4330
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4005
4331
|
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
@@ -4125,7 +4451,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4125
4451
|
*/
|
4126
4452
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4127
4453
|
if (!document) {
|
4128
|
-
return
|
4454
|
+
return {
|
4455
|
+
data: document,
|
4456
|
+
meta: {
|
4457
|
+
availableLocales: [],
|
4458
|
+
availableStatus: []
|
4459
|
+
}
|
4460
|
+
};
|
4129
4461
|
}
|
4130
4462
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4131
4463
|
if (!hasDraftAndPublish) {
|
@@ -4233,10 +4565,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4233
4565
|
async clone(id, body, uid2) {
|
4234
4566
|
const populate = await buildDeepPopulate(uid2);
|
4235
4567
|
const params = {
|
4236
|
-
data:
|
4237
|
-
...omitIdField(body),
|
4238
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4239
|
-
},
|
4568
|
+
data: omitIdField(body),
|
4240
4569
|
populate
|
4241
4570
|
};
|
4242
4571
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4352,7 +4681,8 @@ const services = {
|
|
4352
4681
|
permission,
|
4353
4682
|
"populate-builder": populateBuilder$1,
|
4354
4683
|
uid,
|
4355
|
-
...history.services ? history.services : {}
|
4684
|
+
...history.services ? history.services : {},
|
4685
|
+
...preview.services ? preview.services : {}
|
4356
4686
|
};
|
4357
4687
|
const index = () => {
|
4358
4688
|
return {
|