@strapi/content-manager 0.0.0-experimental.826f263c58b6886b849d3f03b81f7a530bc51c91 → 0.0.0-experimental.8c83c87960f2f5ddf95ae2f0acf849052f4a9ab4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -3
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -1
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs → ComponentConfigurationPage-BgCLcjXO.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-CR5XdR33.mjs.map → ComponentConfigurationPage-BgCLcjXO.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js → ComponentConfigurationPage-DywpTZeV.js} +5 -6
- package/dist/_chunks/{ComponentConfigurationPage-DJcn1DrO.js.map → ComponentConfigurationPage-DywpTZeV.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js → ComponentIcon-CRbtQEUV.js} +2 -3
- package/dist/_chunks/{ComponentIcon-BXdiCGQp.js.map → ComponentIcon-CRbtQEUV.js.map} +1 -1
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -1
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs → EditConfigurationPage-BNjOAHNS.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DmCIb4kD.mjs.map → EditConfigurationPage-BNjOAHNS.mjs.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js → EditConfigurationPage-CxRlP5if.js} +5 -6
- package/dist/_chunks/{EditConfigurationPage-tDtWj7R2.js.map → EditConfigurationPage-CxRlP5if.js.map} +1 -1
- package/dist/_chunks/{EditViewPage-CoQEnFlC.js → EditViewPage-BRewdTqE.js} +101 -51
- package/dist/_chunks/EditViewPage-BRewdTqE.js.map +1 -0
- package/dist/_chunks/{EditViewPage-DvaV7U9b.mjs → EditViewPage-CD_hqc1J.mjs} +102 -51
- package/dist/_chunks/EditViewPage-CD_hqc1J.mjs.map +1 -0
- package/dist/_chunks/{Field-Cz_J9551.mjs → Field-BPkQ-3Ku.mjs} +631 -279
- package/dist/_chunks/Field-BPkQ-3Ku.mjs.map +1 -0
- package/dist/_chunks/{Field-ZdrmmQ4Y.js → Field-DwvmENVf.js} +634 -283
- package/dist/_chunks/Field-DwvmENVf.js.map +1 -0
- package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +1 -1
- package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +1 -1
- package/dist/_chunks/{Form-Bpig5rch.js → Form-C_Gwv8P_.js} +55 -38
- package/dist/_chunks/Form-C_Gwv8P_.js.map +1 -0
- package/dist/_chunks/{Form-Dxmihyw8.mjs → Form-Czi0cf_2.mjs} +55 -37
- package/dist/_chunks/Form-Czi0cf_2.mjs.map +1 -0
- package/dist/_chunks/{History-BfX6XmZK.js → History-C1TKAig-.js} +175 -129
- package/dist/_chunks/History-C1TKAig-.js.map +1 -0
- package/dist/_chunks/{History-BZP8n7KT.mjs → History-CIQHyi4T.mjs} +176 -129
- package/dist/_chunks/History-CIQHyi4T.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-B3CXj8PY.js → ListConfigurationPage-D-NGRLYu.js} +62 -51
- package/dist/_chunks/ListConfigurationPage-D-NGRLYu.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DxKuVkKz.mjs → ListConfigurationPage-DcZsfyEL.mjs} +63 -52
- package/dist/_chunks/ListConfigurationPage-DcZsfyEL.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-D5D3tVPq.mjs → ListViewPage-C10McTK1.mjs} +152 -128
- package/dist/_chunks/ListViewPage-C10McTK1.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-Bk9VO__I.js → ListViewPage-xv5IQoZp.js} +155 -132
- package/dist/_chunks/ListViewPage-xv5IQoZp.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs → NoContentTypePage-CPc0Cd3S.mjs} +2 -2
- package/dist/_chunks/{NoContentTypePage-DnMeuQCj.mjs.map → NoContentTypePage-CPc0Cd3S.mjs.map} +1 -1
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js → NoContentTypePage-Dzw5Yj5u.js} +2 -2
- package/dist/_chunks/{NoContentTypePage-DsB2F7Z1.js.map → NoContentTypePage-Dzw5Yj5u.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js → NoPermissionsPage-DAe5CDCC.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-BQDM64_b.js.map → NoPermissionsPage-DAe5CDCC.js.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs → NoPermissionsPage-wfPBh2_0.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-OyoME_Tf.mjs.map → NoPermissionsPage-wfPBh2_0.mjs.map} +1 -1
- package/dist/_chunks/Preview-B7LyGT_b.js +290 -0
- package/dist/_chunks/Preview-B7LyGT_b.js.map +1 -0
- package/dist/_chunks/Preview-BVFFm7uB.mjs +272 -0
- package/dist/_chunks/Preview-BVFFm7uB.mjs.map +1 -0
- package/dist/_chunks/{Relations-B6B3A3mb.js → Relations-BmYR1AjY.js} +76 -43
- package/dist/_chunks/Relations-BmYR1AjY.js.map +1 -0
- package/dist/_chunks/{Relations-BOYZmuWy.mjs → Relations-JPhWxk-s.mjs} +76 -42
- package/dist/_chunks/Relations-JPhWxk-s.mjs.map +1 -0
- package/dist/_chunks/{en-BN1bvFK7.js → en-BK8Xyl5I.js} +35 -18
- package/dist/_chunks/{en-BN1bvFK7.js.map → en-BK8Xyl5I.js.map} +1 -1
- package/dist/_chunks/{en-Dzv55oQw.mjs → en-Dtk_ot79.mjs} +35 -18
- package/dist/_chunks/{en-Dzv55oQw.mjs.map → en-Dtk_ot79.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/hooks-BAaaKPS_.js.map +1 -1
- package/dist/_chunks/{index-DzN3kBgx.js → index-C2Q_PLWj.js} +1165 -880
- package/dist/_chunks/index-C2Q_PLWj.js.map +1 -0
- package/dist/_chunks/{index-VHviNMeW.mjs → index-DLIkNVnQ.mjs} +1185 -900
- package/dist/_chunks/index-DLIkNVnQ.mjs.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-b91XRlD2.js → layout-7AsWJzZJ.js} +41 -24
- package/dist/_chunks/layout-7AsWJzZJ.js.map +1 -0
- package/dist/_chunks/{layout-CPn1PM6x.mjs → layout-qE8qkNH_.mjs} +42 -24
- package/dist/_chunks/layout-qE8qkNH_.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-BsqxS6tR.mjs → relations-BjHH_1Am.mjs} +6 -7
- package/dist/_chunks/relations-BjHH_1Am.mjs.map +1 -0
- package/dist/_chunks/{relations-CA7IYmcP.js → relations-EifVzf_2.js} +6 -7
- package/dist/_chunks/relations-EifVzf_2.js.map +1 -0
- package/dist/_chunks/{usePrev-B9w_-eYc.js → useDebounce-CtcjDB3L.js} +14 -1
- package/dist/_chunks/useDebounce-CtcjDB3L.js.map +1 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs +29 -0
- package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +1 -0
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js → useDragAndDrop-BMtgCYzL.js} +5 -9
- package/dist/_chunks/{useDragAndDrop-J0TUUbR6.js.map → useDragAndDrop-BMtgCYzL.js.map} +1 -1
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs → useDragAndDrop-DJ6jqvZN.mjs} +4 -7
- package/dist/_chunks/{useDragAndDrop-DdHgKsqq.mjs.map → useDragAndDrop-DJ6jqvZN.mjs.map} +1 -1
- package/dist/admin/index.js +2 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +8 -7
- package/dist/admin/src/exports.d.ts +1 -1
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +1 -1
- package/dist/admin/src/history/index.d.ts +3 -0
- package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +32 -1
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +8 -3
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +20 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygFooter.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +6 -58
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/ListView/components/BulkActions/Actions.d.ts +3 -30
- package/dist/admin/src/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.d.ts +2 -2
- package/dist/admin/src/preview/components/PreviewContent.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewHeader.d.ts +2 -0
- package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
- package/dist/admin/src/preview/constants.d.ts +1 -0
- package/dist/admin/src/preview/index.d.ts +4 -0
- package/dist/admin/src/preview/pages/Preview.d.ts +11 -0
- package/dist/admin/src/preview/routes.d.ts +3 -0
- package/dist/admin/src/preview/services/preview.d.ts +3 -0
- package/dist/admin/src/router.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +3 -3
- package/dist/admin/src/services/documents.d.ts +19 -20
- package/dist/admin/src/services/init.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/validation.d.ts +4 -1
- package/dist/server/index.js +616 -299
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +616 -298
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/relations.d.ts.map +1 -1
- package/dist/server/src/controllers/uid.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +15 -1
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts +4 -2
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +4 -4
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +4 -4
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/preview/constants.d.ts +2 -0
- package/dist/server/src/preview/constants.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/index.d.ts +2 -0
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/preview.d.ts +13 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
- package/dist/server/src/preview/index.d.ts +4 -0
- package/dist/server/src/preview/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/index.d.ts +8 -0
- package/dist/server/src/preview/routes/index.d.ts.map +1 -0
- package/dist/server/src/preview/routes/preview.d.ts +4 -0
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
- package/dist/server/src/preview/services/index.d.ts +16 -0
- package/dist/server/src/preview/services/index.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview-config.d.ts +32 -0
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
- package/dist/server/src/preview/services/preview.d.ts +12 -0
- package/dist/server/src/preview/services/preview.d.ts.map +1 -0
- package/dist/server/src/preview/utils.d.ts +19 -0
- package/dist/server/src/preview/utils.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +8 -8
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +4 -4
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +3 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/index.d.ts +1 -0
- package/dist/shared/contracts/index.d.ts.map +1 -1
- package/dist/shared/contracts/preview.d.ts +27 -0
- package/dist/shared/contracts/preview.d.ts.map +1 -0
- package/dist/shared/index.js +4 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +4 -0
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +15 -15
- package/dist/_chunks/EditViewPage-CoQEnFlC.js.map +0 -1
- package/dist/_chunks/EditViewPage-DvaV7U9b.mjs.map +0 -1
- package/dist/_chunks/Field-Cz_J9551.mjs.map +0 -1
- package/dist/_chunks/Field-ZdrmmQ4Y.js.map +0 -1
- package/dist/_chunks/Form-Bpig5rch.js.map +0 -1
- package/dist/_chunks/Form-Dxmihyw8.mjs.map +0 -1
- package/dist/_chunks/History-BZP8n7KT.mjs.map +0 -1
- package/dist/_chunks/History-BfX6XmZK.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-B3CXj8PY.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DxKuVkKz.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-Bk9VO__I.js.map +0 -1
- package/dist/_chunks/ListViewPage-D5D3tVPq.mjs.map +0 -1
- package/dist/_chunks/Relations-B6B3A3mb.js.map +0 -1
- package/dist/_chunks/Relations-BOYZmuWy.mjs.map +0 -1
- package/dist/_chunks/index-DzN3kBgx.js.map +0 -1
- package/dist/_chunks/index-VHviNMeW.mjs.map +0 -1
- package/dist/_chunks/layout-CPn1PM6x.mjs.map +0 -1
- package/dist/_chunks/layout-b91XRlD2.js.map +0 -1
- package/dist/_chunks/relations-BsqxS6tR.mjs.map +0 -1
- package/dist/_chunks/relations-CA7IYmcP.js.map +0 -1
- package/dist/_chunks/usePrev-B9w_-eYc.js.map +0 -1
- package/dist/_chunks/usePrev-DH6iah0A.mjs +0 -16
- package/dist/_chunks/usePrev-DH6iah0A.mjs.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.js
CHANGED
@@ -10,8 +10,7 @@ const qs = require("qs");
|
|
10
10
|
const slugify = require("@sindresorhus/slugify");
|
11
11
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
12
12
|
function _interopNamespace(e) {
|
13
|
-
if (e && e.__esModule)
|
14
|
-
return e;
|
13
|
+
if (e && e.__esModule) return e;
|
15
14
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
16
15
|
if (e) {
|
17
16
|
for (const k in e) {
|
@@ -33,10 +32,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
32
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
33
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
34
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
35
|
+
const getService$2 = (name) => {
|
37
36
|
return strapi.plugin("content-manager").service(name);
|
38
37
|
};
|
39
|
-
function getService(strapi2, name) {
|
38
|
+
function getService$1(strapi2, name) {
|
40
39
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
40
|
}
|
42
41
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +71,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
71
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
72
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
73
|
}
|
75
|
-
const permissionChecker2 = getService$
|
74
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
75
|
userAbility: ctx.state.userAbility,
|
77
76
|
model: ctx.query.contentType
|
78
77
|
});
|
@@ -80,7 +79,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
79
|
return ctx.forbidden();
|
81
80
|
}
|
82
81
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
82
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
83
|
query: {
|
85
84
|
...query,
|
86
85
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +104,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
104
|
async restoreVersion(ctx) {
|
106
105
|
const request = ctx.request;
|
107
106
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
107
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
108
|
userAbility: ctx.state.userAbility,
|
110
109
|
model: request.body.contentType
|
111
110
|
});
|
112
111
|
if (permissionChecker2.cannot.update()) {
|
113
112
|
throw new strapiUtils.errors.ForbiddenError();
|
114
113
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
114
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
115
|
request.params.versionId
|
117
116
|
);
|
118
117
|
return {
|
@@ -121,7 +120,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
120
|
}
|
122
121
|
};
|
123
122
|
};
|
124
|
-
const controllers$
|
123
|
+
const controllers$2 = {
|
125
124
|
"history-version": createHistoryVersionController
|
126
125
|
/**
|
127
126
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -167,8 +166,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
167
166
|
};
|
168
167
|
const getRelationRestoreValue = async (versionRelationData, attribute) => {
|
169
168
|
if (Array.isArray(versionRelationData)) {
|
170
|
-
if (versionRelationData.length === 0)
|
171
|
-
return versionRelationData;
|
169
|
+
if (versionRelationData.length === 0) return versionRelationData;
|
172
170
|
const existingAndMissingRelations = await Promise.all(
|
173
171
|
versionRelationData.map((relation) => {
|
174
172
|
return strapi2.documents(attribute.target).findOne({
|
@@ -199,10 +197,11 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
197
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
198
|
};
|
201
199
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
200
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
201
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
202
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
203
|
const getLocaleDictionary = async () => {
|
204
|
-
if (!localesService)
|
205
|
-
return {};
|
204
|
+
if (!localesService) return {};
|
206
205
|
const locales = await localesService.find() || [];
|
207
206
|
return locales.reduce(
|
208
207
|
(acc, locale) => {
|
@@ -226,31 +225,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
225
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
226
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
227
|
};
|
229
|
-
const
|
228
|
+
const getComponentFields = (componentUID) => {
|
229
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
230
|
+
(fieldsAcc, [key, attribute]) => {
|
231
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
232
|
+
fieldsAcc.push(key);
|
233
|
+
}
|
234
|
+
return fieldsAcc;
|
235
|
+
},
|
236
|
+
[]
|
237
|
+
);
|
238
|
+
};
|
239
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
240
|
const model = strapi2.getModel(uid2);
|
231
241
|
const attributes = Object.entries(model.attributes);
|
242
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
243
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
244
|
switch (attribute.type) {
|
234
245
|
case "relation": {
|
246
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
247
|
+
if (isMorphRelation) {
|
248
|
+
break;
|
249
|
+
}
|
235
250
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
236
251
|
if (isVisible2) {
|
237
|
-
acc[attributeName] = {
|
252
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
238
253
|
}
|
239
254
|
break;
|
240
255
|
}
|
241
256
|
case "media": {
|
242
|
-
acc[attributeName] = {
|
257
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
243
258
|
break;
|
244
259
|
}
|
245
260
|
case "component": {
|
246
261
|
const populate = getDeepPopulate2(attribute.component);
|
247
|
-
acc[attributeName] = {
|
262
|
+
acc[attributeName] = {
|
263
|
+
populate,
|
264
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
265
|
+
};
|
248
266
|
break;
|
249
267
|
}
|
250
268
|
case "dynamiczone": {
|
251
269
|
const populatedComponents = (attribute.components || []).reduce(
|
252
270
|
(acc2, componentUID) => {
|
253
|
-
acc2[componentUID] = {
|
271
|
+
acc2[componentUID] = {
|
272
|
+
populate: getDeepPopulate2(componentUID),
|
273
|
+
[fieldSelector]: getComponentFields(componentUID)
|
274
|
+
};
|
254
275
|
return acc2;
|
255
276
|
},
|
256
277
|
{}
|
@@ -312,6 +333,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
312
333
|
getRelationRestoreValue,
|
313
334
|
getMediaRestoreValue,
|
314
335
|
getDefaultLocale,
|
336
|
+
isLocalizedContentType,
|
315
337
|
getLocaleDictionary,
|
316
338
|
getRetentionDays,
|
317
339
|
getVersionStatus,
|
@@ -334,7 +356,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
356
|
});
|
335
357
|
},
|
336
358
|
async findVersionsPage(params) {
|
337
|
-
const
|
359
|
+
const model = strapi2.getModel(params.query.contentType);
|
360
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
361
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
362
|
+
let locale = null;
|
363
|
+
if (isLocalizedContentType) {
|
364
|
+
locale = params.query.locale || defaultLocale;
|
365
|
+
}
|
338
366
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
339
367
|
query.findPage({
|
340
368
|
...params.query,
|
@@ -356,7 +384,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
356
384
|
const attributeValue = entry.data[attributeKey];
|
357
385
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
358
386
|
if (attributeSchema.type === "media") {
|
359
|
-
const permissionChecker2 = getService$
|
387
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
360
388
|
userAbility: params.state.userAbility,
|
361
389
|
model: "plugin::upload.file"
|
362
390
|
});
|
@@ -379,7 +407,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
379
407
|
if (userToPopulate == null) {
|
380
408
|
return null;
|
381
409
|
}
|
382
|
-
return strapi2.query("admin::user").findOne({
|
410
|
+
return strapi2.query("admin::user").findOne({
|
411
|
+
where: {
|
412
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
413
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
414
|
+
}
|
415
|
+
});
|
383
416
|
})
|
384
417
|
);
|
385
418
|
return {
|
@@ -392,7 +425,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
392
425
|
[attributeKey]: adminUsers
|
393
426
|
};
|
394
427
|
}
|
395
|
-
const permissionChecker2 = getService$
|
428
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
396
429
|
userAbility: params.state.userAbility,
|
397
430
|
model: attributeSchema.target
|
398
431
|
});
|
@@ -490,13 +523,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
490
523
|
}
|
491
524
|
};
|
492
525
|
};
|
526
|
+
const shouldCreateHistoryVersion = (context) => {
|
527
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
528
|
+
return false;
|
529
|
+
}
|
530
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
return true;
|
540
|
+
};
|
541
|
+
const getSchemas = (uid2) => {
|
542
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
543
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
544
|
+
(currentComponentSchemas, key) => {
|
545
|
+
const fieldSchema = attributesSchema[key];
|
546
|
+
if (fieldSchema.type === "component") {
|
547
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
548
|
+
return {
|
549
|
+
...currentComponentSchemas,
|
550
|
+
[fieldSchema.component]: componentSchema
|
551
|
+
};
|
552
|
+
}
|
553
|
+
return currentComponentSchemas;
|
554
|
+
},
|
555
|
+
{}
|
556
|
+
);
|
557
|
+
return {
|
558
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
559
|
+
componentsSchemas
|
560
|
+
};
|
561
|
+
};
|
493
562
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
563
|
const state = {
|
495
564
|
deleteExpiredJob: null,
|
496
565
|
isInitialized: false
|
497
566
|
};
|
498
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
-
const historyService = getService(strapi2, "history");
|
500
567
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
568
|
return {
|
502
569
|
async bootstrap() {
|
@@ -504,73 +571,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
504
571
|
return;
|
505
572
|
}
|
506
573
|
strapi2.documents.use(async (context, next) => {
|
507
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
-
return next();
|
509
|
-
}
|
510
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
-
return next();
|
512
|
-
}
|
513
|
-
const contentTypeUid = context.contentType.uid;
|
514
|
-
if (!contentTypeUid.startsWith("api::")) {
|
515
|
-
return next();
|
516
|
-
}
|
517
574
|
const result = await next();
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
575
|
+
if (!shouldCreateHistoryVersion(context)) {
|
576
|
+
return result;
|
577
|
+
}
|
578
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
522
579
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
523
|
-
const
|
524
|
-
if (
|
525
|
-
|
526
|
-
"[Content manager history middleware]: An array of locales was provided, but only a single locale is supported for the findOne operation."
|
527
|
-
);
|
528
|
-
return next();
|
580
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
581
|
+
if (!locales.length) {
|
582
|
+
return result;
|
529
583
|
}
|
530
|
-
const
|
531
|
-
|
532
|
-
|
533
|
-
|
584
|
+
const uid2 = context.contentType.uid;
|
585
|
+
const schemas = getSchemas(uid2);
|
586
|
+
const model = strapi2.getModel(uid2);
|
587
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
588
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
589
|
+
where: {
|
590
|
+
documentId,
|
591
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
592
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
593
|
+
},
|
594
|
+
populate: serviceUtils.getDeepPopulate(
|
595
|
+
uid2,
|
596
|
+
true
|
597
|
+
/* use database syntax */
|
598
|
+
)
|
534
599
|
});
|
535
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
536
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
537
|
-
const componentsSchemas = Object.keys(
|
538
|
-
attributesSchema
|
539
|
-
).reduce((currentComponentSchemas, key) => {
|
540
|
-
const fieldSchema = attributesSchema[key];
|
541
|
-
if (fieldSchema.type === "component") {
|
542
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
543
|
-
return {
|
544
|
-
...currentComponentSchemas,
|
545
|
-
[fieldSchema.component]: componentSchema
|
546
|
-
};
|
547
|
-
}
|
548
|
-
return currentComponentSchemas;
|
549
|
-
}, {});
|
550
600
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
551
|
-
onCommit(() => {
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
601
|
+
onCommit(async () => {
|
602
|
+
for (const entry of localeEntries) {
|
603
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
604
|
+
await getService$1(strapi2, "history").createVersion({
|
605
|
+
contentType: uid2,
|
606
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
607
|
+
relatedDocumentId: documentId,
|
608
|
+
locale: entry.locale,
|
609
|
+
status,
|
610
|
+
...schemas
|
611
|
+
});
|
612
|
+
}
|
561
613
|
});
|
562
614
|
});
|
563
615
|
return result;
|
564
616
|
});
|
565
|
-
state.deleteExpiredJob = nodeSchedule.scheduleJob("0 0 * * *", () => {
|
617
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
566
618
|
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
567
619
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
568
|
-
query.deleteMany({
|
620
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
569
621
|
where: {
|
570
622
|
created_at: {
|
571
|
-
$lt: expirationDate
|
623
|
+
$lt: expirationDate
|
572
624
|
}
|
573
625
|
}
|
626
|
+
}).catch((error) => {
|
627
|
+
if (error instanceof Error) {
|
628
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
629
|
+
}
|
574
630
|
});
|
575
631
|
});
|
576
632
|
state.isInitialized = true;
|
@@ -582,17 +638,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
582
638
|
}
|
583
639
|
};
|
584
640
|
};
|
585
|
-
const services$
|
641
|
+
const services$2 = {
|
586
642
|
history: createHistoryService,
|
587
643
|
lifecycles: createLifecyclesService
|
588
644
|
};
|
589
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
645
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
590
646
|
const historyVersionRouter = {
|
591
647
|
type: "admin",
|
592
648
|
routes: [
|
593
649
|
{
|
594
650
|
method: "GET",
|
595
|
-
info,
|
651
|
+
info: info$1,
|
596
652
|
path: "/history-versions",
|
597
653
|
handler: "history-version.findMany",
|
598
654
|
config: {
|
@@ -601,7 +657,7 @@ const historyVersionRouter = {
|
|
601
657
|
},
|
602
658
|
{
|
603
659
|
method: "PUT",
|
604
|
-
info,
|
660
|
+
info: info$1,
|
605
661
|
path: "/history-versions/:versionId/restore",
|
606
662
|
handler: "history-version.restoreVersion",
|
607
663
|
config: {
|
@@ -610,7 +666,7 @@ const historyVersionRouter = {
|
|
610
666
|
}
|
611
667
|
]
|
612
668
|
};
|
613
|
-
const routes$
|
669
|
+
const routes$2 = {
|
614
670
|
"history-version": historyVersionRouter
|
615
671
|
};
|
616
672
|
const historyVersion = {
|
@@ -657,21 +713,21 @@ const historyVersion = {
|
|
657
713
|
}
|
658
714
|
}
|
659
715
|
};
|
660
|
-
const getFeature = () => {
|
716
|
+
const getFeature$1 = () => {
|
661
717
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
662
718
|
return {
|
663
719
|
register({ strapi: strapi2 }) {
|
664
720
|
strapi2.get("models").add(historyVersion);
|
665
721
|
},
|
666
722
|
bootstrap({ strapi: strapi2 }) {
|
667
|
-
getService(strapi2, "lifecycles").bootstrap();
|
723
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
668
724
|
},
|
669
725
|
destroy({ strapi: strapi2 }) {
|
670
|
-
getService(strapi2, "lifecycles").destroy();
|
726
|
+
getService$1(strapi2, "lifecycles").destroy();
|
671
727
|
},
|
672
|
-
controllers: controllers$
|
673
|
-
services: services$
|
674
|
-
routes: routes$
|
728
|
+
controllers: controllers$2,
|
729
|
+
services: services$2,
|
730
|
+
routes: routes$2
|
675
731
|
};
|
676
732
|
}
|
677
733
|
return {
|
@@ -680,9 +736,205 @@ const getFeature = () => {
|
|
680
736
|
}
|
681
737
|
};
|
682
738
|
};
|
683
|
-
const history = getFeature();
|
739
|
+
const history = getFeature$1();
|
740
|
+
const FEATURE_ID = "preview";
|
741
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
742
|
+
const previewRouter = {
|
743
|
+
type: "admin",
|
744
|
+
routes: [
|
745
|
+
{
|
746
|
+
method: "GET",
|
747
|
+
info,
|
748
|
+
path: "/preview/url/:contentType",
|
749
|
+
handler: "preview.getPreviewUrl",
|
750
|
+
config: {
|
751
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
752
|
+
}
|
753
|
+
}
|
754
|
+
]
|
755
|
+
};
|
756
|
+
const routes$1 = {
|
757
|
+
preview: previewRouter
|
758
|
+
};
|
759
|
+
function getService(strapi2, name) {
|
760
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
761
|
+
}
|
762
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
763
|
+
// Will be undefined for single types
|
764
|
+
documentId: yup__namespace.string(),
|
765
|
+
locale: yup__namespace.string().nullable(),
|
766
|
+
status: yup__namespace.string()
|
767
|
+
}).required();
|
768
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
769
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
770
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
771
|
+
const model = strapi2.getModel(uid2);
|
772
|
+
if (!model || model.modelType !== "contentType") {
|
773
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
774
|
+
}
|
775
|
+
const isSingleType = model?.kind === "singleType";
|
776
|
+
if (!isSingleType && !params.documentId) {
|
777
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
778
|
+
}
|
779
|
+
if (isSingleType) {
|
780
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
781
|
+
if (!doc) {
|
782
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
783
|
+
}
|
784
|
+
newParams.documentId = doc?.documentId;
|
785
|
+
}
|
786
|
+
if (!newParams.status) {
|
787
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
788
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
789
|
+
}
|
790
|
+
return newParams;
|
791
|
+
};
|
792
|
+
const createPreviewController = () => {
|
793
|
+
return {
|
794
|
+
/**
|
795
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
796
|
+
* in the Content Manager.
|
797
|
+
*/
|
798
|
+
async getPreviewUrl(ctx) {
|
799
|
+
const uid2 = ctx.params.contentType;
|
800
|
+
const query = ctx.request.query;
|
801
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
802
|
+
const previewService = getService(strapi, "preview");
|
803
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
804
|
+
if (!url) {
|
805
|
+
ctx.status = 204;
|
806
|
+
}
|
807
|
+
return {
|
808
|
+
data: { url }
|
809
|
+
};
|
810
|
+
}
|
811
|
+
};
|
812
|
+
};
|
813
|
+
const controllers$1 = {
|
814
|
+
preview: createPreviewController
|
815
|
+
/**
|
816
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
817
|
+
* passing a controller factory as the value, instead of a controller object directly
|
818
|
+
*/
|
819
|
+
};
|
820
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
821
|
+
const config = getService(strapi2, "preview-config");
|
822
|
+
return {
|
823
|
+
async getPreviewUrl(uid2, params) {
|
824
|
+
const handler = config.getPreviewHandler();
|
825
|
+
try {
|
826
|
+
return handler(uid2, params);
|
827
|
+
} catch (error) {
|
828
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
829
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
830
|
+
}
|
831
|
+
return;
|
832
|
+
}
|
833
|
+
};
|
834
|
+
};
|
835
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
836
|
+
const middlewares = strapi.config.get("middlewares");
|
837
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
838
|
+
if (currentMiddleware === middleware.name) {
|
839
|
+
return middleware;
|
840
|
+
}
|
841
|
+
if (currentMiddleware.name === middleware.name) {
|
842
|
+
return fp.mergeWith(
|
843
|
+
(objValue, srcValue) => {
|
844
|
+
if (Array.isArray(objValue)) {
|
845
|
+
return objValue.concat(srcValue);
|
846
|
+
}
|
847
|
+
return void 0;
|
848
|
+
},
|
849
|
+
currentMiddleware,
|
850
|
+
middleware
|
851
|
+
);
|
852
|
+
}
|
853
|
+
return currentMiddleware;
|
854
|
+
});
|
855
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
856
|
+
};
|
857
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
858
|
+
return {
|
859
|
+
register() {
|
860
|
+
if (!this.isEnabled()) {
|
861
|
+
return;
|
862
|
+
}
|
863
|
+
const config = strapi2.config.get("admin.preview");
|
864
|
+
if (config.config?.allowedOrigins) {
|
865
|
+
extendMiddlewareConfiguration({
|
866
|
+
name: "strapi::security",
|
867
|
+
config: {
|
868
|
+
contentSecurityPolicy: {
|
869
|
+
directives: {
|
870
|
+
"frame-src": config.config.allowedOrigins
|
871
|
+
}
|
872
|
+
}
|
873
|
+
}
|
874
|
+
});
|
875
|
+
}
|
876
|
+
},
|
877
|
+
isEnabled() {
|
878
|
+
const config = strapi2.config.get("admin.preview");
|
879
|
+
if (!config) {
|
880
|
+
return false;
|
881
|
+
}
|
882
|
+
return config?.enabled ?? true;
|
883
|
+
},
|
884
|
+
/**
|
885
|
+
* Validate if the configuration is valid
|
886
|
+
*/
|
887
|
+
validate() {
|
888
|
+
if (!this.isEnabled()) {
|
889
|
+
return;
|
890
|
+
}
|
891
|
+
const handler = this.getPreviewHandler();
|
892
|
+
if (typeof handler !== "function") {
|
893
|
+
throw new strapiUtils.errors.ValidationError(
|
894
|
+
"Preview configuration is invalid. Handler must be a function"
|
895
|
+
);
|
896
|
+
}
|
897
|
+
},
|
898
|
+
/**
|
899
|
+
* Utility to get the preview handler from the configuration
|
900
|
+
*/
|
901
|
+
getPreviewHandler() {
|
902
|
+
const config = strapi2.config.get("admin.preview");
|
903
|
+
const emptyHandler = () => {
|
904
|
+
return void 0;
|
905
|
+
};
|
906
|
+
if (!this.isEnabled()) {
|
907
|
+
return emptyHandler;
|
908
|
+
}
|
909
|
+
return config?.config?.handler || emptyHandler;
|
910
|
+
}
|
911
|
+
};
|
912
|
+
};
|
913
|
+
const services$1 = {
|
914
|
+
preview: createPreviewService,
|
915
|
+
"preview-config": createPreviewConfigService
|
916
|
+
};
|
917
|
+
const getFeature = () => {
|
918
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
919
|
+
return {};
|
920
|
+
}
|
921
|
+
return {
|
922
|
+
register() {
|
923
|
+
const config = getService(strapi, "preview-config");
|
924
|
+
config.validate();
|
925
|
+
config.register();
|
926
|
+
},
|
927
|
+
bootstrap() {
|
928
|
+
},
|
929
|
+
routes: routes$1,
|
930
|
+
controllers: controllers$1,
|
931
|
+
services: services$1
|
932
|
+
};
|
933
|
+
};
|
934
|
+
const preview = getFeature();
|
684
935
|
const register = async ({ strapi: strapi2 }) => {
|
685
936
|
await history.register?.({ strapi: strapi2 });
|
937
|
+
await preview.register?.({ strapi: strapi2 });
|
686
938
|
};
|
687
939
|
const ALLOWED_WEBHOOK_EVENTS = {
|
688
940
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -692,11 +944,12 @@ const bootstrap = async () => {
|
|
692
944
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
693
945
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
694
946
|
});
|
695
|
-
getService$
|
696
|
-
await getService$
|
697
|
-
await getService$
|
698
|
-
await getService$
|
947
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
948
|
+
await getService$2("components").syncConfigurations();
|
949
|
+
await getService$2("content-types").syncConfigurations();
|
950
|
+
await getService$2("permission").registerPermissions();
|
699
951
|
await history.bootstrap?.({ strapi });
|
952
|
+
await preview.bootstrap?.({ strapi });
|
700
953
|
};
|
701
954
|
const destroy = async ({ strapi: strapi2 }) => {
|
702
955
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1186,7 +1439,8 @@ const admin = {
|
|
1186
1439
|
};
|
1187
1440
|
const routes = {
|
1188
1441
|
admin,
|
1189
|
-
...history.routes ? history.routes : {}
|
1442
|
+
...history.routes ? history.routes : {},
|
1443
|
+
...preview.routes ? preview.routes : {}
|
1190
1444
|
};
|
1191
1445
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1192
1446
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1197,6 +1451,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1197
1451
|
const hasPermissions = createPolicy({
|
1198
1452
|
name: "plugin::content-manager.hasPermissions",
|
1199
1453
|
validator: validateHasPermissionsInput,
|
1454
|
+
/**
|
1455
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1456
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1457
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1458
|
+
*/
|
1200
1459
|
handler(ctx, config = {}) {
|
1201
1460
|
const { actions = [], hasAtLeastOne = false } = config;
|
1202
1461
|
const { userAbility } = ctx.state;
|
@@ -1244,8 +1503,7 @@ const isSortable = (schema, name) => {
|
|
1244
1503
|
if (!___default.default.has(schema.attributes, name)) {
|
1245
1504
|
return false;
|
1246
1505
|
}
|
1247
|
-
if (schema.modelType === "component" && name === "id")
|
1248
|
-
return false;
|
1506
|
+
if (schema.modelType === "component" && name === "id") return false;
|
1249
1507
|
const attribute = schema.attributes[name];
|
1250
1508
|
if (NON_SORTABLES.includes(attribute.type)) {
|
1251
1509
|
return false;
|
@@ -1390,8 +1648,7 @@ const createDefaultSettings = async (schema) => {
|
|
1390
1648
|
};
|
1391
1649
|
};
|
1392
1650
|
const syncSettings = async (configuration, schema) => {
|
1393
|
-
if (fp.isEmpty(configuration.settings))
|
1394
|
-
return createDefaultSettings(schema);
|
1651
|
+
if (fp.isEmpty(configuration.settings)) return createDefaultSettings(schema);
|
1395
1652
|
const defaultField = getDefaultMainField(schema);
|
1396
1653
|
const { mainField = defaultField, defaultSortBy = defaultField } = configuration.settings || {};
|
1397
1654
|
return {
|
@@ -1438,7 +1695,7 @@ const createMetadasSchema = (schema) => {
|
|
1438
1695
|
if (!value) {
|
1439
1696
|
return strapiUtils.yup.string();
|
1440
1697
|
}
|
1441
|
-
const targetSchema = getService$
|
1698
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1442
1699
|
schema.attributes[key].targetModel
|
1443
1700
|
);
|
1444
1701
|
if (!targetSchema) {
|
@@ -1567,8 +1824,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1567
1824
|
}
|
1568
1825
|
switch (attribute.type) {
|
1569
1826
|
case "relation": {
|
1570
|
-
if (canCreate(attributePath))
|
1571
|
-
return body2;
|
1827
|
+
if (canCreate(attributePath)) return body2;
|
1572
1828
|
return fp.set(attributePath, { set: [] }, body2);
|
1573
1829
|
}
|
1574
1830
|
case "component": {
|
@@ -1578,8 +1834,7 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1578
1834
|
]);
|
1579
1835
|
}
|
1580
1836
|
default: {
|
1581
|
-
if (canCreate(attributePath))
|
1582
|
-
return body2;
|
1837
|
+
if (canCreate(attributePath)) return body2;
|
1583
1838
|
return fp.set(attributePath, null, body2);
|
1584
1839
|
}
|
1585
1840
|
}
|
@@ -1590,9 +1845,11 @@ const multipleLocaleSchema = strapiUtils.yup.lazy(
|
|
1590
1845
|
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1591
1846
|
);
|
1592
1847
|
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1593
|
-
const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales: false }) => {
|
1848
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1594
1849
|
const { allowMultipleLocales } = opts;
|
1595
|
-
const { locale, status, ...rest } = request || {};
|
1850
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1851
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1852
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1596
1853
|
const schema = strapiUtils.yup.object().shape({
|
1597
1854
|
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1598
1855
|
status: statusSchema
|
@@ -1605,7 +1862,7 @@ const getDocumentLocaleAndStatus = async (request, opts = { allowMultipleLocales
|
|
1605
1862
|
}
|
1606
1863
|
};
|
1607
1864
|
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1608
|
-
const documentMetadata2 = getService$
|
1865
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1609
1866
|
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1610
1867
|
let {
|
1611
1868
|
meta: { availableLocales, availableStatus }
|
@@ -1631,8 +1888,8 @@ const createDocument = async (ctx, opts) => {
|
|
1631
1888
|
const { userAbility, user } = ctx.state;
|
1632
1889
|
const { model } = ctx.params;
|
1633
1890
|
const { body } = ctx.request;
|
1634
|
-
const documentManager2 = getService$
|
1635
|
-
const permissionChecker2 = getService$
|
1891
|
+
const documentManager2 = getService$2("document-manager");
|
1892
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1636
1893
|
if (permissionChecker2.cannot.create()) {
|
1637
1894
|
throw new strapiUtils.errors.ForbiddenError();
|
1638
1895
|
}
|
@@ -1640,7 +1897,7 @@ const createDocument = async (ctx, opts) => {
|
|
1640
1897
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1641
1898
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1642
1899
|
const sanitizedBody = await sanitizeFn(body);
|
1643
|
-
const { locale, status
|
1900
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1644
1901
|
return documentManager2.create(model, {
|
1645
1902
|
data: sanitizedBody,
|
1646
1903
|
locale,
|
@@ -1652,14 +1909,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1652
1909
|
const { userAbility, user } = ctx.state;
|
1653
1910
|
const { id, model } = ctx.params;
|
1654
1911
|
const { body } = ctx.request;
|
1655
|
-
const documentManager2 = getService$
|
1656
|
-
const permissionChecker2 = getService$
|
1912
|
+
const documentManager2 = getService$2("document-manager");
|
1913
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1657
1914
|
if (permissionChecker2.cannot.update()) {
|
1658
1915
|
throw new strapiUtils.errors.ForbiddenError();
|
1659
1916
|
}
|
1660
1917
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1661
|
-
const populate = await getService$
|
1662
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1918
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1919
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1663
1920
|
const [documentVersion, documentExists] = await Promise.all([
|
1664
1921
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1665
1922
|
documentManager2.exists(model, id)
|
@@ -1675,7 +1932,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1675
1932
|
throw new strapiUtils.errors.ForbiddenError();
|
1676
1933
|
}
|
1677
1934
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1678
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1935
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1679
1936
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1680
1937
|
const sanitizedBody = await sanitizeFn(body);
|
1681
1938
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1689,15 +1946,15 @@ const collectionTypes = {
|
|
1689
1946
|
const { userAbility } = ctx.state;
|
1690
1947
|
const { model } = ctx.params;
|
1691
1948
|
const { query } = ctx.request;
|
1692
|
-
const documentMetadata2 = getService$
|
1693
|
-
const documentManager2 = getService$
|
1694
|
-
const permissionChecker2 = getService$
|
1949
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1950
|
+
const documentManager2 = getService$2("document-manager");
|
1951
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1695
1952
|
if (permissionChecker2.cannot.read()) {
|
1696
1953
|
return ctx.forbidden();
|
1697
1954
|
}
|
1698
1955
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1699
|
-
const populate = await getService$
|
1700
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
1956
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1957
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1701
1958
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1702
1959
|
{ ...permissionQuery, populate, locale, status },
|
1703
1960
|
model
|
@@ -1725,14 +1982,14 @@ const collectionTypes = {
|
|
1725
1982
|
async findOne(ctx) {
|
1726
1983
|
const { userAbility } = ctx.state;
|
1727
1984
|
const { model, id } = ctx.params;
|
1728
|
-
const documentManager2 = getService$
|
1729
|
-
const permissionChecker2 = getService$
|
1985
|
+
const documentManager2 = getService$2("document-manager");
|
1986
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1730
1987
|
if (permissionChecker2.cannot.read()) {
|
1731
1988
|
return ctx.forbidden();
|
1732
1989
|
}
|
1733
1990
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1734
|
-
const populate = await getService$
|
1735
|
-
const { locale, status
|
1991
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1992
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1736
1993
|
const version = await documentManager2.findOne(id, model, {
|
1737
1994
|
populate,
|
1738
1995
|
locale,
|
@@ -1747,7 +2004,7 @@ const collectionTypes = {
|
|
1747
2004
|
permissionChecker2,
|
1748
2005
|
model,
|
1749
2006
|
// @ts-expect-error TODO: fix
|
1750
|
-
{ id, locale, publishedAt: null },
|
2007
|
+
{ documentId: id, locale, publishedAt: null },
|
1751
2008
|
{ availableLocales: true, availableStatus: false }
|
1752
2009
|
);
|
1753
2010
|
ctx.body = { data: {}, meta };
|
@@ -1762,7 +2019,7 @@ const collectionTypes = {
|
|
1762
2019
|
async create(ctx) {
|
1763
2020
|
const { userAbility } = ctx.state;
|
1764
2021
|
const { model } = ctx.params;
|
1765
|
-
const permissionChecker2 = getService$
|
2022
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1766
2023
|
const [totalEntries, document] = await Promise.all([
|
1767
2024
|
strapi.db.query(model).count(),
|
1768
2025
|
createDocument(ctx)
|
@@ -1783,7 +2040,7 @@ const collectionTypes = {
|
|
1783
2040
|
async update(ctx) {
|
1784
2041
|
const { userAbility } = ctx.state;
|
1785
2042
|
const { model } = ctx.params;
|
1786
|
-
const permissionChecker2 = getService$
|
2043
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1787
2044
|
const updatedVersion = await updateDocument(ctx);
|
1788
2045
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1789
2046
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
@@ -1792,14 +2049,14 @@ const collectionTypes = {
|
|
1792
2049
|
const { userAbility, user } = ctx.state;
|
1793
2050
|
const { model, sourceId: id } = ctx.params;
|
1794
2051
|
const { body } = ctx.request;
|
1795
|
-
const documentManager2 = getService$
|
1796
|
-
const permissionChecker2 = getService$
|
2052
|
+
const documentManager2 = getService$2("document-manager");
|
2053
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1797
2054
|
if (permissionChecker2.cannot.create()) {
|
1798
2055
|
return ctx.forbidden();
|
1799
2056
|
}
|
1800
2057
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1801
|
-
const populate = await getService$
|
1802
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2058
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2059
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1803
2060
|
const document = await documentManager2.findOne(id, model, {
|
1804
2061
|
populate,
|
1805
2062
|
locale,
|
@@ -1837,14 +2094,14 @@ const collectionTypes = {
|
|
1837
2094
|
async delete(ctx) {
|
1838
2095
|
const { userAbility } = ctx.state;
|
1839
2096
|
const { id, model } = ctx.params;
|
1840
|
-
const documentManager2 = getService$
|
1841
|
-
const permissionChecker2 = getService$
|
2097
|
+
const documentManager2 = getService$2("document-manager");
|
2098
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1842
2099
|
if (permissionChecker2.cannot.delete()) {
|
1843
2100
|
return ctx.forbidden();
|
1844
2101
|
}
|
1845
2102
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1846
|
-
const populate = await getService$
|
1847
|
-
const { locale } = await getDocumentLocaleAndStatus(ctx.query);
|
2103
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2104
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1848
2105
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1849
2106
|
if (documentLocales.length === 0) {
|
1850
2107
|
return ctx.notFound();
|
@@ -1865,19 +2122,42 @@ const collectionTypes = {
|
|
1865
2122
|
const { userAbility } = ctx.state;
|
1866
2123
|
const { id, model } = ctx.params;
|
1867
2124
|
const { body } = ctx.request;
|
1868
|
-
const documentManager2 = getService$
|
1869
|
-
const permissionChecker2 = getService$
|
2125
|
+
const documentManager2 = getService$2("document-manager");
|
2126
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1870
2127
|
if (permissionChecker2.cannot.publish()) {
|
1871
2128
|
return ctx.forbidden();
|
1872
2129
|
}
|
1873
2130
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1874
2131
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1875
|
-
const populate = await getService$
|
1876
|
-
|
2132
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2133
|
+
let document;
|
2134
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2135
|
+
const isCreate = fp.isNil(id);
|
2136
|
+
if (isCreate) {
|
2137
|
+
if (permissionChecker2.cannot.create()) {
|
2138
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2139
|
+
}
|
2140
|
+
document = await createDocument(ctx, { populate });
|
2141
|
+
}
|
2142
|
+
const isUpdate = !isCreate;
|
2143
|
+
if (isUpdate) {
|
2144
|
+
const documentExists = documentManager2.exists(model, id);
|
2145
|
+
if (!documentExists) {
|
2146
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2147
|
+
}
|
2148
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2149
|
+
if (!document) {
|
2150
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2151
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2152
|
+
}
|
2153
|
+
document = await updateDocument(ctx);
|
2154
|
+
} else if (permissionChecker2.can.update(document)) {
|
2155
|
+
await updateDocument(ctx);
|
2156
|
+
}
|
2157
|
+
}
|
1877
2158
|
if (permissionChecker2.cannot.publish(document)) {
|
1878
2159
|
throw new strapiUtils.errors.ForbiddenError();
|
1879
2160
|
}
|
1880
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
1881
2161
|
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1882
2162
|
locale
|
1883
2163
|
// TODO: Allow setting creator fields on publish
|
@@ -1897,14 +2177,16 @@ const collectionTypes = {
|
|
1897
2177
|
const { body } = ctx.request;
|
1898
2178
|
const { documentIds } = body;
|
1899
2179
|
await validateBulkActionInput(body);
|
1900
|
-
const documentManager2 = getService$
|
1901
|
-
const permissionChecker2 = getService$
|
2180
|
+
const documentManager2 = getService$2("document-manager");
|
2181
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1902
2182
|
if (permissionChecker2.cannot.publish()) {
|
1903
2183
|
return ctx.forbidden();
|
1904
2184
|
}
|
1905
2185
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1906
|
-
const populate = await getService$
|
1907
|
-
const { locale } = await getDocumentLocaleAndStatus(body, {
|
2186
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2187
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2188
|
+
allowMultipleLocales: true
|
2189
|
+
});
|
1908
2190
|
const entityPromises = documentIds.map(
|
1909
2191
|
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
1910
2192
|
);
|
@@ -1926,12 +2208,14 @@ const collectionTypes = {
|
|
1926
2208
|
const { body } = ctx.request;
|
1927
2209
|
const { documentIds } = body;
|
1928
2210
|
await validateBulkActionInput(body);
|
1929
|
-
const documentManager2 = getService$
|
1930
|
-
const permissionChecker2 = getService$
|
2211
|
+
const documentManager2 = getService$2("document-manager");
|
2212
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1931
2213
|
if (permissionChecker2.cannot.unpublish()) {
|
1932
2214
|
return ctx.forbidden();
|
1933
2215
|
}
|
1934
|
-
const { locale } = await getDocumentLocaleAndStatus(body
|
2216
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2217
|
+
allowMultipleLocales: true
|
2218
|
+
});
|
1935
2219
|
const entityPromises = documentIds.map(
|
1936
2220
|
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
1937
2221
|
);
|
@@ -1954,8 +2238,8 @@ const collectionTypes = {
|
|
1954
2238
|
const {
|
1955
2239
|
body: { discardDraft, ...body }
|
1956
2240
|
} = ctx.request;
|
1957
|
-
const documentManager2 = getService$
|
1958
|
-
const permissionChecker2 = getService$
|
2241
|
+
const documentManager2 = getService$2("document-manager");
|
2242
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1959
2243
|
if (permissionChecker2.cannot.unpublish()) {
|
1960
2244
|
return ctx.forbidden();
|
1961
2245
|
}
|
@@ -1963,8 +2247,8 @@ const collectionTypes = {
|
|
1963
2247
|
return ctx.forbidden();
|
1964
2248
|
}
|
1965
2249
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1966
|
-
const populate = await getService$
|
1967
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2250
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2251
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1968
2252
|
const document = await documentManager2.findOne(id, model, {
|
1969
2253
|
populate,
|
1970
2254
|
locale,
|
@@ -1994,14 +2278,14 @@ const collectionTypes = {
|
|
1994
2278
|
const { userAbility } = ctx.state;
|
1995
2279
|
const { id, model } = ctx.params;
|
1996
2280
|
const { body } = ctx.request;
|
1997
|
-
const documentManager2 = getService$
|
1998
|
-
const permissionChecker2 = getService$
|
2281
|
+
const documentManager2 = getService$2("document-manager");
|
2282
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1999
2283
|
if (permissionChecker2.cannot.discard()) {
|
2000
2284
|
return ctx.forbidden();
|
2001
2285
|
}
|
2002
2286
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
2003
|
-
const populate = await getService$
|
2004
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2287
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2288
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2005
2289
|
const document = await documentManager2.findOne(id, model, {
|
2006
2290
|
populate,
|
2007
2291
|
locale,
|
@@ -2025,14 +2309,14 @@ const collectionTypes = {
|
|
2025
2309
|
const { query, body } = ctx.request;
|
2026
2310
|
const { documentIds } = body;
|
2027
2311
|
await validateBulkActionInput(body);
|
2028
|
-
const documentManager2 = getService$
|
2029
|
-
const permissionChecker2 = getService$
|
2312
|
+
const documentManager2 = getService$2("document-manager");
|
2313
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2030
2314
|
if (permissionChecker2.cannot.delete()) {
|
2031
2315
|
return ctx.forbidden();
|
2032
2316
|
}
|
2033
2317
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2034
|
-
const populate = await getService$
|
2035
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2318
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2319
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2036
2320
|
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2037
2321
|
populate,
|
2038
2322
|
locale
|
@@ -2052,14 +2336,14 @@ const collectionTypes = {
|
|
2052
2336
|
async countDraftRelations(ctx) {
|
2053
2337
|
const { userAbility } = ctx.state;
|
2054
2338
|
const { model, id } = ctx.params;
|
2055
|
-
const documentManager2 = getService$
|
2056
|
-
const permissionChecker2 = getService$
|
2339
|
+
const documentManager2 = getService$2("document-manager");
|
2340
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2057
2341
|
if (permissionChecker2.cannot.read()) {
|
2058
2342
|
return ctx.forbidden();
|
2059
2343
|
}
|
2060
2344
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2061
|
-
const populate = await getService$
|
2062
|
-
const { locale, status
|
2345
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2346
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2063
2347
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2064
2348
|
if (!entity) {
|
2065
2349
|
return ctx.notFound();
|
@@ -2077,12 +2361,12 @@ const collectionTypes = {
|
|
2077
2361
|
const ids = ctx.request.query.documentIds;
|
2078
2362
|
const locale = ctx.request.query.locale;
|
2079
2363
|
const { model } = ctx.params;
|
2080
|
-
const documentManager2 = getService$
|
2081
|
-
const permissionChecker2 = getService$
|
2364
|
+
const documentManager2 = getService$2("document-manager");
|
2365
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2082
2366
|
if (permissionChecker2.cannot.read()) {
|
2083
2367
|
return ctx.forbidden();
|
2084
2368
|
}
|
2085
|
-
const
|
2369
|
+
const documents = await documentManager2.findMany(
|
2086
2370
|
{
|
2087
2371
|
filters: {
|
2088
2372
|
documentId: ids
|
@@ -2091,7 +2375,7 @@ const collectionTypes = {
|
|
2091
2375
|
},
|
2092
2376
|
model
|
2093
2377
|
);
|
2094
|
-
if (!
|
2378
|
+
if (!documents) {
|
2095
2379
|
return ctx.notFound();
|
2096
2380
|
}
|
2097
2381
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2102,13 +2386,13 @@ const collectionTypes = {
|
|
2102
2386
|
};
|
2103
2387
|
const components$1 = {
|
2104
2388
|
findComponents(ctx) {
|
2105
|
-
const components2 = getService$
|
2106
|
-
const { toDto } = getService$
|
2389
|
+
const components2 = getService$2("components").findAllComponents();
|
2390
|
+
const { toDto } = getService$2("data-mapper");
|
2107
2391
|
ctx.body = { data: components2.map(toDto) };
|
2108
2392
|
},
|
2109
2393
|
async findComponentConfiguration(ctx) {
|
2110
2394
|
const { uid: uid2 } = ctx.params;
|
2111
|
-
const componentService = getService$
|
2395
|
+
const componentService = getService$2("components");
|
2112
2396
|
const component = componentService.findComponent(uid2);
|
2113
2397
|
if (!component) {
|
2114
2398
|
return ctx.notFound("component.notFound");
|
@@ -2125,7 +2409,7 @@ const components$1 = {
|
|
2125
2409
|
async updateComponentConfiguration(ctx) {
|
2126
2410
|
const { uid: uid2 } = ctx.params;
|
2127
2411
|
const { body } = ctx.request;
|
2128
|
-
const componentService = getService$
|
2412
|
+
const componentService = getService$2("components");
|
2129
2413
|
const component = componentService.findComponent(uid2);
|
2130
2414
|
if (!component) {
|
2131
2415
|
return ctx.notFound("component.notFound");
|
@@ -2159,12 +2443,12 @@ const contentTypes = {
|
|
2159
2443
|
} catch (error) {
|
2160
2444
|
return ctx.send({ error }, 400);
|
2161
2445
|
}
|
2162
|
-
const contentTypes2 = getService$
|
2163
|
-
const { toDto } = getService$
|
2446
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2447
|
+
const { toDto } = getService$2("data-mapper");
|
2164
2448
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2165
2449
|
},
|
2166
2450
|
async findContentTypesSettings(ctx) {
|
2167
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2451
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2168
2452
|
const contentTypes2 = await findAllContentTypes();
|
2169
2453
|
const configurations = await Promise.all(
|
2170
2454
|
contentTypes2.map(async (contentType) => {
|
@@ -2178,7 +2462,7 @@ const contentTypes = {
|
|
2178
2462
|
},
|
2179
2463
|
async findContentTypeConfiguration(ctx) {
|
2180
2464
|
const { uid: uid2 } = ctx.params;
|
2181
|
-
const contentTypeService = getService$
|
2465
|
+
const contentTypeService = getService$2("content-types");
|
2182
2466
|
const contentType = await contentTypeService.findContentType(uid2);
|
2183
2467
|
if (!contentType) {
|
2184
2468
|
return ctx.notFound("contentType.notFound");
|
@@ -2200,13 +2484,13 @@ const contentTypes = {
|
|
2200
2484
|
const { userAbility } = ctx.state;
|
2201
2485
|
const { uid: uid2 } = ctx.params;
|
2202
2486
|
const { body } = ctx.request;
|
2203
|
-
const contentTypeService = getService$
|
2204
|
-
const metricsService = getService$
|
2487
|
+
const contentTypeService = getService$2("content-types");
|
2488
|
+
const metricsService = getService$2("metrics");
|
2205
2489
|
const contentType = await contentTypeService.findContentType(uid2);
|
2206
2490
|
if (!contentType) {
|
2207
2491
|
return ctx.notFound("contentType.notFound");
|
2208
2492
|
}
|
2209
|
-
if (!getService$
|
2493
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2210
2494
|
return ctx.forbidden();
|
2211
2495
|
}
|
2212
2496
|
let input;
|
@@ -2239,10 +2523,10 @@ const contentTypes = {
|
|
2239
2523
|
};
|
2240
2524
|
const init = {
|
2241
2525
|
getInitData(ctx) {
|
2242
|
-
const { toDto } = getService$
|
2243
|
-
const { findAllComponents } = getService$
|
2244
|
-
const { getAllFieldSizes } = getService$
|
2245
|
-
const { findAllContentTypes } = getService$
|
2526
|
+
const { toDto } = getService$2("data-mapper");
|
2527
|
+
const { findAllComponents } = getService$2("components");
|
2528
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2529
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2246
2530
|
ctx.body = {
|
2247
2531
|
data: {
|
2248
2532
|
fieldSizes: getAllFieldSizes(),
|
@@ -2278,36 +2562,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2278
2562
|
params.filters.$and.push(filtersClause);
|
2279
2563
|
};
|
2280
2564
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2281
|
-
const permissionChecker2 = getService$
|
2565
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2282
2566
|
userAbility,
|
2283
2567
|
model: model.uid
|
2284
2568
|
});
|
2285
|
-
|
2569
|
+
const isMainFieldListable = isListable(model, mainField);
|
2570
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2571
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2286
2572
|
return "id";
|
2287
2573
|
}
|
2288
|
-
if (
|
2289
|
-
|
2290
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2291
|
-
userAbility,
|
2292
|
-
model: "plugin::users-permissions.user"
|
2293
|
-
});
|
2294
|
-
if (userPermissionChecker.can.read()) {
|
2295
|
-
return "name";
|
2296
|
-
}
|
2297
|
-
}
|
2298
|
-
return "id";
|
2574
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2575
|
+
return "name";
|
2299
2576
|
}
|
2300
2577
|
return mainField;
|
2301
2578
|
};
|
2302
|
-
const addStatusToRelations = async (
|
2303
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2579
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2580
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2304
2581
|
return relations2;
|
2305
2582
|
}
|
2306
|
-
const documentMetadata2 = getService$
|
2307
|
-
|
2583
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2584
|
+
if (!relations2.length) {
|
2585
|
+
return relations2;
|
2586
|
+
}
|
2587
|
+
const firstRelation = relations2[0];
|
2588
|
+
const filters = {
|
2589
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2590
|
+
// NOTE: find the "opposite" status
|
2591
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2592
|
+
};
|
2593
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2594
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2595
|
+
filters
|
2596
|
+
});
|
2308
2597
|
return relations2.map((relation) => {
|
2309
|
-
const availableStatuses =
|
2310
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2598
|
+
const availableStatuses = availableStatus.filter(
|
2599
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2311
2600
|
);
|
2312
2601
|
return {
|
2313
2602
|
...relation,
|
@@ -2328,11 +2617,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2328
2617
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2329
2618
|
const isSourceLocalized = isLocalized(sourceModel);
|
2330
2619
|
const isTargetLocalized = isLocalized(targetModel);
|
2331
|
-
let validatedLocale = locale;
|
2332
|
-
if (!targetModel || !isTargetLocalized)
|
2333
|
-
validatedLocale = void 0;
|
2334
2620
|
return {
|
2335
|
-
locale
|
2621
|
+
locale,
|
2336
2622
|
isSourceLocalized,
|
2337
2623
|
isTargetLocalized
|
2338
2624
|
};
|
@@ -2341,8 +2627,7 @@ const validateStatus = (sourceUid, status) => {
|
|
2341
2627
|
const sourceModel = strapi.getModel(sourceUid);
|
2342
2628
|
const isDP = strapiUtils.contentTypes.hasDraftAndPublish;
|
2343
2629
|
const isSourceDP = isDP(sourceModel);
|
2344
|
-
if (!isSourceDP)
|
2345
|
-
return { status: void 0 };
|
2630
|
+
if (!isSourceDP) return { status: void 0 };
|
2346
2631
|
switch (status) {
|
2347
2632
|
case "published":
|
2348
2633
|
return { status: "published" };
|
@@ -2372,7 +2657,7 @@ const relations = {
|
|
2372
2657
|
ctx.request?.query?.locale
|
2373
2658
|
);
|
2374
2659
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2375
|
-
const permissionChecker2 = getService$
|
2660
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2376
2661
|
userAbility,
|
2377
2662
|
model
|
2378
2663
|
});
|
@@ -2397,7 +2682,7 @@ const relations = {
|
|
2397
2682
|
where.id = id;
|
2398
2683
|
}
|
2399
2684
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2400
|
-
const populate = await getService$
|
2685
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2401
2686
|
const currentEntity = await strapi.db.query(model).findOne({
|
2402
2687
|
where,
|
2403
2688
|
populate
|
@@ -2412,7 +2697,7 @@ const relations = {
|
|
2412
2697
|
}
|
2413
2698
|
entryId = currentEntity.id;
|
2414
2699
|
}
|
2415
|
-
const modelConfig = isComponent2 ? await getService$
|
2700
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2416
2701
|
const targetSchema = strapi.getModel(targetUid);
|
2417
2702
|
const mainField = fp.flow(
|
2418
2703
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2435,7 +2720,7 @@ const relations = {
|
|
2435
2720
|
attribute,
|
2436
2721
|
fieldsToSelect,
|
2437
2722
|
mainField,
|
2438
|
-
source: { schema: sourceSchema },
|
2723
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2439
2724
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2440
2725
|
sourceSchema,
|
2441
2726
|
targetSchema,
|
@@ -2457,7 +2742,8 @@ const relations = {
|
|
2457
2742
|
fieldsToSelect,
|
2458
2743
|
mainField,
|
2459
2744
|
source: {
|
2460
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2745
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2746
|
+
isLocalized: isSourceLocalized
|
2461
2747
|
},
|
2462
2748
|
target: {
|
2463
2749
|
schema: { uid: targetUid },
|
@@ -2465,7 +2751,7 @@ const relations = {
|
|
2465
2751
|
}
|
2466
2752
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2467
2753
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2468
|
-
const permissionChecker2 = getService$
|
2754
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2469
2755
|
userAbility: ctx.state.userAbility,
|
2470
2756
|
model: targetUid
|
2471
2757
|
});
|
@@ -2495,12 +2781,16 @@ const relations = {
|
|
2495
2781
|
} else {
|
2496
2782
|
where.id = id;
|
2497
2783
|
}
|
2498
|
-
|
2499
|
-
|
2784
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2785
|
+
if (!fp.isEmpty(publishedAt)) {
|
2786
|
+
where[`${alias}.published_at`] = publishedAt;
|
2500
2787
|
}
|
2501
|
-
if (
|
2788
|
+
if (isTargetLocalized && locale) {
|
2502
2789
|
where[`${alias}.locale`] = locale;
|
2503
2790
|
}
|
2791
|
+
if (isSourceLocalized && locale) {
|
2792
|
+
where.locale = locale;
|
2793
|
+
}
|
2504
2794
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2505
2795
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2506
2796
|
}
|
@@ -2518,7 +2808,8 @@ const relations = {
|
|
2518
2808
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2519
2809
|
});
|
2520
2810
|
}
|
2521
|
-
const
|
2811
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2812
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2522
2813
|
ctx.body = {
|
2523
2814
|
...res,
|
2524
2815
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2533,29 +2824,39 @@ const relations = {
|
|
2533
2824
|
attribute,
|
2534
2825
|
targetField,
|
2535
2826
|
fieldsToSelect,
|
2536
|
-
|
2537
|
-
|
2538
|
-
}
|
2539
|
-
target: {
|
2540
|
-
schema: { uid: targetUid }
|
2541
|
-
}
|
2827
|
+
status,
|
2828
|
+
source: { schema: sourceSchema },
|
2829
|
+
target: { schema: targetSchema }
|
2542
2830
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2543
|
-
const
|
2831
|
+
const { uid: sourceUid } = sourceSchema;
|
2832
|
+
const { uid: targetUid } = targetSchema;
|
2833
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2544
2834
|
const dbQuery = strapi.db.query(sourceUid);
|
2545
2835
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2836
|
+
const filters = {};
|
2837
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2838
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2839
|
+
if (status === "published") {
|
2840
|
+
filters.publishedAt = { $notNull: true };
|
2841
|
+
} else {
|
2842
|
+
filters.publishedAt = { $null: true };
|
2843
|
+
}
|
2844
|
+
}
|
2845
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2846
|
+
filters.publishedAt = { $null: true };
|
2847
|
+
}
|
2546
2848
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2547
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2849
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2548
2850
|
ordering: "desc",
|
2549
2851
|
page: ctx.request.query.page,
|
2550
|
-
pageSize: ctx.request.query.pageSize
|
2852
|
+
pageSize: ctx.request.query.pageSize,
|
2853
|
+
filters
|
2551
2854
|
});
|
2552
2855
|
const loadedIds = res.results.map((item) => item.id);
|
2553
2856
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2554
2857
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2555
2858
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2556
|
-
ordering: "desc"
|
2557
|
-
page: ctx.request.query.page,
|
2558
|
-
pageSize: ctx.request.query.pageSize
|
2859
|
+
ordering: "desc"
|
2559
2860
|
});
|
2560
2861
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2561
2862
|
ctx.body = {
|
@@ -2570,10 +2871,10 @@ const relations = {
|
|
2570
2871
|
}
|
2571
2872
|
};
|
2572
2873
|
const buildPopulateFromQuery = async (query, model) => {
|
2573
|
-
return getService$
|
2874
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2574
2875
|
};
|
2575
2876
|
const findDocument = async (query, uid2, opts = {}) => {
|
2576
|
-
const documentManager2 = getService$
|
2877
|
+
const documentManager2 = getService$2("document-manager");
|
2577
2878
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2578
2879
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2579
2880
|
};
|
@@ -2581,13 +2882,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2581
2882
|
const { user, userAbility } = ctx.state;
|
2582
2883
|
const { model } = ctx.params;
|
2583
2884
|
const { body, query } = ctx.request;
|
2584
|
-
const documentManager2 = getService$
|
2585
|
-
const permissionChecker2 = getService$
|
2885
|
+
const documentManager2 = getService$2("document-manager");
|
2886
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2586
2887
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2587
2888
|
throw new strapiUtils.errors.ForbiddenError();
|
2588
2889
|
}
|
2589
2890
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2590
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
2891
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2591
2892
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2592
2893
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2593
2894
|
// Find the first document to check if it exists
|
@@ -2623,12 +2924,12 @@ const singleTypes = {
|
|
2623
2924
|
const { userAbility } = ctx.state;
|
2624
2925
|
const { model } = ctx.params;
|
2625
2926
|
const { query = {} } = ctx.request;
|
2626
|
-
const permissionChecker2 = getService$
|
2927
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2627
2928
|
if (permissionChecker2.cannot.read()) {
|
2628
2929
|
return ctx.forbidden();
|
2629
2930
|
}
|
2630
2931
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2631
|
-
const { locale, status } = await getDocumentLocaleAndStatus(query);
|
2932
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2632
2933
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2633
2934
|
if (!version) {
|
2634
2935
|
if (permissionChecker2.cannot.create()) {
|
@@ -2642,7 +2943,7 @@ const singleTypes = {
|
|
2642
2943
|
permissionChecker2,
|
2643
2944
|
model,
|
2644
2945
|
// @ts-expect-error - fix types
|
2645
|
-
{
|
2946
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2646
2947
|
{ availableLocales: true, availableStatus: false }
|
2647
2948
|
);
|
2648
2949
|
ctx.body = { data: {}, meta };
|
@@ -2657,7 +2958,7 @@ const singleTypes = {
|
|
2657
2958
|
async createOrUpdate(ctx) {
|
2658
2959
|
const { userAbility } = ctx.state;
|
2659
2960
|
const { model } = ctx.params;
|
2660
|
-
const permissionChecker2 = getService$
|
2961
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2661
2962
|
const document = await createOrUpdateDocument(ctx);
|
2662
2963
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2663
2964
|
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
@@ -2666,14 +2967,14 @@ const singleTypes = {
|
|
2666
2967
|
const { userAbility } = ctx.state;
|
2667
2968
|
const { model } = ctx.params;
|
2668
2969
|
const { query = {} } = ctx.request;
|
2669
|
-
const documentManager2 = getService$
|
2670
|
-
const permissionChecker2 = getService$
|
2970
|
+
const documentManager2 = getService$2("document-manager");
|
2971
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2671
2972
|
if (permissionChecker2.cannot.delete()) {
|
2672
2973
|
return ctx.forbidden();
|
2673
2974
|
}
|
2674
2975
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2675
2976
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2676
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
2977
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2677
2978
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2678
2979
|
populate,
|
2679
2980
|
locale
|
@@ -2695,8 +2996,8 @@ const singleTypes = {
|
|
2695
2996
|
const { userAbility } = ctx.state;
|
2696
2997
|
const { model } = ctx.params;
|
2697
2998
|
const { query = {} } = ctx.request;
|
2698
|
-
const documentManager2 = getService$
|
2699
|
-
const permissionChecker2 = getService$
|
2999
|
+
const documentManager2 = getService$2("document-manager");
|
3000
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2700
3001
|
if (permissionChecker2.cannot.publish()) {
|
2701
3002
|
return ctx.forbidden();
|
2702
3003
|
}
|
@@ -2710,7 +3011,7 @@ const singleTypes = {
|
|
2710
3011
|
if (permissionChecker2.cannot.publish(document)) {
|
2711
3012
|
throw new strapiUtils.errors.ForbiddenError();
|
2712
3013
|
}
|
2713
|
-
const { locale } = await getDocumentLocaleAndStatus(document);
|
3014
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2714
3015
|
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2715
3016
|
return publishResult.at(0);
|
2716
3017
|
});
|
@@ -2724,8 +3025,8 @@ const singleTypes = {
|
|
2724
3025
|
body: { discardDraft, ...body },
|
2725
3026
|
query = {}
|
2726
3027
|
} = ctx.request;
|
2727
|
-
const documentManager2 = getService$
|
2728
|
-
const permissionChecker2 = getService$
|
3028
|
+
const documentManager2 = getService$2("document-manager");
|
3029
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2729
3030
|
if (permissionChecker2.cannot.unpublish()) {
|
2730
3031
|
return ctx.forbidden();
|
2731
3032
|
}
|
@@ -2733,7 +3034,7 @@ const singleTypes = {
|
|
2733
3034
|
return ctx.forbidden();
|
2734
3035
|
}
|
2735
3036
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2736
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3037
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2737
3038
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2738
3039
|
if (!document) {
|
2739
3040
|
return ctx.notFound();
|
@@ -2759,13 +3060,13 @@ const singleTypes = {
|
|
2759
3060
|
const { userAbility } = ctx.state;
|
2760
3061
|
const { model } = ctx.params;
|
2761
3062
|
const { body, query = {} } = ctx.request;
|
2762
|
-
const documentManager2 = getService$
|
2763
|
-
const permissionChecker2 = getService$
|
3063
|
+
const documentManager2 = getService$2("document-manager");
|
3064
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2764
3065
|
if (permissionChecker2.cannot.discard()) {
|
2765
3066
|
return ctx.forbidden();
|
2766
3067
|
}
|
2767
3068
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2768
|
-
const { locale } = await getDocumentLocaleAndStatus(body);
|
3069
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2769
3070
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2770
3071
|
if (!document) {
|
2771
3072
|
return ctx.notFound();
|
@@ -2783,9 +3084,9 @@ const singleTypes = {
|
|
2783
3084
|
const { userAbility } = ctx.state;
|
2784
3085
|
const { model } = ctx.params;
|
2785
3086
|
const { query } = ctx.request;
|
2786
|
-
const documentManager2 = getService$
|
2787
|
-
const permissionChecker2 = getService$
|
2788
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3087
|
+
const documentManager2 = getService$2("document-manager");
|
3088
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3089
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2789
3090
|
if (permissionChecker2.cannot.read()) {
|
2790
3091
|
return ctx.forbidden();
|
2791
3092
|
}
|
@@ -2806,9 +3107,9 @@ const uid$1 = {
|
|
2806
3107
|
async generateUID(ctx) {
|
2807
3108
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2808
3109
|
const { query = {} } = ctx.request;
|
2809
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3110
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2810
3111
|
await validateUIDField(contentTypeUID, field);
|
2811
|
-
const uidService = getService$
|
3112
|
+
const uidService = getService$2("uid");
|
2812
3113
|
ctx.body = {
|
2813
3114
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2814
3115
|
};
|
@@ -2818,9 +3119,9 @@ const uid$1 = {
|
|
2818
3119
|
ctx.request.body
|
2819
3120
|
);
|
2820
3121
|
const { query = {} } = ctx.request;
|
2821
|
-
const { locale } = await getDocumentLocaleAndStatus(query);
|
3122
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2822
3123
|
await validateUIDField(contentTypeUID, field);
|
2823
|
-
const uidService = getService$
|
3124
|
+
const uidService = getService$2("uid");
|
2824
3125
|
const isAvailable = await uidService.checkUIDAvailability({
|
2825
3126
|
contentTypeUID,
|
2826
3127
|
field,
|
@@ -2841,7 +3142,8 @@ const controllers = {
|
|
2841
3142
|
relations,
|
2842
3143
|
"single-types": singleTypes,
|
2843
3144
|
uid: uid$1,
|
2844
|
-
...history.controllers ? history.controllers : {}
|
3145
|
+
...history.controllers ? history.controllers : {},
|
3146
|
+
...preview.controllers ? preview.controllers : {}
|
2845
3147
|
};
|
2846
3148
|
const keys = {
|
2847
3149
|
CONFIGURATION: "configuration"
|
@@ -2970,18 +3272,15 @@ async function syncMetadatas(configuration, schema) {
|
|
2970
3272
|
___default.default.set(updatedMeta, ["list", "searchable"], false);
|
2971
3273
|
___default.default.set(acc, [key], updatedMeta);
|
2972
3274
|
}
|
2973
|
-
if (!___default.default.has(edit, "mainField"))
|
2974
|
-
return acc;
|
3275
|
+
if (!___default.default.has(edit, "mainField")) return acc;
|
2975
3276
|
if (!isRelation$1(attr)) {
|
2976
3277
|
___default.default.set(updatedMeta, "edit", ___default.default.omit(edit, ["mainField"]));
|
2977
3278
|
___default.default.set(acc, [key], updatedMeta);
|
2978
3279
|
return acc;
|
2979
3280
|
}
|
2980
|
-
if (edit.mainField === "id")
|
2981
|
-
return acc;
|
3281
|
+
if (edit.mainField === "id") return acc;
|
2982
3282
|
const targetSchema = getTargetSchema(attr.targetModel);
|
2983
|
-
if (!targetSchema)
|
2984
|
-
return acc;
|
3283
|
+
if (!targetSchema) return acc;
|
2985
3284
|
if (!isSortable(targetSchema, edit.mainField) && !isListable(targetSchema, edit.mainField)) {
|
2986
3285
|
___default.default.set(updatedMeta, ["edit", "mainField"], getDefaultMainField(targetSchema));
|
2987
3286
|
___default.default.set(acc, [key], updatedMeta);
|
@@ -2992,12 +3291,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2992
3291
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
2993
3292
|
}
|
2994
3293
|
const getTargetSchema = (targetModel) => {
|
2995
|
-
return getService$
|
3294
|
+
return getService$2("content-types").findContentType(targetModel);
|
2996
3295
|
};
|
2997
3296
|
const DEFAULT_LIST_LENGTH = 4;
|
2998
3297
|
const MAX_ROW_SIZE = 12;
|
2999
3298
|
const isAllowedFieldSize = (type, size) => {
|
3000
|
-
const { getFieldSize } = getService$
|
3299
|
+
const { getFieldSize } = getService$2("field-sizes");
|
3001
3300
|
const fieldSize = getFieldSize(type);
|
3002
3301
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
3003
3302
|
return false;
|
@@ -3005,7 +3304,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
3005
3304
|
return size <= MAX_ROW_SIZE;
|
3006
3305
|
};
|
3007
3306
|
const getDefaultFieldSize = (attribute) => {
|
3008
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3307
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
3009
3308
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
3010
3309
|
};
|
3011
3310
|
async function createDefaultLayouts(schema) {
|
@@ -3026,8 +3325,7 @@ function createDefaultEditLayout(schema) {
|
|
3026
3325
|
return appendToEditLayout([], keys2, schema);
|
3027
3326
|
}
|
3028
3327
|
function syncLayouts(configuration, schema) {
|
3029
|
-
if (___default.default.isEmpty(configuration.layouts))
|
3030
|
-
return createDefaultLayouts(schema);
|
3328
|
+
if (___default.default.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
3031
3329
|
const { list = [], editRelations = [], edit = [] } = configuration.layouts || {};
|
3032
3330
|
let cleanList = list.filter((attr) => isListable(schema, attr));
|
3033
3331
|
const cleanEditRelations = editRelations.filter(
|
@@ -3038,9 +3336,8 @@ function syncLayouts(configuration, schema) {
|
|
3038
3336
|
for (const row of edit) {
|
3039
3337
|
const newRow = [];
|
3040
3338
|
for (const el of row) {
|
3041
|
-
if (!hasEditableAttribute(schema, el.name))
|
3042
|
-
|
3043
|
-
const { hasFieldSize } = getService$1("field-sizes");
|
3339
|
+
if (!hasEditableAttribute(schema, el.name)) continue;
|
3340
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
3044
3341
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
3045
3342
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
3046
3343
|
elementsToReAppend.push(el.name);
|
@@ -3070,8 +3367,7 @@ function syncLayouts(configuration, schema) {
|
|
3070
3367
|
};
|
3071
3368
|
}
|
3072
3369
|
const appendToEditLayout = (layout = [], keysToAppend, schema) => {
|
3073
|
-
if (keysToAppend.length === 0)
|
3074
|
-
return layout;
|
3370
|
+
if (keysToAppend.length === 0) return layout;
|
3075
3371
|
let currentRowIndex = Math.max(layout.length - 1, 0);
|
3076
3372
|
if (!layout[currentRowIndex]) {
|
3077
3373
|
layout[currentRowIndex] = [];
|
@@ -3180,17 +3476,17 @@ const configurationService$1 = createConfigurationService({
|
|
3180
3476
|
isComponent: true,
|
3181
3477
|
prefix: STORE_KEY_PREFIX,
|
3182
3478
|
getModels() {
|
3183
|
-
const { toContentManagerModel } = getService$
|
3479
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3184
3480
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3185
3481
|
}
|
3186
3482
|
});
|
3187
3483
|
const components = ({ strapi: strapi2 }) => ({
|
3188
3484
|
findAllComponents() {
|
3189
|
-
const { toContentManagerModel } = getService$
|
3485
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3190
3486
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3191
3487
|
},
|
3192
3488
|
findComponent(uid2) {
|
3193
|
-
const { toContentManagerModel } = getService$
|
3489
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3194
3490
|
const component = strapi2.components[uid2];
|
3195
3491
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3196
3492
|
},
|
@@ -3241,17 +3537,17 @@ const configurationService = createConfigurationService({
|
|
3241
3537
|
storeUtils,
|
3242
3538
|
prefix: "content_types",
|
3243
3539
|
getModels() {
|
3244
|
-
const { toContentManagerModel } = getService$
|
3540
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3245
3541
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3246
3542
|
}
|
3247
3543
|
});
|
3248
3544
|
const service = ({ strapi: strapi2 }) => ({
|
3249
3545
|
findAllContentTypes() {
|
3250
|
-
const { toContentManagerModel } = getService$
|
3546
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3251
3547
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3252
3548
|
},
|
3253
3549
|
findContentType(uid2) {
|
3254
|
-
const { toContentManagerModel } = getService$
|
3550
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3255
3551
|
const contentType = strapi2.contentTypes[uid2];
|
3256
3552
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3257
3553
|
},
|
@@ -3280,7 +3576,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3280
3576
|
return this.findConfiguration(contentType);
|
3281
3577
|
},
|
3282
3578
|
findComponentsConfigurations(contentType) {
|
3283
|
-
return getService$
|
3579
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3284
3580
|
},
|
3285
3581
|
syncConfigurations() {
|
3286
3582
|
return configurationService.syncConfigurations();
|
@@ -3461,12 +3757,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3461
3757
|
ability: userAbility,
|
3462
3758
|
model
|
3463
3759
|
});
|
3464
|
-
const
|
3760
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3761
|
+
const toSubject = (entity) => {
|
3762
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3763
|
+
};
|
3465
3764
|
const can = (action, entity, field) => {
|
3466
|
-
|
3765
|
+
const subject = toSubject(entity);
|
3766
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3767
|
+
return (
|
3768
|
+
// Test the original action to see if it passes
|
3769
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3770
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3771
|
+
);
|
3467
3772
|
};
|
3468
3773
|
const cannot = (action, entity, field) => {
|
3469
|
-
|
3774
|
+
const subject = toSubject(entity);
|
3775
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3776
|
+
return (
|
3777
|
+
// Test both the original action
|
3778
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3779
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3780
|
+
);
|
3470
3781
|
};
|
3471
3782
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3472
3783
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3537,7 +3848,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3537
3848
|
return userAbility.can(action);
|
3538
3849
|
},
|
3539
3850
|
async registerPermissions() {
|
3540
|
-
const displayedContentTypes = getService$
|
3851
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3541
3852
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3542
3853
|
const actions = [
|
3543
3854
|
{
|
@@ -3743,6 +4054,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3743
4054
|
const attribute = model.attributes[attributeName];
|
3744
4055
|
switch (attribute.type) {
|
3745
4056
|
case "relation": {
|
4057
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4058
|
+
if (isMorphRelation) {
|
4059
|
+
break;
|
4060
|
+
}
|
3746
4061
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3747
4062
|
populateAcc[attributeName] = {
|
3748
4063
|
count: true,
|
@@ -3809,7 +4124,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3809
4124
|
return populateQuery;
|
3810
4125
|
};
|
3811
4126
|
const buildDeepPopulate = (uid2) => {
|
3812
|
-
return getService$
|
4127
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3813
4128
|
};
|
3814
4129
|
const populateBuilder = (uid2) => {
|
3815
4130
|
let getInitialPopulate = async () => {
|
@@ -3994,7 +4309,9 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3994
4309
|
*/
|
3995
4310
|
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3996
4311
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
3997
|
-
|
4312
|
+
if (version.locale) {
|
4313
|
+
delete versionsByLocale[version.locale];
|
4314
|
+
}
|
3998
4315
|
const model = strapi2.getModel(uid2);
|
3999
4316
|
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4000
4317
|
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
@@ -4041,8 +4358,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4041
4358
|
const matchStatus = status === "published" ? v.publishedAt !== null : v.publishedAt === null;
|
4042
4359
|
return matchLocale && matchStatus;
|
4043
4360
|
});
|
4044
|
-
if (!availableStatus)
|
4045
|
-
return availableStatus;
|
4361
|
+
if (!availableStatus) return availableStatus;
|
4046
4362
|
return fp.pick(AVAILABLE_STATUS_FIELDS, availableStatus);
|
4047
4363
|
},
|
4048
4364
|
/**
|
@@ -4052,8 +4368,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4052
4368
|
* @returns
|
4053
4369
|
*/
|
4054
4370
|
async getManyAvailableStatus(uid2, documents) {
|
4055
|
-
if (!documents.length)
|
4056
|
-
return [];
|
4371
|
+
if (!documents.length) return [];
|
4057
4372
|
const status = documents[0].publishedAt !== null ? "published" : "draft";
|
4058
4373
|
const locale = documents[0]?.locale;
|
4059
4374
|
const otherStatus = status === "published" ? "draft" : "published";
|
@@ -4080,10 +4395,8 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4080
4395
|
} else if (otherVersion) {
|
4081
4396
|
draftVersion = otherVersion;
|
4082
4397
|
}
|
4083
|
-
if (!draftVersion)
|
4084
|
-
|
4085
|
-
if (!publishedVersion)
|
4086
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
4398
|
+
if (!draftVersion) return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4399
|
+
if (!publishedVersion) return CONTENT_MANAGER_STATUS.DRAFT;
|
4087
4400
|
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4088
4401
|
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
4089
4402
|
},
|
@@ -4120,7 +4433,13 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
4120
4433
|
*/
|
4121
4434
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
4122
4435
|
if (!document) {
|
4123
|
-
return
|
4436
|
+
return {
|
4437
|
+
data: document,
|
4438
|
+
meta: {
|
4439
|
+
availableLocales: [],
|
4440
|
+
availableStatus: []
|
4441
|
+
}
|
4442
|
+
};
|
4124
4443
|
}
|
4125
4444
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
4126
4445
|
if (!hasDraftAndPublish) {
|
@@ -4228,10 +4547,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4228
4547
|
async clone(id, body, uid2) {
|
4229
4548
|
const populate = await buildDeepPopulate(uid2);
|
4230
4549
|
const params = {
|
4231
|
-
data:
|
4232
|
-
...omitIdField(body),
|
4233
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4234
|
-
},
|
4550
|
+
data: omitIdField(body),
|
4235
4551
|
populate
|
4236
4552
|
};
|
4237
4553
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4347,7 +4663,8 @@ const services = {
|
|
4347
4663
|
permission,
|
4348
4664
|
"populate-builder": populateBuilder$1,
|
4349
4665
|
uid,
|
4350
|
-
...history.services ? history.services : {}
|
4666
|
+
...history.services ? history.services : {},
|
4667
|
+
...preview.services ? preview.services : {}
|
4351
4668
|
};
|
4352
4669
|
const index = () => {
|
4353
4670
|
return {
|