@strapi/content-manager 0.0.0-experimental.bd712ad3930045f4a5d2144c119e0b7856e97fc4 → 0.0.0-experimental.bf539fcb8054f8f95f3fd89fb24321df84d0a9f8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js → ComponentConfigurationPage-CpJNPBgk.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BWQv6yRj.js.map → ComponentConfigurationPage-CpJNPBgk.js.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-C7ImeKGM.mjs → ComponentConfigurationPage-TYDPg5WG.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-C7ImeKGM.mjs.map → ComponentConfigurationPage-TYDPg5WG.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js → EditConfigurationPage-CFDe6SA1.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-CEGwxV-L.js.map → EditConfigurationPage-CFDe6SA1.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs → EditConfigurationPage-DqL8Pq5r.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-MItFGzT9.mjs.map → EditConfigurationPage-DqL8Pq5r.mjs.map} +1 -1
- package/dist/_chunks/{EditViewPage-DhmAg0NK.mjs → EditViewPage-RXrFLav2.mjs} +30 -9
- package/dist/_chunks/EditViewPage-RXrFLav2.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-CmMi2Xsn.js → EditViewPage-khfP2CR3.js} +30 -9
- package/dist/_chunks/EditViewPage-khfP2CR3.js.map +1 -0
- package/dist/_chunks/{Field-Cs62u5pl.mjs → Field--rQeS6Zj.mjs} +179 -107
- package/dist/_chunks/Field--rQeS6Zj.mjs.map +1 -0
- package/dist/_chunks/{Field-1DLtcLAI.js → Field-C1ftmTe9.js} +181 -109
- package/dist/_chunks/Field-C1ftmTe9.js.map +1 -0
- package/dist/_chunks/{Form-zYHtzGUX.mjs → Form-COtGXyUE.mjs} +36 -17
- package/dist/_chunks/Form-COtGXyUE.mjs.map +1 -0
- package/dist/_chunks/{Form-CqFA7F_V.js → Form-CwdX5oLw.js} +36 -17
- package/dist/_chunks/Form-CwdX5oLw.js.map +1 -0
- package/dist/_chunks/{History-DalgFQ3D.mjs → History-BevwkPO1.mjs} +55 -48
- package/dist/_chunks/History-BevwkPO1.mjs.map +1 -0
- package/dist/_chunks/{History-BblwXv7-.js → History-DKS2aqqM.js} +54 -47
- package/dist/_chunks/History-DKS2aqqM.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DWy-vRzs.mjs → ListConfigurationPage-DNfZDtDA.mjs} +15 -5
- package/dist/_chunks/ListConfigurationPage-DNfZDtDA.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-Cpy4QqNd.js → ListConfigurationPage-LSYSPZHH.js} +15 -5
- package/dist/_chunks/ListConfigurationPage-LSYSPZHH.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BkAwIW9s.mjs → ListViewPage-C1PyuYRS.mjs} +59 -39
- package/dist/_chunks/ListViewPage-C1PyuYRS.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-DFjn1DNW.js → ListViewPage-DlUpqLIo.js} +61 -41
- package/dist/_chunks/ListViewPage-DlUpqLIo.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs → NoContentTypePage-C9q744z1.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-B9BCNNdL.mjs.map → NoContentTypePage-C9q744z1.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js → NoContentTypePage-m8wt3sf6.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-C-3ykoxs.js.map → NoContentTypePage-m8wt3sf6.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs → NoPermissionsPage-8BM-LWta.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Bt_HWGat.mjs.map → NoPermissionsPage-8BM-LWta.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js → NoPermissionsPage-DLfPsA0Q.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-DKLmDZnZ.js.map → NoPermissionsPage-DLfPsA0Q.js.map} +1 -1
- package/dist/_chunks/{Relations-CJmTbZ8T.mjs → Relations-D25xRcFy.mjs} +73 -37
- package/dist/_chunks/Relations-D25xRcFy.mjs.map +1 -0
- package/dist/_chunks/{Relations-CrxfoH2n.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-D1344xdw.mjs → index-BvGihCJp.mjs} +1075 -695
- package/dist/_chunks/index-BvGihCJp.mjs.map +1 -0
- package/dist/_chunks/{index-Buwn78Rt.js → index-DqZnjo8F.js} +1057 -676
- 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-DRuJUpas.js → layout-CmaemAO3.js} +21 -8
- package/dist/_chunks/layout-CmaemAO3.js.map +1 -0
- package/dist/_chunks/{layout-ChVuUpa1.mjs → layout-ykHSe2KQ.mjs} +22 -9
- 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-DuoUwyJr.js → relations-D9fKsCLY.js} +3 -7
- package/dist/_chunks/relations-D9fKsCLY.js.map +1 -0
- package/dist/_chunks/{relations-B-deMCy4.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 +5 -4
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -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 +4 -48
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- 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 +544 -261
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +545 -262
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +15 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +30 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +18 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +13 -13
- package/dist/_chunks/EditViewPage-CmMi2Xsn.js.map +0 -1
- package/dist/_chunks/EditViewPage-DhmAg0NK.mjs.map +0 -1
- package/dist/_chunks/Field-1DLtcLAI.js.map +0 -1
- package/dist/_chunks/Field-Cs62u5pl.mjs.map +0 -1
- package/dist/_chunks/Form-CqFA7F_V.js.map +0 -1
- package/dist/_chunks/Form-zYHtzGUX.mjs.map +0 -1
- package/dist/_chunks/History-BblwXv7-.js.map +0 -1
- package/dist/_chunks/History-DalgFQ3D.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-Cpy4QqNd.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DWy-vRzs.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-BkAwIW9s.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-DFjn1DNW.js.map +0 -1
- package/dist/_chunks/Relations-CJmTbZ8T.mjs.map +0 -1
- package/dist/_chunks/Relations-CrxfoH2n.js.map +0 -1
- package/dist/_chunks/index-Buwn78Rt.js.map +0 -1
- package/dist/_chunks/index-D1344xdw.mjs.map +0 -1
- package/dist/_chunks/layout-ChVuUpa1.mjs.map +0 -1
- package/dist/_chunks/layout-DRuJUpas.js.map +0 -1
- package/dist/_chunks/relations-B-deMCy4.mjs.map +0 -1
- package/dist/_chunks/relations-DuoUwyJr.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat,
|
2
|
+
import { pick, omit, difference, castArray, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination: pagination2 } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -79,14 +79,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,9 +202,21 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const
|
205
|
+
const getComponentFields = (componentUID) => {
|
206
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
207
|
+
(fieldsAcc, [key, attribute]) => {
|
208
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
209
|
+
fieldsAcc.push(key);
|
210
|
+
}
|
211
|
+
return fieldsAcc;
|
212
|
+
},
|
213
|
+
[]
|
214
|
+
);
|
215
|
+
};
|
216
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
217
|
const model = strapi2.getModel(uid2);
|
205
218
|
const attributes = Object.entries(model.attributes);
|
219
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
220
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
221
|
switch (attribute.type) {
|
208
222
|
case "relation": {
|
@@ -212,23 +226,29 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
212
226
|
}
|
213
227
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
214
228
|
if (isVisible2) {
|
215
|
-
acc[attributeName] = {
|
229
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
216
230
|
}
|
217
231
|
break;
|
218
232
|
}
|
219
233
|
case "media": {
|
220
|
-
acc[attributeName] = {
|
234
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
221
235
|
break;
|
222
236
|
}
|
223
237
|
case "component": {
|
224
238
|
const populate = getDeepPopulate2(attribute.component);
|
225
|
-
acc[attributeName] = {
|
239
|
+
acc[attributeName] = {
|
240
|
+
populate,
|
241
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
242
|
+
};
|
226
243
|
break;
|
227
244
|
}
|
228
245
|
case "dynamiczone": {
|
229
246
|
const populatedComponents = (attribute.components || []).reduce(
|
230
247
|
(acc2, componentUID) => {
|
231
|
-
acc2[componentUID] = {
|
248
|
+
acc2[componentUID] = {
|
249
|
+
populate: getDeepPopulate2(componentUID),
|
250
|
+
[fieldSelector]: getComponentFields(componentUID)
|
251
|
+
};
|
232
252
|
return acc2;
|
233
253
|
},
|
234
254
|
{}
|
@@ -290,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
290
310
|
getRelationRestoreValue,
|
291
311
|
getMediaRestoreValue,
|
292
312
|
getDefaultLocale,
|
313
|
+
isLocalizedContentType,
|
293
314
|
getLocaleDictionary,
|
294
315
|
getRetentionDays,
|
295
316
|
getVersionStatus,
|
@@ -312,7 +333,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
312
333
|
});
|
313
334
|
},
|
314
335
|
async findVersionsPage(params) {
|
315
|
-
const
|
336
|
+
const model = strapi2.getModel(params.query.contentType);
|
337
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
338
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
339
|
+
let locale = null;
|
340
|
+
if (isLocalizedContentType) {
|
341
|
+
locale = params.query.locale || defaultLocale;
|
342
|
+
}
|
316
343
|
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
317
344
|
query.findPage({
|
318
345
|
...params.query,
|
@@ -334,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
361
|
const attributeValue = entry.data[attributeKey];
|
335
362
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
336
363
|
if (attributeSchema.type === "media") {
|
337
|
-
const permissionChecker2 = getService$
|
364
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
338
365
|
userAbility: params.state.userAbility,
|
339
366
|
model: "plugin::upload.file"
|
340
367
|
});
|
@@ -357,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
357
384
|
if (userToPopulate == null) {
|
358
385
|
return null;
|
359
386
|
}
|
360
|
-
return strapi2.query("admin::user").findOne({
|
387
|
+
return strapi2.query("admin::user").findOne({
|
388
|
+
where: {
|
389
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
390
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
391
|
+
}
|
392
|
+
});
|
361
393
|
})
|
362
394
|
);
|
363
395
|
return {
|
@@ -370,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
370
402
|
[attributeKey]: adminUsers
|
371
403
|
};
|
372
404
|
}
|
373
|
-
const permissionChecker2 = getService$
|
405
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
374
406
|
userAbility: params.state.userAbility,
|
375
407
|
model: attributeSchema.target
|
376
408
|
});
|
@@ -468,6 +500,42 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
468
500
|
}
|
469
501
|
};
|
470
502
|
};
|
503
|
+
const shouldCreateHistoryVersion = (context) => {
|
504
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
508
|
+
return false;
|
509
|
+
}
|
510
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
511
|
+
return false;
|
512
|
+
}
|
513
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
514
|
+
return false;
|
515
|
+
}
|
516
|
+
return true;
|
517
|
+
};
|
518
|
+
const getSchemas = (uid2) => {
|
519
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
520
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
521
|
+
(currentComponentSchemas, key) => {
|
522
|
+
const fieldSchema = attributesSchema[key];
|
523
|
+
if (fieldSchema.type === "component") {
|
524
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
525
|
+
return {
|
526
|
+
...currentComponentSchemas,
|
527
|
+
[fieldSchema.component]: componentSchema
|
528
|
+
};
|
529
|
+
}
|
530
|
+
return currentComponentSchemas;
|
531
|
+
},
|
532
|
+
{}
|
533
|
+
);
|
534
|
+
return {
|
535
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
536
|
+
componentsSchemas
|
537
|
+
};
|
538
|
+
};
|
471
539
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
472
540
|
const state = {
|
473
541
|
deleteExpiredJob: null,
|
@@ -480,76 +548,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
480
548
|
return;
|
481
549
|
}
|
482
550
|
strapi2.documents.use(async (context, next) => {
|
483
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
484
|
-
return next();
|
485
|
-
}
|
486
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
487
|
-
return next();
|
488
|
-
}
|
489
|
-
if (context.action === "update" && strapi2.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
490
|
-
return next();
|
491
|
-
}
|
492
|
-
const contentTypeUid = context.contentType.uid;
|
493
|
-
if (!contentTypeUid.startsWith("api::")) {
|
494
|
-
return next();
|
495
|
-
}
|
496
551
|
const result = await next();
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
552
|
+
if (!shouldCreateHistoryVersion(context)) {
|
553
|
+
return result;
|
554
|
+
}
|
555
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
501
556
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
502
|
-
const
|
503
|
-
if (
|
504
|
-
|
505
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
506
|
-
);
|
507
|
-
return next();
|
557
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
558
|
+
if (!locales.length) {
|
559
|
+
return result;
|
508
560
|
}
|
509
|
-
const
|
510
|
-
|
511
|
-
|
512
|
-
|
561
|
+
const uid2 = context.contentType.uid;
|
562
|
+
const schemas = getSchemas(uid2);
|
563
|
+
const model = strapi2.getModel(uid2);
|
564
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
565
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
566
|
+
where: {
|
567
|
+
documentId,
|
568
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
569
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
570
|
+
},
|
571
|
+
populate: serviceUtils.getDeepPopulate(
|
572
|
+
uid2,
|
573
|
+
true
|
574
|
+
/* use database syntax */
|
575
|
+
)
|
513
576
|
});
|
514
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
515
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
516
|
-
const componentsSchemas = Object.keys(
|
517
|
-
attributesSchema
|
518
|
-
).reduce((currentComponentSchemas, key) => {
|
519
|
-
const fieldSchema = attributesSchema[key];
|
520
|
-
if (fieldSchema.type === "component") {
|
521
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
522
|
-
return {
|
523
|
-
...currentComponentSchemas,
|
524
|
-
[fieldSchema.component]: componentSchema
|
525
|
-
};
|
526
|
-
}
|
527
|
-
return currentComponentSchemas;
|
528
|
-
}, {});
|
529
577
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
530
|
-
onCommit(() => {
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
578
|
+
onCommit(async () => {
|
579
|
+
for (const entry of localeEntries) {
|
580
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
581
|
+
await getService$1(strapi2, "history").createVersion({
|
582
|
+
contentType: uid2,
|
583
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
584
|
+
relatedDocumentId: documentId,
|
585
|
+
locale: entry.locale,
|
586
|
+
status,
|
587
|
+
...schemas
|
588
|
+
});
|
589
|
+
}
|
540
590
|
});
|
541
591
|
});
|
542
592
|
return result;
|
543
593
|
});
|
544
|
-
state.deleteExpiredJob = scheduleJob("0 0 * * *", () => {
|
594
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
545
595
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
546
596
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
547
597
|
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
548
598
|
where: {
|
549
599
|
created_at: {
|
550
|
-
$lt: expirationDate
|
600
|
+
$lt: expirationDate
|
551
601
|
}
|
552
602
|
}
|
603
|
+
}).catch((error) => {
|
604
|
+
if (error instanceof Error) {
|
605
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
606
|
+
}
|
553
607
|
});
|
554
608
|
});
|
555
609
|
state.isInitialized = true;
|
@@ -561,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
561
615
|
}
|
562
616
|
};
|
563
617
|
};
|
564
|
-
const services$
|
618
|
+
const services$2 = {
|
565
619
|
history: createHistoryService,
|
566
620
|
lifecycles: createLifecyclesService
|
567
621
|
};
|
568
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
622
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
569
623
|
const historyVersionRouter = {
|
570
624
|
type: "admin",
|
571
625
|
routes: [
|
572
626
|
{
|
573
627
|
method: "GET",
|
574
|
-
info,
|
628
|
+
info: info$1,
|
575
629
|
path: "/history-versions",
|
576
630
|
handler: "history-version.findMany",
|
577
631
|
config: {
|
@@ -580,7 +634,7 @@ const historyVersionRouter = {
|
|
580
634
|
},
|
581
635
|
{
|
582
636
|
method: "PUT",
|
583
|
-
info,
|
637
|
+
info: info$1,
|
584
638
|
path: "/history-versions/:versionId/restore",
|
585
639
|
handler: "history-version.restoreVersion",
|
586
640
|
config: {
|
@@ -589,7 +643,7 @@ const historyVersionRouter = {
|
|
589
643
|
}
|
590
644
|
]
|
591
645
|
};
|
592
|
-
const routes$
|
646
|
+
const routes$2 = {
|
593
647
|
"history-version": historyVersionRouter
|
594
648
|
};
|
595
649
|
const historyVersion = {
|
@@ -636,21 +690,21 @@ const historyVersion = {
|
|
636
690
|
}
|
637
691
|
}
|
638
692
|
};
|
639
|
-
const getFeature = () => {
|
693
|
+
const getFeature$1 = () => {
|
640
694
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
641
695
|
return {
|
642
696
|
register({ strapi: strapi2 }) {
|
643
697
|
strapi2.get("models").add(historyVersion);
|
644
698
|
},
|
645
699
|
bootstrap({ strapi: strapi2 }) {
|
646
|
-
getService(strapi2, "lifecycles").bootstrap();
|
700
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
647
701
|
},
|
648
702
|
destroy({ strapi: strapi2 }) {
|
649
|
-
getService(strapi2, "lifecycles").destroy();
|
703
|
+
getService$1(strapi2, "lifecycles").destroy();
|
650
704
|
},
|
651
|
-
controllers: controllers$
|
652
|
-
services: services$
|
653
|
-
routes: routes$
|
705
|
+
controllers: controllers$2,
|
706
|
+
services: services$2,
|
707
|
+
routes: routes$2
|
654
708
|
};
|
655
709
|
}
|
656
710
|
return {
|
@@ -659,7 +713,7 @@ const getFeature = () => {
|
|
659
713
|
}
|
660
714
|
};
|
661
715
|
};
|
662
|
-
const history = getFeature();
|
716
|
+
const history = getFeature$1();
|
663
717
|
const register = async ({ strapi: strapi2 }) => {
|
664
718
|
await history.register?.({ strapi: strapi2 });
|
665
719
|
};
|
@@ -667,15 +721,165 @@ const ALLOWED_WEBHOOK_EVENTS = {
|
|
667
721
|
ENTRY_PUBLISH: "entry.publish",
|
668
722
|
ENTRY_UNPUBLISH: "entry.unpublish"
|
669
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();
|
670
873
|
const bootstrap = async () => {
|
671
874
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
672
875
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
673
876
|
});
|
674
|
-
getService$
|
675
|
-
await getService$
|
676
|
-
await getService$
|
677
|
-
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();
|
678
881
|
await history.bootstrap?.({ strapi });
|
882
|
+
await preview.bootstrap?.({ strapi });
|
679
883
|
};
|
680
884
|
const destroy = async ({ strapi: strapi2 }) => {
|
681
885
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1165,7 +1369,8 @@ const admin = {
|
|
1165
1369
|
};
|
1166
1370
|
const routes = {
|
1167
1371
|
admin,
|
1168
|
-
...history.routes ? history.routes : {}
|
1372
|
+
...history.routes ? history.routes : {},
|
1373
|
+
...preview.routes ? preview.routes : {}
|
1169
1374
|
};
|
1170
1375
|
const hasPermissionsSchema = yup$1.object({
|
1171
1376
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1176,6 +1381,11 @@ const { createPolicy } = policy;
|
|
1176
1381
|
const hasPermissions = createPolicy({
|
1177
1382
|
name: "plugin::content-manager.hasPermissions",
|
1178
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
|
+
*/
|
1179
1389
|
handler(ctx, config = {}) {
|
1180
1390
|
const { actions = [], hasAtLeastOne = false } = config;
|
1181
1391
|
const { userAbility } = ctx.state;
|
@@ -1417,7 +1627,7 @@ const createMetadasSchema = (schema) => {
|
|
1417
1627
|
if (!value) {
|
1418
1628
|
return yup$1.string();
|
1419
1629
|
}
|
1420
|
-
const targetSchema = getService$
|
1630
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1421
1631
|
schema.attributes[key].targetModel
|
1422
1632
|
);
|
1423
1633
|
if (!targetSchema) {
|
@@ -1569,9 +1779,11 @@ const multipleLocaleSchema = yup$1.lazy(
|
|
1569
1779
|
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1570
1780
|
);
|
1571
1781
|
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1572
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1782
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1573
1783
|
const { allowMultipleLocales } = opts;
|
1574
|
-
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;
|
1575
1787
|
const schema = yup$1.object().shape({
|
1576
1788
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1577
1789
|
status: statusSchema
|
@@ -1584,7 +1796,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1584
1796
|
}
|
1585
1797
|
};
|
1586
1798
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1587
|
-
const documentMetadata2 = getService$
|
1799
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1588
1800
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1589
1801
|
let {
|
1590
1802
|
meta: { availableLocales, availableStatus }
|
@@ -1610,8 +1822,8 @@ const createDocument = async (ctx, opts) => {
|
|
1610
1822
|
const { userAbility, user } = ctx.state;
|
1611
1823
|
const { model } = ctx.params;
|
1612
1824
|
const { body } = ctx.request;
|
1613
|
-
const documentManager2 = getService$
|
1614
|
-
const permissionChecker2 = getService$
|
1825
|
+
const documentManager2 = getService$2("document-manager");
|
1826
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1615
1827
|
if (permissionChecker2.cannot.create()) {
|
1616
1828
|
throw new errors.ForbiddenError();
|
1617
1829
|
}
|
@@ -1619,7 +1831,7 @@ const createDocument = async (ctx, opts) => {
|
|
1619
1831
|
const setCreator = setCreatorFields({ user });
|
1620
1832
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1621
1833
|
const sanitizedBody = await sanitizeFn(body);
|
1622
|
-
const { locale, status
|
1834
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1623
1835
|
return documentManager2.create(model, {
|
1624
1836
|
data: sanitizedBody,
|
1625
1837
|
locale,
|
@@ -1631,14 +1843,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1631
1843
|
const { userAbility, user } = ctx.state;
|
1632
1844
|
const { id, model } = ctx.params;
|
1633
1845
|
const { body } = ctx.request;
|
1634
|
-
const documentManager2 = getService$
|
1635
|
-
const permissionChecker2 = getService$
|
1846
|
+
const documentManager2 = getService$2("document-manager");
|
1847
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1636
1848
|
if (permissionChecker2.cannot.update()) {
|
1637
1849
|
throw new errors.ForbiddenError();
|
1638
1850
|
}
|
1639
1851
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1640
|
-
const populate = await getService$
|
1641
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1852
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1853
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1642
1854
|
const [documentVersion, documentExists] = await Promise.all([
|
1643
1855
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1644
1856
|
documentManager2.exists(model, id)
|
@@ -1654,7 +1866,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1654
1866
|
throw new errors.ForbiddenError();
|
1655
1867
|
}
|
1656
1868
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1657
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1869
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1658
1870
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1659
1871
|
const sanitizedBody = await sanitizeFn(body);
|
1660
1872
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1668,15 +1880,15 @@ const collectionTypes = {
|
|
1668
1880
|
const { userAbility } = ctx.state;
|
1669
1881
|
const { model } = ctx.params;
|
1670
1882
|
const { query } = ctx.request;
|
1671
|
-
const documentMetadata2 = getService$
|
1672
|
-
const documentManager2 = getService$
|
1673
|
-
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 });
|
1674
1886
|
if (permissionChecker2.cannot.read()) {
|
1675
1887
|
return ctx.forbidden();
|
1676
1888
|
}
|
1677
1889
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1678
|
-
const populate = await getService$
|
1679
|
-
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);
|
1680
1892
|
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1681
1893
|
{ ...permissionQuery, populate, locale, status },
|
1682
1894
|
model
|
@@ -1704,14 +1916,14 @@ const collectionTypes = {
|
|
1704
1916
|
async findOne(ctx) {
|
1705
1917
|
const { userAbility } = ctx.state;
|
1706
1918
|
const { model, id } = ctx.params;
|
1707
|
-
const documentManager2 = getService$
|
1708
|
-
const permissionChecker2 = getService$
|
1919
|
+
const documentManager2 = getService$2("document-manager");
|
1920
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1709
1921
|
if (permissionChecker2.cannot.read()) {
|
1710
1922
|
return ctx.forbidden();
|
1711
1923
|
}
|
1712
1924
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1713
|
-
const populate = await getService$
|
1714
|
-
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);
|
1715
1927
|
const version = await documentManager2.findOne(id, model, {
|
1716
1928
|
populate,
|
1717
1929
|
locale,
|
@@ -1726,7 +1938,7 @@ const collectionTypes = {
|
|
1726
1938
|
permissionChecker2,
|
1727
1939
|
model,
|
1728
1940
|
// @ts-expect-error TODO: fix
|
1729
|
-
{ id, locale, publishedAt: null },
|
1941
|
+
{ documentId: id, locale, publishedAt: null },
|
1730
1942
|
{ availableLocales: true, availableStatus: false }
|
1731
1943
|
);
|
1732
1944
|
ctx.body = { data: {}, meta };
|
@@ -1741,7 +1953,7 @@ const collectionTypes = {
|
|
1741
1953
|
async create(ctx) {
|
1742
1954
|
const { userAbility } = ctx.state;
|
1743
1955
|
const { model } = ctx.params;
|
1744
|
-
const permissionChecker2 = getService$
|
1956
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1745
1957
|
const [totalEntries, document] = await Promise.all([
|
1746
1958
|
strapi.db.query(model).count(),
|
1747
1959
|
createDocument(ctx)
|
@@ -1762,7 +1974,7 @@ const collectionTypes = {
|
|
1762
1974
|
async update(ctx) {
|
1763
1975
|
const { userAbility } = ctx.state;
|
1764
1976
|
const { model } = ctx.params;
|
1765
|
-
const permissionChecker2 = getService$
|
1977
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1766
1978
|
const updatedVersion = await updateDocument(ctx);
|
1767
1979
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1768
1980
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1771,14 +1983,14 @@ const collectionTypes = {
|
|
1771
1983
|
const { userAbility, user } = ctx.state;
|
1772
1984
|
const { model, sourceId: id } = ctx.params;
|
1773
1985
|
const { body } = ctx.request;
|
1774
|
-
const documentManager2 = getService$
|
1775
|
-
const permissionChecker2 = getService$
|
1986
|
+
const documentManager2 = getService$2("document-manager");
|
1987
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1776
1988
|
if (permissionChecker2.cannot.create()) {
|
1777
1989
|
return ctx.forbidden();
|
1778
1990
|
}
|
1779
1991
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1780
|
-
const populate = await getService$
|
1781
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1992
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1993
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1782
1994
|
const document = await documentManager2.findOne(id, model, {
|
1783
1995
|
populate,
|
1784
1996
|
locale,
|
@@ -1816,14 +2028,14 @@ const collectionTypes = {
|
|
1816
2028
|
async delete(ctx) {
|
1817
2029
|
const { userAbility } = ctx.state;
|
1818
2030
|
const { id, model } = ctx.params;
|
1819
|
-
const documentManager2 = getService$
|
1820
|
-
const permissionChecker2 = getService$
|
2031
|
+
const documentManager2 = getService$2("document-manager");
|
2032
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1821
2033
|
if (permissionChecker2.cannot.delete()) {
|
1822
2034
|
return ctx.forbidden();
|
1823
2035
|
}
|
1824
2036
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1825
|
-
const populate = await getService$
|
1826
|
-
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);
|
1827
2039
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1828
2040
|
if (documentLocales.length === 0) {
|
1829
2041
|
return ctx.notFound();
|
@@ -1844,19 +2056,42 @@ const collectionTypes = {
|
|
1844
2056
|
const { userAbility } = ctx.state;
|
1845
2057
|
const { id, model } = ctx.params;
|
1846
2058
|
const { body } = ctx.request;
|
1847
|
-
const documentManager2 = getService$
|
1848
|
-
const permissionChecker2 = getService$
|
2059
|
+
const documentManager2 = getService$2("document-manager");
|
2060
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1849
2061
|
if (permissionChecker2.cannot.publish()) {
|
1850
2062
|
return ctx.forbidden();
|
1851
2063
|
}
|
1852
2064
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1853
2065
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1854
|
-
const populate = await getService$
|
1855
|
-
|
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
|
+
}
|
1856
2092
|
if (permissionChecker2.cannot.publish(document)) {
|
1857
2093
|
throw new errors.ForbiddenError();
|
1858
2094
|
}
|
1859
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1860
2095
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1861
2096
|
locale
|
1862
2097
|
// TODO: Allow setting creator fields on publish
|
@@ -1876,14 +2111,16 @@ const collectionTypes = {
|
|
1876
2111
|
const { body } = ctx.request;
|
1877
2112
|
const { documentIds } = body;
|
1878
2113
|
await validateBulkActionInput(body);
|
1879
|
-
const documentManager2 = getService$
|
1880
|
-
const permissionChecker2 = getService$
|
2114
|
+
const documentManager2 = getService$2("document-manager");
|
2115
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1881
2116
|
if (permissionChecker2.cannot.publish()) {
|
1882
2117
|
return ctx.forbidden();
|
1883
2118
|
}
|
1884
2119
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1885
|
-
const populate = await getService$
|
1886
|
-
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
|
+
});
|
1887
2124
|
const entityPromises = documentIds.map(
|
1888
2125
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1889
2126
|
);
|
@@ -1905,12 +2142,14 @@ const collectionTypes = {
|
|
1905
2142
|
const { body } = ctx.request;
|
1906
2143
|
const { documentIds } = body;
|
1907
2144
|
await validateBulkActionInput(body);
|
1908
|
-
const documentManager2 = getService$
|
1909
|
-
const permissionChecker2 = getService$
|
2145
|
+
const documentManager2 = getService$2("document-manager");
|
2146
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1910
2147
|
if (permissionChecker2.cannot.unpublish()) {
|
1911
2148
|
return ctx.forbidden();
|
1912
2149
|
}
|
1913
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2150
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2151
|
+
allowMultipleLocales: true
|
2152
|
+
});
|
1914
2153
|
const entityPromises = documentIds.map(
|
1915
2154
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1916
2155
|
);
|
@@ -1933,8 +2172,8 @@ const collectionTypes = {
|
|
1933
2172
|
const {
|
1934
2173
|
body: { discardDraft, ...body }
|
1935
2174
|
} = ctx.request;
|
1936
|
-
const documentManager2 = getService$
|
1937
|
-
const permissionChecker2 = getService$
|
2175
|
+
const documentManager2 = getService$2("document-manager");
|
2176
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1938
2177
|
if (permissionChecker2.cannot.unpublish()) {
|
1939
2178
|
return ctx.forbidden();
|
1940
2179
|
}
|
@@ -1942,8 +2181,8 @@ const collectionTypes = {
|
|
1942
2181
|
return ctx.forbidden();
|
1943
2182
|
}
|
1944
2183
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1945
|
-
const populate = await getService$
|
1946
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2184
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2185
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1947
2186
|
const document = await documentManager2.findOne(id, model, {
|
1948
2187
|
populate,
|
1949
2188
|
locale,
|
@@ -1973,14 +2212,14 @@ const collectionTypes = {
|
|
1973
2212
|
const { userAbility } = ctx.state;
|
1974
2213
|
const { id, model } = ctx.params;
|
1975
2214
|
const { body } = ctx.request;
|
1976
|
-
const documentManager2 = getService$
|
1977
|
-
const permissionChecker2 = getService$
|
2215
|
+
const documentManager2 = getService$2("document-manager");
|
2216
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1978
2217
|
if (permissionChecker2.cannot.discard()) {
|
1979
2218
|
return ctx.forbidden();
|
1980
2219
|
}
|
1981
2220
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1982
|
-
const populate = await getService$
|
1983
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2221
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2222
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1984
2223
|
const document = await documentManager2.findOne(id, model, {
|
1985
2224
|
populate,
|
1986
2225
|
locale,
|
@@ -2004,14 +2243,14 @@ const collectionTypes = {
|
|
2004
2243
|
const { query, body } = ctx.request;
|
2005
2244
|
const { documentIds } = body;
|
2006
2245
|
await validateBulkActionInput(body);
|
2007
|
-
const documentManager2 = getService$
|
2008
|
-
const permissionChecker2 = getService$
|
2246
|
+
const documentManager2 = getService$2("document-manager");
|
2247
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2009
2248
|
if (permissionChecker2.cannot.delete()) {
|
2010
2249
|
return ctx.forbidden();
|
2011
2250
|
}
|
2012
2251
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2013
|
-
const populate = await getService$
|
2014
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2252
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2253
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2015
2254
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2016
2255
|
populate,
|
2017
2256
|
locale
|
@@ -2031,14 +2270,14 @@ const collectionTypes = {
|
|
2031
2270
|
async countDraftRelations(ctx) {
|
2032
2271
|
const { userAbility } = ctx.state;
|
2033
2272
|
const { model, id } = ctx.params;
|
2034
|
-
const documentManager2 = getService$
|
2035
|
-
const permissionChecker2 = getService$
|
2273
|
+
const documentManager2 = getService$2("document-manager");
|
2274
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2036
2275
|
if (permissionChecker2.cannot.read()) {
|
2037
2276
|
return ctx.forbidden();
|
2038
2277
|
}
|
2039
2278
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2040
|
-
const populate = await getService$
|
2041
|
-
const { locale, status
|
2279
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2280
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2042
2281
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2043
2282
|
if (!entity) {
|
2044
2283
|
return ctx.notFound();
|
@@ -2056,8 +2295,8 @@ const collectionTypes = {
|
|
2056
2295
|
const ids = ctx.request.query.documentIds;
|
2057
2296
|
const locale = ctx.request.query.locale;
|
2058
2297
|
const { model } = ctx.params;
|
2059
|
-
const documentManager2 = getService$
|
2060
|
-
const permissionChecker2 = getService$
|
2298
|
+
const documentManager2 = getService$2("document-manager");
|
2299
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2061
2300
|
if (permissionChecker2.cannot.read()) {
|
2062
2301
|
return ctx.forbidden();
|
2063
2302
|
}
|
@@ -2081,13 +2320,13 @@ const collectionTypes = {
|
|
2081
2320
|
};
|
2082
2321
|
const components$1 = {
|
2083
2322
|
findComponents(ctx) {
|
2084
|
-
const components2 = getService$
|
2085
|
-
const { toDto } = getService$
|
2323
|
+
const components2 = getService$2("components").findAllComponents();
|
2324
|
+
const { toDto } = getService$2("data-mapper");
|
2086
2325
|
ctx.body = { data: components2.map(toDto) };
|
2087
2326
|
},
|
2088
2327
|
async findComponentConfiguration(ctx) {
|
2089
2328
|
const { uid: uid2 } = ctx.params;
|
2090
|
-
const componentService = getService$
|
2329
|
+
const componentService = getService$2("components");
|
2091
2330
|
const component = componentService.findComponent(uid2);
|
2092
2331
|
if (!component) {
|
2093
2332
|
return ctx.notFound("component.notFound");
|
@@ -2104,7 +2343,7 @@ const components$1 = {
|
|
2104
2343
|
async updateComponentConfiguration(ctx) {
|
2105
2344
|
const { uid: uid2 } = ctx.params;
|
2106
2345
|
const { body } = ctx.request;
|
2107
|
-
const componentService = getService$
|
2346
|
+
const componentService = getService$2("components");
|
2108
2347
|
const component = componentService.findComponent(uid2);
|
2109
2348
|
if (!component) {
|
2110
2349
|
return ctx.notFound("component.notFound");
|
@@ -2138,12 +2377,12 @@ const contentTypes = {
|
|
2138
2377
|
} catch (error) {
|
2139
2378
|
return ctx.send({ error }, 400);
|
2140
2379
|
}
|
2141
|
-
const contentTypes2 = getService$
|
2142
|
-
const { toDto } = getService$
|
2380
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2381
|
+
const { toDto } = getService$2("data-mapper");
|
2143
2382
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2144
2383
|
},
|
2145
2384
|
async findContentTypesSettings(ctx) {
|
2146
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2385
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2147
2386
|
const contentTypes2 = await findAllContentTypes();
|
2148
2387
|
const configurations = await Promise.all(
|
2149
2388
|
contentTypes2.map(async (contentType) => {
|
@@ -2157,7 +2396,7 @@ const contentTypes = {
|
|
2157
2396
|
},
|
2158
2397
|
async findContentTypeConfiguration(ctx) {
|
2159
2398
|
const { uid: uid2 } = ctx.params;
|
2160
|
-
const contentTypeService = getService$
|
2399
|
+
const contentTypeService = getService$2("content-types");
|
2161
2400
|
const contentType = await contentTypeService.findContentType(uid2);
|
2162
2401
|
if (!contentType) {
|
2163
2402
|
return ctx.notFound("contentType.notFound");
|
@@ -2179,13 +2418,13 @@ const contentTypes = {
|
|
2179
2418
|
const { userAbility } = ctx.state;
|
2180
2419
|
const { uid: uid2 } = ctx.params;
|
2181
2420
|
const { body } = ctx.request;
|
2182
|
-
const contentTypeService = getService$
|
2183
|
-
const metricsService = getService$
|
2421
|
+
const contentTypeService = getService$2("content-types");
|
2422
|
+
const metricsService = getService$2("metrics");
|
2184
2423
|
const contentType = await contentTypeService.findContentType(uid2);
|
2185
2424
|
if (!contentType) {
|
2186
2425
|
return ctx.notFound("contentType.notFound");
|
2187
2426
|
}
|
2188
|
-
if (!getService$
|
2427
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2189
2428
|
return ctx.forbidden();
|
2190
2429
|
}
|
2191
2430
|
let input;
|
@@ -2218,10 +2457,10 @@ const contentTypes = {
|
|
2218
2457
|
};
|
2219
2458
|
const init = {
|
2220
2459
|
getInitData(ctx) {
|
2221
|
-
const { toDto } = getService$
|
2222
|
-
const { findAllComponents } = getService$
|
2223
|
-
const { getAllFieldSizes } = getService$
|
2224
|
-
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");
|
2225
2464
|
ctx.body = {
|
2226
2465
|
data: {
|
2227
2466
|
fieldSizes: getAllFieldSizes(),
|
@@ -2257,36 +2496,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2257
2496
|
params.filters.$and.push(filtersClause);
|
2258
2497
|
};
|
2259
2498
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2260
|
-
const permissionChecker2 = getService$
|
2499
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2261
2500
|
userAbility,
|
2262
2501
|
model: model.uid
|
2263
2502
|
});
|
2264
|
-
|
2503
|
+
const isMainFieldListable = isListable(model, mainField);
|
2504
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2505
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2265
2506
|
return "id";
|
2266
2507
|
}
|
2267
|
-
if (
|
2268
|
-
|
2269
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2270
|
-
userAbility,
|
2271
|
-
model: "plugin::users-permissions.user"
|
2272
|
-
});
|
2273
|
-
if (userPermissionChecker.can.read()) {
|
2274
|
-
return "name";
|
2275
|
-
}
|
2276
|
-
}
|
2277
|
-
return "id";
|
2508
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2509
|
+
return "name";
|
2278
2510
|
}
|
2279
2511
|
return mainField;
|
2280
2512
|
};
|
2281
|
-
const addStatusToRelations = async (
|
2282
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2513
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2514
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2283
2515
|
return relations2;
|
2284
2516
|
}
|
2285
|
-
const documentMetadata2 = getService$
|
2286
|
-
|
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
|
+
});
|
2287
2531
|
return relations2.map((relation) => {
|
2288
|
-
const availableStatuses =
|
2289
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2532
|
+
const availableStatuses = availableStatus.filter(
|
2533
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2290
2534
|
);
|
2291
2535
|
return {
|
2292
2536
|
...relation,
|
@@ -2307,11 +2551,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2307
2551
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2308
2552
|
const isSourceLocalized = isLocalized(sourceModel);
|
2309
2553
|
const isTargetLocalized = isLocalized(targetModel);
|
2310
|
-
let validatedLocale = locale;
|
2311
|
-
if (!targetModel || !isTargetLocalized)
|
2312
|
-
validatedLocale = void 0;
|
2313
2554
|
return {
|
2314
|
-
locale
|
2555
|
+
locale,
|
2315
2556
|
isSourceLocalized,
|
2316
2557
|
isTargetLocalized
|
2317
2558
|
};
|
@@ -2351,7 +2592,7 @@ const relations = {
|
|
2351
2592
|
ctx.request?.query?.locale
|
2352
2593
|
);
|
2353
2594
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2354
|
-
const permissionChecker2 = getService$
|
2595
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2355
2596
|
userAbility,
|
2356
2597
|
model
|
2357
2598
|
});
|
@@ -2376,7 +2617,7 @@ const relations = {
|
|
2376
2617
|
where.id = id;
|
2377
2618
|
}
|
2378
2619
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2379
|
-
const populate = await getService$
|
2620
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2380
2621
|
const currentEntity = await strapi.db.query(model).findOne({
|
2381
2622
|
where,
|
2382
2623
|
populate
|
@@ -2391,7 +2632,7 @@ const relations = {
|
|
2391
2632
|
}
|
2392
2633
|
entryId = currentEntity.id;
|
2393
2634
|
}
|
2394
|
-
const modelConfig = isComponent2 ? await getService$
|
2635
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2395
2636
|
const targetSchema = strapi.getModel(targetUid);
|
2396
2637
|
const mainField = flow(
|
2397
2638
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2414,7 +2655,7 @@ const relations = {
|
|
2414
2655
|
attribute,
|
2415
2656
|
fieldsToSelect,
|
2416
2657
|
mainField,
|
2417
|
-
source: { schema: sourceSchema },
|
2658
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2418
2659
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2419
2660
|
sourceSchema,
|
2420
2661
|
targetSchema,
|
@@ -2436,7 +2677,8 @@ const relations = {
|
|
2436
2677
|
fieldsToSelect,
|
2437
2678
|
mainField,
|
2438
2679
|
source: {
|
2439
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2680
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2681
|
+
isLocalized: isSourceLocalized
|
2440
2682
|
},
|
2441
2683
|
target: {
|
2442
2684
|
schema: { uid: targetUid },
|
@@ -2444,7 +2686,7 @@ const relations = {
|
|
2444
2686
|
}
|
2445
2687
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2446
2688
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2447
|
-
const permissionChecker2 = getService$
|
2689
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2448
2690
|
userAbility: ctx.state.userAbility,
|
2449
2691
|
model: targetUid
|
2450
2692
|
});
|
@@ -2474,12 +2716,16 @@ const relations = {
|
|
2474
2716
|
} else {
|
2475
2717
|
where.id = id;
|
2476
2718
|
}
|
2477
|
-
|
2478
|
-
|
2719
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2720
|
+
if (!isEmpty(publishedAt)) {
|
2721
|
+
where[`${alias}.published_at`] = publishedAt;
|
2479
2722
|
}
|
2480
|
-
if (
|
2723
|
+
if (isTargetLocalized && locale) {
|
2481
2724
|
where[`${alias}.locale`] = locale;
|
2482
2725
|
}
|
2726
|
+
if (isSourceLocalized && locale) {
|
2727
|
+
where.locale = locale;
|
2728
|
+
}
|
2483
2729
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2484
2730
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2485
2731
|
}
|
@@ -2497,7 +2743,8 @@ const relations = {
|
|
2497
2743
|
id: { $notIn: uniq(idsToOmit) }
|
2498
2744
|
});
|
2499
2745
|
}
|
2500
|
-
const
|
2746
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2747
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2501
2748
|
ctx.body = {
|
2502
2749
|
...res,
|
2503
2750
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2512,29 +2759,39 @@ const relations = {
|
|
2512
2759
|
attribute,
|
2513
2760
|
targetField,
|
2514
2761
|
fieldsToSelect,
|
2515
|
-
|
2516
|
-
|
2517
|
-
}
|
2518
|
-
target: {
|
2519
|
-
schema: { uid: targetUid }
|
2520
|
-
}
|
2762
|
+
status,
|
2763
|
+
source: { schema: sourceSchema },
|
2764
|
+
target: { schema: targetSchema }
|
2521
2765
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2522
|
-
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 });
|
2523
2769
|
const dbQuery = strapi.db.query(sourceUid);
|
2524
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
|
+
}
|
2525
2783
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2526
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2784
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2527
2785
|
ordering: "desc",
|
2528
2786
|
page: ctx.request.query.page,
|
2529
|
-
pageSize: ctx.request.query.pageSize
|
2787
|
+
pageSize: ctx.request.query.pageSize,
|
2788
|
+
filters
|
2530
2789
|
});
|
2531
2790
|
const loadedIds = res.results.map((item) => item.id);
|
2532
2791
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2533
2792
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2534
2793
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2535
|
-
ordering: "desc"
|
2536
|
-
page: ctx.request.query.page,
|
2537
|
-
pageSize: ctx.request.query.pageSize
|
2794
|
+
ordering: "desc"
|
2538
2795
|
});
|
2539
2796
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2540
2797
|
ctx.body = {
|
@@ -2549,10 +2806,10 @@ const relations = {
|
|
2549
2806
|
}
|
2550
2807
|
};
|
2551
2808
|
const buildPopulateFromQuery = async (query, model) => {
|
2552
|
-
return getService$
|
2809
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2553
2810
|
};
|
2554
2811
|
const findDocument = async (query, uid2, opts = {}) => {
|
2555
|
-
const documentManager2 = getService$
|
2812
|
+
const documentManager2 = getService$2("document-manager");
|
2556
2813
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2557
2814
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2558
2815
|
};
|
@@ -2560,13 +2817,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2560
2817
|
const { user, userAbility } = ctx.state;
|
2561
2818
|
const { model } = ctx.params;
|
2562
2819
|
const { body, query } = ctx.request;
|
2563
|
-
const documentManager2 = getService$
|
2564
|
-
const permissionChecker2 = getService$
|
2820
|
+
const documentManager2 = getService$2("document-manager");
|
2821
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2565
2822
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2566
2823
|
throw new errors.ForbiddenError();
|
2567
2824
|
}
|
2568
2825
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2569
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2826
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2570
2827
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2571
2828
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2572
2829
|
// Find the first document to check if it exists
|
@@ -2602,12 +2859,12 @@ const singleTypes = {
|
|
2602
2859
|
const { userAbility } = ctx.state;
|
2603
2860
|
const { model } = ctx.params;
|
2604
2861
|
const { query = {} } = ctx.request;
|
2605
|
-
const permissionChecker2 = getService$
|
2862
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2606
2863
|
if (permissionChecker2.cannot.read()) {
|
2607
2864
|
return ctx.forbidden();
|
2608
2865
|
}
|
2609
2866
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2610
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2867
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2611
2868
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2612
2869
|
if (!version) {
|
2613
2870
|
if (permissionChecker2.cannot.create()) {
|
@@ -2621,7 +2878,7 @@ const singleTypes = {
|
|
2621
2878
|
permissionChecker2,
|
2622
2879
|
model,
|
2623
2880
|
// @ts-expect-error - fix types
|
2624
|
-
{
|
2881
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2625
2882
|
{ availableLocales: true, availableStatus: false }
|
2626
2883
|
);
|
2627
2884
|
ctx.body = { data: {}, meta };
|
@@ -2636,7 +2893,7 @@ const singleTypes = {
|
|
2636
2893
|
async createOrUpdate(ctx) {
|
2637
2894
|
const { userAbility } = ctx.state;
|
2638
2895
|
const { model } = ctx.params;
|
2639
|
-
const permissionChecker2 = getService$
|
2896
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2640
2897
|
const document = await createOrUpdateDocument(ctx);
|
2641
2898
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2642
2899
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2645,14 +2902,14 @@ const singleTypes = {
|
|
2645
2902
|
const { userAbility } = ctx.state;
|
2646
2903
|
const { model } = ctx.params;
|
2647
2904
|
const { query = {} } = ctx.request;
|
2648
|
-
const documentManager2 = getService$
|
2649
|
-
const permissionChecker2 = getService$
|
2905
|
+
const documentManager2 = getService$2("document-manager");
|
2906
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2650
2907
|
if (permissionChecker2.cannot.delete()) {
|
2651
2908
|
return ctx.forbidden();
|
2652
2909
|
}
|
2653
2910
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2654
2911
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2655
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2912
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2656
2913
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2657
2914
|
populate,
|
2658
2915
|
locale
|
@@ -2674,8 +2931,8 @@ const singleTypes = {
|
|
2674
2931
|
const { userAbility } = ctx.state;
|
2675
2932
|
const { model } = ctx.params;
|
2676
2933
|
const { query = {} } = ctx.request;
|
2677
|
-
const documentManager2 = getService$
|
2678
|
-
const permissionChecker2 = getService$
|
2934
|
+
const documentManager2 = getService$2("document-manager");
|
2935
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2679
2936
|
if (permissionChecker2.cannot.publish()) {
|
2680
2937
|
return ctx.forbidden();
|
2681
2938
|
}
|
@@ -2689,7 +2946,7 @@ const singleTypes = {
|
|
2689
2946
|
if (permissionChecker2.cannot.publish(document)) {
|
2690
2947
|
throw new errors.ForbiddenError();
|
2691
2948
|
}
|
2692
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
2949
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2693
2950
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2694
2951
|
return publishResult.at(0);
|
2695
2952
|
});
|
@@ -2703,8 +2960,8 @@ const singleTypes = {
|
|
2703
2960
|
body: { discardDraft, ...body },
|
2704
2961
|
query = {}
|
2705
2962
|
} = ctx.request;
|
2706
|
-
const documentManager2 = getService$
|
2707
|
-
const permissionChecker2 = getService$
|
2963
|
+
const documentManager2 = getService$2("document-manager");
|
2964
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2708
2965
|
if (permissionChecker2.cannot.unpublish()) {
|
2709
2966
|
return ctx.forbidden();
|
2710
2967
|
}
|
@@ -2712,7 +2969,7 @@ const singleTypes = {
|
|
2712
2969
|
return ctx.forbidden();
|
2713
2970
|
}
|
2714
2971
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2715
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2972
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2716
2973
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2717
2974
|
if (!document) {
|
2718
2975
|
return ctx.notFound();
|
@@ -2738,13 +2995,13 @@ const singleTypes = {
|
|
2738
2995
|
const { userAbility } = ctx.state;
|
2739
2996
|
const { model } = ctx.params;
|
2740
2997
|
const { body, query = {} } = ctx.request;
|
2741
|
-
const documentManager2 = getService$
|
2742
|
-
const permissionChecker2 = getService$
|
2998
|
+
const documentManager2 = getService$2("document-manager");
|
2999
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2743
3000
|
if (permissionChecker2.cannot.discard()) {
|
2744
3001
|
return ctx.forbidden();
|
2745
3002
|
}
|
2746
3003
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2747
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3004
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2748
3005
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2749
3006
|
if (!document) {
|
2750
3007
|
return ctx.notFound();
|
@@ -2762,9 +3019,9 @@ const singleTypes = {
|
|
2762
3019
|
const { userAbility } = ctx.state;
|
2763
3020
|
const { model } = ctx.params;
|
2764
3021
|
const { query } = ctx.request;
|
2765
|
-
const documentManager2 = getService$
|
2766
|
-
const permissionChecker2 = getService$
|
2767
|
-
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);
|
2768
3025
|
if (permissionChecker2.cannot.read()) {
|
2769
3026
|
return ctx.forbidden();
|
2770
3027
|
}
|
@@ -2785,9 +3042,9 @@ const uid$1 = {
|
|
2785
3042
|
async generateUID(ctx) {
|
2786
3043
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2787
3044
|
const { query = {} } = ctx.request;
|
2788
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3045
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2789
3046
|
await validateUIDField(contentTypeUID, field);
|
2790
|
-
const uidService = getService$
|
3047
|
+
const uidService = getService$2("uid");
|
2791
3048
|
ctx.body = {
|
2792
3049
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2793
3050
|
};
|
@@ -2797,9 +3054,9 @@ const uid$1 = {
|
|
2797
3054
|
ctx.request.body
|
2798
3055
|
);
|
2799
3056
|
const { query = {} } = ctx.request;
|
2800
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3057
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2801
3058
|
await validateUIDField(contentTypeUID, field);
|
2802
|
-
const uidService = getService$
|
3059
|
+
const uidService = getService$2("uid");
|
2803
3060
|
const isAvailable = await uidService.checkUIDAvailability({
|
2804
3061
|
contentTypeUID,
|
2805
3062
|
field,
|
@@ -2820,7 +3077,8 @@ const controllers = {
|
|
2820
3077
|
relations,
|
2821
3078
|
"single-types": singleTypes,
|
2822
3079
|
uid: uid$1,
|
2823
|
-
...history.controllers ? history.controllers : {}
|
3080
|
+
...history.controllers ? history.controllers : {},
|
3081
|
+
...preview.controllers ? preview.controllers : {}
|
2824
3082
|
};
|
2825
3083
|
const keys = {
|
2826
3084
|
CONFIGURATION: "configuration"
|
@@ -2971,12 +3229,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2971
3229
|
return _.assign(metasWithDefaults, updatedMetas);
|
2972
3230
|
}
|
2973
3231
|
const getTargetSchema = (targetModel) => {
|
2974
|
-
return getService$
|
3232
|
+
return getService$2("content-types").findContentType(targetModel);
|
2975
3233
|
};
|
2976
3234
|
const DEFAULT_LIST_LENGTH = 4;
|
2977
3235
|
const MAX_ROW_SIZE = 12;
|
2978
3236
|
const isAllowedFieldSize = (type, size) => {
|
2979
|
-
const { getFieldSize } = getService$
|
3237
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2980
3238
|
const fieldSize = getFieldSize(type);
|
2981
3239
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2982
3240
|
return false;
|
@@ -2984,7 +3242,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2984
3242
|
return size <= MAX_ROW_SIZE;
|
2985
3243
|
};
|
2986
3244
|
const getDefaultFieldSize = (attribute) => {
|
2987
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3245
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2988
3246
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2989
3247
|
};
|
2990
3248
|
async function createDefaultLayouts(schema) {
|
@@ -3019,7 +3277,7 @@ function syncLayouts(configuration, schema) {
|
|
3019
3277
|
for (const el of row) {
|
3020
3278
|
if (!hasEditableAttribute(schema, el.name))
|
3021
3279
|
continue;
|
3022
|
-
const { hasFieldSize } = getService$
|
3280
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3023
3281
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3024
3282
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3025
3283
|
elementsToReAppend.push(el.name);
|
@@ -3159,17 +3417,17 @@ const configurationService$1 = createConfigurationService({
|
|
3159
3417
|
isComponent: true,
|
3160
3418
|
prefix: STORE_KEY_PREFIX,
|
3161
3419
|
getModels() {
|
3162
|
-
const { toContentManagerModel } = getService$
|
3420
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3163
3421
|
return mapValues(toContentManagerModel, strapi.components);
|
3164
3422
|
}
|
3165
3423
|
});
|
3166
3424
|
const components = ({ strapi: strapi2 }) => ({
|
3167
3425
|
findAllComponents() {
|
3168
|
-
const { toContentManagerModel } = getService$
|
3426
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3169
3427
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3170
3428
|
},
|
3171
3429
|
findComponent(uid2) {
|
3172
|
-
const { toContentManagerModel } = getService$
|
3430
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3173
3431
|
const component = strapi2.components[uid2];
|
3174
3432
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3175
3433
|
},
|
@@ -3220,17 +3478,17 @@ const configurationService = createConfigurationService({
|
|
3220
3478
|
storeUtils,
|
3221
3479
|
prefix: "content_types",
|
3222
3480
|
getModels() {
|
3223
|
-
const { toContentManagerModel } = getService$
|
3481
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3224
3482
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3225
3483
|
}
|
3226
3484
|
});
|
3227
3485
|
const service = ({ strapi: strapi2 }) => ({
|
3228
3486
|
findAllContentTypes() {
|
3229
|
-
const { toContentManagerModel } = getService$
|
3487
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3230
3488
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3231
3489
|
},
|
3232
3490
|
findContentType(uid2) {
|
3233
|
-
const { toContentManagerModel } = getService$
|
3491
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3234
3492
|
const contentType = strapi2.contentTypes[uid2];
|
3235
3493
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3236
3494
|
},
|
@@ -3259,7 +3517,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3259
3517
|
return this.findConfiguration(contentType);
|
3260
3518
|
},
|
3261
3519
|
findComponentsConfigurations(contentType) {
|
3262
|
-
return getService$
|
3520
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3263
3521
|
},
|
3264
3522
|
syncConfigurations() {
|
3265
3523
|
return configurationService.syncConfigurations();
|
@@ -3440,12 +3698,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3440
3698
|
ability: userAbility,
|
3441
3699
|
model
|
3442
3700
|
});
|
3443
|
-
const
|
3701
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3702
|
+
const toSubject = (entity) => {
|
3703
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3704
|
+
};
|
3444
3705
|
const can = (action, entity, field) => {
|
3445
|
-
|
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
|
+
);
|
3446
3713
|
};
|
3447
3714
|
const cannot = (action, entity, field) => {
|
3448
|
-
|
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
|
+
);
|
3449
3722
|
};
|
3450
3723
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3451
3724
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3516,7 +3789,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3516
3789
|
return userAbility.can(action);
|
3517
3790
|
},
|
3518
3791
|
async registerPermissions() {
|
3519
|
-
const displayedContentTypes = getService$
|
3792
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3520
3793
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3521
3794
|
const actions = [
|
3522
3795
|
{
|
@@ -3722,6 +3995,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3722
3995
|
const attribute = model.attributes[attributeName];
|
3723
3996
|
switch (attribute.type) {
|
3724
3997
|
case "relation": {
|
3998
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
3999
|
+
if (isMorphRelation) {
|
4000
|
+
break;
|
4001
|
+
}
|
3725
4002
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3726
4003
|
populateAcc[attributeName] = {
|
3727
4004
|
count: true,
|
@@ -3788,7 +4065,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3788
4065
|
return populateQuery;
|
3789
4066
|
};
|
3790
4067
|
const buildDeepPopulate = (uid2) => {
|
3791
|
-
return getService$
|
4068
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3792
4069
|
};
|
3793
4070
|
const populateBuilder = (uid2) => {
|
3794
4071
|
let getInitialPopulate = async () => {
|
@@ -3973,7 +4250,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3973
4250
|
*/
|
3974
4251
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3975
4252
|
const versionsByLocale = groupBy("locale", allVersions);
|
3976
|
-
|
4253
|
+
if (version.locale) {
|
4254
|
+
delete versionsByLocale[version.locale];
|
4255
|
+
}
|
3977
4256
|
const model = strapi2.getModel(uid2);
|
3978
4257
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
3979
4258
|
const traversalFunction = async (localeVersion) => traverseEntity(
|
@@ -4099,7 +4378,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4099
4378
|
*/
|
4100
4379
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4101
4380
|
if (!document) {
|
4102
|
-
return
|
4381
|
+
return {
|
4382
|
+
data: document,
|
4383
|
+
meta: {
|
4384
|
+
availableLocales: [],
|
4385
|
+
availableStatus: []
|
4386
|
+
}
|
4387
|
+
};
|
4103
4388
|
}
|
4104
4389
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
4105
4390
|
if (!hasDraftAndPublish) {
|
@@ -4207,10 +4492,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4207
4492
|
async clone(id, body, uid2) {
|
4208
4493
|
const populate = await buildDeepPopulate(uid2);
|
4209
4494
|
const params = {
|
4210
|
-
data:
|
4211
|
-
...omitIdField(body),
|
4212
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4213
|
-
},
|
4495
|
+
data: omitIdField(body),
|
4214
4496
|
populate
|
4215
4497
|
};
|
4216
4498
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4326,7 +4608,8 @@ const services = {
|
|
4326
4608
|
permission,
|
4327
4609
|
"populate-builder": populateBuilder$1,
|
4328
4610
|
uid,
|
4329
|
-
...history.services ? history.services : {}
|
4611
|
+
...history.services ? history.services : {},
|
4612
|
+
...preview.services ? preview.services : {}
|
4330
4613
|
};
|
4331
4614
|
const index = () => {
|
4332
4615
|
return {
|