@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.8e52d29d243dccc7c24beb53412cf1c9c0b36d11
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-DJcn1DrO.js → ComponentConfigurationPage--MCP7Aew.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage--MCP7Aew.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-DT41asyM.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-DT41asyM.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-DznPxn9p.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-DznPxn9p.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-qgnNvv_u.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-qgnNvv_u.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-B_k7z288.mjs} +72 -50
- package/dist/_chunks/EditViewPage-B_k7z288.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-Bb4S7p8c.js} +70 -48
- package/dist/_chunks/EditViewPage-Bb4S7p8c.js.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-ByR1mllE.js} +582 -230
- package/dist/_chunks/Field-ByR1mllE.js.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-DmwbE0TL.mjs} +580 -228
- package/dist/_chunks/Field-DmwbE0TL.mjs.map +1 -0
- package/dist/_chunks/{Form-Bpig5rch.js → Form-BpeyAyS1.js} +52 -34
- package/dist/_chunks/Form-BpeyAyS1.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-Dvt5eouJ.mjs} +54 -36
- package/dist/_chunks/Form-Dvt5eouJ.mjs.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-CAERKpYl.mjs} +171 -77
- package/dist/_chunks/History-CAERKpYl.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-d-IgDGPl.js} +170 -76
- package/dist/_chunks/History-d-IgDGPl.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-CVVT45M8.mjs} +59 -49
- package/dist/_chunks/ListConfigurationPage-CVVT45M8.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-DSX98CYb.js} +58 -47
- package/dist/_chunks/ListConfigurationPage-DSX98CYb.js.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-C9gPPp-V.js} +117 -105
- package/dist/_chunks/ListViewPage-C9gPPp-V.js.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-Q4g6kHDl.mjs} +115 -103
- package/dist/_chunks/ListViewPage-Q4g6kHDl.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-BY4YRGs0.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-BY4YRGs0.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-D09gppmy.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-D09gppmy.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-32WgThJG.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-32WgThJG.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-CyM16RKL.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-CyM16RKL.mjs.map} +1 -1
- package/dist/_chunks/Preview-C2WFq4S8.mjs +267 -0
- package/dist/_chunks/Preview-C2WFq4S8.mjs.map +1 -0
- package/dist/_chunks/Preview-PpV3g9wJ.js +286 -0
- package/dist/_chunks/Preview-PpV3g9wJ.js.map +1 -0
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-B_Yn9xGB.mjs} +73 -37
- package/dist/_chunks/Relations-B_Yn9xGB.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-mWaebC5t.js} +72 -36
- package/dist/_chunks/Relations-mWaebC5t.js.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-CHOp_xJv.js} +30 -16
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-CHOp_xJv.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-D_BMf0hT.mjs} +30 -16
- package/dist/_chunks/{en-Dzv55oQw.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-VHviNMeW.mjs → index-CbytGVdz.mjs} +1154 -887
- package/dist/_chunks/index-CbytGVdz.mjs.map +1 -0
- package/dist/_chunks/{index-DzN3kBgx.js → index-iun2i4xv.js} +1133 -865
- package/dist/_chunks/index-iun2i4xv.js.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-Btu_cMRF.mjs} +41 -23
- package/dist/_chunks/layout-Btu_cMRF.mjs.map +1 -0
- package/dist/_chunks/{layout-b91XRlD2.js → layout-CkaP4K5_.js} +39 -21
- package/dist/_chunks/layout-CkaP4K5_.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-BsqxS6tR.mjs → relations-Cn5re8ia.mjs} +6 -7
- package/dist/_chunks/relations-Cn5re8ia.mjs.map +1 -0
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-O_v9g0v_.js} +6 -7
- package/dist/_chunks/relations-O_v9g0v_.js.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.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 +8 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- 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 +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- 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 +551 -263
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +552 -264
- 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-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
- package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
- package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.js
CHANGED
@@ -33,10 +33,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
33
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
34
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
35
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
36
|
+
const getService$2 = (name) => {
|
37
37
|
return strapi.plugin("content-manager").service(name);
|
38
38
|
};
|
39
|
-
function getService(strapi2, name) {
|
39
|
+
function getService$1(strapi2, name) {
|
40
40
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
41
|
}
|
42
42
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +72,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
72
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
73
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
74
|
}
|
75
|
-
const permissionChecker2 = getService$
|
75
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
76
|
userAbility: ctx.state.userAbility,
|
77
77
|
model: ctx.query.contentType
|
78
78
|
});
|
@@ -80,7 +80,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
80
|
return ctx.forbidden();
|
81
81
|
}
|
82
82
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
83
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
84
|
query: {
|
85
85
|
...query,
|
86
86
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +105,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
105
|
async restoreVersion(ctx) {
|
106
106
|
const request = ctx.request;
|
107
107
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
108
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
109
|
userAbility: ctx.state.userAbility,
|
110
110
|
model: request.body.contentType
|
111
111
|
});
|
112
112
|
if (permissionChecker2.cannot.update()) {
|
113
113
|
throw new strapiUtils.errors.ForbiddenError();
|
114
114
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
115
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
116
|
request.params.versionId
|
117
117
|
);
|
118
118
|
return {
|
@@ -121,7 +121,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
121
|
}
|
122
122
|
};
|
123
123
|
};
|
124
|
-
const controllers$
|
124
|
+
const controllers$2 = {
|
125
125
|
"history-version": createHistoryVersionController
|
126
126
|
/**
|
127
127
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -199,7 +199,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
199
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
200
|
};
|
201
201
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
202
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
203
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
204
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
205
|
const getLocaleDictionary = async () => {
|
204
206
|
if (!localesService)
|
205
207
|
return {};
|
@@ -226,31 +228,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
228
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
229
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
230
|
};
|
229
|
-
const
|
231
|
+
const getComponentFields = (componentUID) => {
|
232
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
233
|
+
(fieldsAcc, [key, attribute]) => {
|
234
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
235
|
+
fieldsAcc.push(key);
|
236
|
+
}
|
237
|
+
return fieldsAcc;
|
238
|
+
},
|
239
|
+
[]
|
240
|
+
);
|
241
|
+
};
|
242
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
243
|
const model = strapi2.getModel(uid2);
|
231
244
|
const attributes = Object.entries(model.attributes);
|
245
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
246
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
247
|
switch (attribute.type) {
|
234
248
|
case "relation": {
|
249
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
250
|
+
if (isMorphRelation) {
|
251
|
+
break;
|
252
|
+
}
|
235
253
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
236
254
|
if (isVisible2) {
|
237
|
-
acc[attributeName] = {
|
255
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
238
256
|
}
|
239
257
|
break;
|
240
258
|
}
|
241
259
|
case "media": {
|
242
|
-
acc[attributeName] = {
|
260
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
243
261
|
break;
|
244
262
|
}
|
245
263
|
case "component": {
|
246
264
|
const populate = getDeepPopulate2(attribute.component);
|
247
|
-
acc[attributeName] = {
|
265
|
+
acc[attributeName] = {
|
266
|
+
populate,
|
267
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
268
|
+
};
|
248
269
|
break;
|
249
270
|
}
|
250
271
|
case "dynamiczone": {
|
251
272
|
const populatedComponents = (attribute.components || []).reduce(
|
252
273
|
(acc2, componentUID) => {
|
253
|
-
acc2[componentUID] = {
|
274
|
+
acc2[componentUID] = {
|
275
|
+
populate: getDeepPopulate2(componentUID),
|
276
|
+
[fieldSelector]: getComponentFields(componentUID)
|
277
|
+
};
|
254
278
|
return acc2;
|
255
279
|
},
|
256
280
|
{}
|
@@ -312,6 +336,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
312
336
|
getRelationRestoreValue,
|
313
337
|
getMediaRestoreValue,
|
314
338
|
getDefaultLocale,
|
339
|
+
isLocalizedContentType,
|
315
340
|
getLocaleDictionary,
|
316
341
|
getRetentionDays,
|
317
342
|
getVersionStatus,
|
@@ -334,7 +359,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
359
|
});
|
335
360
|
},
|
336
361
|
async findVersionsPage(params) {
|
337
|
-
const
|
362
|
+
const model = strapi2.getModel(params.query.contentType);
|
363
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
364
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
365
|
+
let locale = null;
|
366
|
+
if (isLocalizedContentType) {
|
367
|
+
locale = params.query.locale || defaultLocale;
|
368
|
+
}
|
338
369
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
339
370
|
query.findPage({
|
340
371
|
...params.query,
|
@@ -356,7 +387,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
356
387
|
const attributeValue = entry.data[attributeKey];
|
357
388
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
358
389
|
if (attributeSchema.type === "media") {
|
359
|
-
const permissionChecker2 = getService$
|
390
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
360
391
|
userAbility: params.state.userAbility,
|
361
392
|
model: "plugin::upload.file"
|
362
393
|
});
|
@@ -379,7 +410,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
379
410
|
if (userToPopulate == null) {
|
380
411
|
return null;
|
381
412
|
}
|
382
|
-
return strapi2.query("admin::user").findOne({
|
413
|
+
return strapi2.query("admin::user").findOne({
|
414
|
+
where: {
|
415
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
416
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
417
|
+
}
|
418
|
+
});
|
383
419
|
})
|
384
420
|
);
|
385
421
|
return {
|
@@ -392,7 +428,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
392
428
|
[attributeKey]: adminUsers
|
393
429
|
};
|
394
430
|
}
|
395
|
-
const permissionChecker2 = getService$
|
431
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
396
432
|
userAbility: params.state.userAbility,
|
397
433
|
model: attributeSchema.target
|
398
434
|
});
|
@@ -490,13 +526,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
490
526
|
}
|
491
527
|
};
|
492
528
|
};
|
529
|
+
const shouldCreateHistoryVersion = (context) => {
|
530
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
540
|
+
return false;
|
541
|
+
}
|
542
|
+
return true;
|
543
|
+
};
|
544
|
+
const getSchemas = (uid2) => {
|
545
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
546
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
547
|
+
(currentComponentSchemas, key) => {
|
548
|
+
const fieldSchema = attributesSchema[key];
|
549
|
+
if (fieldSchema.type === "component") {
|
550
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
551
|
+
return {
|
552
|
+
...currentComponentSchemas,
|
553
|
+
[fieldSchema.component]: componentSchema
|
554
|
+
};
|
555
|
+
}
|
556
|
+
return currentComponentSchemas;
|
557
|
+
},
|
558
|
+
{}
|
559
|
+
);
|
560
|
+
return {
|
561
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
562
|
+
componentsSchemas
|
563
|
+
};
|
564
|
+
};
|
493
565
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
566
|
const state = {
|
495
567
|
deleteExpiredJob: null,
|
496
568
|
isInitialized: false
|
497
569
|
};
|
498
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
-
const historyService = getService(strapi2, "history");
|
500
570
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
571
|
return {
|
502
572
|
async bootstrap() {
|
@@ -504,73 +574,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
504
574
|
return;
|
505
575
|
}
|
506
576
|
strapi2.documents.use(async (context, next) => {
|
507
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
-
return next();
|
509
|
-
}
|
510
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
-
return next();
|
512
|
-
}
|
513
|
-
const contentTypeUid = context.contentType.uid;
|
514
|
-
if (!contentTypeUid.startsWith("api::")) {
|
515
|
-
return next();
|
516
|
-
}
|
517
577
|
const result = await next();
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
578
|
+
if (!shouldCreateHistoryVersion(context)) {
|
579
|
+
return result;
|
580
|
+
}
|
581
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
522
582
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
523
|
-
const
|
524
|
-
if (
|
525
|
-
|
526
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
527
|
-
);
|
528
|
-
return next();
|
583
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
584
|
+
if (!locales.length) {
|
585
|
+
return result;
|
529
586
|
}
|
530
|
-
const
|
531
|
-
|
532
|
-
|
533
|
-
|
587
|
+
const uid2 = context.contentType.uid;
|
588
|
+
const schemas = getSchemas(uid2);
|
589
|
+
const model = strapi2.getModel(uid2);
|
590
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
591
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
592
|
+
where: {
|
593
|
+
documentId,
|
594
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
595
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
596
|
+
},
|
597
|
+
populate: serviceUtils.getDeepPopulate(
|
598
|
+
uid2,
|
599
|
+
true
|
600
|
+
/* use database syntax */
|
601
|
+
)
|
534
602
|
});
|
535
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
536
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
537
|
-
const componentsSchemas = Object.keys(
|
538
|
-
attributesSchema
|
539
|
-
).reduce((currentComponentSchemas, key) => {
|
540
|
-
const fieldSchema = attributesSchema[key];
|
541
|
-
if (fieldSchema.type === "component") {
|
542
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
543
|
-
return {
|
544
|
-
...currentComponentSchemas,
|
545
|
-
[fieldSchema.component]: componentSchema
|
546
|
-
};
|
547
|
-
}
|
548
|
-
return currentComponentSchemas;
|
549
|
-
}, {});
|
550
603
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
551
|
-
onCommit(() => {
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
604
|
+
onCommit(async () => {
|
605
|
+
for (const entry of localeEntries) {
|
606
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
607
|
+
await getService$1(strapi2, "history").createVersion({
|
608
|
+
contentType: uid2,
|
609
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
610
|
+
relatedDocumentId: documentId,
|
611
|
+
locale: entry.locale,
|
612
|
+
status,
|
613
|
+
...schemas
|
614
|
+
});
|
615
|
+
}
|
561
616
|
});
|
562
617
|
});
|
563
618
|
return result;
|
564
619
|
});
|
565
|
-
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
620
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
566
621
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
567
622
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
568
|
-
query.deleteMany({
|
623
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
569
624
|
where: {
|
570
625
|
created_at: {
|
571
|
-
$lt: expirationDate
|
626
|
+
$lt: expirationDate
|
572
627
|
}
|
573
628
|
}
|
629
|
+
}).catch((error) => {
|
630
|
+
if (error instanceof Error) {
|
631
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
632
|
+
}
|
574
633
|
});
|
575
634
|
});
|
576
635
|
state.isInitialized = true;
|
@@ -582,17 +641,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
582
641
|
}
|
583
642
|
};
|
584
643
|
};
|
585
|
-
const services$
|
644
|
+
const services$2 = {
|
586
645
|
history: createHistoryService,
|
587
646
|
lifecycles: createLifecyclesService
|
588
647
|
};
|
589
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
648
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
590
649
|
const historyVersionRouter = {
|
591
650
|
type: "admin",
|
592
651
|
routes: [
|
593
652
|
{
|
594
653
|
method: "GET",
|
595
|
-
info,
|
654
|
+
info: info$1,
|
596
655
|
path: "/history-versions",
|
597
656
|
handler: "history-version.findMany",
|
598
657
|
config: {
|
@@ -601,7 +660,7 @@ const historyVersionRouter = {
|
|
601
660
|
},
|
602
661
|
{
|
603
662
|
method: "PUT",
|
604
|
-
info,
|
663
|
+
info: info$1,
|
605
664
|
path: "/history-versions/:versionId/restore",
|
606
665
|
handler: "history-version.restoreVersion",
|
607
666
|
config: {
|
@@ -610,7 +669,7 @@ const historyVersionRouter = {
|
|
610
669
|
}
|
611
670
|
]
|
612
671
|
};
|
613
|
-
const routes$
|
672
|
+
const routes$2 = {
|
614
673
|
"history-version": historyVersionRouter
|
615
674
|
};
|
616
675
|
const historyVersion = {
|
@@ -657,21 +716,21 @@ const historyVersion = {
|
|
657
716
|
}
|
658
717
|
}
|
659
718
|
};
|
660
|
-
const getFeature = () => {
|
719
|
+
const getFeature$1 = () => {
|
661
720
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
662
721
|
return {
|
663
722
|
register({ strapi: strapi2 }) {
|
664
723
|
strapi2.get("models").add(historyVersion);
|
665
724
|
},
|
666
725
|
bootstrap({ strapi: strapi2 }) {
|
667
|
-
getService(strapi2, "lifecycles").bootstrap();
|
726
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
668
727
|
},
|
669
728
|
destroy({ strapi: strapi2 }) {
|
670
|
-
getService(strapi2, "lifecycles").destroy();
|
729
|
+
getService$1(strapi2, "lifecycles").destroy();
|
671
730
|
},
|
672
|
-
controllers: controllers$
|
673
|
-
services: services$
|
674
|
-
routes: routes$
|
731
|
+
controllers: controllers$2,
|
732
|
+
services: services$2,
|
733
|
+
routes: routes$2
|
675
734
|
};
|
676
735
|
}
|
677
736
|
return {
|
@@ -680,7 +739,7 @@ const getFeature = () => {
|
|
680
739
|
}
|
681
740
|
};
|
682
741
|
};
|
683
|
-
const history = getFeature();
|
742
|
+
const history = getFeature$1();
|
684
743
|
const register = async ({ strapi: strapi2 }) => {
|
685
744
|
await history.register?.({ strapi: strapi2 });
|
686
745
|
};
|
@@ -688,15 +747,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
|
|
688
747
|
ENTRY_PUBLISH: "entry.publish",
|
689
748
|
ENTRY_UNPUBLISH: "entry.unpublish"
|
690
749
|
};
|
750
|
+
const FEATURE_ID = "preview";
|
751
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
752
|
+
const previewRouter = {
|
753
|
+
type: "admin",
|
754
|
+
routes: [
|
755
|
+
{
|
756
|
+
method: "GET",
|
757
|
+
info,
|
758
|
+
path: "/preview/url/:contentType",
|
759
|
+
handler: "preview.getPreviewUrl",
|
760
|
+
config: {
|
761
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
762
|
+
}
|
763
|
+
}
|
764
|
+
]
|
765
|
+
};
|
766
|
+
const routes$1 = {
|
767
|
+
preview: previewRouter
|
768
|
+
};
|
769
|
+
function getService(strapi2, name) {
|
770
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
771
|
+
}
|
772
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
773
|
+
// Will be undefined for single types
|
774
|
+
documentId: yup__namespace.string(),
|
775
|
+
locale: yup__namespace.string().nullable(),
|
776
|
+
status: yup__namespace.string()
|
777
|
+
}).required();
|
778
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
779
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
780
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
781
|
+
const model = strapi2.getModel(uid2);
|
782
|
+
if (!model || model.modelType !== "contentType") {
|
783
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
784
|
+
}
|
785
|
+
const isSingleType = model?.kind === "singleType";
|
786
|
+
if (!isSingleType && !params.documentId) {
|
787
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
788
|
+
}
|
789
|
+
if (isSingleType) {
|
790
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
791
|
+
if (!doc) {
|
792
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
793
|
+
}
|
794
|
+
newParams.documentId = doc?.documentId;
|
795
|
+
}
|
796
|
+
return newParams;
|
797
|
+
};
|
798
|
+
const createPreviewController = () => {
|
799
|
+
return {
|
800
|
+
/**
|
801
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
802
|
+
* in the Content Manager.
|
803
|
+
*/
|
804
|
+
async getPreviewUrl(ctx) {
|
805
|
+
const uid2 = ctx.params.contentType;
|
806
|
+
const query = ctx.request.query;
|
807
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
808
|
+
const previewService = getService(strapi, "preview");
|
809
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
810
|
+
if (!url) {
|
811
|
+
ctx.status = 204;
|
812
|
+
}
|
813
|
+
return {
|
814
|
+
data: { url }
|
815
|
+
};
|
816
|
+
}
|
817
|
+
};
|
818
|
+
};
|
819
|
+
const controllers$1 = {
|
820
|
+
preview: createPreviewController
|
821
|
+
/**
|
822
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
823
|
+
* passing a controller factory as the value, instead of a controller object directly
|
824
|
+
*/
|
825
|
+
};
|
826
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
827
|
+
const config = getService(strapi2, "preview-config");
|
828
|
+
return {
|
829
|
+
async getPreviewUrl(uid2, params) {
|
830
|
+
const handler = config.getPreviewHandler();
|
831
|
+
try {
|
832
|
+
return handler(uid2, params);
|
833
|
+
} catch (error) {
|
834
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
835
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
836
|
+
}
|
837
|
+
return;
|
838
|
+
}
|
839
|
+
};
|
840
|
+
};
|
841
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
842
|
+
return {
|
843
|
+
isEnabled() {
|
844
|
+
const config = strapi2.config.get("admin.preview");
|
845
|
+
if (!config) {
|
846
|
+
return false;
|
847
|
+
}
|
848
|
+
return config?.enabled ?? true;
|
849
|
+
},
|
850
|
+
/**
|
851
|
+
* Validate if the configuration is valid
|
852
|
+
*/
|
853
|
+
validate() {
|
854
|
+
if (!this.isEnabled()) {
|
855
|
+
return;
|
856
|
+
}
|
857
|
+
const handler = this.getPreviewHandler();
|
858
|
+
if (typeof handler !== "function") {
|
859
|
+
throw new strapiUtils.errors.ValidationError(
|
860
|
+
"Preview configuration is invalid. Handler must be a function"
|
861
|
+
);
|
862
|
+
}
|
863
|
+
},
|
864
|
+
/**
|
865
|
+
* Utility to get the preview handler from the configuration
|
866
|
+
*/
|
867
|
+
getPreviewHandler() {
|
868
|
+
const config = strapi2.config.get("admin.preview");
|
869
|
+
const emptyHandler = () => {
|
870
|
+
return void 0;
|
871
|
+
};
|
872
|
+
if (!this.isEnabled()) {
|
873
|
+
return emptyHandler;
|
874
|
+
}
|
875
|
+
return config?.config?.handler || emptyHandler;
|
876
|
+
}
|
877
|
+
};
|
878
|
+
};
|
879
|
+
const services$1 = {
|
880
|
+
preview: createPreviewService,
|
881
|
+
"preview-config": createPreviewConfigService
|
882
|
+
};
|
883
|
+
const getFeature = () => {
|
884
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
885
|
+
return {};
|
886
|
+
}
|
887
|
+
return {
|
888
|
+
bootstrap() {
|
889
|
+
console.log("Bootstrapping preview server");
|
890
|
+
const config = getService(strapi, "preview-config");
|
891
|
+
config.validate();
|
892
|
+
},
|
893
|
+
routes: routes$1,
|
894
|
+
controllers: controllers$1,
|
895
|
+
services: services$1
|
896
|
+
};
|
897
|
+
};
|
898
|
+
const preview = getFeature();
|
691
899
|
const bootstrap = async () => {
|
692
900
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
693
901
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
694
902
|
});
|
695
|
-
getService$
|
696
|
-
await getService$
|
697
|
-
await getService$
|
698
|
-
await getService$
|
903
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
904
|
+
await getService$2("components").syncConfigurations();
|
905
|
+
await getService$2("content-types").syncConfigurations();
|
906
|
+
await getService$2("permission").registerPermissions();
|
699
907
|
await history.bootstrap?.({ strapi });
|
908
|
+
await preview.bootstrap?.({ strapi });
|
700
909
|
};
|
701
910
|
const destroy = async ({ strapi: strapi2 }) => {
|
702
911
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1186,7 +1395,8 @@ const admin = {
|
|
1186
1395
|
};
|
1187
1396
|
const routes = {
|
1188
1397
|
admin,
|
1189
|
-
...history.routes ? history.routes : {}
|
1398
|
+
...history.routes ? history.routes : {},
|
1399
|
+
...preview.routes ? preview.routes : {}
|
1190
1400
|
};
|
1191
1401
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1192
1402
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1197,6 +1407,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1197
1407
|
const hasPermissions = createPolicy({
|
1198
1408
|
name: "plugin::content-manager.hasPermissions",
|
1199
1409
|
validator: validateHasPermissionsInput,
|
1410
|
+
/**
|
1411
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1412
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1413
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1414
|
+
*/
|
1200
1415
|
handler(ctx, config = {}) {
|
1201
1416
|
const { actions = [], hasAtLeastOne = false } = config;
|
1202
1417
|
const { userAbility } = ctx.state;
|
@@ -1438,7 +1653,7 @@ const createMetadasSchema = (schema) => {
|
|
1438
1653
|
if (!value) {
|
1439
1654
|
return strapiUtils.yup.string();
|
1440
1655
|
}
|
1441
|
-
const targetSchema = getService$
|
1656
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1442
1657
|
schema.attributes[key].targetModel
|
1443
1658
|
);
|
1444
1659
|
if (!targetSchema) {
|
@@ -1590,9 +1805,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1590
1805
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1591
1806
|
);
|
1592
1807
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1593
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1808
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1594
1809
|
const { allowMultipleLocales } = opts;
|
1595
|
-
const { locale, status, ...rest } = request || {};
|
1810
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1811
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1812
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1596
1813
|
const schema = strapiUtils.yup.object().shape({
|
1597
1814
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1598
1815
|
status: statusSchema
|
@@ -1605,7 +1822,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1605
1822
|
}
|
1606
1823
|
};
|
1607
1824
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1608
|
-
const documentMetadata2 = getService$
|
1825
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1609
1826
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1610
1827
|
let {
|
1611
1828
|
meta: { availableLocales, availableStatus }
|
@@ -1631,8 +1848,8 @@ const createDocument = async (ctx, opts) => {
|
|
1631
1848
|
const { userAbility, user } = ctx.state;
|
1632
1849
|
const { model } = ctx.params;
|
1633
1850
|
const { body } = ctx.request;
|
1634
|
-
const documentManager2 = getService$
|
1635
|
-
const permissionChecker2 = getService$
|
1851
|
+
const documentManager2 = getService$2("document-manager");
|
1852
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1636
1853
|
if (permissionChecker2.cannot.create()) {
|
1637
1854
|
throw new strapiUtils.errors.ForbiddenError();
|
1638
1855
|
}
|
@@ -1640,7 +1857,7 @@ const createDocument = async (ctx, opts) => {
|
|
1640
1857
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1641
1858
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1642
1859
|
const sanitizedBody = await sanitizeFn(body);
|
1643
|
-
const { locale, status
|
1860
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1644
1861
|
return documentManager2.create(model, {
|
1645
1862
|
data: sanitizedBody,
|
1646
1863
|
locale,
|
@@ -1652,14 +1869,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1652
1869
|
const { userAbility, user } = ctx.state;
|
1653
1870
|
const { id, model } = ctx.params;
|
1654
1871
|
const { body } = ctx.request;
|
1655
|
-
const documentManager2 = getService$
|
1656
|
-
const permissionChecker2 = getService$
|
1872
|
+
const documentManager2 = getService$2("document-manager");
|
1873
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1657
1874
|
if (permissionChecker2.cannot.update()) {
|
1658
1875
|
throw new strapiUtils.errors.ForbiddenError();
|
1659
1876
|
}
|
1660
1877
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1661
|
-
const populate = await getService$
|
1662
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1878
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1879
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1663
1880
|
const [documentVersion, documentExists] = await Promise.all([
|
1664
1881
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1665
1882
|
documentManager2.exists(model, id)
|
@@ -1675,7 +1892,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1675
1892
|
throw new strapiUtils.errors.ForbiddenError();
|
1676
1893
|
}
|
1677
1894
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1678
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1895
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1679
1896
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1680
1897
|
const sanitizedBody = await sanitizeFn(body);
|
1681
1898
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1689,15 +1906,15 @@ const collectionTypes = {
|
|
1689
1906
|
const { userAbility } = ctx.state;
|
1690
1907
|
const { model } = ctx.params;
|
1691
1908
|
const { query } = ctx.request;
|
1692
|
-
const documentMetadata2 = getService$
|
1693
|
-
const documentManager2 = getService$
|
1694
|
-
const permissionChecker2 = getService$
|
1909
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1910
|
+
const documentManager2 = getService$2("document-manager");
|
1911
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1695
1912
|
if (permissionChecker2.cannot.read()) {
|
1696
1913
|
return ctx.forbidden();
|
1697
1914
|
}
|
1698
1915
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1699
|
-
const populate = await getService$
|
1700
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1916
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1917
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1701
1918
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1702
1919
|
{ ...permissionQuery, populate, locale, status },
|
1703
1920
|
model
|
@@ -1725,14 +1942,14 @@ const collectionTypes = {
|
|
1725
1942
|
async findOne(ctx) {
|
1726
1943
|
const { userAbility } = ctx.state;
|
1727
1944
|
const { model, id } = ctx.params;
|
1728
|
-
const documentManager2 = getService$
|
1729
|
-
const permissionChecker2 = getService$
|
1945
|
+
const documentManager2 = getService$2("document-manager");
|
1946
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1730
1947
|
if (permissionChecker2.cannot.read()) {
|
1731
1948
|
return ctx.forbidden();
|
1732
1949
|
}
|
1733
1950
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1734
|
-
const populate = await getService$
|
1735
|
-
const { locale, status
|
1951
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1952
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1736
1953
|
const version = await documentManager2.findOne(id, model, {
|
1737
1954
|
populate,
|
1738
1955
|
locale,
|
@@ -1747,7 +1964,7 @@ const collectionTypes = {
|
|
1747
1964
|
permissionChecker2,
|
1748
1965
|
model,
|
1749
1966
|
// @ts-expect-error TODO: fix
|
1750
|
-
{ id, locale, publishedAt: null },
|
1967
|
+
{ documentId: id, locale, publishedAt: null },
|
1751
1968
|
{ availableLocales: true, availableStatus: false }
|
1752
1969
|
);
|
1753
1970
|
ctx.body = { data: {}, meta };
|
@@ -1762,7 +1979,7 @@ const collectionTypes = {
|
|
1762
1979
|
async create(ctx) {
|
1763
1980
|
const { userAbility } = ctx.state;
|
1764
1981
|
const { model } = ctx.params;
|
1765
|
-
const permissionChecker2 = getService$
|
1982
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1766
1983
|
const [totalEntries, document] = await Promise.all([
|
1767
1984
|
strapi.db.query(model).count(),
|
1768
1985
|
createDocument(ctx)
|
@@ -1783,7 +2000,7 @@ const collectionTypes = {
|
|
1783
2000
|
async update(ctx) {
|
1784
2001
|
const { userAbility } = ctx.state;
|
1785
2002
|
const { model } = ctx.params;
|
1786
|
-
const permissionChecker2 = getService$
|
2003
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1787
2004
|
const updatedVersion = await updateDocument(ctx);
|
1788
2005
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1789
2006
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1792,14 +2009,14 @@ const collectionTypes = {
|
|
1792
2009
|
const { userAbility, user } = ctx.state;
|
1793
2010
|
const { model, sourceId: id } = ctx.params;
|
1794
2011
|
const { body } = ctx.request;
|
1795
|
-
const documentManager2 = getService$
|
1796
|
-
const permissionChecker2 = getService$
|
2012
|
+
const documentManager2 = getService$2("document-manager");
|
2013
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1797
2014
|
if (permissionChecker2.cannot.create()) {
|
1798
2015
|
return ctx.forbidden();
|
1799
2016
|
}
|
1800
2017
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1801
|
-
const populate = await getService$
|
1802
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2018
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2019
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1803
2020
|
const document = await documentManager2.findOne(id, model, {
|
1804
2021
|
populate,
|
1805
2022
|
locale,
|
@@ -1837,14 +2054,14 @@ const collectionTypes = {
|
|
1837
2054
|
async delete(ctx) {
|
1838
2055
|
const { userAbility } = ctx.state;
|
1839
2056
|
const { id, model } = ctx.params;
|
1840
|
-
const documentManager2 = getService$
|
1841
|
-
const permissionChecker2 = getService$
|
2057
|
+
const documentManager2 = getService$2("document-manager");
|
2058
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1842
2059
|
if (permissionChecker2.cannot.delete()) {
|
1843
2060
|
return ctx.forbidden();
|
1844
2061
|
}
|
1845
2062
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1846
|
-
const populate = await getService$
|
1847
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2063
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2064
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1848
2065
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1849
2066
|
if (documentLocales.length === 0) {
|
1850
2067
|
return ctx.notFound();
|
@@ -1865,19 +2082,42 @@ const collectionTypes = {
|
|
1865
2082
|
const { userAbility } = ctx.state;
|
1866
2083
|
const { id, model } = ctx.params;
|
1867
2084
|
const { body } = ctx.request;
|
1868
|
-
const documentManager2 = getService$
|
1869
|
-
const permissionChecker2 = getService$
|
2085
|
+
const documentManager2 = getService$2("document-manager");
|
2086
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1870
2087
|
if (permissionChecker2.cannot.publish()) {
|
1871
2088
|
return ctx.forbidden();
|
1872
2089
|
}
|
1873
2090
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1874
2091
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1875
|
-
const populate = await getService$
|
1876
|
-
|
2092
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2093
|
+
let document;
|
2094
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2095
|
+
const isCreate = fp.isNil(id);
|
2096
|
+
if (isCreate) {
|
2097
|
+
if (permissionChecker2.cannot.create()) {
|
2098
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2099
|
+
}
|
2100
|
+
document = await createDocument(ctx, { populate });
|
2101
|
+
}
|
2102
|
+
const isUpdate = !isCreate;
|
2103
|
+
if (isUpdate) {
|
2104
|
+
const documentExists = documentManager2.exists(model, id);
|
2105
|
+
if (!documentExists) {
|
2106
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2107
|
+
}
|
2108
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2109
|
+
if (!document) {
|
2110
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2111
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2112
|
+
}
|
2113
|
+
document = await updateDocument(ctx);
|
2114
|
+
} else if (permissionChecker2.can.update(document)) {
|
2115
|
+
await updateDocument(ctx);
|
2116
|
+
}
|
2117
|
+
}
|
1877
2118
|
if (permissionChecker2.cannot.publish(document)) {
|
1878
2119
|
throw new strapiUtils.errors.ForbiddenError();
|
1879
2120
|
}
|
1880
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1881
2121
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1882
2122
|
locale
|
1883
2123
|
// TODO: Allow setting creator fields on publish
|
@@ -1897,14 +2137,16 @@ const collectionTypes = {
|
|
1897
2137
|
const { body } = ctx.request;
|
1898
2138
|
const { documentIds } = body;
|
1899
2139
|
await validateBulkActionInput(body);
|
1900
|
-
const documentManager2 = getService$
|
1901
|
-
const permissionChecker2 = getService$
|
2140
|
+
const documentManager2 = getService$2("document-manager");
|
2141
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1902
2142
|
if (permissionChecker2.cannot.publish()) {
|
1903
2143
|
return ctx.forbidden();
|
1904
2144
|
}
|
1905
2145
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1906
|
-
const populate = await getService$
|
1907
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2146
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2147
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2148
|
+
allowMultipleLocales: true
|
2149
|
+
});
|
1908
2150
|
const entityPromises = documentIds.map(
|
1909
2151
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1910
2152
|
);
|
@@ -1926,12 +2168,14 @@ const collectionTypes = {
|
|
1926
2168
|
const { body } = ctx.request;
|
1927
2169
|
const { documentIds } = body;
|
1928
2170
|
await validateBulkActionInput(body);
|
1929
|
-
const documentManager2 = getService$
|
1930
|
-
const permissionChecker2 = getService$
|
2171
|
+
const documentManager2 = getService$2("document-manager");
|
2172
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1931
2173
|
if (permissionChecker2.cannot.unpublish()) {
|
1932
2174
|
return ctx.forbidden();
|
1933
2175
|
}
|
1934
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2176
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2177
|
+
allowMultipleLocales: true
|
2178
|
+
});
|
1935
2179
|
const entityPromises = documentIds.map(
|
1936
2180
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1937
2181
|
);
|
@@ -1954,8 +2198,8 @@ const collectionTypes = {
|
|
1954
2198
|
const {
|
1955
2199
|
body: { discardDraft, ...body }
|
1956
2200
|
} = ctx.request;
|
1957
|
-
const documentManager2 = getService$
|
1958
|
-
const permissionChecker2 = getService$
|
2201
|
+
const documentManager2 = getService$2("document-manager");
|
2202
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1959
2203
|
if (permissionChecker2.cannot.unpublish()) {
|
1960
2204
|
return ctx.forbidden();
|
1961
2205
|
}
|
@@ -1963,8 +2207,8 @@ const collectionTypes = {
|
|
1963
2207
|
return ctx.forbidden();
|
1964
2208
|
}
|
1965
2209
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1966
|
-
const populate = await getService$
|
1967
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2210
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2211
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1968
2212
|
const document = await documentManager2.findOne(id, model, {
|
1969
2213
|
populate,
|
1970
2214
|
locale,
|
@@ -1994,14 +2238,14 @@ const collectionTypes = {
|
|
1994
2238
|
const { userAbility } = ctx.state;
|
1995
2239
|
const { id, model } = ctx.params;
|
1996
2240
|
const { body } = ctx.request;
|
1997
|
-
const documentManager2 = getService$
|
1998
|
-
const permissionChecker2 = getService$
|
2241
|
+
const documentManager2 = getService$2("document-manager");
|
2242
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1999
2243
|
if (permissionChecker2.cannot.discard()) {
|
2000
2244
|
return ctx.forbidden();
|
2001
2245
|
}
|
2002
2246
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2003
|
-
const populate = await getService$
|
2004
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2247
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2248
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2005
2249
|
const document = await documentManager2.findOne(id, model, {
|
2006
2250
|
populate,
|
2007
2251
|
locale,
|
@@ -2025,14 +2269,14 @@ const collectionTypes = {
|
|
2025
2269
|
const { query, body } = ctx.request;
|
2026
2270
|
const { documentIds } = body;
|
2027
2271
|
await validateBulkActionInput(body);
|
2028
|
-
const documentManager2 = getService$
|
2029
|
-
const permissionChecker2 = getService$
|
2272
|
+
const documentManager2 = getService$2("document-manager");
|
2273
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2030
2274
|
if (permissionChecker2.cannot.delete()) {
|
2031
2275
|
return ctx.forbidden();
|
2032
2276
|
}
|
2033
2277
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2034
|
-
const populate = await getService$
|
2035
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2278
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2279
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2036
2280
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2037
2281
|
populate,
|
2038
2282
|
locale
|
@@ -2052,14 +2296,14 @@ const collectionTypes = {
|
|
2052
2296
|
async countDraftRelations(ctx) {
|
2053
2297
|
const { userAbility } = ctx.state;
|
2054
2298
|
const { model, id } = ctx.params;
|
2055
|
-
const documentManager2 = getService$
|
2056
|
-
const permissionChecker2 = getService$
|
2299
|
+
const documentManager2 = getService$2("document-manager");
|
2300
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2057
2301
|
if (permissionChecker2.cannot.read()) {
|
2058
2302
|
return ctx.forbidden();
|
2059
2303
|
}
|
2060
2304
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2061
|
-
const populate = await getService$
|
2062
|
-
const { locale, status
|
2305
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2306
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2063
2307
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2064
2308
|
if (!entity) {
|
2065
2309
|
return ctx.notFound();
|
@@ -2077,12 +2321,12 @@ const collectionTypes = {
|
|
2077
2321
|
const ids = ctx.request.query.documentIds;
|
2078
2322
|
const locale = ctx.request.query.locale;
|
2079
2323
|
const { model } = ctx.params;
|
2080
|
-
const documentManager2 = getService$
|
2081
|
-
const permissionChecker2 = getService$
|
2324
|
+
const documentManager2 = getService$2("document-manager");
|
2325
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2082
2326
|
if (permissionChecker2.cannot.read()) {
|
2083
2327
|
return ctx.forbidden();
|
2084
2328
|
}
|
2085
|
-
const
|
2329
|
+
const documents = await documentManager2.findMany(
|
2086
2330
|
{
|
2087
2331
|
filters: {
|
2088
2332
|
documentId: ids
|
@@ -2091,7 +2335,7 @@ const collectionTypes = {
|
|
2091
2335
|
},
|
2092
2336
|
model
|
2093
2337
|
);
|
2094
|
-
if (!
|
2338
|
+
if (!documents) {
|
2095
2339
|
return ctx.notFound();
|
2096
2340
|
}
|
2097
2341
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2102,13 +2346,13 @@ const collectionTypes = {
|
|
2102
2346
|
};
|
2103
2347
|
const components$1 = {
|
2104
2348
|
findComponents(ctx) {
|
2105
|
-
const components2 = getService$
|
2106
|
-
const { toDto } = getService$
|
2349
|
+
const components2 = getService$2("components").findAllComponents();
|
2350
|
+
const { toDto } = getService$2("data-mapper");
|
2107
2351
|
ctx.body = { data: components2.map(toDto) };
|
2108
2352
|
},
|
2109
2353
|
async findComponentConfiguration(ctx) {
|
2110
2354
|
const { uid: uid2 } = ctx.params;
|
2111
|
-
const componentService = getService$
|
2355
|
+
const componentService = getService$2("components");
|
2112
2356
|
const component = componentService.findComponent(uid2);
|
2113
2357
|
if (!component) {
|
2114
2358
|
return ctx.notFound("component.notFound");
|
@@ -2125,7 +2369,7 @@ const components$1 = {
|
|
2125
2369
|
async updateComponentConfiguration(ctx) {
|
2126
2370
|
const { uid: uid2 } = ctx.params;
|
2127
2371
|
const { body } = ctx.request;
|
2128
|
-
const componentService = getService$
|
2372
|
+
const componentService = getService$2("components");
|
2129
2373
|
const component = componentService.findComponent(uid2);
|
2130
2374
|
if (!component) {
|
2131
2375
|
return ctx.notFound("component.notFound");
|
@@ -2159,12 +2403,12 @@ const contentTypes = {
|
|
2159
2403
|
} catch (error) {
|
2160
2404
|
return ctx.send({ error }, 400);
|
2161
2405
|
}
|
2162
|
-
const contentTypes2 = getService$
|
2163
|
-
const { toDto } = getService$
|
2406
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2407
|
+
const { toDto } = getService$2("data-mapper");
|
2164
2408
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2165
2409
|
},
|
2166
2410
|
async findContentTypesSettings(ctx) {
|
2167
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2411
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2168
2412
|
const contentTypes2 = await findAllContentTypes();
|
2169
2413
|
const configurations = await Promise.all(
|
2170
2414
|
contentTypes2.map(async (contentType) => {
|
@@ -2178,7 +2422,7 @@ const contentTypes = {
|
|
2178
2422
|
},
|
2179
2423
|
async findContentTypeConfiguration(ctx) {
|
2180
2424
|
const { uid: uid2 } = ctx.params;
|
2181
|
-
const contentTypeService = getService$
|
2425
|
+
const contentTypeService = getService$2("content-types");
|
2182
2426
|
const contentType = await contentTypeService.findContentType(uid2);
|
2183
2427
|
if (!contentType) {
|
2184
2428
|
return ctx.notFound("contentType.notFound");
|
@@ -2200,13 +2444,13 @@ const contentTypes = {
|
|
2200
2444
|
const { userAbility } = ctx.state;
|
2201
2445
|
const { uid: uid2 } = ctx.params;
|
2202
2446
|
const { body } = ctx.request;
|
2203
|
-
const contentTypeService = getService$
|
2204
|
-
const metricsService = getService$
|
2447
|
+
const contentTypeService = getService$2("content-types");
|
2448
|
+
const metricsService = getService$2("metrics");
|
2205
2449
|
const contentType = await contentTypeService.findContentType(uid2);
|
2206
2450
|
if (!contentType) {
|
2207
2451
|
return ctx.notFound("contentType.notFound");
|
2208
2452
|
}
|
2209
|
-
if (!getService$
|
2453
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2210
2454
|
return ctx.forbidden();
|
2211
2455
|
}
|
2212
2456
|
let input;
|
@@ -2239,10 +2483,10 @@ const contentTypes = {
|
|
2239
2483
|
};
|
2240
2484
|
const init = {
|
2241
2485
|
getInitData(ctx) {
|
2242
|
-
const { toDto } = getService$
|
2243
|
-
const { findAllComponents } = getService$
|
2244
|
-
const { getAllFieldSizes } = getService$
|
2245
|
-
const { findAllContentTypes } = getService$
|
2486
|
+
const { toDto } = getService$2("data-mapper");
|
2487
|
+
const { findAllComponents } = getService$2("components");
|
2488
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2489
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2246
2490
|
ctx.body = {
|
2247
2491
|
data: {
|
2248
2492
|
fieldSizes: getAllFieldSizes(),
|
@@ -2278,36 +2522,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2278
2522
|
params.filters.$and.push(filtersClause);
|
2279
2523
|
};
|
2280
2524
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2281
|
-
const permissionChecker2 = getService$
|
2525
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2282
2526
|
userAbility,
|
2283
2527
|
model: model.uid
|
2284
2528
|
});
|
2285
|
-
|
2529
|
+
const isMainFieldListable = isListable(model, mainField);
|
2530
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2531
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2286
2532
|
return "id";
|
2287
2533
|
}
|
2288
|
-
if (
|
2289
|
-
|
2290
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2291
|
-
userAbility,
|
2292
|
-
model: "plugin::users-permissions.user"
|
2293
|
-
});
|
2294
|
-
if (userPermissionChecker.can.read()) {
|
2295
|
-
return "name";
|
2296
|
-
}
|
2297
|
-
}
|
2298
|
-
return "id";
|
2534
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2535
|
+
return "name";
|
2299
2536
|
}
|
2300
2537
|
return mainField;
|
2301
2538
|
};
|
2302
|
-
const addStatusToRelations = async (
|
2303
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2539
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2540
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2304
2541
|
return relations2;
|
2305
2542
|
}
|
2306
|
-
const documentMetadata2 = getService$
|
2307
|
-
|
2543
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2544
|
+
if (!relations2.length) {
|
2545
|
+
return relations2;
|
2546
|
+
}
|
2547
|
+
const firstRelation = relations2[0];
|
2548
|
+
const filters = {
|
2549
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2550
|
+
// NOTE: find the "opposite" status
|
2551
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2552
|
+
};
|
2553
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2554
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2555
|
+
filters
|
2556
|
+
});
|
2308
2557
|
return relations2.map((relation) => {
|
2309
|
-
const availableStatuses =
|
2310
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2558
|
+
const availableStatuses = availableStatus.filter(
|
2559
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2311
2560
|
);
|
2312
2561
|
return {
|
2313
2562
|
...relation,
|
@@ -2328,11 +2577,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2328
2577
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2329
2578
|
const isSourceLocalized = isLocalized(sourceModel);
|
2330
2579
|
const isTargetLocalized = isLocalized(targetModel);
|
2331
|
-
let validatedLocale = locale;
|
2332
|
-
if (!targetModel || !isTargetLocalized)
|
2333
|
-
validatedLocale = void 0;
|
2334
2580
|
return {
|
2335
|
-
locale
|
2581
|
+
locale,
|
2336
2582
|
isSourceLocalized,
|
2337
2583
|
isTargetLocalized
|
2338
2584
|
};
|
@@ -2372,7 +2618,7 @@ const relations = {
|
|
2372
2618
|
ctx.request?.query?.locale
|
2373
2619
|
);
|
2374
2620
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2375
|
-
const permissionChecker2 = getService$
|
2621
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2376
2622
|
userAbility,
|
2377
2623
|
model
|
2378
2624
|
});
|
@@ -2397,7 +2643,7 @@ const relations = {
|
|
2397
2643
|
where.id = id;
|
2398
2644
|
}
|
2399
2645
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2400
|
-
const populate = await getService$
|
2646
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2401
2647
|
const currentEntity = await strapi.db.query(model).findOne({
|
2402
2648
|
where,
|
2403
2649
|
populate
|
@@ -2412,7 +2658,7 @@ const relations = {
|
|
2412
2658
|
}
|
2413
2659
|
entryId = currentEntity.id;
|
2414
2660
|
}
|
2415
|
-
const modelConfig = isComponent2 ? await getService$
|
2661
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2416
2662
|
const targetSchema = strapi.getModel(targetUid);
|
2417
2663
|
const mainField = fp.flow(
|
2418
2664
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2435,7 +2681,7 @@ const relations = {
|
|
2435
2681
|
attribute,
|
2436
2682
|
fieldsToSelect,
|
2437
2683
|
mainField,
|
2438
|
-
source: { schema: sourceSchema },
|
2684
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2439
2685
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2440
2686
|
sourceSchema,
|
2441
2687
|
targetSchema,
|
@@ -2457,7 +2703,8 @@ const relations = {
|
|
2457
2703
|
fieldsToSelect,
|
2458
2704
|
mainField,
|
2459
2705
|
source: {
|
2460
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2706
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2707
|
+
isLocalized: isSourceLocalized
|
2461
2708
|
},
|
2462
2709
|
target: {
|
2463
2710
|
schema: { uid: targetUid },
|
@@ -2465,7 +2712,7 @@ const relations = {
|
|
2465
2712
|
}
|
2466
2713
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2467
2714
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2468
|
-
const permissionChecker2 = getService$
|
2715
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2469
2716
|
userAbility: ctx.state.userAbility,
|
2470
2717
|
model: targetUid
|
2471
2718
|
});
|
@@ -2495,12 +2742,16 @@ const relations = {
|
|
2495
2742
|
} else {
|
2496
2743
|
where.id = id;
|
2497
2744
|
}
|
2498
|
-
|
2499
|
-
|
2745
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2746
|
+
if (!fp.isEmpty(publishedAt)) {
|
2747
|
+
where[`${alias}.published_at`] = publishedAt;
|
2500
2748
|
}
|
2501
|
-
if (
|
2749
|
+
if (isTargetLocalized && locale) {
|
2502
2750
|
where[`${alias}.locale`] = locale;
|
2503
2751
|
}
|
2752
|
+
if (isSourceLocalized && locale) {
|
2753
|
+
where.locale = locale;
|
2754
|
+
}
|
2504
2755
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2505
2756
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2506
2757
|
}
|
@@ -2518,7 +2769,8 @@ const relations = {
|
|
2518
2769
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2519
2770
|
});
|
2520
2771
|
}
|
2521
|
-
const
|
2772
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2773
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2522
2774
|
ctx.body = {
|
2523
2775
|
...res,
|
2524
2776
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2533,29 +2785,39 @@ const relations = {
|
|
2533
2785
|
attribute,
|
2534
2786
|
targetField,
|
2535
2787
|
fieldsToSelect,
|
2536
|
-
|
2537
|
-
|
2538
|
-
}
|
2539
|
-
target: {
|
2540
|
-
schema: { uid: targetUid }
|
2541
|
-
}
|
2788
|
+
status,
|
2789
|
+
source: { schema: sourceSchema },
|
2790
|
+
target: { schema: targetSchema }
|
2542
2791
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2543
|
-
const
|
2792
|
+
const { uid: sourceUid } = sourceSchema;
|
2793
|
+
const { uid: targetUid } = targetSchema;
|
2794
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2544
2795
|
const dbQuery = strapi.db.query(sourceUid);
|
2545
2796
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2797
|
+
const filters = {};
|
2798
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2799
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2800
|
+
if (status === "published") {
|
2801
|
+
filters.publishedAt = { $notNull: true };
|
2802
|
+
} else {
|
2803
|
+
filters.publishedAt = { $null: true };
|
2804
|
+
}
|
2805
|
+
}
|
2806
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2807
|
+
filters.publishedAt = { $null: true };
|
2808
|
+
}
|
2546
2809
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2547
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2810
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2548
2811
|
ordering: "desc",
|
2549
2812
|
page: ctx.request.query.page,
|
2550
|
-
pageSize: ctx.request.query.pageSize
|
2813
|
+
pageSize: ctx.request.query.pageSize,
|
2814
|
+
filters
|
2551
2815
|
});
|
2552
2816
|
const loadedIds = res.results.map((item) => item.id);
|
2553
2817
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2554
2818
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2555
2819
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2556
|
-
ordering: "desc"
|
2557
|
-
page: ctx.request.query.page,
|
2558
|
-
pageSize: ctx.request.query.pageSize
|
2820
|
+
ordering: "desc"
|
2559
2821
|
});
|
2560
2822
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2561
2823
|
ctx.body = {
|
@@ -2570,10 +2832,10 @@ const relations = {
|
|
2570
2832
|
}
|
2571
2833
|
};
|
2572
2834
|
const buildPopulateFromQuery = async (query, model) => {
|
2573
|
-
return getService$
|
2835
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2574
2836
|
};
|
2575
2837
|
const findDocument = async (query, uid2, opts = {}) => {
|
2576
|
-
const documentManager2 = getService$
|
2838
|
+
const documentManager2 = getService$2("document-manager");
|
2577
2839
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2578
2840
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2579
2841
|
};
|
@@ -2581,13 +2843,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2581
2843
|
const { user, userAbility } = ctx.state;
|
2582
2844
|
const { model } = ctx.params;
|
2583
2845
|
const { body, query } = ctx.request;
|
2584
|
-
const documentManager2 = getService$
|
2585
|
-
const permissionChecker2 = getService$
|
2846
|
+
const documentManager2 = getService$2("document-manager");
|
2847
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2586
2848
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2587
2849
|
throw new strapiUtils.errors.ForbiddenError();
|
2588
2850
|
}
|
2589
2851
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2590
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2852
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2591
2853
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2592
2854
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2593
2855
|
// Find the first document to check if it exists
|
@@ -2623,12 +2885,12 @@ const singleTypes = {
|
|
2623
2885
|
const { userAbility } = ctx.state;
|
2624
2886
|
const { model } = ctx.params;
|
2625
2887
|
const { query = {} } = ctx.request;
|
2626
|
-
const permissionChecker2 = getService$
|
2888
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2627
2889
|
if (permissionChecker2.cannot.read()) {
|
2628
2890
|
return ctx.forbidden();
|
2629
2891
|
}
|
2630
2892
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2631
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2893
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2632
2894
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2633
2895
|
if (!version) {
|
2634
2896
|
if (permissionChecker2.cannot.create()) {
|
@@ -2642,7 +2904,7 @@ const singleTypes = {
|
|
2642
2904
|
permissionChecker2,
|
2643
2905
|
model,
|
2644
2906
|
// @ts-expect-error - fix types
|
2645
|
-
{
|
2907
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2646
2908
|
{ availableLocales: true, availableStatus: false }
|
2647
2909
|
);
|
2648
2910
|
ctx.body = { data: {}, meta };
|
@@ -2657,7 +2919,7 @@ const singleTypes = {
|
|
2657
2919
|
async createOrUpdate(ctx) {
|
2658
2920
|
const { userAbility } = ctx.state;
|
2659
2921
|
const { model } = ctx.params;
|
2660
|
-
const permissionChecker2 = getService$
|
2922
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2661
2923
|
const document = await createOrUpdateDocument(ctx);
|
2662
2924
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2663
2925
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2666,14 +2928,14 @@ const singleTypes = {
|
|
2666
2928
|
const { userAbility } = ctx.state;
|
2667
2929
|
const { model } = ctx.params;
|
2668
2930
|
const { query = {} } = ctx.request;
|
2669
|
-
const documentManager2 = getService$
|
2670
|
-
const permissionChecker2 = getService$
|
2931
|
+
const documentManager2 = getService$2("document-manager");
|
2932
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2671
2933
|
if (permissionChecker2.cannot.delete()) {
|
2672
2934
|
return ctx.forbidden();
|
2673
2935
|
}
|
2674
2936
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2675
2937
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2676
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2938
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2677
2939
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2678
2940
|
populate,
|
2679
2941
|
locale
|
@@ -2695,8 +2957,8 @@ const singleTypes = {
|
|
2695
2957
|
const { userAbility } = ctx.state;
|
2696
2958
|
const { model } = ctx.params;
|
2697
2959
|
const { query = {} } = ctx.request;
|
2698
|
-
const documentManager2 = getService$
|
2699
|
-
const permissionChecker2 = getService$
|
2960
|
+
const documentManager2 = getService$2("document-manager");
|
2961
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2700
2962
|
if (permissionChecker2.cannot.publish()) {
|
2701
2963
|
return ctx.forbidden();
|
2702
2964
|
}
|
@@ -2710,7 +2972,7 @@ const singleTypes = {
|
|
2710
2972
|
if (permissionChecker2.cannot.publish(document)) {
|
2711
2973
|
throw new strapiUtils.errors.ForbiddenError();
|
2712
2974
|
}
|
2713
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2975
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2714
2976
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2715
2977
|
return publishResult.at(0);
|
2716
2978
|
});
|
@@ -2724,8 +2986,8 @@ const singleTypes = {
|
|
2724
2986
|
body: { discardDraft, ...body },
|
2725
2987
|
query = {}
|
2726
2988
|
} = ctx.request;
|
2727
|
-
const documentManager2 = getService$
|
2728
|
-
const permissionChecker2 = getService$
|
2989
|
+
const documentManager2 = getService$2("document-manager");
|
2990
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2729
2991
|
if (permissionChecker2.cannot.unpublish()) {
|
2730
2992
|
return ctx.forbidden();
|
2731
2993
|
}
|
@@ -2733,7 +2995,7 @@ const singleTypes = {
|
|
2733
2995
|
return ctx.forbidden();
|
2734
2996
|
}
|
2735
2997
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2736
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2998
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2737
2999
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2738
3000
|
if (!document) {
|
2739
3001
|
return ctx.notFound();
|
@@ -2759,13 +3021,13 @@ const singleTypes = {
|
|
2759
3021
|
const { userAbility } = ctx.state;
|
2760
3022
|
const { model } = ctx.params;
|
2761
3023
|
const { body, query = {} } = ctx.request;
|
2762
|
-
const documentManager2 = getService$
|
2763
|
-
const permissionChecker2 = getService$
|
3024
|
+
const documentManager2 = getService$2("document-manager");
|
3025
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2764
3026
|
if (permissionChecker2.cannot.discard()) {
|
2765
3027
|
return ctx.forbidden();
|
2766
3028
|
}
|
2767
3029
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2768
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3030
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2769
3031
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2770
3032
|
if (!document) {
|
2771
3033
|
return ctx.notFound();
|
@@ -2783,9 +3045,9 @@ const singleTypes = {
|
|
2783
3045
|
const { userAbility } = ctx.state;
|
2784
3046
|
const { model } = ctx.params;
|
2785
3047
|
const { query } = ctx.request;
|
2786
|
-
const documentManager2 = getService$
|
2787
|
-
const permissionChecker2 = getService$
|
2788
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3048
|
+
const documentManager2 = getService$2("document-manager");
|
3049
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3050
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2789
3051
|
if (permissionChecker2.cannot.read()) {
|
2790
3052
|
return ctx.forbidden();
|
2791
3053
|
}
|
@@ -2806,9 +3068,9 @@ const uid$1 = {
|
|
2806
3068
|
async generateUID(ctx) {
|
2807
3069
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2808
3070
|
const { query = {} } = ctx.request;
|
2809
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3071
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2810
3072
|
await validateUIDField(contentTypeUID, field);
|
2811
|
-
const uidService = getService$
|
3073
|
+
const uidService = getService$2("uid");
|
2812
3074
|
ctx.body = {
|
2813
3075
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2814
3076
|
};
|
@@ -2818,9 +3080,9 @@ const uid$1 = {
|
|
2818
3080
|
ctx.request.body
|
2819
3081
|
);
|
2820
3082
|
const { query = {} } = ctx.request;
|
2821
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3083
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2822
3084
|
await validateUIDField(contentTypeUID, field);
|
2823
|
-
const uidService = getService$
|
3085
|
+
const uidService = getService$2("uid");
|
2824
3086
|
const isAvailable = await uidService.checkUIDAvailability({
|
2825
3087
|
contentTypeUID,
|
2826
3088
|
field,
|
@@ -2841,7 +3103,8 @@ const controllers = {
|
|
2841
3103
|
relations,
|
2842
3104
|
"single-types": singleTypes,
|
2843
3105
|
uid: uid$1,
|
2844
|
-
...history.controllers ? history.controllers : {}
|
3106
|
+
...history.controllers ? history.controllers : {},
|
3107
|
+
...preview.controllers ? preview.controllers : {}
|
2845
3108
|
};
|
2846
3109
|
const keys = {
|
2847
3110
|
CONFIGURATION: "configuration"
|
@@ -2992,12 +3255,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2992
3255
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
2993
3256
|
}
|
2994
3257
|
const getTargetSchema = (targetModel) => {
|
2995
|
-
return getService$
|
3258
|
+
return getService$2("content-types").findContentType(targetModel);
|
2996
3259
|
};
|
2997
3260
|
const DEFAULT_LIST_LENGTH = 4;
|
2998
3261
|
const MAX_ROW_SIZE = 12;
|
2999
3262
|
const isAllowedFieldSize = (type, size) => {
|
3000
|
-
const { getFieldSize } = getService$
|
3263
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3001
3264
|
const fieldSize = getFieldSize(type);
|
3002
3265
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3003
3266
|
return false;
|
@@ -3005,7 +3268,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3005
3268
|
return size <= MAX_ROW_SIZE;
|
3006
3269
|
};
|
3007
3270
|
const getDefaultFieldSize = (attribute) => {
|
3008
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3271
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3009
3272
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3010
3273
|
};
|
3011
3274
|
async function createDefaultLayouts(schema) {
|
@@ -3040,7 +3303,7 @@ function syncLayouts(configuration, schema) {
|
|
3040
3303
|
for (const el of row) {
|
3041
3304
|
if (!hasEditableAttribute(schema, el.name))
|
3042
3305
|
continue;
|
3043
|
-
const { hasFieldSize } = getService$
|
3306
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3044
3307
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3045
3308
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3046
3309
|
elementsToReAppend.push(el.name);
|
@@ -3180,17 +3443,17 @@ const configurationService$1 = createConfigurationService({
|
|
3180
3443
|
isComponent: true,
|
3181
3444
|
prefix: STORE_KEY_PREFIX,
|
3182
3445
|
getModels() {
|
3183
|
-
const { toContentManagerModel } = getService$
|
3446
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3184
3447
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3185
3448
|
}
|
3186
3449
|
});
|
3187
3450
|
const components = ({ strapi: strapi2 }) => ({
|
3188
3451
|
findAllComponents() {
|
3189
|
-
const { toContentManagerModel } = getService$
|
3452
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3190
3453
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3191
3454
|
},
|
3192
3455
|
findComponent(uid2) {
|
3193
|
-
const { toContentManagerModel } = getService$
|
3456
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3194
3457
|
const component = strapi2.components[uid2];
|
3195
3458
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3196
3459
|
},
|
@@ -3241,17 +3504,17 @@ const configurationService = createConfigurationService({
|
|
3241
3504
|
storeUtils,
|
3242
3505
|
prefix: "content_types",
|
3243
3506
|
getModels() {
|
3244
|
-
const { toContentManagerModel } = getService$
|
3507
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3245
3508
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3246
3509
|
}
|
3247
3510
|
});
|
3248
3511
|
const service = ({ strapi: strapi2 }) => ({
|
3249
3512
|
findAllContentTypes() {
|
3250
|
-
const { toContentManagerModel } = getService$
|
3513
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3251
3514
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3252
3515
|
},
|
3253
3516
|
findContentType(uid2) {
|
3254
|
-
const { toContentManagerModel } = getService$
|
3517
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3255
3518
|
const contentType = strapi2.contentTypes[uid2];
|
3256
3519
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3257
3520
|
},
|
@@ -3280,7 +3543,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3280
3543
|
return this.findConfiguration(contentType);
|
3281
3544
|
},
|
3282
3545
|
findComponentsConfigurations(contentType) {
|
3283
|
-
return getService$
|
3546
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3284
3547
|
},
|
3285
3548
|
syncConfigurations() {
|
3286
3549
|
return configurationService.syncConfigurations();
|
@@ -3461,12 +3724,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3461
3724
|
ability: userAbility,
|
3462
3725
|
model
|
3463
3726
|
});
|
3464
|
-
const
|
3727
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3728
|
+
const toSubject = (entity) => {
|
3729
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3730
|
+
};
|
3465
3731
|
const can = (action, entity, field) => {
|
3466
|
-
|
3732
|
+
const subject = toSubject(entity);
|
3733
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3734
|
+
return (
|
3735
|
+
// Test the original action to see if it passes
|
3736
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3737
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3738
|
+
);
|
3467
3739
|
};
|
3468
3740
|
const cannot = (action, entity, field) => {
|
3469
|
-
|
3741
|
+
const subject = toSubject(entity);
|
3742
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3743
|
+
return (
|
3744
|
+
// Test both the original action
|
3745
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3746
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3747
|
+
);
|
3470
3748
|
};
|
3471
3749
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3472
3750
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3537,7 +3815,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3537
3815
|
return userAbility.can(action);
|
3538
3816
|
},
|
3539
3817
|
async registerPermissions() {
|
3540
|
-
const displayedContentTypes = getService$
|
3818
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3541
3819
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3542
3820
|
const actions = [
|
3543
3821
|
{
|
@@ -3743,6 +4021,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3743
4021
|
const attribute = model.attributes[attributeName];
|
3744
4022
|
switch (attribute.type) {
|
3745
4023
|
case "relation": {
|
4024
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4025
|
+
if (isMorphRelation) {
|
4026
|
+
break;
|
4027
|
+
}
|
3746
4028
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3747
4029
|
populateAcc[attributeName] = {
|
3748
4030
|
count: true,
|
@@ -3809,7 +4091,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3809
4091
|
return populateQuery;
|
3810
4092
|
};
|
3811
4093
|
const buildDeepPopulate = (uid2) => {
|
3812
|
-
return getService$
|
4094
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3813
4095
|
};
|
3814
4096
|
const populateBuilder = (uid2) => {
|
3815
4097
|
let getInitialPopulate = async () => {
|
@@ -3994,7 +4276,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3994
4276
|
*/
|
3995
4277
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3996
4278
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
3997
|
-
|
4279
|
+
if (version.locale) {
|
4280
|
+
delete versionsByLocale[version.locale];
|
4281
|
+
}
|
3998
4282
|
const model = strapi2.getModel(uid2);
|
3999
4283
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4000
4284
|
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
@@ -4120,7 +4404,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4120
4404
|
*/
|
4121
4405
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4122
4406
|
if (!document) {
|
4123
|
-
return
|
4407
|
+
return {
|
4408
|
+
data: document,
|
4409
|
+
meta: {
|
4410
|
+
availableLocales: [],
|
4411
|
+
availableStatus: []
|
4412
|
+
}
|
4413
|
+
};
|
4124
4414
|
}
|
4125
4415
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4126
4416
|
if (!hasDraftAndPublish) {
|
@@ -4228,10 +4518,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4228
4518
|
async clone(id, body, uid2) {
|
4229
4519
|
const populate = await buildDeepPopulate(uid2);
|
4230
4520
|
const params = {
|
4231
|
-
data:
|
4232
|
-
...omitIdField(body),
|
4233
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4234
|
-
},
|
4521
|
+
data: omitIdField(body),
|
4235
4522
|
populate
|
4236
4523
|
};
|
4237
4524
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4347,7 +4634,8 @@ const services = {
|
|
4347
4634
|
permission,
|
4348
4635
|
"populate-builder": populateBuilder$1,
|
4349
4636
|
uid,
|
4350
|
-
...history.services ? history.services : {}
|
4637
|
+
...history.services ? history.services : {},
|
4638
|
+
...preview.services ? preview.services : {}
|
4351
4639
|
};
|
4352
4640
|
const index = () => {
|
4353
4641
|
return {
|