@strapi/content-manager 0.0.0-experimental.9df68962083938acba06546a7901c68a63266aec → 0.0.0-experimental.a13c58eec89ab119f0e381fb79c0252979e9c125
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/LICENSE +18 -3
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js → ComponentConfigurationPage-CB0JNNKL.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-C-49MccQ.js.map → ComponentConfigurationPage-CB0JNNKL.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs → ComponentConfigurationPage-CTCh51QS.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DmwmiFQy.mjs.map → ComponentConfigurationPage-CTCh51QS.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js → EditConfigurationPage-BxTVjxBG.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DjFJw56M.js.map → EditConfigurationPage-BxTVjxBG.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs → EditConfigurationPage-CVyURlPG.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-JT3E7NZy.mjs.map → EditConfigurationPage-CVyURlPG.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-zT3fBr4Y.js → EditViewPage-Cg78RUyS.js} +62 -11
- package/dist/_chunks/EditViewPage-Cg78RUyS.js.map +1 -0
- package/dist/_chunks/{EditViewPage-CPj61RMh.mjs → EditViewPage-M1OkTFHV.mjs} +63 -12
- package/dist/_chunks/EditViewPage-M1OkTFHV.mjs.map +1 -0
- package/dist/_chunks/{Field-Boxf9Ajp.js → Field-BQoMs_At.js} +271 -154
- package/dist/_chunks/Field-BQoMs_At.js.map +1 -0
- package/dist/_chunks/{Field-dha5VnIQ.mjs → Field-D1UGGscZ.mjs} +269 -152
- package/dist/_chunks/Field-D1UGGscZ.mjs.map +1 -0
- package/dist/_chunks/{Form-y5g1SRsh.js → Form-2uPHazrg.js} +36 -17
- package/dist/_chunks/Form-2uPHazrg.js.map +1 -0
- package/dist/_chunks/{Form-DHrru2AV.mjs → Form-JOjqloMg.mjs} +36 -17
- package/dist/_chunks/Form-JOjqloMg.mjs.map +1 -0
- package/dist/_chunks/{History-Bru_KoeP.mjs → History-D6LWunSa.mjs} +77 -62
- package/dist/_chunks/History-D6LWunSa.mjs.map +1 -0
- package/dist/_chunks/{History-CqN6K7SX.js → History-DoIdauuE.js} +76 -61
- package/dist/_chunks/History-DoIdauuE.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-R_p-SbHZ.js → ListConfigurationPage-C1eYSCV7.js} +21 -9
- package/dist/_chunks/ListConfigurationPage-C1eYSCV7.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-D8wGABj0.mjs → ListConfigurationPage-C8J_y4eX.mjs} +21 -9
- package/dist/_chunks/ListConfigurationPage-C8J_y4eX.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-pEw_zug9.js → ListViewPage-Nd8_ZHjF.js} +86 -46
- package/dist/_chunks/ListViewPage-Nd8_ZHjF.js.map +1 -0
- package/dist/_chunks/{ListViewPage-SID6TRb9.mjs → ListViewPage-vkipJOxG.mjs} +84 -44
- package/dist/_chunks/ListViewPage-vkipJOxG.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs → NoContentTypePage-CAxkF2Vg.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-CJ7UXwrQ.mjs.map → NoContentTypePage-CAxkF2Vg.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js → NoContentTypePage-CsI4DiJk.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C5dcQojD.js.map → NoContentTypePage-CsI4DiJk.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js → NoPermissionsPage-D7c29n-i.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BtPrImPP.js.map → NoPermissionsPage-D7c29n-i.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs → NoPermissionsPage-DA5ACuoK.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-B7syEq5E.mjs.map → NoPermissionsPage-DA5ACuoK.mjs.map} +1 -1
- package/dist/_chunks/Preview-Bwo9ft4j.mjs +288 -0
- package/dist/_chunks/Preview-Bwo9ft4j.mjs.map +1 -0
- package/dist/_chunks/Preview-DLxVMS5f.js +307 -0
- package/dist/_chunks/Preview-DLxVMS5f.js.map +1 -0
- package/dist/_chunks/{Relations-B9Crnhnn.mjs → Relations-Bddj_dxS.mjs} +73 -37
- package/dist/_chunks/Relations-Bddj_dxS.mjs.map +1 -0
- package/dist/_chunks/{Relations-DjTQ5kGB.js → Relations-CdFEx0mp.js} +72 -36
- package/dist/_chunks/Relations-CdFEx0mp.js.map +1 -0
- package/dist/_chunks/{en-fbKQxLGn.js → en-CHOp_xJv.js} +27 -16
- package/dist/_chunks/{en-fbKQxLGn.js.map → en-CHOp_xJv.js.map} +1 -1
- package/dist/_chunks/{en-Ux26r5pl.mjs → en-D_BMf0hT.mjs} +27 -16
- package/dist/_chunks/{en-Ux26r5pl.mjs.map → en-D_BMf0hT.mjs.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/{index-DVPWZkbS.js → index-CltLAahy.js} +1066 -658
- package/dist/_chunks/index-CltLAahy.js.map +1 -0
- package/dist/_chunks/{index-DJXJw9V5.mjs → index-DmNeuXH0.mjs} +1086 -679
- package/dist/_chunks/index-DmNeuXH0.mjs.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-Bau7ZfLV.mjs → layout-D63qmUOu.mjs} +25 -12
- package/dist/_chunks/layout-D63qmUOu.mjs.map +1 -0
- package/dist/_chunks/{layout-Dm6fbiQj.js → layout-DslPJR5e.js} +24 -11
- package/dist/_chunks/layout-DslPJR5e.js.map +1 -0
- package/dist/_chunks/{objects-gigeqt7s.js → objects-BcXOv6_9.js} +2 -4
- package/dist/_chunks/{objects-gigeqt7s.js.map → objects-BcXOv6_9.js.map} +1 -1
- package/dist/_chunks/{objects-mKMAmfec.mjs → objects-D6yBsdmx.mjs} +2 -4
- package/dist/_chunks/{objects-mKMAmfec.mjs.map → objects-D6yBsdmx.mjs.map} +1 -1
- package/dist/_chunks/{relations-CKnpRgrN.js → relations-B2h_O2Xw.js} +6 -7
- package/dist/_chunks/relations-B2h_O2Xw.js.map +1 -0
- package/dist/_chunks/{relations-BH_kBSJ0.mjs → relations-X3M9aO-m.mjs} +6 -7
- package/dist/_chunks/relations-X3M9aO-m.mjs.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/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 +1 -1
- 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/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 -17
- 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 +548 -261
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +549 -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 +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -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 +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- 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 +13 -13
- package/dist/_chunks/EditViewPage-CPj61RMh.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-zT3fBr4Y.js.map +0 -1
- package/dist/_chunks/Field-Boxf9Ajp.js.map +0 -1
- package/dist/_chunks/Field-dha5VnIQ.mjs.map +0 -1
- package/dist/_chunks/Form-DHrru2AV.mjs.map +0 -1
- package/dist/_chunks/Form-y5g1SRsh.js.map +0 -1
- package/dist/_chunks/History-Bru_KoeP.mjs.map +0 -1
- package/dist/_chunks/History-CqN6K7SX.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-D8wGABj0.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-R_p-SbHZ.js.map +0 -1
- package/dist/_chunks/ListViewPage-SID6TRb9.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-pEw_zug9.js.map +0 -1
- package/dist/_chunks/Relations-B9Crnhnn.mjs.map +0 -1
- package/dist/_chunks/Relations-DjTQ5kGB.js.map +0 -1
- package/dist/_chunks/index-DJXJw9V5.mjs.map +0 -1
- package/dist/_chunks/index-DVPWZkbS.js.map +0 -1
- package/dist/_chunks/layout-Bau7ZfLV.mjs.map +0 -1
- package/dist/_chunks/layout-Dm6fbiQj.js.map +0 -1
- package/dist/_chunks/relations-BH_kBSJ0.mjs.map +0 -1
- package/dist/_chunks/relations-CKnpRgrN.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,31 +202,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const
|
205
|
+
const getComponentFields = (componentUID) => {
|
206
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
207
|
+
(fieldsAcc, [key, attribute]) => {
|
208
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
209
|
+
fieldsAcc.push(key);
|
210
|
+
}
|
211
|
+
return fieldsAcc;
|
212
|
+
},
|
213
|
+
[]
|
214
|
+
);
|
215
|
+
};
|
216
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
217
|
const model = strapi2.getModel(uid2);
|
205
218
|
const attributes = Object.entries(model.attributes);
|
219
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
220
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
221
|
switch (attribute.type) {
|
208
222
|
case "relation": {
|
223
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
224
|
+
if (isMorphRelation) {
|
225
|
+
break;
|
226
|
+
}
|
209
227
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
228
|
if (isVisible2) {
|
211
|
-
acc[attributeName] = {
|
229
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
212
230
|
}
|
213
231
|
break;
|
214
232
|
}
|
215
233
|
case "media": {
|
216
|
-
acc[attributeName] = {
|
234
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
217
235
|
break;
|
218
236
|
}
|
219
237
|
case "component": {
|
220
238
|
const populate = getDeepPopulate2(attribute.component);
|
221
|
-
acc[attributeName] = {
|
239
|
+
acc[attributeName] = {
|
240
|
+
populate,
|
241
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
242
|
+
};
|
222
243
|
break;
|
223
244
|
}
|
224
245
|
case "dynamiczone": {
|
225
246
|
const populatedComponents = (attribute.components || []).reduce(
|
226
247
|
(acc2, componentUID) => {
|
227
|
-
acc2[componentUID] = {
|
248
|
+
acc2[componentUID] = {
|
249
|
+
populate: getDeepPopulate2(componentUID),
|
250
|
+
[fieldSelector]: getComponentFields(componentUID)
|
251
|
+
};
|
228
252
|
return acc2;
|
229
253
|
},
|
230
254
|
{}
|
@@ -286,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
286
310
|
getRelationRestoreValue,
|
287
311
|
getMediaRestoreValue,
|
288
312
|
getDefaultLocale,
|
313
|
+
isLocalizedContentType,
|
289
314
|
getLocaleDictionary,
|
290
315
|
getRetentionDays,
|
291
316
|
getVersionStatus,
|
@@ -308,7 +333,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
308
333
|
});
|
309
334
|
},
|
310
335
|
async findVersionsPage(params) {
|
311
|
-
const
|
336
|
+
const model = strapi2.getModel(params.query.contentType);
|
337
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
338
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
339
|
+
let locale = null;
|
340
|
+
if (isLocalizedContentType) {
|
341
|
+
locale = params.query.locale || defaultLocale;
|
342
|
+
}
|
312
343
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
344
|
query.findPage({
|
314
345
|
...params.query,
|
@@ -330,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
330
361
|
const attributeValue = entry.data[attributeKey];
|
331
362
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
332
363
|
if (attributeSchema.type === "media") {
|
333
|
-
const permissionChecker2 = getService$
|
364
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
334
365
|
userAbility: params.state.userAbility,
|
335
366
|
model: "plugin::upload.file"
|
336
367
|
});
|
@@ -353,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
353
384
|
if (userToPopulate == null) {
|
354
385
|
return null;
|
355
386
|
}
|
356
|
-
return strapi2.query("admin::user").findOne({
|
387
|
+
return strapi2.query("admin::user").findOne({
|
388
|
+
where: {
|
389
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
390
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
391
|
+
}
|
392
|
+
});
|
357
393
|
})
|
358
394
|
);
|
359
395
|
return {
|
@@ -366,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
366
402
|
[attributeKey]: adminUsers
|
367
403
|
};
|
368
404
|
}
|
369
|
-
const permissionChecker2 = getService$
|
405
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
370
406
|
userAbility: params.state.userAbility,
|
371
407
|
model: attributeSchema.target
|
372
408
|
});
|
@@ -464,6 +500,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
464
500
|
}
|
465
501
|
};
|
466
502
|
};
|
503
|
+
const shouldCreateHistoryVersion = (context) => {
|
504
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
508
|
+
return false;
|
509
|
+
}
|
510
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
511
|
+
return false;
|
512
|
+
}
|
513
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
514
|
+
return false;
|
515
|
+
}
|
516
|
+
return true;
|
517
|
+
};
|
518
|
+
const getSchemas = (uid2) => {
|
519
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
520
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
521
|
+
(currentComponentSchemas, key) => {
|
522
|
+
const fieldSchema = attributesSchema[key];
|
523
|
+
if (fieldSchema.type === "component") {
|
524
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
525
|
+
return {
|
526
|
+
...currentComponentSchemas,
|
527
|
+
[fieldSchema.component]: componentSchema
|
528
|
+
};
|
529
|
+
}
|
530
|
+
return currentComponentSchemas;
|
531
|
+
},
|
532
|
+
{}
|
533
|
+
);
|
534
|
+
return {
|
535
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
536
|
+
componentsSchemas
|
537
|
+
};
|
538
|
+
};
|
467
539
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
540
|
const state = {
|
469
541
|
deleteExpiredJob: null,
|
@@ -476,76 +548,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
476
548
|
return;
|
477
549
|
}
|
478
550
|
strapi2.documents.use(async (context, next) => {
|
479
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
480
|
-
return next();
|
481
|
-
}
|
482
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
483
|
-
return next();
|
484
|
-
}
|
485
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
486
|
-
return next();
|
487
|
-
}
|
488
|
-
const contentTypeUid = context.contentType.uid;
|
489
|
-
if (!contentTypeUid.startsWith("api::")) {
|
490
|
-
return next();
|
491
|
-
}
|
492
551
|
const result = await next();
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
552
|
+
if (!shouldCreateHistoryVersion(context)) {
|
553
|
+
return result;
|
554
|
+
}
|
555
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
497
556
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
498
|
-
const
|
499
|
-
if (
|
500
|
-
|
501
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
502
|
-
);
|
503
|
-
return next();
|
557
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
558
|
+
if (!locales.length) {
|
559
|
+
return result;
|
504
560
|
}
|
505
|
-
const
|
506
|
-
|
507
|
-
|
508
|
-
|
561
|
+
const uid2 = context.contentType.uid;
|
562
|
+
const schemas = getSchemas(uid2);
|
563
|
+
const model = strapi2.getModel(uid2);
|
564
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
565
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
566
|
+
where: {
|
567
|
+
documentId,
|
568
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
569
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
570
|
+
},
|
571
|
+
populate: serviceUtils.getDeepPopulate(
|
572
|
+
uid2,
|
573
|
+
true
|
574
|
+
/* use database syntax */
|
575
|
+
)
|
509
576
|
});
|
510
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
511
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
512
|
-
const componentsSchemas = Object.keys(
|
513
|
-
attributesSchema
|
514
|
-
).reduce((currentComponentSchemas, key) => {
|
515
|
-
const fieldSchema = attributesSchema[key];
|
516
|
-
if (fieldSchema.type === "component") {
|
517
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
518
|
-
return {
|
519
|
-
...currentComponentSchemas,
|
520
|
-
[fieldSchema.component]: componentSchema
|
521
|
-
};
|
522
|
-
}
|
523
|
-
return currentComponentSchemas;
|
524
|
-
}, {});
|
525
577
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
526
|
-
onCommit(() => {
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
578
|
+
onCommit(async () => {
|
579
|
+
for (const entry of localeEntries) {
|
580
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
581
|
+
await getService$1(strapi2, "history").createVersion({
|
582
|
+
contentType: uid2,
|
583
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
584
|
+
relatedDocumentId: documentId,
|
585
|
+
locale: entry.locale,
|
586
|
+
status,
|
587
|
+
...schemas
|
588
|
+
});
|
589
|
+
}
|
536
590
|
});
|
537
591
|
});
|
538
592
|
return result;
|
539
593
|
});
|
540
|
-
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
594
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
541
595
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
542
596
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
543
597
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
544
598
|
where: {
|
545
599
|
created_at: {
|
546
|
-
$lt: expirationDate
|
600
|
+
$lt: expirationDate
|
547
601
|
}
|
548
602
|
}
|
603
|
+
}).catch((error) => {
|
604
|
+
if (error instanceof Error) {
|
605
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
606
|
+
}
|
549
607
|
});
|
550
608
|
});
|
551
609
|
state.isInitialized = true;
|
@@ -557,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
557
615
|
}
|
558
616
|
};
|
559
617
|
};
|
560
|
-
const services$
|
618
|
+
const services$2 = {
|
561
619
|
history: createHistoryService,
|
562
620
|
lifecycles: createLifecyclesService
|
563
621
|
};
|
564
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
622
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
565
623
|
const historyVersionRouter = {
|
566
624
|
type: "admin",
|
567
625
|
routes: [
|
568
626
|
{
|
569
627
|
method: "GET",
|
570
|
-
info,
|
628
|
+
info: info$1,
|
571
629
|
path: "/history-versions",
|
572
630
|
handler: "history-version.findMany",
|
573
631
|
config: {
|
@@ -576,7 +634,7 @@ const historyVersionRouter = {
|
|
576
634
|
},
|
577
635
|
{
|
578
636
|
method: "PUT",
|
579
|
-
info,
|
637
|
+
info: info$1,
|
580
638
|
path: "/history-versions/:versionId/restore",
|
581
639
|
handler: "history-version.restoreVersion",
|
582
640
|
config: {
|
@@ -585,7 +643,7 @@ const historyVersionRouter = {
|
|
585
643
|
}
|
586
644
|
]
|
587
645
|
};
|
588
|
-
const routes$
|
646
|
+
const routes$2 = {
|
589
647
|
"history-version": historyVersionRouter
|
590
648
|
};
|
591
649
|
const historyVersion = {
|
@@ -632,21 +690,21 @@ const historyVersion = {
|
|
632
690
|
}
|
633
691
|
}
|
634
692
|
};
|
635
|
-
const getFeature = () => {
|
693
|
+
const getFeature$1 = () => {
|
636
694
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
637
695
|
return {
|
638
696
|
register({ strapi: strapi2 }) {
|
639
697
|
strapi2.get("models").add(historyVersion);
|
640
698
|
},
|
641
699
|
bootstrap({ strapi: strapi2 }) {
|
642
|
-
getService(strapi2, "lifecycles").bootstrap();
|
700
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
643
701
|
},
|
644
702
|
destroy({ strapi: strapi2 }) {
|
645
|
-
getService(strapi2, "lifecycles").destroy();
|
703
|
+
getService$1(strapi2, "lifecycles").destroy();
|
646
704
|
},
|
647
|
-
controllers: controllers$
|
648
|
-
services: services$
|
649
|
-
routes: routes$
|
705
|
+
controllers: controllers$2,
|
706
|
+
services: services$2,
|
707
|
+
routes: routes$2
|
650
708
|
};
|
651
709
|
}
|
652
710
|
return {
|
@@ -655,7 +713,7 @@ const getFeature = () => {
|
|
655
713
|
}
|
656
714
|
};
|
657
715
|
};
|
658
|
-
const history = getFeature();
|
716
|
+
const history = getFeature$1();
|
659
717
|
const register = async ({ strapi: strapi2 }) => {
|
660
718
|
await history.register?.({ strapi: strapi2 });
|
661
719
|
};
|
@@ -663,15 +721,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
|
|
663
721
|
ENTRY_PUBLISH: "entry.publish",
|
664
722
|
ENTRY_UNPUBLISH: "entry.unpublish"
|
665
723
|
};
|
724
|
+
const FEATURE_ID = "preview";
|
725
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
726
|
+
const previewRouter = {
|
727
|
+
type: "admin",
|
728
|
+
routes: [
|
729
|
+
{
|
730
|
+
method: "GET",
|
731
|
+
info,
|
732
|
+
path: "/preview/url/:contentType",
|
733
|
+
handler: "preview.getPreviewUrl",
|
734
|
+
config: {
|
735
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
736
|
+
}
|
737
|
+
}
|
738
|
+
]
|
739
|
+
};
|
740
|
+
const routes$1 = {
|
741
|
+
preview: previewRouter
|
742
|
+
};
|
743
|
+
function getService(strapi2, name) {
|
744
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
745
|
+
}
|
746
|
+
const getPreviewUrlSchema = yup.object().shape({
|
747
|
+
// Will be undefined for single types
|
748
|
+
documentId: yup.string(),
|
749
|
+
locale: yup.string().nullable(),
|
750
|
+
status: yup.string()
|
751
|
+
}).required();
|
752
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
753
|
+
await validateYupSchema(getPreviewUrlSchema)(params);
|
754
|
+
const newParams = pick(["documentId", "locale", "status"], params);
|
755
|
+
const model = strapi2.getModel(uid2);
|
756
|
+
if (!model || model.modelType !== "contentType") {
|
757
|
+
throw new errors.ValidationError("Invalid content type");
|
758
|
+
}
|
759
|
+
const isSingleType = model?.kind === "singleType";
|
760
|
+
if (!isSingleType && !params.documentId) {
|
761
|
+
throw new errors.ValidationError("documentId is required for Collection Types");
|
762
|
+
}
|
763
|
+
if (isSingleType) {
|
764
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
765
|
+
if (!doc) {
|
766
|
+
throw new errors.NotFoundError("Document not found");
|
767
|
+
}
|
768
|
+
newParams.documentId = doc?.documentId;
|
769
|
+
}
|
770
|
+
return newParams;
|
771
|
+
};
|
772
|
+
const createPreviewController = () => {
|
773
|
+
return {
|
774
|
+
/**
|
775
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
776
|
+
* in the Content Manager.
|
777
|
+
*/
|
778
|
+
async getPreviewUrl(ctx) {
|
779
|
+
const uid2 = ctx.params.contentType;
|
780
|
+
const query = ctx.request.query;
|
781
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
782
|
+
const previewService = getService(strapi, "preview");
|
783
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
784
|
+
if (!url) {
|
785
|
+
ctx.status = 204;
|
786
|
+
}
|
787
|
+
return {
|
788
|
+
data: { url }
|
789
|
+
};
|
790
|
+
}
|
791
|
+
};
|
792
|
+
};
|
793
|
+
const controllers$1 = {
|
794
|
+
preview: createPreviewController
|
795
|
+
/**
|
796
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
797
|
+
* passing a controller factory as the value, instead of a controller object directly
|
798
|
+
*/
|
799
|
+
};
|
800
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
801
|
+
const config = getService(strapi2, "preview-config");
|
802
|
+
return {
|
803
|
+
async getPreviewUrl(uid2, params) {
|
804
|
+
const handler = config.getPreviewHandler();
|
805
|
+
try {
|
806
|
+
return handler(uid2, params);
|
807
|
+
} catch (error) {
|
808
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
809
|
+
throw new errors.ApplicationError("Failed to get preview URL");
|
810
|
+
}
|
811
|
+
return;
|
812
|
+
}
|
813
|
+
};
|
814
|
+
};
|
815
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
816
|
+
return {
|
817
|
+
isEnabled() {
|
818
|
+
const config = strapi2.config.get("admin.preview");
|
819
|
+
if (!config) {
|
820
|
+
return false;
|
821
|
+
}
|
822
|
+
return config?.enabled ?? true;
|
823
|
+
},
|
824
|
+
/**
|
825
|
+
* Validate if the configuration is valid
|
826
|
+
*/
|
827
|
+
validate() {
|
828
|
+
if (!this.isEnabled()) {
|
829
|
+
return;
|
830
|
+
}
|
831
|
+
const handler = this.getPreviewHandler();
|
832
|
+
if (typeof handler !== "function") {
|
833
|
+
throw new errors.ValidationError(
|
834
|
+
"Preview configuration is invalid. Handler must be a function"
|
835
|
+
);
|
836
|
+
}
|
837
|
+
},
|
838
|
+
/**
|
839
|
+
* Utility to get the preview handler from the configuration
|
840
|
+
*/
|
841
|
+
getPreviewHandler() {
|
842
|
+
const config = strapi2.config.get("admin.preview");
|
843
|
+
const emptyHandler = () => {
|
844
|
+
return void 0;
|
845
|
+
};
|
846
|
+
if (!this.isEnabled()) {
|
847
|
+
return emptyHandler;
|
848
|
+
}
|
849
|
+
return config?.config?.handler || emptyHandler;
|
850
|
+
}
|
851
|
+
};
|
852
|
+
};
|
853
|
+
const services$1 = {
|
854
|
+
preview: createPreviewService,
|
855
|
+
"preview-config": createPreviewConfigService
|
856
|
+
};
|
857
|
+
const getFeature = () => {
|
858
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
859
|
+
return {};
|
860
|
+
}
|
861
|
+
return {
|
862
|
+
bootstrap() {
|
863
|
+
console.log("Bootstrapping preview server");
|
864
|
+
const config = getService(strapi, "preview-config");
|
865
|
+
config.validate();
|
866
|
+
},
|
867
|
+
routes: routes$1,
|
868
|
+
controllers: controllers$1,
|
869
|
+
services: services$1
|
870
|
+
};
|
871
|
+
};
|
872
|
+
const preview = getFeature();
|
666
873
|
const bootstrap = async () => {
|
667
874
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
668
875
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
669
876
|
});
|
670
|
-
getService$
|
671
|
-
await getService$
|
672
|
-
await getService$
|
673
|
-
await getService$
|
877
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
878
|
+
await getService$2("components").syncConfigurations();
|
879
|
+
await getService$2("content-types").syncConfigurations();
|
880
|
+
await getService$2("permission").registerPermissions();
|
674
881
|
await history.bootstrap?.({ strapi });
|
882
|
+
await preview.bootstrap?.({ strapi });
|
675
883
|
};
|
676
884
|
const destroy = async ({ strapi: strapi2 }) => {
|
677
885
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1161,7 +1369,8 @@ const admin = {
|
|
1161
1369
|
};
|
1162
1370
|
const routes = {
|
1163
1371
|
admin,
|
1164
|
-
...history.routes ? history.routes : {}
|
1372
|
+
...history.routes ? history.routes : {},
|
1373
|
+
...preview.routes ? preview.routes : {}
|
1165
1374
|
};
|
1166
1375
|
const hasPermissionsSchema = yup$1.object({
|
1167
1376
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1172,6 +1381,11 @@ const { createPolicy } = policy;
|
|
1172
1381
|
const hasPermissions = createPolicy({
|
1173
1382
|
name: "plugin::content-manager.hasPermissions",
|
1174
1383
|
validator: validateHasPermissionsInput,
|
1384
|
+
/**
|
1385
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1386
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1387
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1388
|
+
*/
|
1175
1389
|
handler(ctx, config = {}) {
|
1176
1390
|
const { actions = [], hasAtLeastOne = false } = config;
|
1177
1391
|
const { userAbility } = ctx.state;
|
@@ -1413,7 +1627,7 @@ const createMetadasSchema = (schema) => {
|
|
1413
1627
|
if (!value) {
|
1414
1628
|
return yup$1.string();
|
1415
1629
|
}
|
1416
|
-
const targetSchema = getService$
|
1630
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1417
1631
|
schema.attributes[key].targetModel
|
1418
1632
|
);
|
1419
1633
|
if (!targetSchema) {
|
@@ -1565,9 +1779,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1565
1779
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1566
1780
|
);
|
1567
1781
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1568
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1782
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1569
1783
|
const { allowMultipleLocales } = opts;
|
1570
|
-
const { locale, status, ...rest } = request || {};
|
1784
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1785
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1786
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1571
1787
|
const schema = yup$1.object().shape({
|
1572
1788
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1573
1789
|
status: statusSchema
|
@@ -1580,7 +1796,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1580
1796
|
}
|
1581
1797
|
};
|
1582
1798
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1583
|
-
const documentMetadata2 = getService$
|
1799
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1584
1800
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1585
1801
|
let {
|
1586
1802
|
meta: { availableLocales, availableStatus }
|
@@ -1606,8 +1822,8 @@ const createDocument = async (ctx, opts) => {
|
|
1606
1822
|
const { userAbility, user } = ctx.state;
|
1607
1823
|
const { model } = ctx.params;
|
1608
1824
|
const { body } = ctx.request;
|
1609
|
-
const documentManager2 = getService$
|
1610
|
-
const permissionChecker2 = getService$
|
1825
|
+
const documentManager2 = getService$2("document-manager");
|
1826
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1611
1827
|
if (permissionChecker2.cannot.create()) {
|
1612
1828
|
throw new errors.ForbiddenError();
|
1613
1829
|
}
|
@@ -1615,7 +1831,7 @@ const createDocument = async (ctx, opts) => {
|
|
1615
1831
|
const setCreator = setCreatorFields({ user });
|
1616
1832
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1617
1833
|
const sanitizedBody = await sanitizeFn(body);
|
1618
|
-
const { locale, status
|
1834
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1619
1835
|
return documentManager2.create(model, {
|
1620
1836
|
data: sanitizedBody,
|
1621
1837
|
locale,
|
@@ -1627,14 +1843,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1627
1843
|
const { userAbility, user } = ctx.state;
|
1628
1844
|
const { id, model } = ctx.params;
|
1629
1845
|
const { body } = ctx.request;
|
1630
|
-
const documentManager2 = getService$
|
1631
|
-
const permissionChecker2 = getService$
|
1846
|
+
const documentManager2 = getService$2("document-manager");
|
1847
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1632
1848
|
if (permissionChecker2.cannot.update()) {
|
1633
1849
|
throw new errors.ForbiddenError();
|
1634
1850
|
}
|
1635
1851
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1636
|
-
const populate = await getService$
|
1637
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1852
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1853
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1638
1854
|
const [documentVersion, documentExists] = await Promise.all([
|
1639
1855
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1640
1856
|
documentManager2.exists(model, id)
|
@@ -1650,7 +1866,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1650
1866
|
throw new errors.ForbiddenError();
|
1651
1867
|
}
|
1652
1868
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1653
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1869
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1654
1870
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1655
1871
|
const sanitizedBody = await sanitizeFn(body);
|
1656
1872
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1664,15 +1880,15 @@ const collectionTypes = {
|
|
1664
1880
|
const { userAbility } = ctx.state;
|
1665
1881
|
const { model } = ctx.params;
|
1666
1882
|
const { query } = ctx.request;
|
1667
|
-
const documentMetadata2 = getService$
|
1668
|
-
const documentManager2 = getService$
|
1669
|
-
const permissionChecker2 = getService$
|
1883
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1884
|
+
const documentManager2 = getService$2("document-manager");
|
1885
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1670
1886
|
if (permissionChecker2.cannot.read()) {
|
1671
1887
|
return ctx.forbidden();
|
1672
1888
|
}
|
1673
1889
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1674
|
-
const populate = await getService$
|
1675
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1890
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1891
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1676
1892
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1677
1893
|
{ ...permissionQuery, populate, locale, status },
|
1678
1894
|
model
|
@@ -1700,14 +1916,14 @@ const collectionTypes = {
|
|
1700
1916
|
async findOne(ctx) {
|
1701
1917
|
const { userAbility } = ctx.state;
|
1702
1918
|
const { model, id } = ctx.params;
|
1703
|
-
const documentManager2 = getService$
|
1704
|
-
const permissionChecker2 = getService$
|
1919
|
+
const documentManager2 = getService$2("document-manager");
|
1920
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1705
1921
|
if (permissionChecker2.cannot.read()) {
|
1706
1922
|
return ctx.forbidden();
|
1707
1923
|
}
|
1708
1924
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1709
|
-
const populate = await getService$
|
1710
|
-
const { locale, status
|
1925
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1926
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1711
1927
|
const version = await documentManager2.findOne(id, model, {
|
1712
1928
|
populate,
|
1713
1929
|
locale,
|
@@ -1722,7 +1938,7 @@ const collectionTypes = {
|
|
1722
1938
|
permissionChecker2,
|
1723
1939
|
model,
|
1724
1940
|
// @ts-expect-error TODO: fix
|
1725
|
-
{ id, locale, publishedAt: null },
|
1941
|
+
{ documentId: id, locale, publishedAt: null },
|
1726
1942
|
{ availableLocales: true, availableStatus: false }
|
1727
1943
|
);
|
1728
1944
|
ctx.body = { data: {}, meta };
|
@@ -1737,7 +1953,7 @@ const collectionTypes = {
|
|
1737
1953
|
async create(ctx) {
|
1738
1954
|
const { userAbility } = ctx.state;
|
1739
1955
|
const { model } = ctx.params;
|
1740
|
-
const permissionChecker2 = getService$
|
1956
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1741
1957
|
const [totalEntries, document] = await Promise.all([
|
1742
1958
|
strapi.db.query(model).count(),
|
1743
1959
|
createDocument(ctx)
|
@@ -1758,7 +1974,7 @@ const collectionTypes = {
|
|
1758
1974
|
async update(ctx) {
|
1759
1975
|
const { userAbility } = ctx.state;
|
1760
1976
|
const { model } = ctx.params;
|
1761
|
-
const permissionChecker2 = getService$
|
1977
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1762
1978
|
const updatedVersion = await updateDocument(ctx);
|
1763
1979
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1764
1980
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1767,14 +1983,14 @@ const collectionTypes = {
|
|
1767
1983
|
const { userAbility, user } = ctx.state;
|
1768
1984
|
const { model, sourceId: id } = ctx.params;
|
1769
1985
|
const { body } = ctx.request;
|
1770
|
-
const documentManager2 = getService$
|
1771
|
-
const permissionChecker2 = getService$
|
1986
|
+
const documentManager2 = getService$2("document-manager");
|
1987
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1772
1988
|
if (permissionChecker2.cannot.create()) {
|
1773
1989
|
return ctx.forbidden();
|
1774
1990
|
}
|
1775
1991
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1776
|
-
const populate = await getService$
|
1777
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1992
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1993
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1778
1994
|
const document = await documentManager2.findOne(id, model, {
|
1779
1995
|
populate,
|
1780
1996
|
locale,
|
@@ -1812,14 +2028,14 @@ const collectionTypes = {
|
|
1812
2028
|
async delete(ctx) {
|
1813
2029
|
const { userAbility } = ctx.state;
|
1814
2030
|
const { id, model } = ctx.params;
|
1815
|
-
const documentManager2 = getService$
|
1816
|
-
const permissionChecker2 = getService$
|
2031
|
+
const documentManager2 = getService$2("document-manager");
|
2032
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1817
2033
|
if (permissionChecker2.cannot.delete()) {
|
1818
2034
|
return ctx.forbidden();
|
1819
2035
|
}
|
1820
2036
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1821
|
-
const populate = await getService$
|
1822
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2037
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2038
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1823
2039
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1824
2040
|
if (documentLocales.length === 0) {
|
1825
2041
|
return ctx.notFound();
|
@@ -1840,19 +2056,42 @@ const collectionTypes = {
|
|
1840
2056
|
const { userAbility } = ctx.state;
|
1841
2057
|
const { id, model } = ctx.params;
|
1842
2058
|
const { body } = ctx.request;
|
1843
|
-
const documentManager2 = getService$
|
1844
|
-
const permissionChecker2 = getService$
|
2059
|
+
const documentManager2 = getService$2("document-manager");
|
2060
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1845
2061
|
if (permissionChecker2.cannot.publish()) {
|
1846
2062
|
return ctx.forbidden();
|
1847
2063
|
}
|
1848
2064
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1849
2065
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1850
|
-
const populate = await getService$
|
1851
|
-
|
2066
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2067
|
+
let document;
|
2068
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2069
|
+
const isCreate = isNil$1(id);
|
2070
|
+
if (isCreate) {
|
2071
|
+
if (permissionChecker2.cannot.create()) {
|
2072
|
+
throw new errors.ForbiddenError();
|
2073
|
+
}
|
2074
|
+
document = await createDocument(ctx, { populate });
|
2075
|
+
}
|
2076
|
+
const isUpdate = !isCreate;
|
2077
|
+
if (isUpdate) {
|
2078
|
+
const documentExists = documentManager2.exists(model, id);
|
2079
|
+
if (!documentExists) {
|
2080
|
+
throw new errors.NotFoundError("Document not found");
|
2081
|
+
}
|
2082
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2083
|
+
if (!document) {
|
2084
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2085
|
+
throw new errors.ForbiddenError();
|
2086
|
+
}
|
2087
|
+
document = await updateDocument(ctx);
|
2088
|
+
} else if (permissionChecker2.can.update(document)) {
|
2089
|
+
await updateDocument(ctx);
|
2090
|
+
}
|
2091
|
+
}
|
1852
2092
|
if (permissionChecker2.cannot.publish(document)) {
|
1853
2093
|
throw new errors.ForbiddenError();
|
1854
2094
|
}
|
1855
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1856
2095
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1857
2096
|
locale
|
1858
2097
|
// TODO: Allow setting creator fields on publish
|
@@ -1872,14 +2111,16 @@ const collectionTypes = {
|
|
1872
2111
|
const { body } = ctx.request;
|
1873
2112
|
const { documentIds } = body;
|
1874
2113
|
await validateBulkActionInput(body);
|
1875
|
-
const documentManager2 = getService$
|
1876
|
-
const permissionChecker2 = getService$
|
2114
|
+
const documentManager2 = getService$2("document-manager");
|
2115
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1877
2116
|
if (permissionChecker2.cannot.publish()) {
|
1878
2117
|
return ctx.forbidden();
|
1879
2118
|
}
|
1880
2119
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1881
|
-
const populate = await getService$
|
1882
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2120
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2121
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2122
|
+
allowMultipleLocales: true
|
2123
|
+
});
|
1883
2124
|
const entityPromises = documentIds.map(
|
1884
2125
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1885
2126
|
);
|
@@ -1901,12 +2142,14 @@ const collectionTypes = {
|
|
1901
2142
|
const { body } = ctx.request;
|
1902
2143
|
const { documentIds } = body;
|
1903
2144
|
await validateBulkActionInput(body);
|
1904
|
-
const documentManager2 = getService$
|
1905
|
-
const permissionChecker2 = getService$
|
2145
|
+
const documentManager2 = getService$2("document-manager");
|
2146
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1906
2147
|
if (permissionChecker2.cannot.unpublish()) {
|
1907
2148
|
return ctx.forbidden();
|
1908
2149
|
}
|
1909
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2150
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2151
|
+
allowMultipleLocales: true
|
2152
|
+
});
|
1910
2153
|
const entityPromises = documentIds.map(
|
1911
2154
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1912
2155
|
);
|
@@ -1929,8 +2172,8 @@ const collectionTypes = {
|
|
1929
2172
|
const {
|
1930
2173
|
body: { discardDraft, ...body }
|
1931
2174
|
} = ctx.request;
|
1932
|
-
const documentManager2 = getService$
|
1933
|
-
const permissionChecker2 = getService$
|
2175
|
+
const documentManager2 = getService$2("document-manager");
|
2176
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1934
2177
|
if (permissionChecker2.cannot.unpublish()) {
|
1935
2178
|
return ctx.forbidden();
|
1936
2179
|
}
|
@@ -1938,8 +2181,8 @@ const collectionTypes = {
|
|
1938
2181
|
return ctx.forbidden();
|
1939
2182
|
}
|
1940
2183
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1941
|
-
const populate = await getService$
|
1942
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2184
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2185
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1943
2186
|
const document = await documentManager2.findOne(id, model, {
|
1944
2187
|
populate,
|
1945
2188
|
locale,
|
@@ -1969,14 +2212,14 @@ const collectionTypes = {
|
|
1969
2212
|
const { userAbility } = ctx.state;
|
1970
2213
|
const { id, model } = ctx.params;
|
1971
2214
|
const { body } = ctx.request;
|
1972
|
-
const documentManager2 = getService$
|
1973
|
-
const permissionChecker2 = getService$
|
2215
|
+
const documentManager2 = getService$2("document-manager");
|
2216
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1974
2217
|
if (permissionChecker2.cannot.discard()) {
|
1975
2218
|
return ctx.forbidden();
|
1976
2219
|
}
|
1977
2220
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1978
|
-
const populate = await getService$
|
1979
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2221
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2222
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1980
2223
|
const document = await documentManager2.findOne(id, model, {
|
1981
2224
|
populate,
|
1982
2225
|
locale,
|
@@ -2000,14 +2243,14 @@ const collectionTypes = {
|
|
2000
2243
|
const { query, body } = ctx.request;
|
2001
2244
|
const { documentIds } = body;
|
2002
2245
|
await validateBulkActionInput(body);
|
2003
|
-
const documentManager2 = getService$
|
2004
|
-
const permissionChecker2 = getService$
|
2246
|
+
const documentManager2 = getService$2("document-manager");
|
2247
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2005
2248
|
if (permissionChecker2.cannot.delete()) {
|
2006
2249
|
return ctx.forbidden();
|
2007
2250
|
}
|
2008
2251
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2009
|
-
const populate = await getService$
|
2010
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2252
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2253
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2011
2254
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2012
2255
|
populate,
|
2013
2256
|
locale
|
@@ -2027,14 +2270,14 @@ const collectionTypes = {
|
|
2027
2270
|
async countDraftRelations(ctx) {
|
2028
2271
|
const { userAbility } = ctx.state;
|
2029
2272
|
const { model, id } = ctx.params;
|
2030
|
-
const documentManager2 = getService$
|
2031
|
-
const permissionChecker2 = getService$
|
2273
|
+
const documentManager2 = getService$2("document-manager");
|
2274
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2032
2275
|
if (permissionChecker2.cannot.read()) {
|
2033
2276
|
return ctx.forbidden();
|
2034
2277
|
}
|
2035
2278
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2036
|
-
const populate = await getService$
|
2037
|
-
const { locale, status
|
2279
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2280
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2038
2281
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2039
2282
|
if (!entity) {
|
2040
2283
|
return ctx.notFound();
|
@@ -2052,8 +2295,8 @@ const collectionTypes = {
|
|
2052
2295
|
const ids = ctx.request.query.documentIds;
|
2053
2296
|
const locale = ctx.request.query.locale;
|
2054
2297
|
const { model } = ctx.params;
|
2055
|
-
const documentManager2 = getService$
|
2056
|
-
const permissionChecker2 = getService$
|
2298
|
+
const documentManager2 = getService$2("document-manager");
|
2299
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2057
2300
|
if (permissionChecker2.cannot.read()) {
|
2058
2301
|
return ctx.forbidden();
|
2059
2302
|
}
|
@@ -2077,13 +2320,13 @@ const collectionTypes = {
|
|
2077
2320
|
};
|
2078
2321
|
const components$1 = {
|
2079
2322
|
findComponents(ctx) {
|
2080
|
-
const components2 = getService$
|
2081
|
-
const { toDto } = getService$
|
2323
|
+
const components2 = getService$2("components").findAllComponents();
|
2324
|
+
const { toDto } = getService$2("data-mapper");
|
2082
2325
|
ctx.body = { data: components2.map(toDto) };
|
2083
2326
|
},
|
2084
2327
|
async findComponentConfiguration(ctx) {
|
2085
2328
|
const { uid: uid2 } = ctx.params;
|
2086
|
-
const componentService = getService$
|
2329
|
+
const componentService = getService$2("components");
|
2087
2330
|
const component = componentService.findComponent(uid2);
|
2088
2331
|
if (!component) {
|
2089
2332
|
return ctx.notFound("component.notFound");
|
@@ -2100,7 +2343,7 @@ const components$1 = {
|
|
2100
2343
|
async updateComponentConfiguration(ctx) {
|
2101
2344
|
const { uid: uid2 } = ctx.params;
|
2102
2345
|
const { body } = ctx.request;
|
2103
|
-
const componentService = getService$
|
2346
|
+
const componentService = getService$2("components");
|
2104
2347
|
const component = componentService.findComponent(uid2);
|
2105
2348
|
if (!component) {
|
2106
2349
|
return ctx.notFound("component.notFound");
|
@@ -2134,12 +2377,12 @@ const contentTypes = {
|
|
2134
2377
|
} catch (error) {
|
2135
2378
|
return ctx.send({ error }, 400);
|
2136
2379
|
}
|
2137
|
-
const contentTypes2 = getService$
|
2138
|
-
const { toDto } = getService$
|
2380
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2381
|
+
const { toDto } = getService$2("data-mapper");
|
2139
2382
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2140
2383
|
},
|
2141
2384
|
async findContentTypesSettings(ctx) {
|
2142
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2385
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2143
2386
|
const contentTypes2 = await findAllContentTypes();
|
2144
2387
|
const configurations = await Promise.all(
|
2145
2388
|
contentTypes2.map(async (contentType) => {
|
@@ -2153,7 +2396,7 @@ const contentTypes = {
|
|
2153
2396
|
},
|
2154
2397
|
async findContentTypeConfiguration(ctx) {
|
2155
2398
|
const { uid: uid2 } = ctx.params;
|
2156
|
-
const contentTypeService = getService$
|
2399
|
+
const contentTypeService = getService$2("content-types");
|
2157
2400
|
const contentType = await contentTypeService.findContentType(uid2);
|
2158
2401
|
if (!contentType) {
|
2159
2402
|
return ctx.notFound("contentType.notFound");
|
@@ -2175,13 +2418,13 @@ const contentTypes = {
|
|
2175
2418
|
const { userAbility } = ctx.state;
|
2176
2419
|
const { uid: uid2 } = ctx.params;
|
2177
2420
|
const { body } = ctx.request;
|
2178
|
-
const contentTypeService = getService$
|
2179
|
-
const metricsService = getService$
|
2421
|
+
const contentTypeService = getService$2("content-types");
|
2422
|
+
const metricsService = getService$2("metrics");
|
2180
2423
|
const contentType = await contentTypeService.findContentType(uid2);
|
2181
2424
|
if (!contentType) {
|
2182
2425
|
return ctx.notFound("contentType.notFound");
|
2183
2426
|
}
|
2184
|
-
if (!getService$
|
2427
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2185
2428
|
return ctx.forbidden();
|
2186
2429
|
}
|
2187
2430
|
let input;
|
@@ -2214,10 +2457,10 @@ const contentTypes = {
|
|
2214
2457
|
};
|
2215
2458
|
const init = {
|
2216
2459
|
getInitData(ctx) {
|
2217
|
-
const { toDto } = getService$
|
2218
|
-
const { findAllComponents } = getService$
|
2219
|
-
const { getAllFieldSizes } = getService$
|
2220
|
-
const { findAllContentTypes } = getService$
|
2460
|
+
const { toDto } = getService$2("data-mapper");
|
2461
|
+
const { findAllComponents } = getService$2("components");
|
2462
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2463
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2221
2464
|
ctx.body = {
|
2222
2465
|
data: {
|
2223
2466
|
fieldSizes: getAllFieldSizes(),
|
@@ -2253,36 +2496,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2253
2496
|
params.filters.$and.push(filtersClause);
|
2254
2497
|
};
|
2255
2498
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2256
|
-
const permissionChecker2 = getService$
|
2499
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2257
2500
|
userAbility,
|
2258
2501
|
model: model.uid
|
2259
2502
|
});
|
2260
|
-
|
2503
|
+
const isMainFieldListable = isListable(model, mainField);
|
2504
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2505
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2261
2506
|
return "id";
|
2262
2507
|
}
|
2263
|
-
if (
|
2264
|
-
|
2265
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2266
|
-
userAbility,
|
2267
|
-
model: "plugin::users-permissions.user"
|
2268
|
-
});
|
2269
|
-
if (userPermissionChecker.can.read()) {
|
2270
|
-
return "name";
|
2271
|
-
}
|
2272
|
-
}
|
2273
|
-
return "id";
|
2508
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2509
|
+
return "name";
|
2274
2510
|
}
|
2275
2511
|
return mainField;
|
2276
2512
|
};
|
2277
|
-
const addStatusToRelations = async (
|
2278
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2513
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2514
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2279
2515
|
return relations2;
|
2280
2516
|
}
|
2281
|
-
const documentMetadata2 = getService$
|
2282
|
-
|
2517
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2518
|
+
if (!relations2.length) {
|
2519
|
+
return relations2;
|
2520
|
+
}
|
2521
|
+
const firstRelation = relations2[0];
|
2522
|
+
const filters = {
|
2523
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2524
|
+
// NOTE: find the "opposite" status
|
2525
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2526
|
+
};
|
2527
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2528
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2529
|
+
filters
|
2530
|
+
});
|
2283
2531
|
return relations2.map((relation) => {
|
2284
|
-
const availableStatuses =
|
2285
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2532
|
+
const availableStatuses = availableStatus.filter(
|
2533
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2286
2534
|
);
|
2287
2535
|
return {
|
2288
2536
|
...relation,
|
@@ -2303,11 +2551,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2303
2551
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2304
2552
|
const isSourceLocalized = isLocalized(sourceModel);
|
2305
2553
|
const isTargetLocalized = isLocalized(targetModel);
|
2306
|
-
let validatedLocale = locale;
|
2307
|
-
if (!targetModel || !isTargetLocalized)
|
2308
|
-
validatedLocale = void 0;
|
2309
2554
|
return {
|
2310
|
-
locale
|
2555
|
+
locale,
|
2311
2556
|
isSourceLocalized,
|
2312
2557
|
isTargetLocalized
|
2313
2558
|
};
|
@@ -2347,7 +2592,7 @@ const relations = {
|
|
2347
2592
|
ctx.request?.query?.locale
|
2348
2593
|
);
|
2349
2594
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2350
|
-
const permissionChecker2 = getService$
|
2595
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2351
2596
|
userAbility,
|
2352
2597
|
model
|
2353
2598
|
});
|
@@ -2372,7 +2617,7 @@ const relations = {
|
|
2372
2617
|
where.id = id;
|
2373
2618
|
}
|
2374
2619
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2375
|
-
const populate = await getService$
|
2620
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2376
2621
|
const currentEntity = await strapi.db.query(model).findOne({
|
2377
2622
|
where,
|
2378
2623
|
populate
|
@@ -2387,7 +2632,7 @@ const relations = {
|
|
2387
2632
|
}
|
2388
2633
|
entryId = currentEntity.id;
|
2389
2634
|
}
|
2390
|
-
const modelConfig = isComponent2 ? await getService$
|
2635
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2391
2636
|
const targetSchema = strapi.getModel(targetUid);
|
2392
2637
|
const mainField = flow(
|
2393
2638
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2410,7 +2655,7 @@ const relations = {
|
|
2410
2655
|
attribute,
|
2411
2656
|
fieldsToSelect,
|
2412
2657
|
mainField,
|
2413
|
-
source: { schema: sourceSchema },
|
2658
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2414
2659
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2415
2660
|
sourceSchema,
|
2416
2661
|
targetSchema,
|
@@ -2432,7 +2677,8 @@ const relations = {
|
|
2432
2677
|
fieldsToSelect,
|
2433
2678
|
mainField,
|
2434
2679
|
source: {
|
2435
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2680
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2681
|
+
isLocalized: isSourceLocalized
|
2436
2682
|
},
|
2437
2683
|
target: {
|
2438
2684
|
schema: { uid: targetUid },
|
@@ -2440,7 +2686,7 @@ const relations = {
|
|
2440
2686
|
}
|
2441
2687
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2442
2688
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2443
|
-
const permissionChecker2 = getService$
|
2689
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2444
2690
|
userAbility: ctx.state.userAbility,
|
2445
2691
|
model: targetUid
|
2446
2692
|
});
|
@@ -2470,12 +2716,16 @@ const relations = {
|
|
2470
2716
|
} else {
|
2471
2717
|
where.id = id;
|
2472
2718
|
}
|
2473
|
-
|
2474
|
-
|
2719
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2720
|
+
if (!isEmpty(publishedAt)) {
|
2721
|
+
where[`${alias}.published_at`] = publishedAt;
|
2475
2722
|
}
|
2476
|
-
if (
|
2723
|
+
if (isTargetLocalized && locale) {
|
2477
2724
|
where[`${alias}.locale`] = locale;
|
2478
2725
|
}
|
2726
|
+
if (isSourceLocalized && locale) {
|
2727
|
+
where.locale = locale;
|
2728
|
+
}
|
2479
2729
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2480
2730
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2481
2731
|
}
|
@@ -2493,7 +2743,8 @@ const relations = {
|
|
2493
2743
|
id: { $notIn: uniq(idsToOmit) }
|
2494
2744
|
});
|
2495
2745
|
}
|
2496
|
-
const
|
2746
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2747
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2497
2748
|
ctx.body = {
|
2498
2749
|
...res,
|
2499
2750
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2508,29 +2759,39 @@ const relations = {
|
|
2508
2759
|
attribute,
|
2509
2760
|
targetField,
|
2510
2761
|
fieldsToSelect,
|
2511
|
-
|
2512
|
-
|
2513
|
-
}
|
2514
|
-
target: {
|
2515
|
-
schema: { uid: targetUid }
|
2516
|
-
}
|
2762
|
+
status,
|
2763
|
+
source: { schema: sourceSchema },
|
2764
|
+
target: { schema: targetSchema }
|
2517
2765
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2518
|
-
const
|
2766
|
+
const { uid: sourceUid } = sourceSchema;
|
2767
|
+
const { uid: targetUid } = targetSchema;
|
2768
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2519
2769
|
const dbQuery = strapi.db.query(sourceUid);
|
2520
2770
|
const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2771
|
+
const filters = {};
|
2772
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2773
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2774
|
+
if (status === "published") {
|
2775
|
+
filters.publishedAt = { $notNull: true };
|
2776
|
+
} else {
|
2777
|
+
filters.publishedAt = { $null: true };
|
2778
|
+
}
|
2779
|
+
}
|
2780
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2781
|
+
filters.publishedAt = { $null: true };
|
2782
|
+
}
|
2521
2783
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2522
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2784
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2523
2785
|
ordering: "desc",
|
2524
2786
|
page: ctx.request.query.page,
|
2525
|
-
pageSize: ctx.request.query.pageSize
|
2787
|
+
pageSize: ctx.request.query.pageSize,
|
2788
|
+
filters
|
2526
2789
|
});
|
2527
2790
|
const loadedIds = res.results.map((item) => item.id);
|
2528
2791
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2529
2792
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2530
2793
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2531
|
-
ordering: "desc"
|
2532
|
-
page: ctx.request.query.page,
|
2533
|
-
pageSize: ctx.request.query.pageSize
|
2794
|
+
ordering: "desc"
|
2534
2795
|
});
|
2535
2796
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2536
2797
|
ctx.body = {
|
@@ -2545,10 +2806,10 @@ const relations = {
|
|
2545
2806
|
}
|
2546
2807
|
};
|
2547
2808
|
const buildPopulateFromQuery = async (query, model) => {
|
2548
|
-
return getService$
|
2809
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2549
2810
|
};
|
2550
2811
|
const findDocument = async (query, uid2, opts = {}) => {
|
2551
|
-
const documentManager2 = getService$
|
2812
|
+
const documentManager2 = getService$2("document-manager");
|
2552
2813
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2553
2814
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2554
2815
|
};
|
@@ -2556,13 +2817,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2556
2817
|
const { user, userAbility } = ctx.state;
|
2557
2818
|
const { model } = ctx.params;
|
2558
2819
|
const { body, query } = ctx.request;
|
2559
|
-
const documentManager2 = getService$
|
2560
|
-
const permissionChecker2 = getService$
|
2820
|
+
const documentManager2 = getService$2("document-manager");
|
2821
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2561
2822
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2562
2823
|
throw new errors.ForbiddenError();
|
2563
2824
|
}
|
2564
2825
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2565
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2826
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2566
2827
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2567
2828
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2568
2829
|
// Find the first document to check if it exists
|
@@ -2598,12 +2859,12 @@ const singleTypes = {
|
|
2598
2859
|
const { userAbility } = ctx.state;
|
2599
2860
|
const { model } = ctx.params;
|
2600
2861
|
const { query = {} } = ctx.request;
|
2601
|
-
const permissionChecker2 = getService$
|
2862
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2602
2863
|
if (permissionChecker2.cannot.read()) {
|
2603
2864
|
return ctx.forbidden();
|
2604
2865
|
}
|
2605
2866
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2606
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2867
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2607
2868
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2608
2869
|
if (!version) {
|
2609
2870
|
if (permissionChecker2.cannot.create()) {
|
@@ -2617,7 +2878,7 @@ const singleTypes = {
|
|
2617
2878
|
permissionChecker2,
|
2618
2879
|
model,
|
2619
2880
|
// @ts-expect-error - fix types
|
2620
|
-
{
|
2881
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2621
2882
|
{ availableLocales: true, availableStatus: false }
|
2622
2883
|
);
|
2623
2884
|
ctx.body = { data: {}, meta };
|
@@ -2632,7 +2893,7 @@ const singleTypes = {
|
|
2632
2893
|
async createOrUpdate(ctx) {
|
2633
2894
|
const { userAbility } = ctx.state;
|
2634
2895
|
const { model } = ctx.params;
|
2635
|
-
const permissionChecker2 = getService$
|
2896
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2636
2897
|
const document = await createOrUpdateDocument(ctx);
|
2637
2898
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2638
2899
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2641,14 +2902,14 @@ const singleTypes = {
|
|
2641
2902
|
const { userAbility } = ctx.state;
|
2642
2903
|
const { model } = ctx.params;
|
2643
2904
|
const { query = {} } = ctx.request;
|
2644
|
-
const documentManager2 = getService$
|
2645
|
-
const permissionChecker2 = getService$
|
2905
|
+
const documentManager2 = getService$2("document-manager");
|
2906
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2646
2907
|
if (permissionChecker2.cannot.delete()) {
|
2647
2908
|
return ctx.forbidden();
|
2648
2909
|
}
|
2649
2910
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2650
2911
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2651
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2912
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2652
2913
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2653
2914
|
populate,
|
2654
2915
|
locale
|
@@ -2670,8 +2931,8 @@ const singleTypes = {
|
|
2670
2931
|
const { userAbility } = ctx.state;
|
2671
2932
|
const { model } = ctx.params;
|
2672
2933
|
const { query = {} } = ctx.request;
|
2673
|
-
const documentManager2 = getService$
|
2674
|
-
const permissionChecker2 = getService$
|
2934
|
+
const documentManager2 = getService$2("document-manager");
|
2935
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2675
2936
|
if (permissionChecker2.cannot.publish()) {
|
2676
2937
|
return ctx.forbidden();
|
2677
2938
|
}
|
@@ -2685,7 +2946,7 @@ const singleTypes = {
|
|
2685
2946
|
if (permissionChecker2.cannot.publish(document)) {
|
2686
2947
|
throw new errors.ForbiddenError();
|
2687
2948
|
}
|
2688
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2949
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2689
2950
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2690
2951
|
return publishResult.at(0);
|
2691
2952
|
});
|
@@ -2699,8 +2960,8 @@ const singleTypes = {
|
|
2699
2960
|
body: { discardDraft, ...body },
|
2700
2961
|
query = {}
|
2701
2962
|
} = ctx.request;
|
2702
|
-
const documentManager2 = getService$
|
2703
|
-
const permissionChecker2 = getService$
|
2963
|
+
const documentManager2 = getService$2("document-manager");
|
2964
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2704
2965
|
if (permissionChecker2.cannot.unpublish()) {
|
2705
2966
|
return ctx.forbidden();
|
2706
2967
|
}
|
@@ -2708,7 +2969,7 @@ const singleTypes = {
|
|
2708
2969
|
return ctx.forbidden();
|
2709
2970
|
}
|
2710
2971
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2711
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2972
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2712
2973
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2713
2974
|
if (!document) {
|
2714
2975
|
return ctx.notFound();
|
@@ -2734,13 +2995,13 @@ const singleTypes = {
|
|
2734
2995
|
const { userAbility } = ctx.state;
|
2735
2996
|
const { model } = ctx.params;
|
2736
2997
|
const { body, query = {} } = ctx.request;
|
2737
|
-
const documentManager2 = getService$
|
2738
|
-
const permissionChecker2 = getService$
|
2998
|
+
const documentManager2 = getService$2("document-manager");
|
2999
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2739
3000
|
if (permissionChecker2.cannot.discard()) {
|
2740
3001
|
return ctx.forbidden();
|
2741
3002
|
}
|
2742
3003
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2743
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3004
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2744
3005
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2745
3006
|
if (!document) {
|
2746
3007
|
return ctx.notFound();
|
@@ -2758,9 +3019,9 @@ const singleTypes = {
|
|
2758
3019
|
const { userAbility } = ctx.state;
|
2759
3020
|
const { model } = ctx.params;
|
2760
3021
|
const { query } = ctx.request;
|
2761
|
-
const documentManager2 = getService$
|
2762
|
-
const permissionChecker2 = getService$
|
2763
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3022
|
+
const documentManager2 = getService$2("document-manager");
|
3023
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3024
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2764
3025
|
if (permissionChecker2.cannot.read()) {
|
2765
3026
|
return ctx.forbidden();
|
2766
3027
|
}
|
@@ -2781,9 +3042,9 @@ const uid$1 = {
|
|
2781
3042
|
async generateUID(ctx) {
|
2782
3043
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2783
3044
|
const { query = {} } = ctx.request;
|
2784
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3045
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2785
3046
|
await validateUIDField(contentTypeUID, field);
|
2786
|
-
const uidService = getService$
|
3047
|
+
const uidService = getService$2("uid");
|
2787
3048
|
ctx.body = {
|
2788
3049
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2789
3050
|
};
|
@@ -2793,9 +3054,9 @@ const uid$1 = {
|
|
2793
3054
|
ctx.request.body
|
2794
3055
|
);
|
2795
3056
|
const { query = {} } = ctx.request;
|
2796
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3057
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2797
3058
|
await validateUIDField(contentTypeUID, field);
|
2798
|
-
const uidService = getService$
|
3059
|
+
const uidService = getService$2("uid");
|
2799
3060
|
const isAvailable = await uidService.checkUIDAvailability({
|
2800
3061
|
contentTypeUID,
|
2801
3062
|
field,
|
@@ -2816,7 +3077,8 @@ const controllers = {
|
|
2816
3077
|
relations,
|
2817
3078
|
"single-types": singleTypes,
|
2818
3079
|
uid: uid$1,
|
2819
|
-
...history.controllers ? history.controllers : {}
|
3080
|
+
...history.controllers ? history.controllers : {},
|
3081
|
+
...preview.controllers ? preview.controllers : {}
|
2820
3082
|
};
|
2821
3083
|
const keys = {
|
2822
3084
|
CONFIGURATION: "configuration"
|
@@ -2967,12 +3229,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2967
3229
|
return _.assign(metasWithDefaults, updatedMetas);
|
2968
3230
|
}
|
2969
3231
|
const getTargetSchema = (targetModel) => {
|
2970
|
-
return getService$
|
3232
|
+
return getService$2("content-types").findContentType(targetModel);
|
2971
3233
|
};
|
2972
3234
|
const DEFAULT_LIST_LENGTH = 4;
|
2973
3235
|
const MAX_ROW_SIZE = 12;
|
2974
3236
|
const isAllowedFieldSize = (type, size) => {
|
2975
|
-
const { getFieldSize } = getService$
|
3237
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2976
3238
|
const fieldSize = getFieldSize(type);
|
2977
3239
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2978
3240
|
return false;
|
@@ -2980,7 +3242,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2980
3242
|
return size <= MAX_ROW_SIZE;
|
2981
3243
|
};
|
2982
3244
|
const getDefaultFieldSize = (attribute) => {
|
2983
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3245
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2984
3246
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2985
3247
|
};
|
2986
3248
|
async function createDefaultLayouts(schema) {
|
@@ -3015,7 +3277,7 @@ function syncLayouts(configuration, schema) {
|
|
3015
3277
|
for (const el of row) {
|
3016
3278
|
if (!hasEditableAttribute(schema, el.name))
|
3017
3279
|
continue;
|
3018
|
-
const { hasFieldSize } = getService$
|
3280
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3019
3281
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3020
3282
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3021
3283
|
elementsToReAppend.push(el.name);
|
@@ -3155,17 +3417,17 @@ const configurationService$1 = createConfigurationService({
|
|
3155
3417
|
isComponent: true,
|
3156
3418
|
prefix: STORE_KEY_PREFIX,
|
3157
3419
|
getModels() {
|
3158
|
-
const { toContentManagerModel } = getService$
|
3420
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3159
3421
|
return mapValues(toContentManagerModel, strapi.components);
|
3160
3422
|
}
|
3161
3423
|
});
|
3162
3424
|
const components = ({ strapi: strapi2 }) => ({
|
3163
3425
|
findAllComponents() {
|
3164
|
-
const { toContentManagerModel } = getService$
|
3426
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3165
3427
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3166
3428
|
},
|
3167
3429
|
findComponent(uid2) {
|
3168
|
-
const { toContentManagerModel } = getService$
|
3430
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3169
3431
|
const component = strapi2.components[uid2];
|
3170
3432
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3171
3433
|
},
|
@@ -3216,17 +3478,17 @@ const configurationService = createConfigurationService({
|
|
3216
3478
|
storeUtils,
|
3217
3479
|
prefix: "content_types",
|
3218
3480
|
getModels() {
|
3219
|
-
const { toContentManagerModel } = getService$
|
3481
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3220
3482
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3221
3483
|
}
|
3222
3484
|
});
|
3223
3485
|
const service = ({ strapi: strapi2 }) => ({
|
3224
3486
|
findAllContentTypes() {
|
3225
|
-
const { toContentManagerModel } = getService$
|
3487
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3226
3488
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3227
3489
|
},
|
3228
3490
|
findContentType(uid2) {
|
3229
|
-
const { toContentManagerModel } = getService$
|
3491
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3230
3492
|
const contentType = strapi2.contentTypes[uid2];
|
3231
3493
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3232
3494
|
},
|
@@ -3255,7 +3517,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3255
3517
|
return this.findConfiguration(contentType);
|
3256
3518
|
},
|
3257
3519
|
findComponentsConfigurations(contentType) {
|
3258
|
-
return getService$
|
3520
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3259
3521
|
},
|
3260
3522
|
syncConfigurations() {
|
3261
3523
|
return configurationService.syncConfigurations();
|
@@ -3436,12 +3698,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3436
3698
|
ability: userAbility,
|
3437
3699
|
model
|
3438
3700
|
});
|
3439
|
-
const
|
3701
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3702
|
+
const toSubject = (entity) => {
|
3703
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3704
|
+
};
|
3440
3705
|
const can = (action, entity, field) => {
|
3441
|
-
|
3706
|
+
const subject = toSubject(entity);
|
3707
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3708
|
+
return (
|
3709
|
+
// Test the original action to see if it passes
|
3710
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3711
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3712
|
+
);
|
3442
3713
|
};
|
3443
3714
|
const cannot = (action, entity, field) => {
|
3444
|
-
|
3715
|
+
const subject = toSubject(entity);
|
3716
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3717
|
+
return (
|
3718
|
+
// Test both the original action
|
3719
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3720
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3721
|
+
);
|
3445
3722
|
};
|
3446
3723
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3447
3724
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3512,7 +3789,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3512
3789
|
return userAbility.can(action);
|
3513
3790
|
},
|
3514
3791
|
async registerPermissions() {
|
3515
|
-
const displayedContentTypes = getService$
|
3792
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3516
3793
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3517
3794
|
const actions = [
|
3518
3795
|
{
|
@@ -3718,6 +3995,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3718
3995
|
const attribute = model.attributes[attributeName];
|
3719
3996
|
switch (attribute.type) {
|
3720
3997
|
case "relation": {
|
3998
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3999
|
+
if (isMorphRelation) {
|
4000
|
+
break;
|
4001
|
+
}
|
3721
4002
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3722
4003
|
populateAcc[attributeName] = {
|
3723
4004
|
count: true,
|
@@ -3784,7 +4065,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3784
4065
|
return populateQuery;
|
3785
4066
|
};
|
3786
4067
|
const buildDeepPopulate = (uid2) => {
|
3787
|
-
return getService$
|
4068
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3788
4069
|
};
|
3789
4070
|
const populateBuilder = (uid2) => {
|
3790
4071
|
let getInitialPopulate = async () => {
|
@@ -3969,7 +4250,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3969
4250
|
*/
|
3970
4251
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3971
4252
|
const versionsByLocale = groupBy("locale", allVersions);
|
3972
|
-
|
4253
|
+
if (version.locale) {
|
4254
|
+
delete versionsByLocale[version.locale];
|
4255
|
+
}
|
3973
4256
|
const model = strapi2.getModel(uid2);
|
3974
4257
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3975
4258
|
const traversalFunction = async (localeVersion) => traverseEntity(
|
@@ -4095,7 +4378,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4095
4378
|
*/
|
4096
4379
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4097
4380
|
if (!document) {
|
4098
|
-
return
|
4381
|
+
return {
|
4382
|
+
data: document,
|
4383
|
+
meta: {
|
4384
|
+
availableLocales: [],
|
4385
|
+
availableStatus: []
|
4386
|
+
}
|
4387
|
+
};
|
4099
4388
|
}
|
4100
4389
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4101
4390
|
if (!hasDraftAndPublish) {
|
@@ -4203,10 +4492,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4203
4492
|
async clone(id, body, uid2) {
|
4204
4493
|
const populate = await buildDeepPopulate(uid2);
|
4205
4494
|
const params = {
|
4206
|
-
data:
|
4207
|
-
...omitIdField(body),
|
4208
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4209
|
-
},
|
4495
|
+
data: omitIdField(body),
|
4210
4496
|
populate
|
4211
4497
|
};
|
4212
4498
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4322,7 +4608,8 @@ const services = {
|
|
4322
4608
|
permission,
|
4323
4609
|
"populate-builder": populateBuilder$1,
|
4324
4610
|
uid,
|
4325
|
-
...history.services ? history.services : {}
|
4611
|
+
...history.services ? history.services : {},
|
4612
|
+
...preview.services ? preview.services : {}
|
4326
4613
|
};
|
4327
4614
|
const index = () => {
|
4328
4615
|
return {
|