@strapi/content-manager 0.0.0-experimental.e60ec1829240dae21c1e1d29076681c322288813 → 0.0.0-experimental.eba25ec571b091c6bde1104eb6c753debdf15462
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-DSVYodBX.js → CardDragPreview-C0QyJgRA.js} +10 -14
- package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +1 -0
- package/dist/_chunks/{CardDragPreview-ikSG4M46.mjs → CardDragPreview-DOxamsuj.mjs} +7 -9
- package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +1 -0
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs → ComponentConfigurationPage-BaJMOQyq.mjs} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-BPvzFjM7.mjs.map → ComponentConfigurationPage-BaJMOQyq.mjs.map} +1 -1
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js → ComponentConfigurationPage-N-CTtgQa.js} +4 -4
- package/dist/_chunks/{ComponentConfigurationPage-DjWJdz6Y.js.map → ComponentConfigurationPage-N-CTtgQa.js.map} +1 -1
- package/dist/_chunks/{ComponentIcon-BBQsYCVn.js → ComponentIcon-BXdiCGQp.js} +8 -2
- package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +1 -0
- package/dist/_chunks/{ComponentIcon-BOFnK76n.mjs → ComponentIcon-u4bIXTFY.mjs} +9 -3
- package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +1 -0
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js → EditConfigurationPage-BHkjAbxH.js} +4 -4
- package/dist/_chunks/{EditConfigurationPage-Dmv83RlS.js.map → EditConfigurationPage-BHkjAbxH.js.map} +1 -1
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs → EditConfigurationPage-CKK-5LfX.mjs} +4 -4
- package/dist/_chunks/{EditConfigurationPage-DacbqQ_f.mjs.map → EditConfigurationPage-CKK-5LfX.mjs.map} +1 -1
- package/dist/_chunks/EditViewPage-B11aeMcf.mjs +254 -0
- package/dist/_chunks/EditViewPage-B11aeMcf.mjs.map +1 -0
- package/dist/_chunks/{EditViewPage-DvNpQkam.js → EditViewPage-QPUftxUd.js} +101 -52
- package/dist/_chunks/EditViewPage-QPUftxUd.js.map +1 -0
- package/dist/_chunks/{Field-6gvGdPBV.mjs → Field-Bj_RgtGo.mjs} +1077 -814
- package/dist/_chunks/Field-Bj_RgtGo.mjs.map +1 -0
- package/dist/_chunks/{Field-DmVKIAOo.js → Field-DUK83cfh.js} +1121 -859
- package/dist/_chunks/Field-DUK83cfh.js.map +1 -0
- package/dist/_chunks/{Form-CPZC9vWa.js → Form-DHmBRlHd.js} +66 -46
- package/dist/_chunks/Form-DHmBRlHd.js.map +1 -0
- package/dist/_chunks/{Form-DW6K1IH-.mjs → Form-DLMSoXV7.mjs} +66 -45
- package/dist/_chunks/Form-DLMSoXV7.mjs.map +1 -0
- package/dist/_chunks/{History-Dmr9fmUA.mjs → History-CfCSNlG9.mjs} +181 -144
- package/dist/_chunks/History-CfCSNlG9.mjs.map +1 -0
- package/dist/_chunks/{History-DeAPlvtv.js → History-Di3zm4HT.js} +181 -145
- package/dist/_chunks/History-Di3zm4HT.js.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DhwvYcNv.mjs → ListConfigurationPage-0mtv_iqk.mjs} +67 -56
- package/dist/_chunks/ListConfigurationPage-0mtv_iqk.mjs.map +1 -0
- package/dist/_chunks/{ListConfigurationPage-DPCwW5Vr.js → ListConfigurationPage-Cq361KIt.js} +70 -60
- package/dist/_chunks/ListConfigurationPage-Cq361KIt.js.map +1 -0
- package/dist/_chunks/{ListViewPage-BtAwuYLE.mjs → ListViewPage-BxLVROX8.mjs} +175 -159
- package/dist/_chunks/ListViewPage-BxLVROX8.mjs.map +1 -0
- package/dist/_chunks/{ListViewPage-5ySZ-VUs.js → ListViewPage-DFDcG8gM.js} +178 -162
- package/dist/_chunks/ListViewPage-DFDcG8gM.js.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DSPxnxxp.mjs → NoContentTypePage-BRfDd67_.mjs} +3 -3
- package/dist/_chunks/NoContentTypePage-BRfDd67_.mjs.map +1 -0
- package/dist/_chunks/{NoContentTypePage-DOC_yWOf.js → NoContentTypePage-BSyvnDZZ.js} +3 -3
- package/dist/_chunks/NoContentTypePage-BSyvnDZZ.js.map +1 -0
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs → NoPermissionsPage-CV9V8KWa.mjs} +2 -2
- package/dist/_chunks/{NoPermissionsPage-UWDC-1Tw.mjs.map → NoPermissionsPage-CV9V8KWa.mjs.map} +1 -1
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js → NoPermissionsPage-DyLphsn_.js} +2 -2
- package/dist/_chunks/{NoPermissionsPage-Dwu8rRJu.js.map → NoPermissionsPage-DyLphsn_.js.map} +1 -1
- package/dist/_chunks/Preview-C_B1nx3g.mjs +272 -0
- package/dist/_chunks/Preview-C_B1nx3g.mjs.map +1 -0
- package/dist/_chunks/Preview-D_3aO6Ly.js +291 -0
- package/dist/_chunks/Preview-D_3aO6Ly.js.map +1 -0
- package/dist/_chunks/{Relations-J8cscLlR.mjs → Relations-C6pwmDXh.mjs} +135 -89
- package/dist/_chunks/Relations-C6pwmDXh.mjs.map +1 -0
- package/dist/_chunks/{Relations-CgWtgnPe.js → Relations-Cne2AlrL.js} +138 -93
- package/dist/_chunks/Relations-Cne2AlrL.js.map +1 -0
- package/dist/_chunks/{en-MBPul9Su.mjs → en-DhFUjrNW.mjs} +37 -18
- package/dist/_chunks/{en-MBPul9Su.mjs.map → en-DhFUjrNW.mjs.map} +1 -1
- package/dist/_chunks/{en-C-V1_90f.js → en-Ic0kXjxB.js} +37 -18
- package/dist/_chunks/{en-C-V1_90f.js.map → en-Ic0kXjxB.js.map} +1 -1
- package/dist/_chunks/{es-EUonQTon.js → es-9K52xZIr.js} +2 -2
- package/dist/_chunks/{ja-CcFe8diO.js.map → es-9K52xZIr.js.map} +1 -1
- package/dist/_chunks/{es-CeXiYflN.mjs → es-D34tqjMw.mjs} +2 -2
- package/dist/_chunks/{es-CeXiYflN.mjs.map → es-D34tqjMw.mjs.map} +1 -1
- package/dist/_chunks/{fr-CD9VFbPM.mjs → fr--pg5jUbt.mjs} +13 -3
- package/dist/_chunks/{fr-CD9VFbPM.mjs.map → fr--pg5jUbt.mjs.map} +1 -1
- package/dist/_chunks/{fr-B7kGGg3E.js → fr-B2Kyv8Z9.js} +13 -3
- package/dist/_chunks/{fr-B7kGGg3E.js.map → fr-B2Kyv8Z9.js.map} +1 -1
- package/dist/_chunks/{index-CwRRo1V9.mjs → index-BpxR3En4.mjs} +1835 -824
- package/dist/_chunks/index-BpxR3En4.mjs.map +1 -0
- package/dist/_chunks/{index-C6AH2hEl.js → index-T-aWjbj2.js} +1788 -777
- package/dist/_chunks/index-T-aWjbj2.js.map +1 -0
- package/dist/_chunks/{ja-CcFe8diO.js → ja-7sfIbjxE.js} +2 -2
- package/dist/_chunks/{es-EUonQTon.js.map → ja-7sfIbjxE.js.map} +1 -1
- package/dist/_chunks/{ja-CtsUxOvk.mjs → ja-BHqhDq4V.mjs} +2 -2
- package/dist/_chunks/{ja-CtsUxOvk.mjs.map → ja-BHqhDq4V.mjs.map} +1 -1
- package/dist/_chunks/{layout-B_SXLhqf.js → layout-BEuNwv-F.js} +45 -29
- package/dist/_chunks/layout-BEuNwv-F.js.map +1 -0
- package/dist/_chunks/{layout-jIDzX0Fp.mjs → layout-DhMZ_lDx.mjs} +45 -27
- package/dist/_chunks/layout-DhMZ_lDx.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-CuvIgCqI.mjs → relations-BdnxoX6f.mjs} +6 -7
- package/dist/_chunks/relations-BdnxoX6f.mjs.map +1 -0
- package/dist/_chunks/{relations-iBMa_OFG.js → relations-kLcuobLk.js} +6 -7
- package/dist/_chunks/relations-kLcuobLk.js.map +1 -0
- package/dist/_chunks/useDebounce-CtcjDB3L.js +28 -0
- 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-DdHgKsqq.mjs.map +1 -1
- package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +1 -1
- package/dist/admin/index.js +3 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +9 -7
- package/dist/admin/src/components/ComponentIcon.d.ts +6 -3
- package/dist/admin/src/content-manager.d.ts +3 -3
- package/dist/admin/src/exports.d.ts +2 -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 +37 -9
- package/dist/admin/src/hooks/useDocumentActions.d.ts +24 -3
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +2 -2
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -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 +11 -4
- package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.d.ts +3 -3
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +4 -0
- package/dist/admin/src/pages/EditView/components/FormInputs/Component/Input.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.d.ts +3 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +30 -18
- package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +3 -49
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/Field.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 +16 -53
- package/dist/admin/src/pages/EditView/components/Header.d.ts +11 -11
- package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -10
- 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/pages/ListView/components/BulkActions/PublishAction.d.ts +9 -26
- 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 +2 -3
- package/dist/admin/src/services/components.d.ts +2 -2
- package/dist/admin/src/services/contentTypes.d.ts +5 -5
- package/dist/admin/src/services/documents.d.ts +31 -20
- package/dist/admin/src/services/init.d.ts +2 -2
- package/dist/admin/src/services/relations.d.ts +3 -3
- package/dist/admin/src/services/uid.d.ts +3 -3
- package/dist/admin/src/utils/api.d.ts +4 -18
- package/dist/admin/src/utils/validation.d.ts +5 -7
- package/dist/server/index.js +852 -436
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +859 -443
- 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/single-types.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 +22 -0
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts +11 -0
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/index.d.ts +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 +21 -42
- package/dist/server/src/index.d.ts.map +1 -1
- 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 +13 -12
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +14 -35
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +21 -42
- 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 +8 -1
- 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 +17 -7
- 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/contracts/relations.d.ts +2 -2
- package/dist/shared/contracts/relations.d.ts.map +1 -1
- 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 +19 -20
- package/dist/_chunks/CardDragPreview-DSVYodBX.js.map +0 -1
- package/dist/_chunks/CardDragPreview-ikSG4M46.mjs.map +0 -1
- package/dist/_chunks/ComponentIcon-BBQsYCVn.js.map +0 -1
- package/dist/_chunks/ComponentIcon-BOFnK76n.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DDS6H9HO.mjs +0 -203
- package/dist/_chunks/EditViewPage-DDS6H9HO.mjs.map +0 -1
- package/dist/_chunks/EditViewPage-DvNpQkam.js.map +0 -1
- package/dist/_chunks/Field-6gvGdPBV.mjs.map +0 -1
- package/dist/_chunks/Field-DmVKIAOo.js.map +0 -1
- package/dist/_chunks/Form-CPZC9vWa.js.map +0 -1
- package/dist/_chunks/Form-DW6K1IH-.mjs.map +0 -1
- package/dist/_chunks/History-DeAPlvtv.js.map +0 -1
- package/dist/_chunks/History-Dmr9fmUA.mjs.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DPCwW5Vr.js.map +0 -1
- package/dist/_chunks/ListConfigurationPage-DhwvYcNv.mjs.map +0 -1
- package/dist/_chunks/ListViewPage-5ySZ-VUs.js.map +0 -1
- package/dist/_chunks/ListViewPage-BtAwuYLE.mjs.map +0 -1
- package/dist/_chunks/NoContentTypePage-DOC_yWOf.js.map +0 -1
- package/dist/_chunks/NoContentTypePage-DSPxnxxp.mjs.map +0 -1
- package/dist/_chunks/Relations-CgWtgnPe.js.map +0 -1
- package/dist/_chunks/Relations-J8cscLlR.mjs.map +0 -1
- package/dist/_chunks/index-C6AH2hEl.js.map +0 -1
- package/dist/_chunks/index-CwRRo1V9.mjs.map +0 -1
- package/dist/_chunks/layout-B_SXLhqf.js.map +0 -1
- package/dist/_chunks/layout-jIDzX0Fp.mjs.map +0 -1
- package/dist/_chunks/relations-CuvIgCqI.mjs.map +0 -1
- package/dist/_chunks/relations-iBMa_OFG.js.map +0 -1
- package/dist/_chunks/urls-CbOsUOoW.mjs +0 -7
- package/dist/_chunks/urls-CbOsUOoW.mjs.map +0 -1
- package/dist/_chunks/urls-DzZya_gm.js +0 -6
- package/dist/_chunks/urls-DzZya_gm.js.map +0 -1
- package/dist/server/src/controllers/utils/dimensions.d.ts +0 -5
- package/dist/server/src/controllers/utils/dimensions.d.ts.map +0 -1
- package/strapi-server.js +0 -3
package/dist/server/index.js
CHANGED
@@ -33,10 +33,10 @@ const isNil__default = /* @__PURE__ */ _interopDefault(isNil);
|
|
33
33
|
const ___default = /* @__PURE__ */ _interopDefault(_);
|
34
34
|
const qs__default = /* @__PURE__ */ _interopDefault(qs);
|
35
35
|
const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
|
36
|
-
const getService$
|
36
|
+
const getService$2 = (name) => {
|
37
37
|
return strapi.plugin("content-manager").service(name);
|
38
38
|
};
|
39
|
-
function getService(strapi2, name) {
|
39
|
+
function getService$1(strapi2, name) {
|
40
40
|
return strapi2.service(`plugin::content-manager.${name}`);
|
41
41
|
}
|
42
42
|
const historyRestoreVersionSchema = yup__namespace.object().shape({
|
@@ -72,7 +72,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
72
72
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
73
73
|
throw new strapiUtils.errors.ForbiddenError("contentType and documentId are required");
|
74
74
|
}
|
75
|
-
const permissionChecker2 = getService$
|
75
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
76
76
|
userAbility: ctx.state.userAbility,
|
77
77
|
model: ctx.query.contentType
|
78
78
|
});
|
@@ -80,7 +80,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
80
80
|
return ctx.forbidden();
|
81
81
|
}
|
82
82
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
83
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
83
|
+
const { results, pagination } = await getService$1(strapi2, "history").findVersionsPage({
|
84
84
|
query: {
|
85
85
|
...query,
|
86
86
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -105,14 +105,14 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
105
105
|
async restoreVersion(ctx) {
|
106
106
|
const request = ctx.request;
|
107
107
|
await validateRestoreVersion(request.body, "contentType is required");
|
108
|
-
const permissionChecker2 = getService$
|
108
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
109
109
|
userAbility: ctx.state.userAbility,
|
110
110
|
model: request.body.contentType
|
111
111
|
});
|
112
112
|
if (permissionChecker2.cannot.update()) {
|
113
113
|
throw new strapiUtils.errors.ForbiddenError();
|
114
114
|
}
|
115
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
115
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
116
116
|
request.params.versionId
|
117
117
|
);
|
118
118
|
return {
|
@@ -121,7 +121,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
121
121
|
}
|
122
122
|
};
|
123
123
|
};
|
124
|
-
const controllers$
|
124
|
+
const controllers$2 = {
|
125
125
|
"history-version": createHistoryVersionController
|
126
126
|
/**
|
127
127
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -199,7 +199,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
199
199
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
200
200
|
};
|
201
201
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
202
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
202
203
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
204
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
203
205
|
const getLocaleDictionary = async () => {
|
204
206
|
if (!localesService)
|
205
207
|
return {};
|
@@ -226,31 +228,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
226
228
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
227
229
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
228
230
|
};
|
229
|
-
const
|
231
|
+
const getComponentFields = (componentUID) => {
|
232
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
233
|
+
(fieldsAcc, [key, attribute]) => {
|
234
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
235
|
+
fieldsAcc.push(key);
|
236
|
+
}
|
237
|
+
return fieldsAcc;
|
238
|
+
},
|
239
|
+
[]
|
240
|
+
);
|
241
|
+
};
|
242
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
230
243
|
const model = strapi2.getModel(uid2);
|
231
244
|
const attributes = Object.entries(model.attributes);
|
245
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
232
246
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
233
247
|
switch (attribute.type) {
|
234
248
|
case "relation": {
|
249
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
250
|
+
if (isMorphRelation) {
|
251
|
+
break;
|
252
|
+
}
|
235
253
|
const isVisible2 = strapiUtils.contentTypes.isVisibleAttribute(model, attributeName);
|
236
254
|
if (isVisible2) {
|
237
|
-
acc[attributeName] = {
|
255
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
238
256
|
}
|
239
257
|
break;
|
240
258
|
}
|
241
259
|
case "media": {
|
242
|
-
acc[attributeName] = {
|
260
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
243
261
|
break;
|
244
262
|
}
|
245
263
|
case "component": {
|
246
264
|
const populate = getDeepPopulate2(attribute.component);
|
247
|
-
acc[attributeName] = {
|
265
|
+
acc[attributeName] = {
|
266
|
+
populate,
|
267
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
268
|
+
};
|
248
269
|
break;
|
249
270
|
}
|
250
271
|
case "dynamiczone": {
|
251
272
|
const populatedComponents = (attribute.components || []).reduce(
|
252
273
|
(acc2, componentUID) => {
|
253
|
-
acc2[componentUID] = {
|
274
|
+
acc2[componentUID] = {
|
275
|
+
populate: getDeepPopulate2(componentUID),
|
276
|
+
[fieldSelector]: getComponentFields(componentUID)
|
277
|
+
};
|
254
278
|
return acc2;
|
255
279
|
},
|
256
280
|
{}
|
@@ -312,6 +336,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
312
336
|
getRelationRestoreValue,
|
313
337
|
getMediaRestoreValue,
|
314
338
|
getDefaultLocale,
|
339
|
+
isLocalizedContentType,
|
315
340
|
getLocaleDictionary,
|
316
341
|
getRetentionDays,
|
317
342
|
getVersionStatus,
|
@@ -334,7 +359,13 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
334
359
|
});
|
335
360
|
},
|
336
361
|
async findVersionsPage(params) {
|
337
|
-
const
|
362
|
+
const model = strapi2.getModel(params.query.contentType);
|
363
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
364
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
365
|
+
let locale = null;
|
366
|
+
if (isLocalizedContentType) {
|
367
|
+
locale = params.query.locale || defaultLocale;
|
368
|
+
}
|
338
369
|
const [{ results, pagination }, localeDictionary] = await Promise.all([
|
339
370
|
query.findPage({
|
340
371
|
...params.query,
|
@@ -356,7 +387,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
356
387
|
const attributeValue = entry.data[attributeKey];
|
357
388
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
358
389
|
if (attributeSchema.type === "media") {
|
359
|
-
const permissionChecker2 = getService$
|
390
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
360
391
|
userAbility: params.state.userAbility,
|
361
392
|
model: "plugin::upload.file"
|
362
393
|
});
|
@@ -379,7 +410,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
379
410
|
if (userToPopulate == null) {
|
380
411
|
return null;
|
381
412
|
}
|
382
|
-
return strapi2.query("admin::user").findOne({
|
413
|
+
return strapi2.query("admin::user").findOne({
|
414
|
+
where: {
|
415
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
416
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
417
|
+
}
|
418
|
+
});
|
383
419
|
})
|
384
420
|
);
|
385
421
|
return {
|
@@ -392,7 +428,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
392
428
|
[attributeKey]: adminUsers
|
393
429
|
};
|
394
430
|
}
|
395
|
-
const permissionChecker2 = getService$
|
431
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
396
432
|
userAbility: params.state.userAbility,
|
397
433
|
model: attributeSchema.target
|
398
434
|
});
|
@@ -490,13 +526,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
490
526
|
}
|
491
527
|
};
|
492
528
|
};
|
529
|
+
const shouldCreateHistoryVersion = (context) => {
|
530
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
534
|
+
return false;
|
535
|
+
}
|
536
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
537
|
+
return false;
|
538
|
+
}
|
539
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
540
|
+
return false;
|
541
|
+
}
|
542
|
+
return true;
|
543
|
+
};
|
544
|
+
const getSchemas = (uid2) => {
|
545
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
546
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
547
|
+
(currentComponentSchemas, key) => {
|
548
|
+
const fieldSchema = attributesSchema[key];
|
549
|
+
if (fieldSchema.type === "component") {
|
550
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
551
|
+
return {
|
552
|
+
...currentComponentSchemas,
|
553
|
+
[fieldSchema.component]: componentSchema
|
554
|
+
};
|
555
|
+
}
|
556
|
+
return currentComponentSchemas;
|
557
|
+
},
|
558
|
+
{}
|
559
|
+
);
|
560
|
+
return {
|
561
|
+
schema: fp.omit(FIELDS_TO_IGNORE, attributesSchema),
|
562
|
+
componentsSchemas
|
563
|
+
};
|
564
|
+
};
|
493
565
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
494
566
|
const state = {
|
495
567
|
deleteExpiredJob: null,
|
496
568
|
isInitialized: false
|
497
569
|
};
|
498
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
499
|
-
const historyService = getService(strapi2, "history");
|
500
570
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
501
571
|
return {
|
502
572
|
async bootstrap() {
|
@@ -504,65 +574,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
504
574
|
return;
|
505
575
|
}
|
506
576
|
strapi2.documents.use(async (context, next) => {
|
507
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
508
|
-
return next();
|
509
|
-
}
|
510
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
511
|
-
return next();
|
512
|
-
}
|
513
|
-
const contentTypeUid = context.contentType.uid;
|
514
|
-
if (!contentTypeUid.startsWith("api::")) {
|
515
|
-
return next();
|
516
|
-
}
|
517
577
|
const result = await next();
|
518
|
-
|
578
|
+
if (!shouldCreateHistoryVersion(context)) {
|
579
|
+
return result;
|
580
|
+
}
|
581
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
519
582
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
520
|
-
const
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
583
|
+
const locales = fp.castArray(context.params?.locale || defaultLocale);
|
584
|
+
if (!locales.length) {
|
585
|
+
return result;
|
586
|
+
}
|
587
|
+
const uid2 = context.contentType.uid;
|
588
|
+
const schemas = getSchemas(uid2);
|
589
|
+
const model = strapi2.getModel(uid2);
|
590
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
591
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
592
|
+
where: {
|
593
|
+
documentId,
|
594
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
595
|
+
...strapiUtils.contentTypes.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
596
|
+
},
|
597
|
+
populate: serviceUtils.getDeepPopulate(
|
598
|
+
uid2,
|
599
|
+
true
|
600
|
+
/* use database syntax */
|
601
|
+
)
|
525
602
|
});
|
526
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
527
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
528
|
-
const componentsSchemas = Object.keys(
|
529
|
-
attributesSchema
|
530
|
-
).reduce((currentComponentSchemas, key) => {
|
531
|
-
const fieldSchema = attributesSchema[key];
|
532
|
-
if (fieldSchema.type === "component") {
|
533
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
534
|
-
return {
|
535
|
-
...currentComponentSchemas,
|
536
|
-
[fieldSchema.component]: componentSchema
|
537
|
-
};
|
538
|
-
}
|
539
|
-
return currentComponentSchemas;
|
540
|
-
}, {});
|
541
603
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
542
|
-
onCommit(() => {
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
604
|
+
onCommit(async () => {
|
605
|
+
for (const entry of localeEntries) {
|
606
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
607
|
+
await getService$1(strapi2, "history").createVersion({
|
608
|
+
contentType: uid2,
|
609
|
+
data: fp.omit(FIELDS_TO_IGNORE, entry),
|
610
|
+
relatedDocumentId: documentId,
|
611
|
+
locale: entry.locale,
|
612
|
+
status,
|
613
|
+
...schemas
|
614
|
+
});
|
615
|
+
}
|
552
616
|
});
|
553
617
|
});
|
554
618
|
return result;
|
555
619
|
});
|
556
|
-
|
557
|
-
|
558
|
-
const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
|
620
|
+
state.deleteExpiredJob = nodeSchedule.scheduleJob("historyDaily", "0 0 * * *", () => {
|
621
|
+
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
559
622
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
560
|
-
query.deleteMany({
|
623
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
561
624
|
where: {
|
562
625
|
created_at: {
|
563
|
-
$lt: expirationDate
|
626
|
+
$lt: expirationDate
|
564
627
|
}
|
565
628
|
}
|
629
|
+
}).catch((error) => {
|
630
|
+
if (error instanceof Error) {
|
631
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
632
|
+
}
|
566
633
|
});
|
567
634
|
});
|
568
635
|
state.isInitialized = true;
|
@@ -574,17 +641,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
574
641
|
}
|
575
642
|
};
|
576
643
|
};
|
577
|
-
const services$
|
644
|
+
const services$2 = {
|
578
645
|
history: createHistoryService,
|
579
646
|
lifecycles: createLifecyclesService
|
580
647
|
};
|
581
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
648
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
582
649
|
const historyVersionRouter = {
|
583
650
|
type: "admin",
|
584
651
|
routes: [
|
585
652
|
{
|
586
653
|
method: "GET",
|
587
|
-
info,
|
654
|
+
info: info$1,
|
588
655
|
path: "/history-versions",
|
589
656
|
handler: "history-version.findMany",
|
590
657
|
config: {
|
@@ -593,7 +660,7 @@ const historyVersionRouter = {
|
|
593
660
|
},
|
594
661
|
{
|
595
662
|
method: "PUT",
|
596
|
-
info,
|
663
|
+
info: info$1,
|
597
664
|
path: "/history-versions/:versionId/restore",
|
598
665
|
handler: "history-version.restoreVersion",
|
599
666
|
config: {
|
@@ -602,7 +669,7 @@ const historyVersionRouter = {
|
|
602
669
|
}
|
603
670
|
]
|
604
671
|
};
|
605
|
-
const routes$
|
672
|
+
const routes$2 = {
|
606
673
|
"history-version": historyVersionRouter
|
607
674
|
};
|
608
675
|
const historyVersion = {
|
@@ -649,21 +716,21 @@ const historyVersion = {
|
|
649
716
|
}
|
650
717
|
}
|
651
718
|
};
|
652
|
-
const getFeature = () => {
|
719
|
+
const getFeature$1 = () => {
|
653
720
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
654
721
|
return {
|
655
722
|
register({ strapi: strapi2 }) {
|
656
723
|
strapi2.get("models").add(historyVersion);
|
657
724
|
},
|
658
725
|
bootstrap({ strapi: strapi2 }) {
|
659
|
-
getService(strapi2, "lifecycles").bootstrap();
|
726
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
660
727
|
},
|
661
728
|
destroy({ strapi: strapi2 }) {
|
662
|
-
getService(strapi2, "lifecycles").destroy();
|
729
|
+
getService$1(strapi2, "lifecycles").destroy();
|
663
730
|
},
|
664
|
-
controllers: controllers$
|
665
|
-
services: services$
|
666
|
-
routes: routes$
|
731
|
+
controllers: controllers$2,
|
732
|
+
services: services$2,
|
733
|
+
routes: routes$2
|
667
734
|
};
|
668
735
|
}
|
669
736
|
return {
|
@@ -672,9 +739,205 @@ const getFeature = () => {
|
|
672
739
|
}
|
673
740
|
};
|
674
741
|
};
|
675
|
-
const history = getFeature();
|
742
|
+
const history = getFeature$1();
|
743
|
+
const FEATURE_ID = "preview";
|
744
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
745
|
+
const previewRouter = {
|
746
|
+
type: "admin",
|
747
|
+
routes: [
|
748
|
+
{
|
749
|
+
method: "GET",
|
750
|
+
info,
|
751
|
+
path: "/preview/url/:contentType",
|
752
|
+
handler: "preview.getPreviewUrl",
|
753
|
+
config: {
|
754
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
755
|
+
}
|
756
|
+
}
|
757
|
+
]
|
758
|
+
};
|
759
|
+
const routes$1 = {
|
760
|
+
preview: previewRouter
|
761
|
+
};
|
762
|
+
function getService(strapi2, name) {
|
763
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
764
|
+
}
|
765
|
+
const getPreviewUrlSchema = yup__namespace.object().shape({
|
766
|
+
// Will be undefined for single types
|
767
|
+
documentId: yup__namespace.string(),
|
768
|
+
locale: yup__namespace.string().nullable(),
|
769
|
+
status: yup__namespace.string()
|
770
|
+
}).required();
|
771
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
772
|
+
await strapiUtils.validateYupSchema(getPreviewUrlSchema)(params);
|
773
|
+
const newParams = fp.pick(["documentId", "locale", "status"], params);
|
774
|
+
const model = strapi2.getModel(uid2);
|
775
|
+
if (!model || model.modelType !== "contentType") {
|
776
|
+
throw new strapiUtils.errors.ValidationError("Invalid content type");
|
777
|
+
}
|
778
|
+
const isSingleType = model?.kind === "singleType";
|
779
|
+
if (!isSingleType && !params.documentId) {
|
780
|
+
throw new strapiUtils.errors.ValidationError("documentId is required for Collection Types");
|
781
|
+
}
|
782
|
+
if (isSingleType) {
|
783
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
784
|
+
if (!doc) {
|
785
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
786
|
+
}
|
787
|
+
newParams.documentId = doc?.documentId;
|
788
|
+
}
|
789
|
+
if (!newParams.status) {
|
790
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
791
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
792
|
+
}
|
793
|
+
return newParams;
|
794
|
+
};
|
795
|
+
const createPreviewController = () => {
|
796
|
+
return {
|
797
|
+
/**
|
798
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
799
|
+
* in the Content Manager.
|
800
|
+
*/
|
801
|
+
async getPreviewUrl(ctx) {
|
802
|
+
const uid2 = ctx.params.contentType;
|
803
|
+
const query = ctx.request.query;
|
804
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
805
|
+
const previewService = getService(strapi, "preview");
|
806
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
807
|
+
if (!url) {
|
808
|
+
ctx.status = 204;
|
809
|
+
}
|
810
|
+
return {
|
811
|
+
data: { url }
|
812
|
+
};
|
813
|
+
}
|
814
|
+
};
|
815
|
+
};
|
816
|
+
const controllers$1 = {
|
817
|
+
preview: createPreviewController
|
818
|
+
/**
|
819
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
820
|
+
* passing a controller factory as the value, instead of a controller object directly
|
821
|
+
*/
|
822
|
+
};
|
823
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
824
|
+
const config = getService(strapi2, "preview-config");
|
825
|
+
return {
|
826
|
+
async getPreviewUrl(uid2, params) {
|
827
|
+
const handler = config.getPreviewHandler();
|
828
|
+
try {
|
829
|
+
return handler(uid2, params);
|
830
|
+
} catch (error) {
|
831
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
832
|
+
throw new strapiUtils.errors.ApplicationError("Failed to get preview URL");
|
833
|
+
}
|
834
|
+
return;
|
835
|
+
}
|
836
|
+
};
|
837
|
+
};
|
838
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
839
|
+
const middlewares = strapi.config.get("middlewares");
|
840
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
841
|
+
if (currentMiddleware === middleware.name) {
|
842
|
+
return middleware;
|
843
|
+
}
|
844
|
+
if (currentMiddleware.name === middleware.name) {
|
845
|
+
return fp.mergeWith(
|
846
|
+
(objValue, srcValue) => {
|
847
|
+
if (Array.isArray(objValue)) {
|
848
|
+
return objValue.concat(srcValue);
|
849
|
+
}
|
850
|
+
return void 0;
|
851
|
+
},
|
852
|
+
currentMiddleware,
|
853
|
+
middleware
|
854
|
+
);
|
855
|
+
}
|
856
|
+
return currentMiddleware;
|
857
|
+
});
|
858
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
859
|
+
};
|
860
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
861
|
+
return {
|
862
|
+
register() {
|
863
|
+
if (!this.isEnabled()) {
|
864
|
+
return;
|
865
|
+
}
|
866
|
+
const config = strapi2.config.get("admin.preview");
|
867
|
+
if (config.config?.allowedOrigins) {
|
868
|
+
extendMiddlewareConfiguration({
|
869
|
+
name: "strapi::security",
|
870
|
+
config: {
|
871
|
+
contentSecurityPolicy: {
|
872
|
+
directives: {
|
873
|
+
"frame-src": config.config.allowedOrigins
|
874
|
+
}
|
875
|
+
}
|
876
|
+
}
|
877
|
+
});
|
878
|
+
}
|
879
|
+
},
|
880
|
+
isEnabled() {
|
881
|
+
const config = strapi2.config.get("admin.preview");
|
882
|
+
if (!config) {
|
883
|
+
return false;
|
884
|
+
}
|
885
|
+
return config?.enabled ?? true;
|
886
|
+
},
|
887
|
+
/**
|
888
|
+
* Validate if the configuration is valid
|
889
|
+
*/
|
890
|
+
validate() {
|
891
|
+
if (!this.isEnabled()) {
|
892
|
+
return;
|
893
|
+
}
|
894
|
+
const handler = this.getPreviewHandler();
|
895
|
+
if (typeof handler !== "function") {
|
896
|
+
throw new strapiUtils.errors.ValidationError(
|
897
|
+
"Preview configuration is invalid. Handler must be a function"
|
898
|
+
);
|
899
|
+
}
|
900
|
+
},
|
901
|
+
/**
|
902
|
+
* Utility to get the preview handler from the configuration
|
903
|
+
*/
|
904
|
+
getPreviewHandler() {
|
905
|
+
const config = strapi2.config.get("admin.preview");
|
906
|
+
const emptyHandler = () => {
|
907
|
+
return void 0;
|
908
|
+
};
|
909
|
+
if (!this.isEnabled()) {
|
910
|
+
return emptyHandler;
|
911
|
+
}
|
912
|
+
return config?.config?.handler || emptyHandler;
|
913
|
+
}
|
914
|
+
};
|
915
|
+
};
|
916
|
+
const services$1 = {
|
917
|
+
preview: createPreviewService,
|
918
|
+
"preview-config": createPreviewConfigService
|
919
|
+
};
|
920
|
+
const getFeature = () => {
|
921
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
922
|
+
return {};
|
923
|
+
}
|
924
|
+
return {
|
925
|
+
register() {
|
926
|
+
const config = getService(strapi, "preview-config");
|
927
|
+
config.validate();
|
928
|
+
config.register();
|
929
|
+
},
|
930
|
+
bootstrap() {
|
931
|
+
},
|
932
|
+
routes: routes$1,
|
933
|
+
controllers: controllers$1,
|
934
|
+
services: services$1
|
935
|
+
};
|
936
|
+
};
|
937
|
+
const preview = getFeature();
|
676
938
|
const register = async ({ strapi: strapi2 }) => {
|
677
939
|
await history.register?.({ strapi: strapi2 });
|
940
|
+
await preview.register?.({ strapi: strapi2 });
|
678
941
|
};
|
679
942
|
const ALLOWED_WEBHOOK_EVENTS = {
|
680
943
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -684,11 +947,12 @@ const bootstrap = async () => {
|
|
684
947
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
685
948
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
686
949
|
});
|
687
|
-
getService$
|
688
|
-
await getService$
|
689
|
-
await getService$
|
690
|
-
await getService$
|
950
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
951
|
+
await getService$2("components").syncConfigurations();
|
952
|
+
await getService$2("content-types").syncConfigurations();
|
953
|
+
await getService$2("permission").registerPermissions();
|
691
954
|
await history.bootstrap?.({ strapi });
|
955
|
+
await preview.bootstrap?.({ strapi });
|
692
956
|
};
|
693
957
|
const destroy = async ({ strapi: strapi2 }) => {
|
694
958
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1178,7 +1442,8 @@ const admin = {
|
|
1178
1442
|
};
|
1179
1443
|
const routes = {
|
1180
1444
|
admin,
|
1181
|
-
...history.routes ? history.routes : {}
|
1445
|
+
...history.routes ? history.routes : {},
|
1446
|
+
...preview.routes ? preview.routes : {}
|
1182
1447
|
};
|
1183
1448
|
const hasPermissionsSchema = strapiUtils.yup.object({
|
1184
1449
|
actions: strapiUtils.yup.array().of(strapiUtils.yup.string()),
|
@@ -1189,6 +1454,11 @@ const { createPolicy } = strapiUtils.policy;
|
|
1189
1454
|
const hasPermissions = createPolicy({
|
1190
1455
|
name: "plugin::content-manager.hasPermissions",
|
1191
1456
|
validator: validateHasPermissionsInput,
|
1457
|
+
/**
|
1458
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1459
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1460
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1461
|
+
*/
|
1192
1462
|
handler(ctx, config = {}) {
|
1193
1463
|
const { actions = [], hasAtLeastOne = false } = config;
|
1194
1464
|
const { userAbility } = ctx.state;
|
@@ -1430,7 +1700,7 @@ const createMetadasSchema = (schema) => {
|
|
1430
1700
|
if (!value) {
|
1431
1701
|
return strapiUtils.yup.string();
|
1432
1702
|
}
|
1433
|
-
const targetSchema = getService$
|
1703
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1434
1704
|
schema.attributes[key].targetModel
|
1435
1705
|
);
|
1436
1706
|
if (!targetSchema) {
|
@@ -1478,7 +1748,7 @@ const { PaginationError, ValidationError } = strapiUtils.errors;
|
|
1478
1748
|
const TYPES = ["singleType", "collectionType"];
|
1479
1749
|
const kindSchema = strapiUtils.yup.string().oneOf(TYPES).nullable();
|
1480
1750
|
const bulkActionInputSchema = strapiUtils.yup.object({
|
1481
|
-
|
1751
|
+
documentIds: strapiUtils.yup.array().of(strapiUtils.yup.strapiID()).min(1).required()
|
1482
1752
|
}).required();
|
1483
1753
|
const generateUIDInputSchema = strapiUtils.yup.object({
|
1484
1754
|
contentTypeUID: strapiUtils.yup.string().required(),
|
@@ -1577,22 +1847,56 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1577
1847
|
}
|
1578
1848
|
}, body);
|
1579
1849
|
};
|
1580
|
-
const
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1850
|
+
const singleLocaleSchema = strapiUtils.yup.string().nullable();
|
1851
|
+
const multipleLocaleSchema = strapiUtils.yup.lazy(
|
1852
|
+
(value) => Array.isArray(value) ? strapiUtils.yup.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1853
|
+
);
|
1854
|
+
const statusSchema = strapiUtils.yup.mixed().oneOf(["draft", "published"], "Invalid status");
|
1855
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1856
|
+
const { allowMultipleLocales } = opts;
|
1857
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1858
|
+
const defaultStatus = strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1859
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1860
|
+
const schema = strapiUtils.yup.object().shape({
|
1861
|
+
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1862
|
+
status: statusSchema
|
1863
|
+
});
|
1864
|
+
try {
|
1865
|
+
await strapiUtils.validateYupSchema(schema, { strict: true, abortEarly: false })(request);
|
1866
|
+
return { locale, status, ...rest };
|
1867
|
+
} catch (error) {
|
1868
|
+
throw new strapiUtils.errors.ValidationError(`Validation error: ${error.message}`);
|
1587
1869
|
}
|
1588
|
-
|
1870
|
+
};
|
1871
|
+
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1872
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1873
|
+
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1874
|
+
let {
|
1875
|
+
meta: { availableLocales, availableStatus }
|
1876
|
+
} = serviceOutput;
|
1877
|
+
const metadataSanitizer = permissionChecker2.sanitizeOutput;
|
1878
|
+
availableLocales = await strapiUtils.async.map(
|
1879
|
+
availableLocales,
|
1880
|
+
async (localeDocument) => metadataSanitizer(localeDocument)
|
1881
|
+
);
|
1882
|
+
availableStatus = await strapiUtils.async.map(
|
1883
|
+
availableStatus,
|
1884
|
+
async (statusDocument) => metadataSanitizer(statusDocument)
|
1885
|
+
);
|
1886
|
+
return {
|
1887
|
+
...serviceOutput,
|
1888
|
+
meta: {
|
1889
|
+
availableLocales,
|
1890
|
+
availableStatus
|
1891
|
+
}
|
1892
|
+
};
|
1589
1893
|
};
|
1590
1894
|
const createDocument = async (ctx, opts) => {
|
1591
1895
|
const { userAbility, user } = ctx.state;
|
1592
1896
|
const { model } = ctx.params;
|
1593
1897
|
const { body } = ctx.request;
|
1594
|
-
const documentManager2 = getService$
|
1595
|
-
const permissionChecker2 = getService$
|
1898
|
+
const documentManager2 = getService$2("document-manager");
|
1899
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1596
1900
|
if (permissionChecker2.cannot.create()) {
|
1597
1901
|
throw new strapiUtils.errors.ForbiddenError();
|
1598
1902
|
}
|
@@ -1600,7 +1904,7 @@ const createDocument = async (ctx, opts) => {
|
|
1600
1904
|
const setCreator = strapiUtils.setCreatorFields({ user });
|
1601
1905
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1602
1906
|
const sanitizedBody = await sanitizeFn(body);
|
1603
|
-
const { locale, status
|
1907
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1604
1908
|
return documentManager2.create(model, {
|
1605
1909
|
data: sanitizedBody,
|
1606
1910
|
locale,
|
@@ -1612,14 +1916,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1612
1916
|
const { userAbility, user } = ctx.state;
|
1613
1917
|
const { id, model } = ctx.params;
|
1614
1918
|
const { body } = ctx.request;
|
1615
|
-
const documentManager2 = getService$
|
1616
|
-
const permissionChecker2 = getService$
|
1919
|
+
const documentManager2 = getService$2("document-manager");
|
1920
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1617
1921
|
if (permissionChecker2.cannot.update()) {
|
1618
1922
|
throw new strapiUtils.errors.ForbiddenError();
|
1619
1923
|
}
|
1620
1924
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1621
|
-
const populate = await getService$
|
1622
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1925
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1926
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1623
1927
|
const [documentVersion, documentExists] = await Promise.all([
|
1624
1928
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1625
1929
|
documentManager2.exists(model, id)
|
@@ -1635,7 +1939,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1635
1939
|
throw new strapiUtils.errors.ForbiddenError();
|
1636
1940
|
}
|
1637
1941
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1638
|
-
const setCreator = strapiUtils.setCreatorFields({ user, isEdition: true });
|
1942
|
+
const setCreator = documentVersion ? strapiUtils.setCreatorFields({ user, isEdition: true }) : strapiUtils.setCreatorFields({ user });
|
1639
1943
|
const sanitizeFn = strapiUtils.async.pipe(pickPermittedFields, setCreator);
|
1640
1944
|
const sanitizedBody = await sanitizeFn(body);
|
1641
1945
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1649,15 +1953,15 @@ const collectionTypes = {
|
|
1649
1953
|
const { userAbility } = ctx.state;
|
1650
1954
|
const { model } = ctx.params;
|
1651
1955
|
const { query } = ctx.request;
|
1652
|
-
const documentMetadata2 = getService$
|
1653
|
-
const documentManager2 = getService$
|
1654
|
-
const permissionChecker2 = getService$
|
1956
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1957
|
+
const documentManager2 = getService$2("document-manager");
|
1958
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1655
1959
|
if (permissionChecker2.cannot.read()) {
|
1656
1960
|
return ctx.forbidden();
|
1657
1961
|
}
|
1658
1962
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1659
|
-
const populate = await getService$
|
1660
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1963
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1964
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1661
1965
|
const { results: documents, pagination } = await documentManager2.findPage(
|
1662
1966
|
{ ...permissionQuery, populate, locale, status },
|
1663
1967
|
model
|
@@ -1685,15 +1989,14 @@ const collectionTypes = {
|
|
1685
1989
|
async findOne(ctx) {
|
1686
1990
|
const { userAbility } = ctx.state;
|
1687
1991
|
const { model, id } = ctx.params;
|
1688
|
-
const documentManager2 = getService$
|
1689
|
-
const
|
1690
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1992
|
+
const documentManager2 = getService$2("document-manager");
|
1993
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1691
1994
|
if (permissionChecker2.cannot.read()) {
|
1692
1995
|
return ctx.forbidden();
|
1693
1996
|
}
|
1694
1997
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1695
|
-
const populate = await getService$
|
1696
|
-
const { locale, status
|
1998
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1999
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1697
2000
|
const version = await documentManager2.findOne(id, model, {
|
1698
2001
|
populate,
|
1699
2002
|
locale,
|
@@ -1704,9 +2007,11 @@ const collectionTypes = {
|
|
1704
2007
|
if (!exists) {
|
1705
2008
|
return ctx.notFound();
|
1706
2009
|
}
|
1707
|
-
const { meta } = await
|
2010
|
+
const { meta } = await formatDocumentWithMetadata(
|
2011
|
+
permissionChecker2,
|
1708
2012
|
model,
|
1709
|
-
|
2013
|
+
// @ts-expect-error TODO: fix
|
2014
|
+
{ documentId: id, locale, publishedAt: null },
|
1710
2015
|
{ availableLocales: true, availableStatus: false }
|
1711
2016
|
);
|
1712
2017
|
ctx.body = { data: {}, meta };
|
@@ -1716,20 +2021,19 @@ const collectionTypes = {
|
|
1716
2021
|
return ctx.forbidden();
|
1717
2022
|
}
|
1718
2023
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1719
|
-
ctx.body = await
|
2024
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1720
2025
|
},
|
1721
2026
|
async create(ctx) {
|
1722
2027
|
const { userAbility } = ctx.state;
|
1723
2028
|
const { model } = ctx.params;
|
1724
|
-
const
|
1725
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2029
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1726
2030
|
const [totalEntries, document] = await Promise.all([
|
1727
2031
|
strapi.db.query(model).count(),
|
1728
2032
|
createDocument(ctx)
|
1729
2033
|
]);
|
1730
2034
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1731
2035
|
ctx.status = 201;
|
1732
|
-
ctx.body = await
|
2036
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1733
2037
|
// Empty metadata as it's not relevant for a new document
|
1734
2038
|
availableLocales: false,
|
1735
2039
|
availableStatus: false
|
@@ -1743,25 +2047,23 @@ const collectionTypes = {
|
|
1743
2047
|
async update(ctx) {
|
1744
2048
|
const { userAbility } = ctx.state;
|
1745
2049
|
const { model } = ctx.params;
|
1746
|
-
const
|
1747
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2050
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1748
2051
|
const updatedVersion = await updateDocument(ctx);
|
1749
2052
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1750
|
-
ctx.body = await
|
2053
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1751
2054
|
},
|
1752
2055
|
async clone(ctx) {
|
1753
2056
|
const { userAbility, user } = ctx.state;
|
1754
2057
|
const { model, sourceId: id } = ctx.params;
|
1755
2058
|
const { body } = ctx.request;
|
1756
|
-
const documentManager2 = getService$
|
1757
|
-
const
|
1758
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2059
|
+
const documentManager2 = getService$2("document-manager");
|
2060
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1759
2061
|
if (permissionChecker2.cannot.create()) {
|
1760
2062
|
return ctx.forbidden();
|
1761
2063
|
}
|
1762
2064
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1763
|
-
const populate = await getService$
|
1764
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2065
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2066
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1765
2067
|
const document = await documentManager2.findOne(id, model, {
|
1766
2068
|
populate,
|
1767
2069
|
locale,
|
@@ -1777,7 +2079,7 @@ const collectionTypes = {
|
|
1777
2079
|
const sanitizedBody = await sanitizeFn(body);
|
1778
2080
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1779
2081
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1780
|
-
ctx.body = await
|
2082
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1781
2083
|
// Empty metadata as it's not relevant for a new document
|
1782
2084
|
availableLocales: false,
|
1783
2085
|
availableStatus: false
|
@@ -1799,14 +2101,14 @@ const collectionTypes = {
|
|
1799
2101
|
async delete(ctx) {
|
1800
2102
|
const { userAbility } = ctx.state;
|
1801
2103
|
const { id, model } = ctx.params;
|
1802
|
-
const documentManager2 = getService$
|
1803
|
-
const permissionChecker2 = getService$
|
2104
|
+
const documentManager2 = getService$2("document-manager");
|
2105
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1804
2106
|
if (permissionChecker2.cannot.delete()) {
|
1805
2107
|
return ctx.forbidden();
|
1806
2108
|
}
|
1807
2109
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1808
|
-
const populate = await getService$
|
1809
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
2110
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2111
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1810
2112
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1811
2113
|
if (documentLocales.length === 0) {
|
1812
2114
|
return ctx.notFound();
|
@@ -1827,44 +2129,75 @@ const collectionTypes = {
|
|
1827
2129
|
const { userAbility } = ctx.state;
|
1828
2130
|
const { id, model } = ctx.params;
|
1829
2131
|
const { body } = ctx.request;
|
1830
|
-
const documentManager2 = getService$
|
1831
|
-
const
|
1832
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2132
|
+
const documentManager2 = getService$2("document-manager");
|
2133
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1833
2134
|
if (permissionChecker2.cannot.publish()) {
|
1834
2135
|
return ctx.forbidden();
|
1835
2136
|
}
|
1836
2137
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1837
2138
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1838
|
-
const populate = await getService$
|
1839
|
-
|
2139
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2140
|
+
let document;
|
2141
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2142
|
+
const isCreate = fp.isNil(id);
|
2143
|
+
if (isCreate) {
|
2144
|
+
if (permissionChecker2.cannot.create()) {
|
2145
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2146
|
+
}
|
2147
|
+
document = await createDocument(ctx, { populate });
|
2148
|
+
}
|
2149
|
+
const isUpdate = !isCreate;
|
2150
|
+
if (isUpdate) {
|
2151
|
+
const documentExists = documentManager2.exists(model, id);
|
2152
|
+
if (!documentExists) {
|
2153
|
+
throw new strapiUtils.errors.NotFoundError("Document not found");
|
2154
|
+
}
|
2155
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2156
|
+
if (!document) {
|
2157
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2158
|
+
throw new strapiUtils.errors.ForbiddenError();
|
2159
|
+
}
|
2160
|
+
document = await updateDocument(ctx);
|
2161
|
+
} else if (permissionChecker2.can.update(document)) {
|
2162
|
+
await updateDocument(ctx);
|
2163
|
+
}
|
2164
|
+
}
|
1840
2165
|
if (permissionChecker2.cannot.publish(document)) {
|
1841
2166
|
throw new strapiUtils.errors.ForbiddenError();
|
1842
2167
|
}
|
1843
|
-
const
|
1844
|
-
return documentManager2.publish(document.documentId, model, {
|
2168
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1845
2169
|
locale
|
1846
2170
|
// TODO: Allow setting creator fields on publish
|
1847
2171
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1848
2172
|
});
|
2173
|
+
if (!publishResult || publishResult.length === 0) {
|
2174
|
+
throw new strapiUtils.errors.NotFoundError("Document not found or already published.");
|
2175
|
+
}
|
2176
|
+
return publishResult[0];
|
1849
2177
|
});
|
1850
2178
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1851
|
-
ctx.body = await
|
2179
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1852
2180
|
},
|
1853
2181
|
async bulkPublish(ctx) {
|
1854
2182
|
const { userAbility } = ctx.state;
|
1855
2183
|
const { model } = ctx.params;
|
1856
2184
|
const { body } = ctx.request;
|
1857
|
-
const {
|
2185
|
+
const { documentIds } = body;
|
1858
2186
|
await validateBulkActionInput(body);
|
1859
|
-
const documentManager2 = getService$
|
1860
|
-
const permissionChecker2 = getService$
|
2187
|
+
const documentManager2 = getService$2("document-manager");
|
2188
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1861
2189
|
if (permissionChecker2.cannot.publish()) {
|
1862
2190
|
return ctx.forbidden();
|
1863
2191
|
}
|
1864
2192
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1865
|
-
const populate = await getService$
|
1866
|
-
const
|
1867
|
-
|
2193
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2194
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2195
|
+
allowMultipleLocales: true
|
2196
|
+
});
|
2197
|
+
const entityPromises = documentIds.map(
|
2198
|
+
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
2199
|
+
);
|
2200
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1868
2201
|
for (const entity of entities) {
|
1869
2202
|
if (!entity) {
|
1870
2203
|
return ctx.notFound();
|
@@ -1873,24 +2206,27 @@ const collectionTypes = {
|
|
1873
2206
|
return ctx.forbidden();
|
1874
2207
|
}
|
1875
2208
|
}
|
1876
|
-
const
|
2209
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1877
2210
|
ctx.body = { count };
|
1878
2211
|
},
|
1879
2212
|
async bulkUnpublish(ctx) {
|
1880
2213
|
const { userAbility } = ctx.state;
|
1881
2214
|
const { model } = ctx.params;
|
1882
2215
|
const { body } = ctx.request;
|
1883
|
-
const {
|
2216
|
+
const { documentIds } = body;
|
1884
2217
|
await validateBulkActionInput(body);
|
1885
|
-
const documentManager2 = getService$
|
1886
|
-
const permissionChecker2 = getService$
|
2218
|
+
const documentManager2 = getService$2("document-manager");
|
2219
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1887
2220
|
if (permissionChecker2.cannot.unpublish()) {
|
1888
2221
|
return ctx.forbidden();
|
1889
2222
|
}
|
1890
|
-
const
|
1891
|
-
|
1892
|
-
|
1893
|
-
const
|
2223
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2224
|
+
allowMultipleLocales: true
|
2225
|
+
});
|
2226
|
+
const entityPromises = documentIds.map(
|
2227
|
+
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
2228
|
+
);
|
2229
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1894
2230
|
for (const entity of entities) {
|
1895
2231
|
if (!entity) {
|
1896
2232
|
return ctx.notFound();
|
@@ -1899,7 +2235,8 @@ const collectionTypes = {
|
|
1899
2235
|
return ctx.forbidden();
|
1900
2236
|
}
|
1901
2237
|
}
|
1902
|
-
const
|
2238
|
+
const entitiesIds = entities.map((document) => document.documentId);
|
2239
|
+
const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
|
1903
2240
|
ctx.body = { count };
|
1904
2241
|
},
|
1905
2242
|
async unpublish(ctx) {
|
@@ -1908,9 +2245,8 @@ const collectionTypes = {
|
|
1908
2245
|
const {
|
1909
2246
|
body: { discardDraft, ...body }
|
1910
2247
|
} = ctx.request;
|
1911
|
-
const documentManager2 = getService$
|
1912
|
-
const
|
1913
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2248
|
+
const documentManager2 = getService$2("document-manager");
|
2249
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1914
2250
|
if (permissionChecker2.cannot.unpublish()) {
|
1915
2251
|
return ctx.forbidden();
|
1916
2252
|
}
|
@@ -1918,8 +2254,8 @@ const collectionTypes = {
|
|
1918
2254
|
return ctx.forbidden();
|
1919
2255
|
}
|
1920
2256
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1921
|
-
const populate = await getService$
|
1922
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2257
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2258
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1923
2259
|
const document = await documentManager2.findOne(id, model, {
|
1924
2260
|
populate,
|
1925
2261
|
locale,
|
@@ -1941,7 +2277,7 @@ const collectionTypes = {
|
|
1941
2277
|
ctx.body = await strapiUtils.async.pipe(
|
1942
2278
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1943
2279
|
permissionChecker2.sanitizeOutput,
|
1944
|
-
(document2) =>
|
2280
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1945
2281
|
)(document);
|
1946
2282
|
});
|
1947
2283
|
},
|
@@ -1949,15 +2285,14 @@ const collectionTypes = {
|
|
1949
2285
|
const { userAbility } = ctx.state;
|
1950
2286
|
const { id, model } = ctx.params;
|
1951
2287
|
const { body } = ctx.request;
|
1952
|
-
const documentManager2 = getService$
|
1953
|
-
const
|
1954
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2288
|
+
const documentManager2 = getService$2("document-manager");
|
2289
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1955
2290
|
if (permissionChecker2.cannot.discard()) {
|
1956
2291
|
return ctx.forbidden();
|
1957
2292
|
}
|
1958
2293
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1959
|
-
const populate = await getService$
|
1960
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2294
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2295
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1961
2296
|
const document = await documentManager2.findOne(id, model, {
|
1962
2297
|
populate,
|
1963
2298
|
locale,
|
@@ -1972,42 +2307,50 @@ const collectionTypes = {
|
|
1972
2307
|
ctx.body = await strapiUtils.async.pipe(
|
1973
2308
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1974
2309
|
permissionChecker2.sanitizeOutput,
|
1975
|
-
(document2) =>
|
2310
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1976
2311
|
)(document);
|
1977
2312
|
},
|
1978
2313
|
async bulkDelete(ctx) {
|
1979
2314
|
const { userAbility } = ctx.state;
|
1980
2315
|
const { model } = ctx.params;
|
1981
2316
|
const { query, body } = ctx.request;
|
1982
|
-
const {
|
2317
|
+
const { documentIds } = body;
|
1983
2318
|
await validateBulkActionInput(body);
|
1984
|
-
const documentManager2 = getService$
|
1985
|
-
const permissionChecker2 = getService$
|
2319
|
+
const documentManager2 = getService$2("document-manager");
|
2320
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1986
2321
|
if (permissionChecker2.cannot.delete()) {
|
1987
2322
|
return ctx.forbidden();
|
1988
2323
|
}
|
1989
2324
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1990
|
-
const
|
1991
|
-
const
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
2325
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2326
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2327
|
+
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2328
|
+
populate,
|
2329
|
+
locale
|
2330
|
+
});
|
2331
|
+
if (documentLocales.length === 0) {
|
2332
|
+
return ctx.notFound();
|
2333
|
+
}
|
2334
|
+
for (const document of documentLocales) {
|
2335
|
+
if (permissionChecker2.cannot.delete(document)) {
|
2336
|
+
return ctx.forbidden();
|
1995
2337
|
}
|
1996
|
-
}
|
1997
|
-
const
|
2338
|
+
}
|
2339
|
+
const localeDocumentsIds = documentLocales.map((document) => document.documentId);
|
2340
|
+
const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
|
1998
2341
|
ctx.body = { count };
|
1999
2342
|
},
|
2000
2343
|
async countDraftRelations(ctx) {
|
2001
2344
|
const { userAbility } = ctx.state;
|
2002
2345
|
const { model, id } = ctx.params;
|
2003
|
-
const documentManager2 = getService$
|
2004
|
-
const permissionChecker2 = getService$
|
2346
|
+
const documentManager2 = getService$2("document-manager");
|
2347
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2005
2348
|
if (permissionChecker2.cannot.read()) {
|
2006
2349
|
return ctx.forbidden();
|
2007
2350
|
}
|
2008
2351
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2009
|
-
const populate = await getService$
|
2010
|
-
const { locale, status
|
2352
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2353
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
2011
2354
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
2012
2355
|
if (!entity) {
|
2013
2356
|
return ctx.notFound();
|
@@ -2022,24 +2365,24 @@ const collectionTypes = {
|
|
2022
2365
|
},
|
2023
2366
|
async countManyEntriesDraftRelations(ctx) {
|
2024
2367
|
const { userAbility } = ctx.state;
|
2025
|
-
const ids = ctx.request.query.
|
2368
|
+
const ids = ctx.request.query.documentIds;
|
2026
2369
|
const locale = ctx.request.query.locale;
|
2027
2370
|
const { model } = ctx.params;
|
2028
|
-
const documentManager2 = getService$
|
2029
|
-
const permissionChecker2 = getService$
|
2371
|
+
const documentManager2 = getService$2("document-manager");
|
2372
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2030
2373
|
if (permissionChecker2.cannot.read()) {
|
2031
2374
|
return ctx.forbidden();
|
2032
2375
|
}
|
2033
|
-
const
|
2376
|
+
const documents = await documentManager2.findMany(
|
2034
2377
|
{
|
2035
2378
|
filters: {
|
2036
|
-
|
2379
|
+
documentId: ids
|
2037
2380
|
},
|
2038
2381
|
locale
|
2039
2382
|
},
|
2040
2383
|
model
|
2041
2384
|
);
|
2042
|
-
if (!
|
2385
|
+
if (!documents) {
|
2043
2386
|
return ctx.notFound();
|
2044
2387
|
}
|
2045
2388
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2050,13 +2393,13 @@ const collectionTypes = {
|
|
2050
2393
|
};
|
2051
2394
|
const components$1 = {
|
2052
2395
|
findComponents(ctx) {
|
2053
|
-
const components2 = getService$
|
2054
|
-
const { toDto } = getService$
|
2396
|
+
const components2 = getService$2("components").findAllComponents();
|
2397
|
+
const { toDto } = getService$2("data-mapper");
|
2055
2398
|
ctx.body = { data: components2.map(toDto) };
|
2056
2399
|
},
|
2057
2400
|
async findComponentConfiguration(ctx) {
|
2058
2401
|
const { uid: uid2 } = ctx.params;
|
2059
|
-
const componentService = getService$
|
2402
|
+
const componentService = getService$2("components");
|
2060
2403
|
const component = componentService.findComponent(uid2);
|
2061
2404
|
if (!component) {
|
2062
2405
|
return ctx.notFound("component.notFound");
|
@@ -2073,7 +2416,7 @@ const components$1 = {
|
|
2073
2416
|
async updateComponentConfiguration(ctx) {
|
2074
2417
|
const { uid: uid2 } = ctx.params;
|
2075
2418
|
const { body } = ctx.request;
|
2076
|
-
const componentService = getService$
|
2419
|
+
const componentService = getService$2("components");
|
2077
2420
|
const component = componentService.findComponent(uid2);
|
2078
2421
|
if (!component) {
|
2079
2422
|
return ctx.notFound("component.notFound");
|
@@ -2107,12 +2450,12 @@ const contentTypes = {
|
|
2107
2450
|
} catch (error) {
|
2108
2451
|
return ctx.send({ error }, 400);
|
2109
2452
|
}
|
2110
|
-
const contentTypes2 = getService$
|
2111
|
-
const { toDto } = getService$
|
2453
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2454
|
+
const { toDto } = getService$2("data-mapper");
|
2112
2455
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2113
2456
|
},
|
2114
2457
|
async findContentTypesSettings(ctx) {
|
2115
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2458
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2116
2459
|
const contentTypes2 = await findAllContentTypes();
|
2117
2460
|
const configurations = await Promise.all(
|
2118
2461
|
contentTypes2.map(async (contentType) => {
|
@@ -2126,7 +2469,7 @@ const contentTypes = {
|
|
2126
2469
|
},
|
2127
2470
|
async findContentTypeConfiguration(ctx) {
|
2128
2471
|
const { uid: uid2 } = ctx.params;
|
2129
|
-
const contentTypeService = getService$
|
2472
|
+
const contentTypeService = getService$2("content-types");
|
2130
2473
|
const contentType = await contentTypeService.findContentType(uid2);
|
2131
2474
|
if (!contentType) {
|
2132
2475
|
return ctx.notFound("contentType.notFound");
|
@@ -2148,13 +2491,13 @@ const contentTypes = {
|
|
2148
2491
|
const { userAbility } = ctx.state;
|
2149
2492
|
const { uid: uid2 } = ctx.params;
|
2150
2493
|
const { body } = ctx.request;
|
2151
|
-
const contentTypeService = getService$
|
2152
|
-
const metricsService = getService$
|
2494
|
+
const contentTypeService = getService$2("content-types");
|
2495
|
+
const metricsService = getService$2("metrics");
|
2153
2496
|
const contentType = await contentTypeService.findContentType(uid2);
|
2154
2497
|
if (!contentType) {
|
2155
2498
|
return ctx.notFound("contentType.notFound");
|
2156
2499
|
}
|
2157
|
-
if (!getService$
|
2500
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2158
2501
|
return ctx.forbidden();
|
2159
2502
|
}
|
2160
2503
|
let input;
|
@@ -2187,10 +2530,10 @@ const contentTypes = {
|
|
2187
2530
|
};
|
2188
2531
|
const init = {
|
2189
2532
|
getInitData(ctx) {
|
2190
|
-
const { toDto } = getService$
|
2191
|
-
const { findAllComponents } = getService$
|
2192
|
-
const { getAllFieldSizes } = getService$
|
2193
|
-
const { findAllContentTypes } = getService$
|
2533
|
+
const { toDto } = getService$2("data-mapper");
|
2534
|
+
const { findAllComponents } = getService$2("components");
|
2535
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2536
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2194
2537
|
ctx.body = {
|
2195
2538
|
data: {
|
2196
2539
|
fieldSizes: getAllFieldSizes(),
|
@@ -2226,36 +2569,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2226
2569
|
params.filters.$and.push(filtersClause);
|
2227
2570
|
};
|
2228
2571
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2229
|
-
const permissionChecker2 = getService$
|
2572
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2230
2573
|
userAbility,
|
2231
2574
|
model: model.uid
|
2232
2575
|
});
|
2233
|
-
|
2576
|
+
const isMainFieldListable = isListable(model, mainField);
|
2577
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2578
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2234
2579
|
return "id";
|
2235
2580
|
}
|
2236
|
-
if (
|
2237
|
-
|
2238
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2239
|
-
userAbility,
|
2240
|
-
model: "plugin::users-permissions.user"
|
2241
|
-
});
|
2242
|
-
if (userPermissionChecker.can.read()) {
|
2243
|
-
return "name";
|
2244
|
-
}
|
2245
|
-
}
|
2246
|
-
return "id";
|
2581
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2582
|
+
return "name";
|
2247
2583
|
}
|
2248
2584
|
return mainField;
|
2249
2585
|
};
|
2250
|
-
const addStatusToRelations = async (
|
2251
|
-
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.
|
2586
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2587
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2252
2588
|
return relations2;
|
2253
2589
|
}
|
2254
|
-
const documentMetadata2 = getService$
|
2255
|
-
|
2590
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2591
|
+
if (!relations2.length) {
|
2592
|
+
return relations2;
|
2593
|
+
}
|
2594
|
+
const firstRelation = relations2[0];
|
2595
|
+
const filters = {
|
2596
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2597
|
+
// NOTE: find the "opposite" status
|
2598
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2599
|
+
};
|
2600
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2601
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2602
|
+
filters
|
2603
|
+
});
|
2256
2604
|
return relations2.map((relation) => {
|
2257
|
-
const availableStatuses =
|
2258
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2605
|
+
const availableStatuses = availableStatus.filter(
|
2606
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2259
2607
|
);
|
2260
2608
|
return {
|
2261
2609
|
...relation,
|
@@ -2276,11 +2624,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2276
2624
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2277
2625
|
const isSourceLocalized = isLocalized(sourceModel);
|
2278
2626
|
const isTargetLocalized = isLocalized(targetModel);
|
2279
|
-
let validatedLocale = locale;
|
2280
|
-
if (!targetModel || !isTargetLocalized)
|
2281
|
-
validatedLocale = void 0;
|
2282
2627
|
return {
|
2283
|
-
locale
|
2628
|
+
locale,
|
2284
2629
|
isSourceLocalized,
|
2285
2630
|
isTargetLocalized
|
2286
2631
|
};
|
@@ -2320,7 +2665,7 @@ const relations = {
|
|
2320
2665
|
ctx.request?.query?.locale
|
2321
2666
|
);
|
2322
2667
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2323
|
-
const permissionChecker2 = getService$
|
2668
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2324
2669
|
userAbility,
|
2325
2670
|
model
|
2326
2671
|
});
|
@@ -2345,7 +2690,7 @@ const relations = {
|
|
2345
2690
|
where.id = id;
|
2346
2691
|
}
|
2347
2692
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2348
|
-
const populate = await getService$
|
2693
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2349
2694
|
const currentEntity = await strapi.db.query(model).findOne({
|
2350
2695
|
where,
|
2351
2696
|
populate
|
@@ -2360,7 +2705,7 @@ const relations = {
|
|
2360
2705
|
}
|
2361
2706
|
entryId = currentEntity.id;
|
2362
2707
|
}
|
2363
|
-
const modelConfig = isComponent2 ? await getService$
|
2708
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2364
2709
|
const targetSchema = strapi.getModel(targetUid);
|
2365
2710
|
const mainField = fp.flow(
|
2366
2711
|
fp.prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2383,7 +2728,7 @@ const relations = {
|
|
2383
2728
|
attribute,
|
2384
2729
|
fieldsToSelect,
|
2385
2730
|
mainField,
|
2386
|
-
source: { schema: sourceSchema },
|
2731
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2387
2732
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2388
2733
|
sourceSchema,
|
2389
2734
|
targetSchema,
|
@@ -2405,7 +2750,8 @@ const relations = {
|
|
2405
2750
|
fieldsToSelect,
|
2406
2751
|
mainField,
|
2407
2752
|
source: {
|
2408
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2753
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2754
|
+
isLocalized: isSourceLocalized
|
2409
2755
|
},
|
2410
2756
|
target: {
|
2411
2757
|
schema: { uid: targetUid },
|
@@ -2413,7 +2759,7 @@ const relations = {
|
|
2413
2759
|
}
|
2414
2760
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2415
2761
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2416
|
-
const permissionChecker2 = getService$
|
2762
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2417
2763
|
userAbility: ctx.state.userAbility,
|
2418
2764
|
model: targetUid
|
2419
2765
|
});
|
@@ -2443,12 +2789,16 @@ const relations = {
|
|
2443
2789
|
} else {
|
2444
2790
|
where.id = id;
|
2445
2791
|
}
|
2446
|
-
|
2447
|
-
|
2792
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2793
|
+
if (!fp.isEmpty(publishedAt)) {
|
2794
|
+
where[`${alias}.published_at`] = publishedAt;
|
2448
2795
|
}
|
2449
|
-
if (
|
2796
|
+
if (isTargetLocalized && locale) {
|
2450
2797
|
where[`${alias}.locale`] = locale;
|
2451
2798
|
}
|
2799
|
+
if (isSourceLocalized && locale) {
|
2800
|
+
where.locale = locale;
|
2801
|
+
}
|
2452
2802
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2453
2803
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2454
2804
|
}
|
@@ -2466,7 +2816,8 @@ const relations = {
|
|
2466
2816
|
id: { $notIn: fp.uniq(idsToOmit) }
|
2467
2817
|
});
|
2468
2818
|
}
|
2469
|
-
const
|
2819
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2820
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2470
2821
|
ctx.body = {
|
2471
2822
|
...res,
|
2472
2823
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2481,29 +2832,39 @@ const relations = {
|
|
2481
2832
|
attribute,
|
2482
2833
|
targetField,
|
2483
2834
|
fieldsToSelect,
|
2484
|
-
|
2485
|
-
|
2486
|
-
}
|
2487
|
-
target: {
|
2488
|
-
schema: { uid: targetUid }
|
2489
|
-
}
|
2835
|
+
status,
|
2836
|
+
source: { schema: sourceSchema },
|
2837
|
+
target: { schema: targetSchema }
|
2490
2838
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2491
|
-
const
|
2839
|
+
const { uid: sourceUid } = sourceSchema;
|
2840
|
+
const { uid: targetUid } = targetSchema;
|
2841
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2492
2842
|
const dbQuery = strapi.db.query(sourceUid);
|
2493
2843
|
const loadRelations = strapiUtils.relations.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2844
|
+
const filters = {};
|
2845
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2846
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2847
|
+
if (status === "published") {
|
2848
|
+
filters.publishedAt = { $notNull: true };
|
2849
|
+
} else {
|
2850
|
+
filters.publishedAt = { $null: true };
|
2851
|
+
}
|
2852
|
+
}
|
2853
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2854
|
+
filters.publishedAt = { $null: true };
|
2855
|
+
}
|
2494
2856
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2495
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2857
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2496
2858
|
ordering: "desc",
|
2497
2859
|
page: ctx.request.query.page,
|
2498
|
-
pageSize: ctx.request.query.pageSize
|
2860
|
+
pageSize: ctx.request.query.pageSize,
|
2861
|
+
filters
|
2499
2862
|
});
|
2500
2863
|
const loadedIds = res.results.map((item) => item.id);
|
2501
2864
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2502
2865
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2503
2866
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2504
|
-
ordering: "desc"
|
2505
|
-
page: ctx.request.query.page,
|
2506
|
-
pageSize: ctx.request.query.pageSize
|
2867
|
+
ordering: "desc"
|
2507
2868
|
});
|
2508
2869
|
const relationsUnion = fp.uniqBy("id", fp.concat(sanitizedRes.results, res.results));
|
2509
2870
|
ctx.body = {
|
@@ -2518,10 +2879,10 @@ const relations = {
|
|
2518
2879
|
}
|
2519
2880
|
};
|
2520
2881
|
const buildPopulateFromQuery = async (query, model) => {
|
2521
|
-
return getService$
|
2882
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2522
2883
|
};
|
2523
2884
|
const findDocument = async (query, uid2, opts = {}) => {
|
2524
|
-
const documentManager2 = getService$
|
2885
|
+
const documentManager2 = getService$2("document-manager");
|
2525
2886
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2526
2887
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2527
2888
|
};
|
@@ -2529,13 +2890,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2529
2890
|
const { user, userAbility } = ctx.state;
|
2530
2891
|
const { model } = ctx.params;
|
2531
2892
|
const { body, query } = ctx.request;
|
2532
|
-
const documentManager2 = getService$
|
2533
|
-
const permissionChecker2 = getService$
|
2893
|
+
const documentManager2 = getService$2("document-manager");
|
2894
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2534
2895
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2535
2896
|
throw new strapiUtils.errors.ForbiddenError();
|
2536
2897
|
}
|
2537
2898
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2538
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2899
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2539
2900
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2540
2901
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2541
2902
|
// Find the first document to check if it exists
|
@@ -2571,13 +2932,12 @@ const singleTypes = {
|
|
2571
2932
|
const { userAbility } = ctx.state;
|
2572
2933
|
const { model } = ctx.params;
|
2573
2934
|
const { query = {} } = ctx.request;
|
2574
|
-
const permissionChecker2 = getService$
|
2575
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2935
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2576
2936
|
if (permissionChecker2.cannot.read()) {
|
2577
2937
|
return ctx.forbidden();
|
2578
2938
|
}
|
2579
2939
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2580
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2940
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2581
2941
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2582
2942
|
if (!version) {
|
2583
2943
|
if (permissionChecker2.cannot.create()) {
|
@@ -2587,9 +2947,11 @@ const singleTypes = {
|
|
2587
2947
|
if (!document) {
|
2588
2948
|
return ctx.notFound();
|
2589
2949
|
}
|
2590
|
-
const { meta } = await
|
2950
|
+
const { meta } = await formatDocumentWithMetadata(
|
2951
|
+
permissionChecker2,
|
2591
2952
|
model,
|
2592
|
-
|
2953
|
+
// @ts-expect-error - fix types
|
2954
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2593
2955
|
{ availableLocales: true, availableStatus: false }
|
2594
2956
|
);
|
2595
2957
|
ctx.body = { data: {}, meta };
|
@@ -2599,29 +2961,28 @@ const singleTypes = {
|
|
2599
2961
|
return ctx.forbidden();
|
2600
2962
|
}
|
2601
2963
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2602
|
-
ctx.body = await
|
2964
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2603
2965
|
},
|
2604
2966
|
async createOrUpdate(ctx) {
|
2605
2967
|
const { userAbility } = ctx.state;
|
2606
2968
|
const { model } = ctx.params;
|
2607
|
-
const
|
2608
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2969
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2609
2970
|
const document = await createOrUpdateDocument(ctx);
|
2610
2971
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2611
|
-
ctx.body = await
|
2972
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2612
2973
|
},
|
2613
2974
|
async delete(ctx) {
|
2614
2975
|
const { userAbility } = ctx.state;
|
2615
2976
|
const { model } = ctx.params;
|
2616
2977
|
const { query = {} } = ctx.request;
|
2617
|
-
const documentManager2 = getService$
|
2618
|
-
const permissionChecker2 = getService$
|
2978
|
+
const documentManager2 = getService$2("document-manager");
|
2979
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2619
2980
|
if (permissionChecker2.cannot.delete()) {
|
2620
2981
|
return ctx.forbidden();
|
2621
2982
|
}
|
2622
2983
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2623
2984
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2624
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2985
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2625
2986
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2626
2987
|
populate,
|
2627
2988
|
locale
|
@@ -2643,9 +3004,8 @@ const singleTypes = {
|
|
2643
3004
|
const { userAbility } = ctx.state;
|
2644
3005
|
const { model } = ctx.params;
|
2645
3006
|
const { query = {} } = ctx.request;
|
2646
|
-
const documentManager2 = getService$
|
2647
|
-
const
|
2648
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
3007
|
+
const documentManager2 = getService$2("document-manager");
|
3008
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2649
3009
|
if (permissionChecker2.cannot.publish()) {
|
2650
3010
|
return ctx.forbidden();
|
2651
3011
|
}
|
@@ -2659,11 +3019,12 @@ const singleTypes = {
|
|
2659
3019
|
if (permissionChecker2.cannot.publish(document)) {
|
2660
3020
|
throw new strapiUtils.errors.ForbiddenError();
|
2661
3021
|
}
|
2662
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2663
|
-
|
3022
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
3023
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
3024
|
+
return publishResult.at(0);
|
2664
3025
|
});
|
2665
3026
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2666
|
-
ctx.body = await
|
3027
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2667
3028
|
},
|
2668
3029
|
async unpublish(ctx) {
|
2669
3030
|
const { userAbility } = ctx.state;
|
@@ -2672,9 +3033,8 @@ const singleTypes = {
|
|
2672
3033
|
body: { discardDraft, ...body },
|
2673
3034
|
query = {}
|
2674
3035
|
} = ctx.request;
|
2675
|
-
const documentManager2 = getService$
|
2676
|
-
const
|
2677
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
3036
|
+
const documentManager2 = getService$2("document-manager");
|
3037
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2678
3038
|
if (permissionChecker2.cannot.unpublish()) {
|
2679
3039
|
return ctx.forbidden();
|
2680
3040
|
}
|
@@ -2682,7 +3042,7 @@ const singleTypes = {
|
|
2682
3042
|
return ctx.forbidden();
|
2683
3043
|
}
|
2684
3044
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2685
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
3045
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2686
3046
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2687
3047
|
if (!document) {
|
2688
3048
|
return ctx.notFound();
|
@@ -2700,7 +3060,7 @@ const singleTypes = {
|
|
2700
3060
|
ctx.body = await strapiUtils.async.pipe(
|
2701
3061
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2702
3062
|
permissionChecker2.sanitizeOutput,
|
2703
|
-
(document2) =>
|
3063
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2704
3064
|
)(document);
|
2705
3065
|
});
|
2706
3066
|
},
|
@@ -2708,14 +3068,13 @@ const singleTypes = {
|
|
2708
3068
|
const { userAbility } = ctx.state;
|
2709
3069
|
const { model } = ctx.params;
|
2710
3070
|
const { body, query = {} } = ctx.request;
|
2711
|
-
const documentManager2 = getService$
|
2712
|
-
const
|
2713
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
3071
|
+
const documentManager2 = getService$2("document-manager");
|
3072
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2714
3073
|
if (permissionChecker2.cannot.discard()) {
|
2715
3074
|
return ctx.forbidden();
|
2716
3075
|
}
|
2717
3076
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2718
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
3077
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2719
3078
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2720
3079
|
if (!document) {
|
2721
3080
|
return ctx.notFound();
|
@@ -2726,16 +3085,16 @@ const singleTypes = {
|
|
2726
3085
|
ctx.body = await strapiUtils.async.pipe(
|
2727
3086
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2728
3087
|
permissionChecker2.sanitizeOutput,
|
2729
|
-
(document2) =>
|
3088
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2730
3089
|
)(document);
|
2731
3090
|
},
|
2732
3091
|
async countDraftRelations(ctx) {
|
2733
3092
|
const { userAbility } = ctx.state;
|
2734
3093
|
const { model } = ctx.params;
|
2735
3094
|
const { query } = ctx.request;
|
2736
|
-
const documentManager2 = getService$
|
2737
|
-
const permissionChecker2 = getService$
|
2738
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3095
|
+
const documentManager2 = getService$2("document-manager");
|
3096
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3097
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2739
3098
|
if (permissionChecker2.cannot.read()) {
|
2740
3099
|
return ctx.forbidden();
|
2741
3100
|
}
|
@@ -2756,9 +3115,9 @@ const uid$1 = {
|
|
2756
3115
|
async generateUID(ctx) {
|
2757
3116
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2758
3117
|
const { query = {} } = ctx.request;
|
2759
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3118
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2760
3119
|
await validateUIDField(contentTypeUID, field);
|
2761
|
-
const uidService = getService$
|
3120
|
+
const uidService = getService$2("uid");
|
2762
3121
|
ctx.body = {
|
2763
3122
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2764
3123
|
};
|
@@ -2768,9 +3127,9 @@ const uid$1 = {
|
|
2768
3127
|
ctx.request.body
|
2769
3128
|
);
|
2770
3129
|
const { query = {} } = ctx.request;
|
2771
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3130
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2772
3131
|
await validateUIDField(contentTypeUID, field);
|
2773
|
-
const uidService = getService$
|
3132
|
+
const uidService = getService$2("uid");
|
2774
3133
|
const isAvailable = await uidService.checkUIDAvailability({
|
2775
3134
|
contentTypeUID,
|
2776
3135
|
field,
|
@@ -2791,7 +3150,8 @@ const controllers = {
|
|
2791
3150
|
relations,
|
2792
3151
|
"single-types": singleTypes,
|
2793
3152
|
uid: uid$1,
|
2794
|
-
...history.controllers ? history.controllers : {}
|
3153
|
+
...history.controllers ? history.controllers : {},
|
3154
|
+
...preview.controllers ? preview.controllers : {}
|
2795
3155
|
};
|
2796
3156
|
const keys = {
|
2797
3157
|
CONFIGURATION: "configuration"
|
@@ -2942,12 +3302,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2942
3302
|
return ___default.default.assign(metasWithDefaults, updatedMetas);
|
2943
3303
|
}
|
2944
3304
|
const getTargetSchema = (targetModel) => {
|
2945
|
-
return getService$
|
3305
|
+
return getService$2("content-types").findContentType(targetModel);
|
2946
3306
|
};
|
2947
3307
|
const DEFAULT_LIST_LENGTH = 4;
|
2948
3308
|
const MAX_ROW_SIZE = 12;
|
2949
3309
|
const isAllowedFieldSize = (type, size) => {
|
2950
|
-
const { getFieldSize } = getService$
|
3310
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2951
3311
|
const fieldSize = getFieldSize(type);
|
2952
3312
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2953
3313
|
return false;
|
@@ -2955,7 +3315,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2955
3315
|
return size <= MAX_ROW_SIZE;
|
2956
3316
|
};
|
2957
3317
|
const getDefaultFieldSize = (attribute) => {
|
2958
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3318
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2959
3319
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2960
3320
|
};
|
2961
3321
|
async function createDefaultLayouts(schema) {
|
@@ -2990,7 +3350,7 @@ function syncLayouts(configuration, schema) {
|
|
2990
3350
|
for (const el of row) {
|
2991
3351
|
if (!hasEditableAttribute(schema, el.name))
|
2992
3352
|
continue;
|
2993
|
-
const { hasFieldSize } = getService$
|
3353
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
2994
3354
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
2995
3355
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
2996
3356
|
elementsToReAppend.push(el.name);
|
@@ -3130,17 +3490,17 @@ const configurationService$1 = createConfigurationService({
|
|
3130
3490
|
isComponent: true,
|
3131
3491
|
prefix: STORE_KEY_PREFIX,
|
3132
3492
|
getModels() {
|
3133
|
-
const { toContentManagerModel } = getService$
|
3493
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3134
3494
|
return fp.mapValues(toContentManagerModel, strapi.components);
|
3135
3495
|
}
|
3136
3496
|
});
|
3137
3497
|
const components = ({ strapi: strapi2 }) => ({
|
3138
3498
|
findAllComponents() {
|
3139
|
-
const { toContentManagerModel } = getService$
|
3499
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3140
3500
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3141
3501
|
},
|
3142
3502
|
findComponent(uid2) {
|
3143
|
-
const { toContentManagerModel } = getService$
|
3503
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3144
3504
|
const component = strapi2.components[uid2];
|
3145
3505
|
return fp.isNil(component) ? component : toContentManagerModel(component);
|
3146
3506
|
},
|
@@ -3191,17 +3551,17 @@ const configurationService = createConfigurationService({
|
|
3191
3551
|
storeUtils,
|
3192
3552
|
prefix: "content_types",
|
3193
3553
|
getModels() {
|
3194
|
-
const { toContentManagerModel } = getService$
|
3554
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3195
3555
|
return fp.mapValues(toContentManagerModel, strapi.contentTypes);
|
3196
3556
|
}
|
3197
3557
|
});
|
3198
3558
|
const service = ({ strapi: strapi2 }) => ({
|
3199
3559
|
findAllContentTypes() {
|
3200
|
-
const { toContentManagerModel } = getService$
|
3560
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3201
3561
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3202
3562
|
},
|
3203
3563
|
findContentType(uid2) {
|
3204
|
-
const { toContentManagerModel } = getService$
|
3564
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3205
3565
|
const contentType = strapi2.contentTypes[uid2];
|
3206
3566
|
return fp.isNil(contentType) ? contentType : toContentManagerModel(contentType);
|
3207
3567
|
},
|
@@ -3230,7 +3590,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3230
3590
|
return this.findConfiguration(contentType);
|
3231
3591
|
},
|
3232
3592
|
findComponentsConfigurations(contentType) {
|
3233
|
-
return getService$
|
3593
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3234
3594
|
},
|
3235
3595
|
syncConfigurations() {
|
3236
3596
|
return configurationService.syncConfigurations();
|
@@ -3411,12 +3771,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3411
3771
|
ability: userAbility,
|
3412
3772
|
model
|
3413
3773
|
});
|
3414
|
-
const
|
3774
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3775
|
+
const toSubject = (entity) => {
|
3776
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3777
|
+
};
|
3415
3778
|
const can = (action, entity, field) => {
|
3416
|
-
|
3779
|
+
const subject = toSubject(entity);
|
3780
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3781
|
+
return (
|
3782
|
+
// Test the original action to see if it passes
|
3783
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3784
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3785
|
+
);
|
3417
3786
|
};
|
3418
3787
|
const cannot = (action, entity, field) => {
|
3419
|
-
|
3788
|
+
const subject = toSubject(entity);
|
3789
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3790
|
+
return (
|
3791
|
+
// Test both the original action
|
3792
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3793
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3794
|
+
);
|
3420
3795
|
};
|
3421
3796
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3422
3797
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3487,7 +3862,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3487
3862
|
return userAbility.can(action);
|
3488
3863
|
},
|
3489
3864
|
async registerPermissions() {
|
3490
|
-
const displayedContentTypes = getService$
|
3865
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3491
3866
|
const contentTypesUids = displayedContentTypes.map(fp.prop("uid"));
|
3492
3867
|
const actions = [
|
3493
3868
|
{
|
@@ -3559,7 +3934,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3559
3934
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3560
3935
|
}
|
3561
3936
|
});
|
3562
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils__default.default.contentTypes;
|
3937
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils__default.default.contentTypes;
|
3563
3938
|
const { isAnyToMany } = strapiUtils__default.default.relations;
|
3564
3939
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils__default.default.contentTypes.constants;
|
3565
3940
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3650,6 +4025,42 @@ const getDeepPopulate = (uid2, {
|
|
3650
4025
|
{}
|
3651
4026
|
);
|
3652
4027
|
};
|
4028
|
+
const getValidatableFieldsPopulate = (uid2, {
|
4029
|
+
initialPopulate = {},
|
4030
|
+
countMany = false,
|
4031
|
+
countOne = false,
|
4032
|
+
maxLevel = Infinity
|
4033
|
+
} = {}, level = 1) => {
|
4034
|
+
if (level > maxLevel) {
|
4035
|
+
return {};
|
4036
|
+
}
|
4037
|
+
const model = strapi.getModel(uid2);
|
4038
|
+
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
4039
|
+
if (!getDoesAttributeRequireValidation(attribute)) {
|
4040
|
+
return populateAcc;
|
4041
|
+
}
|
4042
|
+
if (isScalarAttribute(attribute)) {
|
4043
|
+
return fp.merge(populateAcc, {
|
4044
|
+
[attributeName]: true
|
4045
|
+
});
|
4046
|
+
}
|
4047
|
+
return fp.merge(
|
4048
|
+
populateAcc,
|
4049
|
+
getPopulateFor(
|
4050
|
+
attributeName,
|
4051
|
+
model,
|
4052
|
+
{
|
4053
|
+
// @ts-expect-error - improve types
|
4054
|
+
initialPopulate: initialPopulate?.[attributeName],
|
4055
|
+
countMany,
|
4056
|
+
countOne,
|
4057
|
+
maxLevel
|
4058
|
+
},
|
4059
|
+
level
|
4060
|
+
)
|
4061
|
+
);
|
4062
|
+
}, {});
|
4063
|
+
};
|
3653
4064
|
const getDeepPopulateDraftCount = (uid2) => {
|
3654
4065
|
const model = strapi.getModel(uid2);
|
3655
4066
|
let hasRelations = false;
|
@@ -3657,6 +4068,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3657
4068
|
const attribute = model.attributes[attributeName];
|
3658
4069
|
switch (attribute.type) {
|
3659
4070
|
case "relation": {
|
4071
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4072
|
+
if (isMorphRelation) {
|
4073
|
+
break;
|
4074
|
+
}
|
3660
4075
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3661
4076
|
populateAcc[attributeName] = {
|
3662
4077
|
count: true,
|
@@ -3671,22 +4086,24 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3671
4086
|
attribute.component
|
3672
4087
|
);
|
3673
4088
|
if (childHasRelations) {
|
3674
|
-
populateAcc[attributeName] = {
|
4089
|
+
populateAcc[attributeName] = {
|
4090
|
+
populate: populate2
|
4091
|
+
};
|
3675
4092
|
hasRelations = true;
|
3676
4093
|
}
|
3677
4094
|
break;
|
3678
4095
|
}
|
3679
4096
|
case "dynamiczone": {
|
3680
|
-
const
|
3681
|
-
const { populate:
|
3682
|
-
if (
|
4097
|
+
const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {
|
4098
|
+
const { populate: componentPopulate, hasRelations: componentHasRelations } = getDeepPopulateDraftCount(componentUID);
|
4099
|
+
if (componentHasRelations) {
|
3683
4100
|
hasRelations = true;
|
3684
|
-
return
|
4101
|
+
return { ...acc, [componentUID]: { populate: componentPopulate } };
|
3685
4102
|
}
|
3686
4103
|
return acc;
|
3687
4104
|
}, {});
|
3688
|
-
if (!fp.isEmpty(
|
3689
|
-
populateAcc[attributeName] = {
|
4105
|
+
if (!fp.isEmpty(dzPopulateFragment)) {
|
4106
|
+
populateAcc[attributeName] = { on: dzPopulateFragment };
|
3690
4107
|
}
|
3691
4108
|
break;
|
3692
4109
|
}
|
@@ -3721,7 +4138,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3721
4138
|
return populateQuery;
|
3722
4139
|
};
|
3723
4140
|
const buildDeepPopulate = (uid2) => {
|
3724
|
-
return getService$
|
4141
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3725
4142
|
};
|
3726
4143
|
const populateBuilder = (uid2) => {
|
3727
4144
|
let getInitialPopulate = async () => {
|
@@ -3878,41 +4295,72 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3878
4295
|
"updatedBy",
|
3879
4296
|
"status"
|
3880
4297
|
];
|
3881
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
4298
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
4299
|
+
"id",
|
4300
|
+
"locale",
|
4301
|
+
"updatedAt",
|
4302
|
+
"createdAt",
|
4303
|
+
"status",
|
4304
|
+
"publishedAt",
|
4305
|
+
"documentId"
|
4306
|
+
];
|
3882
4307
|
const CONTENT_MANAGER_STATUS = {
|
3883
4308
|
PUBLISHED: "published",
|
3884
4309
|
DRAFT: "draft",
|
3885
4310
|
MODIFIED: "modified"
|
3886
4311
|
};
|
3887
|
-
const
|
3888
|
-
if (!
|
4312
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
4313
|
+
if (!version || !version.updatedAt) {
|
3889
4314
|
return false;
|
3890
4315
|
}
|
3891
|
-
const
|
3892
|
-
const
|
3893
|
-
|
3894
|
-
return difference <= threshold;
|
4316
|
+
const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;
|
4317
|
+
const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;
|
4318
|
+
return versionUpdatedAt > otherUpdatedAt;
|
3895
4319
|
};
|
3896
4320
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3897
4321
|
/**
|
3898
4322
|
* Returns available locales of a document for the current status
|
3899
4323
|
*/
|
3900
|
-
getAvailableLocales(uid2, version, allVersions) {
|
4324
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3901
4325
|
const versionsByLocale = fp.groupBy("locale", allVersions);
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
|
3906
|
-
|
3907
|
-
|
3908
|
-
|
3909
|
-
|
3910
|
-
|
3911
|
-
|
3912
|
-
|
3913
|
-
|
3914
|
-
}
|
3915
|
-
|
4326
|
+
if (version.locale) {
|
4327
|
+
delete versionsByLocale[version.locale];
|
4328
|
+
}
|
4329
|
+
const model = strapi2.getModel(uid2);
|
4330
|
+
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4331
|
+
const traversalFunction = async (localeVersion) => strapiUtils.traverseEntity(
|
4332
|
+
({ key }, { remove }) => {
|
4333
|
+
if (keysToKeep.includes(key)) {
|
4334
|
+
return;
|
4335
|
+
}
|
4336
|
+
remove(key);
|
4337
|
+
},
|
4338
|
+
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
4339
|
+
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
4340
|
+
localeVersion
|
4341
|
+
);
|
4342
|
+
const mappingResult = await strapiUtils.async.map(
|
4343
|
+
Object.values(versionsByLocale),
|
4344
|
+
async (localeVersions) => {
|
4345
|
+
const mappedLocaleVersions = await strapiUtils.async.map(
|
4346
|
+
localeVersions,
|
4347
|
+
traversalFunction
|
4348
|
+
);
|
4349
|
+
if (!strapiUtils.contentTypes.hasDraftAndPublish(model)) {
|
4350
|
+
return mappedLocaleVersions[0];
|
4351
|
+
}
|
4352
|
+
const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
|
4353
|
+
const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
|
4354
|
+
if (!draftVersion) {
|
4355
|
+
return;
|
4356
|
+
}
|
4357
|
+
return {
|
4358
|
+
...draftVersion,
|
4359
|
+
status: this.getStatus(draftVersion, otherVersions)
|
4360
|
+
};
|
4361
|
+
}
|
4362
|
+
);
|
4363
|
+
return mappingResult.filter(Boolean);
|
3916
4364
|
},
|
3917
4365
|
/**
|
3918
4366
|
* Returns available status of a document for the current locale
|
@@ -3950,26 +4398,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3950
4398
|
});
|
3951
4399
|
},
|
3952
4400
|
getStatus(version, otherDocumentStatuses) {
|
3953
|
-
|
3954
|
-
|
3955
|
-
|
4401
|
+
let draftVersion;
|
4402
|
+
let publishedVersion;
|
4403
|
+
if (version.publishedAt) {
|
4404
|
+
publishedVersion = version;
|
4405
|
+
} else {
|
4406
|
+
draftVersion = version;
|
3956
4407
|
}
|
3957
|
-
|
3958
|
-
|
3959
|
-
|
3960
|
-
|
3961
|
-
|
4408
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4409
|
+
if (otherVersion?.publishedAt) {
|
4410
|
+
publishedVersion = otherVersion;
|
4411
|
+
} else if (otherVersion) {
|
4412
|
+
draftVersion = otherVersion;
|
3962
4413
|
}
|
3963
|
-
if (
|
4414
|
+
if (!draftVersion)
|
3964
4415
|
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
3965
|
-
|
3966
|
-
|
4416
|
+
if (!publishedVersion)
|
4417
|
+
return CONTENT_MANAGER_STATUS.DRAFT;
|
4418
|
+
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4419
|
+
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
3967
4420
|
},
|
4421
|
+
// TODO is it necessary to return metadata on every page of the CM
|
4422
|
+
// We could refactor this so the locales are only loaded when they're
|
4423
|
+
// needed. e.g. in the bulk locale action modal.
|
3968
4424
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4425
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3969
4426
|
const versions = await strapi2.db.query(uid2).findMany({
|
3970
4427
|
where: { documentId: version.documentId },
|
3971
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3972
4428
|
populate: {
|
4429
|
+
// Populate only fields that require validation for bulk locale actions
|
4430
|
+
...populate,
|
4431
|
+
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
3973
4432
|
createdBy: {
|
3974
4433
|
select: ["id", "firstname", "lastname", "email"]
|
3975
4434
|
},
|
@@ -3978,7 +4437,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3978
4437
|
}
|
3979
4438
|
}
|
3980
4439
|
});
|
3981
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4440
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3982
4441
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3983
4442
|
return {
|
3984
4443
|
availableLocales: availableLocalesResult,
|
@@ -3991,8 +4450,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3991
4450
|
* - Available status of the document for the current locale
|
3992
4451
|
*/
|
3993
4452
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3994
|
-
if (!document)
|
3995
|
-
return
|
4453
|
+
if (!document) {
|
4454
|
+
return {
|
4455
|
+
data: document,
|
4456
|
+
meta: {
|
4457
|
+
availableLocales: [],
|
4458
|
+
availableStatus: []
|
4459
|
+
}
|
4460
|
+
};
|
4461
|
+
}
|
3996
4462
|
const hasDraftAndPublish = strapiUtils.contentTypes.hasDraftAndPublish(strapi2.getModel(uid2));
|
3997
4463
|
if (!hasDraftAndPublish) {
|
3998
4464
|
opts.availableStatus = false;
|
@@ -4042,26 +4508,9 @@ const sumDraftCounts = (entity, uid2) => {
|
|
4042
4508
|
}, 0);
|
4043
4509
|
};
|
4044
4510
|
const { ApplicationError } = strapiUtils.errors;
|
4045
|
-
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
|
4046
4511
|
const { PUBLISHED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
|
4047
4512
|
const omitPublishedAtField = fp.omit(PUBLISHED_AT_ATTRIBUTE);
|
4048
4513
|
const omitIdField = fp.omit("id");
|
4049
|
-
const emitEvent = async (uid2, event, document) => {
|
4050
|
-
const modelDef = strapi.getModel(uid2);
|
4051
|
-
const sanitizedDocument = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput(
|
4052
|
-
{
|
4053
|
-
schema: modelDef,
|
4054
|
-
getModel(uid22) {
|
4055
|
-
return strapi.getModel(uid22);
|
4056
|
-
}
|
4057
|
-
},
|
4058
|
-
document
|
4059
|
-
);
|
4060
|
-
strapi.eventHub.emit(event, {
|
4061
|
-
model: modelDef.modelName,
|
4062
|
-
entry: sanitizedDocument
|
4063
|
-
});
|
4064
|
-
};
|
4065
4514
|
const documentManager = ({ strapi: strapi2 }) => {
|
4066
4515
|
return {
|
4067
4516
|
async findOne(id, uid2, opts = {}) {
|
@@ -4080,6 +4529,9 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4080
4529
|
} else if (opts.locale && opts.locale !== "*") {
|
4081
4530
|
where.locale = opts.locale;
|
4082
4531
|
}
|
4532
|
+
if (typeof opts.isPublished === "boolean") {
|
4533
|
+
where.publishedAt = { $notNull: opts.isPublished };
|
4534
|
+
}
|
4083
4535
|
return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
|
4084
4536
|
},
|
4085
4537
|
async findMany(opts, uid2) {
|
@@ -4087,20 +4539,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4087
4539
|
return strapi2.documents(uid2).findMany(params);
|
4088
4540
|
},
|
4089
4541
|
async findPage(opts, uid2) {
|
4090
|
-
const
|
4091
|
-
|
4542
|
+
const params = strapiUtils.pagination.withDefaultPagination(opts || {}, {
|
4543
|
+
maxLimit: 1e3
|
4544
|
+
});
|
4092
4545
|
const [documents, total = 0] = await Promise.all([
|
4093
|
-
strapi2.documents(uid2).findMany(
|
4094
|
-
strapi2.documents(uid2).count(
|
4546
|
+
strapi2.documents(uid2).findMany(params),
|
4547
|
+
strapi2.documents(uid2).count(params)
|
4095
4548
|
]);
|
4096
4549
|
return {
|
4097
4550
|
results: documents,
|
4098
|
-
pagination:
|
4099
|
-
page,
|
4100
|
-
pageSize,
|
4101
|
-
pageCount: Math.ceil(total / pageSize),
|
4102
|
-
total
|
4103
|
-
}
|
4551
|
+
pagination: strapiUtils.pagination.transformPagedPaginationInfo(params, total)
|
4104
4552
|
};
|
4105
4553
|
},
|
4106
4554
|
async create(uid2, opts = {}) {
|
@@ -4117,10 +4565,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4117
4565
|
async clone(id, body, uid2) {
|
4118
4566
|
const populate = await buildDeepPopulate(uid2);
|
4119
4567
|
const params = {
|
4120
|
-
data:
|
4121
|
-
...omitIdField(body),
|
4122
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4123
|
-
},
|
4568
|
+
data: omitIdField(body),
|
4124
4569
|
populate
|
4125
4570
|
};
|
4126
4571
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4146,70 +4591,36 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4146
4591
|
return {};
|
4147
4592
|
},
|
4148
4593
|
// FIXME: handle relations
|
4149
|
-
async deleteMany(
|
4150
|
-
const
|
4151
|
-
|
4152
|
-
|
4153
|
-
}
|
4154
|
-
return { count: docs.length };
|
4594
|
+
async deleteMany(documentIds, uid2, opts = {}) {
|
4595
|
+
const deletedEntries = await strapi2.db.transaction(async () => {
|
4596
|
+
return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
|
4597
|
+
});
|
4598
|
+
return { count: deletedEntries.length };
|
4155
4599
|
},
|
4156
4600
|
async publish(id, uid2, opts = {}) {
|
4157
4601
|
const populate = await buildDeepPopulate(uid2);
|
4158
4602
|
const params = { ...opts, populate };
|
4159
|
-
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries
|
4603
|
+
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries);
|
4160
4604
|
},
|
4161
|
-
async publishMany(
|
4162
|
-
|
4163
|
-
|
4164
|
-
|
4165
|
-
|
4166
|
-
|
4167
|
-
|
4168
|
-
strapi2.getModel(uid2),
|
4169
|
-
document,
|
4170
|
-
void 0,
|
4171
|
-
// @ts-expect-error - FIXME: entity here is unnecessary
|
4172
|
-
document
|
4173
|
-
);
|
4174
|
-
})
|
4175
|
-
);
|
4176
|
-
const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
|
4177
|
-
const filters = { id: { $in: entitiesToPublish } };
|
4178
|
-
const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
|
4179
|
-
const populate = await buildDeepPopulate(uid2);
|
4180
|
-
const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4181
|
-
where: filters,
|
4182
|
-
data
|
4183
|
-
});
|
4184
|
-
const publishedEntities = await strapi2.db.query(uid2).findMany({
|
4185
|
-
where: filters,
|
4186
|
-
populate
|
4605
|
+
async publishMany(uid2, documentIds, locale) {
|
4606
|
+
return strapi2.db.transaction(async () => {
|
4607
|
+
const results = await Promise.all(
|
4608
|
+
documentIds.map((documentId) => this.publish(documentId, uid2, { locale }))
|
4609
|
+
);
|
4610
|
+
const publishedEntitiesCount = results.flat().filter(Boolean).length;
|
4611
|
+
return publishedEntitiesCount;
|
4187
4612
|
});
|
4188
|
-
await Promise.all(
|
4189
|
-
publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
|
4190
|
-
);
|
4191
|
-
return publishedEntitiesCount;
|
4192
4613
|
},
|
4193
|
-
async unpublishMany(
|
4194
|
-
|
4195
|
-
return
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
const populate = await buildDeepPopulate(uid2);
|
4201
|
-
const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4202
|
-
where: filters,
|
4203
|
-
data
|
4204
|
-
});
|
4205
|
-
const unpublishedEntities = await strapi2.db.query(uid2).findMany({
|
4206
|
-
where: filters,
|
4207
|
-
populate
|
4614
|
+
async unpublishMany(documentIds, uid2, opts = {}) {
|
4615
|
+
const unpublishedEntries = await strapi2.db.transaction(async () => {
|
4616
|
+
return Promise.all(
|
4617
|
+
documentIds.map(
|
4618
|
+
(id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
|
4619
|
+
)
|
4620
|
+
);
|
4208
4621
|
});
|
4209
|
-
|
4210
|
-
|
4211
|
-
);
|
4212
|
-
return unpublishedEntitiesCount;
|
4622
|
+
const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
|
4623
|
+
return { count: unpublishedEntitiesCount };
|
4213
4624
|
},
|
4214
4625
|
async unpublish(id, uid2, opts = {}) {
|
4215
4626
|
const populate = await buildDeepPopulate(uid2);
|
@@ -4234,16 +4645,20 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4234
4645
|
}
|
4235
4646
|
return sumDraftCounts(document, uid2);
|
4236
4647
|
},
|
4237
|
-
async countManyEntriesDraftRelations(
|
4648
|
+
async countManyEntriesDraftRelations(documentIds, uid2, locale) {
|
4238
4649
|
const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
|
4239
4650
|
if (!hasRelations) {
|
4240
4651
|
return 0;
|
4241
4652
|
}
|
4653
|
+
let localeFilter = {};
|
4654
|
+
if (locale) {
|
4655
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4656
|
+
}
|
4242
4657
|
const entities = await strapi2.db.query(uid2).findMany({
|
4243
4658
|
populate,
|
4244
4659
|
where: {
|
4245
|
-
|
4246
|
-
...
|
4660
|
+
documentId: { $in: documentIds },
|
4661
|
+
...localeFilter
|
4247
4662
|
}
|
4248
4663
|
});
|
4249
4664
|
const totalNumberDraftRelations = entities.reduce(
|
@@ -4266,7 +4681,8 @@ const services = {
|
|
4266
4681
|
permission,
|
4267
4682
|
"populate-builder": populateBuilder$1,
|
4268
4683
|
uid,
|
4269
|
-
...history.services ? history.services : {}
|
4684
|
+
...history.services ? history.services : {},
|
4685
|
+
...preview.services ? preview.services : {}
|
4270
4686
|
};
|
4271
4687
|
const index = () => {
|
4272
4688
|
return {
|