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