@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.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1,
|
2
|
-
import { pick, omit, difference, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy
|
1
|
+
import strapiUtils, { validateYupSchema, errors, async, contentTypes as contentTypes$1, yup as yup$1, validateYupSchemaSync, policy, traverse, setCreatorFields, isOperatorOfType, relations as relations$1, traverseEntity, pagination } from "@strapi/utils";
|
2
|
+
import { pick, omit, difference, castArray, mergeWith, intersection, pipe, propOr, isEqual, isEmpty, set, isNil as isNil$1, has, prop, assoc, mapValues, flow, uniq, uniqBy, concat, getOr, propEq, merge, groupBy } from "lodash/fp";
|
3
3
|
import "@strapi/types";
|
4
4
|
import * as yup from "yup";
|
5
5
|
import { scheduleJob } from "node-schedule";
|
@@ -7,10 +7,10 @@ import isNil from "lodash/isNil";
|
|
7
7
|
import _, { intersection as intersection$1, difference as difference$1 } from "lodash";
|
8
8
|
import qs from "qs";
|
9
9
|
import slugify from "@sindresorhus/slugify";
|
10
|
-
const getService$
|
10
|
+
const getService$2 = (name) => {
|
11
11
|
return strapi.plugin("content-manager").service(name);
|
12
12
|
};
|
13
|
-
function getService(strapi2, name) {
|
13
|
+
function getService$1(strapi2, name) {
|
14
14
|
return strapi2.service(`plugin::content-manager.${name}`);
|
15
15
|
}
|
16
16
|
const historyRestoreVersionSchema = yup.object().shape({
|
@@ -46,7 +46,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
46
46
|
if (!isSingleType && (!contentTypeUid || !ctx.query.documentId)) {
|
47
47
|
throw new errors.ForbiddenError("contentType and documentId are required");
|
48
48
|
}
|
49
|
-
const permissionChecker2 = getService$
|
49
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
50
50
|
userAbility: ctx.state.userAbility,
|
51
51
|
model: ctx.query.contentType
|
52
52
|
});
|
@@ -54,7 +54,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
54
54
|
return ctx.forbidden();
|
55
55
|
}
|
56
56
|
const query = await permissionChecker2.sanitizeQuery(ctx.query);
|
57
|
-
const { results, pagination } = await getService(strapi2, "history").findVersionsPage({
|
57
|
+
const { results, pagination: pagination2 } = await getService$1(strapi2, "history").findVersionsPage({
|
58
58
|
query: {
|
59
59
|
...query,
|
60
60
|
...getValidPagination({ page: query.page, pageSize: query.pageSize })
|
@@ -73,20 +73,20 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
73
73
|
);
|
74
74
|
return {
|
75
75
|
data: sanitizedResults,
|
76
|
-
meta: { pagination }
|
76
|
+
meta: { pagination: pagination2 }
|
77
77
|
};
|
78
78
|
},
|
79
79
|
async restoreVersion(ctx) {
|
80
80
|
const request = ctx.request;
|
81
81
|
await validateRestoreVersion(request.body, "contentType is required");
|
82
|
-
const permissionChecker2 = getService$
|
82
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
83
83
|
userAbility: ctx.state.userAbility,
|
84
84
|
model: request.body.contentType
|
85
85
|
});
|
86
86
|
if (permissionChecker2.cannot.update()) {
|
87
87
|
throw new errors.ForbiddenError();
|
88
88
|
}
|
89
|
-
const restoredDocument = await getService(strapi2, "history").restoreVersion(
|
89
|
+
const restoredDocument = await getService$1(strapi2, "history").restoreVersion(
|
90
90
|
request.params.versionId
|
91
91
|
);
|
92
92
|
return {
|
@@ -95,7 +95,7 @@ const createHistoryVersionController = ({ strapi: strapi2 }) => {
|
|
95
95
|
}
|
96
96
|
};
|
97
97
|
};
|
98
|
-
const controllers$
|
98
|
+
const controllers$2 = {
|
99
99
|
"history-version": createHistoryVersionController
|
100
100
|
/**
|
101
101
|
* Casting is needed because the types aren't aware that Strapi supports
|
@@ -173,7 +173,9 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
173
173
|
return strapi2.db.query("plugin::upload.file").findOne({ where: { id: versionRelationData.id } });
|
174
174
|
};
|
175
175
|
const localesService = strapi2.plugin("i18n")?.service("locales");
|
176
|
+
const i18nContentTypeService = strapi2.plugin("i18n")?.service("content-types");
|
176
177
|
const getDefaultLocale = async () => localesService ? localesService.getDefaultLocale() : null;
|
178
|
+
const isLocalizedContentType = (model) => i18nContentTypeService ? i18nContentTypeService.isLocalizedContentType(model) : false;
|
177
179
|
const getLocaleDictionary = async () => {
|
178
180
|
if (!localesService)
|
179
181
|
return {};
|
@@ -200,31 +202,53 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
200
202
|
const meta = await documentMetadataService.getMetadata(contentTypeUid, document);
|
201
203
|
return documentMetadataService.getStatus(document, meta.availableStatus);
|
202
204
|
};
|
203
|
-
const
|
205
|
+
const getComponentFields = (componentUID) => {
|
206
|
+
return Object.entries(strapi2.getModel(componentUID).attributes).reduce(
|
207
|
+
(fieldsAcc, [key, attribute]) => {
|
208
|
+
if (!["relation", "media", "component", "dynamiczone"].includes(attribute.type)) {
|
209
|
+
fieldsAcc.push(key);
|
210
|
+
}
|
211
|
+
return fieldsAcc;
|
212
|
+
},
|
213
|
+
[]
|
214
|
+
);
|
215
|
+
};
|
216
|
+
const getDeepPopulate2 = (uid2, useDatabaseSyntax = false) => {
|
204
217
|
const model = strapi2.getModel(uid2);
|
205
218
|
const attributes = Object.entries(model.attributes);
|
219
|
+
const fieldSelector = useDatabaseSyntax ? "select" : "fields";
|
206
220
|
return attributes.reduce((acc, [attributeName, attribute]) => {
|
207
221
|
switch (attribute.type) {
|
208
222
|
case "relation": {
|
223
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
224
|
+
if (isMorphRelation) {
|
225
|
+
break;
|
226
|
+
}
|
209
227
|
const isVisible2 = contentTypes$1.isVisibleAttribute(model, attributeName);
|
210
228
|
if (isVisible2) {
|
211
|
-
acc[attributeName] = {
|
229
|
+
acc[attributeName] = { [fieldSelector]: ["documentId", "locale", "publishedAt"] };
|
212
230
|
}
|
213
231
|
break;
|
214
232
|
}
|
215
233
|
case "media": {
|
216
|
-
acc[attributeName] = {
|
234
|
+
acc[attributeName] = { [fieldSelector]: ["id"] };
|
217
235
|
break;
|
218
236
|
}
|
219
237
|
case "component": {
|
220
238
|
const populate = getDeepPopulate2(attribute.component);
|
221
|
-
acc[attributeName] = {
|
239
|
+
acc[attributeName] = {
|
240
|
+
populate,
|
241
|
+
[fieldSelector]: getComponentFields(attribute.component)
|
242
|
+
};
|
222
243
|
break;
|
223
244
|
}
|
224
245
|
case "dynamiczone": {
|
225
246
|
const populatedComponents = (attribute.components || []).reduce(
|
226
247
|
(acc2, componentUID) => {
|
227
|
-
acc2[componentUID] = {
|
248
|
+
acc2[componentUID] = {
|
249
|
+
populate: getDeepPopulate2(componentUID),
|
250
|
+
[fieldSelector]: getComponentFields(componentUID)
|
251
|
+
};
|
228
252
|
return acc2;
|
229
253
|
},
|
230
254
|
{}
|
@@ -286,6 +310,7 @@ const createServiceUtils = ({ strapi: strapi2 }) => {
|
|
286
310
|
getRelationRestoreValue,
|
287
311
|
getMediaRestoreValue,
|
288
312
|
getDefaultLocale,
|
313
|
+
isLocalizedContentType,
|
289
314
|
getLocaleDictionary,
|
290
315
|
getRetentionDays,
|
291
316
|
getVersionStatus,
|
@@ -308,8 +333,14 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
308
333
|
});
|
309
334
|
},
|
310
335
|
async findVersionsPage(params) {
|
311
|
-
const
|
312
|
-
const
|
336
|
+
const model = strapi2.getModel(params.query.contentType);
|
337
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
338
|
+
const defaultLocale = await serviceUtils.getDefaultLocale();
|
339
|
+
let locale = null;
|
340
|
+
if (isLocalizedContentType) {
|
341
|
+
locale = params.query.locale || defaultLocale;
|
342
|
+
}
|
343
|
+
const [{ results, pagination: pagination2 }, localeDictionary] = await Promise.all([
|
313
344
|
query.findPage({
|
314
345
|
...params.query,
|
315
346
|
where: {
|
@@ -330,7 +361,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
330
361
|
const attributeValue = entry.data[attributeKey];
|
331
362
|
const attributeValues = Array.isArray(attributeValue) ? attributeValue : [attributeValue];
|
332
363
|
if (attributeSchema.type === "media") {
|
333
|
-
const permissionChecker2 = getService$
|
364
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
334
365
|
userAbility: params.state.userAbility,
|
335
366
|
model: "plugin::upload.file"
|
336
367
|
});
|
@@ -353,7 +384,12 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
353
384
|
if (userToPopulate == null) {
|
354
385
|
return null;
|
355
386
|
}
|
356
|
-
return strapi2.query("admin::user").findOne({
|
387
|
+
return strapi2.query("admin::user").findOne({
|
388
|
+
where: {
|
389
|
+
...userToPopulate.id ? { id: userToPopulate.id } : {},
|
390
|
+
...userToPopulate.documentId ? { documentId: userToPopulate.documentId } : {}
|
391
|
+
}
|
392
|
+
});
|
357
393
|
})
|
358
394
|
);
|
359
395
|
return {
|
@@ -366,7 +402,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
366
402
|
[attributeKey]: adminUsers
|
367
403
|
};
|
368
404
|
}
|
369
|
-
const permissionChecker2 = getService$
|
405
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
370
406
|
userAbility: params.state.userAbility,
|
371
407
|
model: attributeSchema.target
|
372
408
|
});
|
@@ -408,7 +444,7 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
408
444
|
);
|
409
445
|
return {
|
410
446
|
results: formattedResults,
|
411
|
-
pagination
|
447
|
+
pagination: pagination2
|
412
448
|
};
|
413
449
|
},
|
414
450
|
async restoreVersion(versionId) {
|
@@ -464,13 +500,47 @@ const createHistoryService = ({ strapi: strapi2 }) => {
|
|
464
500
|
}
|
465
501
|
};
|
466
502
|
};
|
503
|
+
const shouldCreateHistoryVersion = (context) => {
|
504
|
+
if (!strapi.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
if (context.action !== "create" && context.action !== "update" && context.action !== "clone" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
508
|
+
return false;
|
509
|
+
}
|
510
|
+
if (context.action === "update" && strapi.requestContext.get()?.request.url.endsWith("/actions/publish")) {
|
511
|
+
return false;
|
512
|
+
}
|
513
|
+
if (!context.contentType.uid.startsWith("api::")) {
|
514
|
+
return false;
|
515
|
+
}
|
516
|
+
return true;
|
517
|
+
};
|
518
|
+
const getSchemas = (uid2) => {
|
519
|
+
const attributesSchema = strapi.getModel(uid2).attributes;
|
520
|
+
const componentsSchemas = Object.keys(attributesSchema).reduce(
|
521
|
+
(currentComponentSchemas, key) => {
|
522
|
+
const fieldSchema = attributesSchema[key];
|
523
|
+
if (fieldSchema.type === "component") {
|
524
|
+
const componentSchema = strapi.getModel(fieldSchema.component).attributes;
|
525
|
+
return {
|
526
|
+
...currentComponentSchemas,
|
527
|
+
[fieldSchema.component]: componentSchema
|
528
|
+
};
|
529
|
+
}
|
530
|
+
return currentComponentSchemas;
|
531
|
+
},
|
532
|
+
{}
|
533
|
+
);
|
534
|
+
return {
|
535
|
+
schema: omit(FIELDS_TO_IGNORE, attributesSchema),
|
536
|
+
componentsSchemas
|
537
|
+
};
|
538
|
+
};
|
467
539
|
const createLifecyclesService = ({ strapi: strapi2 }) => {
|
468
540
|
const state = {
|
469
541
|
deleteExpiredJob: null,
|
470
542
|
isInitialized: false
|
471
543
|
};
|
472
|
-
const query = strapi2.db.query(HISTORY_VERSION_UID);
|
473
|
-
const historyService = getService(strapi2, "history");
|
474
544
|
const serviceUtils = createServiceUtils({ strapi: strapi2 });
|
475
545
|
return {
|
476
546
|
async bootstrap() {
|
@@ -478,65 +548,62 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
478
548
|
return;
|
479
549
|
}
|
480
550
|
strapi2.documents.use(async (context, next) => {
|
481
|
-
if (!strapi2.requestContext.get()?.request.url.startsWith("/content-manager")) {
|
482
|
-
return next();
|
483
|
-
}
|
484
|
-
if (context.action !== "create" && context.action !== "update" && context.action !== "publish" && context.action !== "unpublish" && context.action !== "discardDraft") {
|
485
|
-
return next();
|
486
|
-
}
|
487
|
-
const contentTypeUid = context.contentType.uid;
|
488
|
-
if (!contentTypeUid.startsWith("api::")) {
|
489
|
-
return next();
|
490
|
-
}
|
491
551
|
const result = await next();
|
492
|
-
|
552
|
+
if (!shouldCreateHistoryVersion(context)) {
|
553
|
+
return result;
|
554
|
+
}
|
555
|
+
const documentId = context.action === "create" || context.action === "clone" ? result.documentId : context.params.documentId;
|
493
556
|
const defaultLocale = await serviceUtils.getDefaultLocale();
|
494
|
-
const
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
557
|
+
const locales = castArray(context.params?.locale || defaultLocale);
|
558
|
+
if (!locales.length) {
|
559
|
+
return result;
|
560
|
+
}
|
561
|
+
const uid2 = context.contentType.uid;
|
562
|
+
const schemas = getSchemas(uid2);
|
563
|
+
const model = strapi2.getModel(uid2);
|
564
|
+
const isLocalizedContentType = serviceUtils.isLocalizedContentType(model);
|
565
|
+
const localeEntries = await strapi2.db.query(uid2).findMany({
|
566
|
+
where: {
|
567
|
+
documentId,
|
568
|
+
...isLocalizedContentType ? { locale: { $in: locales } } : {},
|
569
|
+
...contentTypes$1.hasDraftAndPublish(strapi2.contentTypes[uid2]) ? { publishedAt: null } : {}
|
570
|
+
},
|
571
|
+
populate: serviceUtils.getDeepPopulate(
|
572
|
+
uid2,
|
573
|
+
true
|
574
|
+
/* use database syntax */
|
575
|
+
)
|
499
576
|
});
|
500
|
-
const status = await serviceUtils.getVersionStatus(contentTypeUid, document);
|
501
|
-
const attributesSchema = strapi2.getModel(contentTypeUid).attributes;
|
502
|
-
const componentsSchemas = Object.keys(
|
503
|
-
attributesSchema
|
504
|
-
).reduce((currentComponentSchemas, key) => {
|
505
|
-
const fieldSchema = attributesSchema[key];
|
506
|
-
if (fieldSchema.type === "component") {
|
507
|
-
const componentSchema = strapi2.getModel(fieldSchema.component).attributes;
|
508
|
-
return {
|
509
|
-
...currentComponentSchemas,
|
510
|
-
[fieldSchema.component]: componentSchema
|
511
|
-
};
|
512
|
-
}
|
513
|
-
return currentComponentSchemas;
|
514
|
-
}, {});
|
515
577
|
await strapi2.db.transaction(async ({ onCommit }) => {
|
516
|
-
onCommit(() => {
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
578
|
+
onCommit(async () => {
|
579
|
+
for (const entry of localeEntries) {
|
580
|
+
const status = await serviceUtils.getVersionStatus(uid2, entry);
|
581
|
+
await getService$1(strapi2, "history").createVersion({
|
582
|
+
contentType: uid2,
|
583
|
+
data: omit(FIELDS_TO_IGNORE, entry),
|
584
|
+
relatedDocumentId: documentId,
|
585
|
+
locale: entry.locale,
|
586
|
+
status,
|
587
|
+
...schemas
|
588
|
+
});
|
589
|
+
}
|
526
590
|
});
|
527
591
|
});
|
528
592
|
return result;
|
529
593
|
});
|
530
|
-
|
531
|
-
|
532
|
-
const retentionDaysInMilliseconds = retentionDays * 24 * 60 * 60 * 1e3;
|
594
|
+
state.deleteExpiredJob = scheduleJob("historyDaily", "0 0 * * *", () => {
|
595
|
+
const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1e3;
|
533
596
|
const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
|
534
|
-
query.deleteMany({
|
597
|
+
strapi2.db.query(HISTORY_VERSION_UID).deleteMany({
|
535
598
|
where: {
|
536
599
|
created_at: {
|
537
|
-
$lt: expirationDate
|
600
|
+
$lt: expirationDate
|
538
601
|
}
|
539
602
|
}
|
603
|
+
}).catch((error) => {
|
604
|
+
if (error instanceof Error) {
|
605
|
+
strapi2.log.error("Error deleting expired history versions", error.message);
|
606
|
+
}
|
540
607
|
});
|
541
608
|
});
|
542
609
|
state.isInitialized = true;
|
@@ -548,17 +615,17 @@ const createLifecyclesService = ({ strapi: strapi2 }) => {
|
|
548
615
|
}
|
549
616
|
};
|
550
617
|
};
|
551
|
-
const services$
|
618
|
+
const services$2 = {
|
552
619
|
history: createHistoryService,
|
553
620
|
lifecycles: createLifecyclesService
|
554
621
|
};
|
555
|
-
const info = { pluginName: "content-manager", type: "admin" };
|
622
|
+
const info$1 = { pluginName: "content-manager", type: "admin" };
|
556
623
|
const historyVersionRouter = {
|
557
624
|
type: "admin",
|
558
625
|
routes: [
|
559
626
|
{
|
560
627
|
method: "GET",
|
561
|
-
info,
|
628
|
+
info: info$1,
|
562
629
|
path: "/history-versions",
|
563
630
|
handler: "history-version.findMany",
|
564
631
|
config: {
|
@@ -567,7 +634,7 @@ const historyVersionRouter = {
|
|
567
634
|
},
|
568
635
|
{
|
569
636
|
method: "PUT",
|
570
|
-
info,
|
637
|
+
info: info$1,
|
571
638
|
path: "/history-versions/:versionId/restore",
|
572
639
|
handler: "history-version.restoreVersion",
|
573
640
|
config: {
|
@@ -576,7 +643,7 @@ const historyVersionRouter = {
|
|
576
643
|
}
|
577
644
|
]
|
578
645
|
};
|
579
|
-
const routes$
|
646
|
+
const routes$2 = {
|
580
647
|
"history-version": historyVersionRouter
|
581
648
|
};
|
582
649
|
const historyVersion = {
|
@@ -623,21 +690,21 @@ const historyVersion = {
|
|
623
690
|
}
|
624
691
|
}
|
625
692
|
};
|
626
|
-
const getFeature = () => {
|
693
|
+
const getFeature$1 = () => {
|
627
694
|
if (strapi.ee.features.isEnabled("cms-content-history")) {
|
628
695
|
return {
|
629
696
|
register({ strapi: strapi2 }) {
|
630
697
|
strapi2.get("models").add(historyVersion);
|
631
698
|
},
|
632
699
|
bootstrap({ strapi: strapi2 }) {
|
633
|
-
getService(strapi2, "lifecycles").bootstrap();
|
700
|
+
getService$1(strapi2, "lifecycles").bootstrap();
|
634
701
|
},
|
635
702
|
destroy({ strapi: strapi2 }) {
|
636
|
-
getService(strapi2, "lifecycles").destroy();
|
703
|
+
getService$1(strapi2, "lifecycles").destroy();
|
637
704
|
},
|
638
|
-
controllers: controllers$
|
639
|
-
services: services$
|
640
|
-
routes: routes$
|
705
|
+
controllers: controllers$2,
|
706
|
+
services: services$2,
|
707
|
+
routes: routes$2
|
641
708
|
};
|
642
709
|
}
|
643
710
|
return {
|
@@ -646,9 +713,205 @@ const getFeature = () => {
|
|
646
713
|
}
|
647
714
|
};
|
648
715
|
};
|
649
|
-
const history = getFeature();
|
716
|
+
const history = getFeature$1();
|
717
|
+
const FEATURE_ID = "preview";
|
718
|
+
const info = { pluginName: "content-manager", type: "admin" };
|
719
|
+
const previewRouter = {
|
720
|
+
type: "admin",
|
721
|
+
routes: [
|
722
|
+
{
|
723
|
+
method: "GET",
|
724
|
+
info,
|
725
|
+
path: "/preview/url/:contentType",
|
726
|
+
handler: "preview.getPreviewUrl",
|
727
|
+
config: {
|
728
|
+
policies: ["admin::isAuthenticatedAdmin"]
|
729
|
+
}
|
730
|
+
}
|
731
|
+
]
|
732
|
+
};
|
733
|
+
const routes$1 = {
|
734
|
+
preview: previewRouter
|
735
|
+
};
|
736
|
+
function getService(strapi2, name) {
|
737
|
+
return strapi2.service(`plugin::content-manager.${name}`);
|
738
|
+
}
|
739
|
+
const getPreviewUrlSchema = yup.object().shape({
|
740
|
+
// Will be undefined for single types
|
741
|
+
documentId: yup.string(),
|
742
|
+
locale: yup.string().nullable(),
|
743
|
+
status: yup.string()
|
744
|
+
}).required();
|
745
|
+
const validatePreviewUrl = async (strapi2, uid2, params) => {
|
746
|
+
await validateYupSchema(getPreviewUrlSchema)(params);
|
747
|
+
const newParams = pick(["documentId", "locale", "status"], params);
|
748
|
+
const model = strapi2.getModel(uid2);
|
749
|
+
if (!model || model.modelType !== "contentType") {
|
750
|
+
throw new errors.ValidationError("Invalid content type");
|
751
|
+
}
|
752
|
+
const isSingleType = model?.kind === "singleType";
|
753
|
+
if (!isSingleType && !params.documentId) {
|
754
|
+
throw new errors.ValidationError("documentId is required for Collection Types");
|
755
|
+
}
|
756
|
+
if (isSingleType) {
|
757
|
+
const doc = await strapi2.documents(uid2).findFirst();
|
758
|
+
if (!doc) {
|
759
|
+
throw new errors.NotFoundError("Document not found");
|
760
|
+
}
|
761
|
+
newParams.documentId = doc?.documentId;
|
762
|
+
}
|
763
|
+
if (!newParams.status) {
|
764
|
+
const isDPEnabled = model?.options?.draftAndPublish;
|
765
|
+
newParams.status = isDPEnabled ? "draft" : "published";
|
766
|
+
}
|
767
|
+
return newParams;
|
768
|
+
};
|
769
|
+
const createPreviewController = () => {
|
770
|
+
return {
|
771
|
+
/**
|
772
|
+
* Transforms an entry into a preview URL, so that it can be previewed
|
773
|
+
* in the Content Manager.
|
774
|
+
*/
|
775
|
+
async getPreviewUrl(ctx) {
|
776
|
+
const uid2 = ctx.params.contentType;
|
777
|
+
const query = ctx.request.query;
|
778
|
+
const params = await validatePreviewUrl(strapi, uid2, query);
|
779
|
+
const previewService = getService(strapi, "preview");
|
780
|
+
const url = await previewService.getPreviewUrl(uid2, params);
|
781
|
+
if (!url) {
|
782
|
+
ctx.status = 204;
|
783
|
+
}
|
784
|
+
return {
|
785
|
+
data: { url }
|
786
|
+
};
|
787
|
+
}
|
788
|
+
};
|
789
|
+
};
|
790
|
+
const controllers$1 = {
|
791
|
+
preview: createPreviewController
|
792
|
+
/**
|
793
|
+
* Casting is needed because the types aren't aware that Strapi supports
|
794
|
+
* passing a controller factory as the value, instead of a controller object directly
|
795
|
+
*/
|
796
|
+
};
|
797
|
+
const createPreviewService = ({ strapi: strapi2 }) => {
|
798
|
+
const config = getService(strapi2, "preview-config");
|
799
|
+
return {
|
800
|
+
async getPreviewUrl(uid2, params) {
|
801
|
+
const handler = config.getPreviewHandler();
|
802
|
+
try {
|
803
|
+
return handler(uid2, params);
|
804
|
+
} catch (error) {
|
805
|
+
strapi2.log.error(`Failed to get preview URL: ${error}`);
|
806
|
+
throw new errors.ApplicationError("Failed to get preview URL");
|
807
|
+
}
|
808
|
+
return;
|
809
|
+
}
|
810
|
+
};
|
811
|
+
};
|
812
|
+
const extendMiddlewareConfiguration = (middleware = { name: "", config: {} }) => {
|
813
|
+
const middlewares = strapi.config.get("middlewares");
|
814
|
+
const configuredMiddlewares = middlewares.map((currentMiddleware) => {
|
815
|
+
if (currentMiddleware === middleware.name) {
|
816
|
+
return middleware;
|
817
|
+
}
|
818
|
+
if (currentMiddleware.name === middleware.name) {
|
819
|
+
return mergeWith(
|
820
|
+
(objValue, srcValue) => {
|
821
|
+
if (Array.isArray(objValue)) {
|
822
|
+
return objValue.concat(srcValue);
|
823
|
+
}
|
824
|
+
return void 0;
|
825
|
+
},
|
826
|
+
currentMiddleware,
|
827
|
+
middleware
|
828
|
+
);
|
829
|
+
}
|
830
|
+
return currentMiddleware;
|
831
|
+
});
|
832
|
+
strapi.config.set("middlewares", configuredMiddlewares);
|
833
|
+
};
|
834
|
+
const createPreviewConfigService = ({ strapi: strapi2 }) => {
|
835
|
+
return {
|
836
|
+
register() {
|
837
|
+
if (!this.isEnabled()) {
|
838
|
+
return;
|
839
|
+
}
|
840
|
+
const config = strapi2.config.get("admin.preview");
|
841
|
+
if (config.config?.allowedOrigins) {
|
842
|
+
extendMiddlewareConfiguration({
|
843
|
+
name: "strapi::security",
|
844
|
+
config: {
|
845
|
+
contentSecurityPolicy: {
|
846
|
+
directives: {
|
847
|
+
"frame-src": config.config.allowedOrigins
|
848
|
+
}
|
849
|
+
}
|
850
|
+
}
|
851
|
+
});
|
852
|
+
}
|
853
|
+
},
|
854
|
+
isEnabled() {
|
855
|
+
const config = strapi2.config.get("admin.preview");
|
856
|
+
if (!config) {
|
857
|
+
return false;
|
858
|
+
}
|
859
|
+
return config?.enabled ?? true;
|
860
|
+
},
|
861
|
+
/**
|
862
|
+
* Validate if the configuration is valid
|
863
|
+
*/
|
864
|
+
validate() {
|
865
|
+
if (!this.isEnabled()) {
|
866
|
+
return;
|
867
|
+
}
|
868
|
+
const handler = this.getPreviewHandler();
|
869
|
+
if (typeof handler !== "function") {
|
870
|
+
throw new errors.ValidationError(
|
871
|
+
"Preview configuration is invalid. Handler must be a function"
|
872
|
+
);
|
873
|
+
}
|
874
|
+
},
|
875
|
+
/**
|
876
|
+
* Utility to get the preview handler from the configuration
|
877
|
+
*/
|
878
|
+
getPreviewHandler() {
|
879
|
+
const config = strapi2.config.get("admin.preview");
|
880
|
+
const emptyHandler = () => {
|
881
|
+
return void 0;
|
882
|
+
};
|
883
|
+
if (!this.isEnabled()) {
|
884
|
+
return emptyHandler;
|
885
|
+
}
|
886
|
+
return config?.config?.handler || emptyHandler;
|
887
|
+
}
|
888
|
+
};
|
889
|
+
};
|
890
|
+
const services$1 = {
|
891
|
+
preview: createPreviewService,
|
892
|
+
"preview-config": createPreviewConfigService
|
893
|
+
};
|
894
|
+
const getFeature = () => {
|
895
|
+
if (!strapi.features.future.isEnabled(FEATURE_ID)) {
|
896
|
+
return {};
|
897
|
+
}
|
898
|
+
return {
|
899
|
+
register() {
|
900
|
+
const config = getService(strapi, "preview-config");
|
901
|
+
config.validate();
|
902
|
+
config.register();
|
903
|
+
},
|
904
|
+
bootstrap() {
|
905
|
+
},
|
906
|
+
routes: routes$1,
|
907
|
+
controllers: controllers$1,
|
908
|
+
services: services$1
|
909
|
+
};
|
910
|
+
};
|
911
|
+
const preview = getFeature();
|
650
912
|
const register = async ({ strapi: strapi2 }) => {
|
651
913
|
await history.register?.({ strapi: strapi2 });
|
914
|
+
await preview.register?.({ strapi: strapi2 });
|
652
915
|
};
|
653
916
|
const ALLOWED_WEBHOOK_EVENTS = {
|
654
917
|
ENTRY_PUBLISH: "entry.publish",
|
@@ -658,11 +921,12 @@ const bootstrap = async () => {
|
|
658
921
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
659
922
|
strapi.get("webhookStore").addAllowedEvent(key, value);
|
660
923
|
});
|
661
|
-
getService$
|
662
|
-
await getService$
|
663
|
-
await getService$
|
664
|
-
await getService$
|
924
|
+
getService$2("field-sizes").setCustomFieldInputSizes();
|
925
|
+
await getService$2("components").syncConfigurations();
|
926
|
+
await getService$2("content-types").syncConfigurations();
|
927
|
+
await getService$2("permission").registerPermissions();
|
665
928
|
await history.bootstrap?.({ strapi });
|
929
|
+
await preview.bootstrap?.({ strapi });
|
666
930
|
};
|
667
931
|
const destroy = async ({ strapi: strapi2 }) => {
|
668
932
|
await history.destroy?.({ strapi: strapi2 });
|
@@ -1152,7 +1416,8 @@ const admin = {
|
|
1152
1416
|
};
|
1153
1417
|
const routes = {
|
1154
1418
|
admin,
|
1155
|
-
...history.routes ? history.routes : {}
|
1419
|
+
...history.routes ? history.routes : {},
|
1420
|
+
...preview.routes ? preview.routes : {}
|
1156
1421
|
};
|
1157
1422
|
const hasPermissionsSchema = yup$1.object({
|
1158
1423
|
actions: yup$1.array().of(yup$1.string()),
|
@@ -1163,6 +1428,11 @@ const { createPolicy } = policy;
|
|
1163
1428
|
const hasPermissions = createPolicy({
|
1164
1429
|
name: "plugin::content-manager.hasPermissions",
|
1165
1430
|
validator: validateHasPermissionsInput,
|
1431
|
+
/**
|
1432
|
+
* NOTE: Action aliases are currently not checked at this level (policy).
|
1433
|
+
* This is currently the intended behavior to avoid changing the behavior of API related permissions.
|
1434
|
+
* If you want to add support for it, please create a dedicated RFC with a list of potential side effect this could have.
|
1435
|
+
*/
|
1166
1436
|
handler(ctx, config = {}) {
|
1167
1437
|
const { actions = [], hasAtLeastOne = false } = config;
|
1168
1438
|
const { userAbility } = ctx.state;
|
@@ -1404,7 +1674,7 @@ const createMetadasSchema = (schema) => {
|
|
1404
1674
|
if (!value) {
|
1405
1675
|
return yup$1.string();
|
1406
1676
|
}
|
1407
|
-
const targetSchema = getService$
|
1677
|
+
const targetSchema = getService$2("content-types").findContentType(
|
1408
1678
|
schema.attributes[key].targetModel
|
1409
1679
|
);
|
1410
1680
|
if (!targetSchema) {
|
@@ -1452,7 +1722,7 @@ const { PaginationError, ValidationError } = errors;
|
|
1452
1722
|
const TYPES = ["singleType", "collectionType"];
|
1453
1723
|
const kindSchema = yup$1.string().oneOf(TYPES).nullable();
|
1454
1724
|
const bulkActionInputSchema = yup$1.object({
|
1455
|
-
|
1725
|
+
documentIds: yup$1.array().of(yup$1.strapiID()).min(1).required()
|
1456
1726
|
}).required();
|
1457
1727
|
const generateUIDInputSchema = yup$1.object({
|
1458
1728
|
contentTypeUID: yup$1.string().required(),
|
@@ -1551,22 +1821,56 @@ const excludeNotCreatableFields = (uid2, permissionChecker2) => (body, path = []
|
|
1551
1821
|
}
|
1552
1822
|
}, body);
|
1553
1823
|
};
|
1554
|
-
const
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1824
|
+
const singleLocaleSchema = yup$1.string().nullable();
|
1825
|
+
const multipleLocaleSchema = yup$1.lazy(
|
1826
|
+
(value) => Array.isArray(value) ? yup$1.array().of(singleLocaleSchema.required()) : singleLocaleSchema
|
1827
|
+
);
|
1828
|
+
const statusSchema = yup$1.mixed().oneOf(["draft", "published"], "Invalid status");
|
1829
|
+
const getDocumentLocaleAndStatus = async (request, model, opts = { allowMultipleLocales: false }) => {
|
1830
|
+
const { allowMultipleLocales } = opts;
|
1831
|
+
const { locale, status: providedStatus, ...rest } = request || {};
|
1832
|
+
const defaultStatus = contentTypes$1.hasDraftAndPublish(strapi.getModel(model)) ? void 0 : "published";
|
1833
|
+
const status = providedStatus !== void 0 ? providedStatus : defaultStatus;
|
1834
|
+
const schema = yup$1.object().shape({
|
1835
|
+
locale: allowMultipleLocales ? multipleLocaleSchema : singleLocaleSchema,
|
1836
|
+
status: statusSchema
|
1837
|
+
});
|
1838
|
+
try {
|
1839
|
+
await validateYupSchema(schema, { strict: true, abortEarly: false })(request);
|
1840
|
+
return { locale, status, ...rest };
|
1841
|
+
} catch (error) {
|
1842
|
+
throw new errors.ValidationError(`Validation error: ${error.message}`);
|
1561
1843
|
}
|
1562
|
-
|
1844
|
+
};
|
1845
|
+
const formatDocumentWithMetadata = async (permissionChecker2, uid2, document, opts = {}) => {
|
1846
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1847
|
+
const serviceOutput = await documentMetadata2.formatDocumentWithMetadata(uid2, document, opts);
|
1848
|
+
let {
|
1849
|
+
meta: { availableLocales, availableStatus }
|
1850
|
+
} = serviceOutput;
|
1851
|
+
const metadataSanitizer = permissionChecker2.sanitizeOutput;
|
1852
|
+
availableLocales = await async.map(
|
1853
|
+
availableLocales,
|
1854
|
+
async (localeDocument) => metadataSanitizer(localeDocument)
|
1855
|
+
);
|
1856
|
+
availableStatus = await async.map(
|
1857
|
+
availableStatus,
|
1858
|
+
async (statusDocument) => metadataSanitizer(statusDocument)
|
1859
|
+
);
|
1860
|
+
return {
|
1861
|
+
...serviceOutput,
|
1862
|
+
meta: {
|
1863
|
+
availableLocales,
|
1864
|
+
availableStatus
|
1865
|
+
}
|
1866
|
+
};
|
1563
1867
|
};
|
1564
1868
|
const createDocument = async (ctx, opts) => {
|
1565
1869
|
const { userAbility, user } = ctx.state;
|
1566
1870
|
const { model } = ctx.params;
|
1567
1871
|
const { body } = ctx.request;
|
1568
|
-
const documentManager2 = getService$
|
1569
|
-
const permissionChecker2 = getService$
|
1872
|
+
const documentManager2 = getService$2("document-manager");
|
1873
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1570
1874
|
if (permissionChecker2.cannot.create()) {
|
1571
1875
|
throw new errors.ForbiddenError();
|
1572
1876
|
}
|
@@ -1574,7 +1878,7 @@ const createDocument = async (ctx, opts) => {
|
|
1574
1878
|
const setCreator = setCreatorFields({ user });
|
1575
1879
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1576
1880
|
const sanitizedBody = await sanitizeFn(body);
|
1577
|
-
const { locale, status
|
1881
|
+
const { locale, status } = await getDocumentLocaleAndStatus(body, model);
|
1578
1882
|
return documentManager2.create(model, {
|
1579
1883
|
data: sanitizedBody,
|
1580
1884
|
locale,
|
@@ -1586,14 +1890,14 @@ const updateDocument = async (ctx, opts) => {
|
|
1586
1890
|
const { userAbility, user } = ctx.state;
|
1587
1891
|
const { id, model } = ctx.params;
|
1588
1892
|
const { body } = ctx.request;
|
1589
|
-
const documentManager2 = getService$
|
1590
|
-
const permissionChecker2 = getService$
|
1893
|
+
const documentManager2 = getService$2("document-manager");
|
1894
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1591
1895
|
if (permissionChecker2.cannot.update()) {
|
1592
1896
|
throw new errors.ForbiddenError();
|
1593
1897
|
}
|
1594
1898
|
const permissionQuery = await permissionChecker2.sanitizedQuery.update(ctx.query);
|
1595
|
-
const populate = await getService$
|
1596
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
1899
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
1900
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1597
1901
|
const [documentVersion, documentExists] = await Promise.all([
|
1598
1902
|
documentManager2.findOne(id, model, { populate, locale, status: "draft" }),
|
1599
1903
|
documentManager2.exists(model, id)
|
@@ -1609,7 +1913,7 @@ const updateDocument = async (ctx, opts) => {
|
|
1609
1913
|
throw new errors.ForbiddenError();
|
1610
1914
|
}
|
1611
1915
|
const pickPermittedFields = documentVersion ? permissionChecker2.sanitizeUpdateInput(documentVersion) : permissionChecker2.sanitizeCreateInput;
|
1612
|
-
const setCreator = setCreatorFields({ user, isEdition: true });
|
1916
|
+
const setCreator = documentVersion ? setCreatorFields({ user, isEdition: true }) : setCreatorFields({ user });
|
1613
1917
|
const sanitizeFn = async.pipe(pickPermittedFields, setCreator);
|
1614
1918
|
const sanitizedBody = await sanitizeFn(body);
|
1615
1919
|
return documentManager2.update(documentVersion?.documentId || id, model, {
|
@@ -1623,16 +1927,16 @@ const collectionTypes = {
|
|
1623
1927
|
const { userAbility } = ctx.state;
|
1624
1928
|
const { model } = ctx.params;
|
1625
1929
|
const { query } = ctx.request;
|
1626
|
-
const documentMetadata2 = getService$
|
1627
|
-
const documentManager2 = getService$
|
1628
|
-
const permissionChecker2 = getService$
|
1930
|
+
const documentMetadata2 = getService$2("document-metadata");
|
1931
|
+
const documentManager2 = getService$2("document-manager");
|
1932
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1629
1933
|
if (permissionChecker2.cannot.read()) {
|
1630
1934
|
return ctx.forbidden();
|
1631
1935
|
}
|
1632
1936
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
1633
|
-
const populate = await getService$
|
1634
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
1635
|
-
const { results: documents, pagination } = await documentManager2.findPage(
|
1937
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(1).countRelations({ toOne: false, toMany: true }).build();
|
1938
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
1939
|
+
const { results: documents, pagination: pagination2 } = await documentManager2.findPage(
|
1636
1940
|
{ ...permissionQuery, populate, locale, status },
|
1637
1941
|
model
|
1638
1942
|
);
|
@@ -1653,21 +1957,20 @@ const collectionTypes = {
|
|
1653
1957
|
);
|
1654
1958
|
ctx.body = {
|
1655
1959
|
results,
|
1656
|
-
pagination
|
1960
|
+
pagination: pagination2
|
1657
1961
|
};
|
1658
1962
|
},
|
1659
1963
|
async findOne(ctx) {
|
1660
1964
|
const { userAbility } = ctx.state;
|
1661
1965
|
const { model, id } = ctx.params;
|
1662
|
-
const documentManager2 = getService$
|
1663
|
-
const
|
1664
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
1966
|
+
const documentManager2 = getService$2("document-manager");
|
1967
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1665
1968
|
if (permissionChecker2.cannot.read()) {
|
1666
1969
|
return ctx.forbidden();
|
1667
1970
|
}
|
1668
1971
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1669
|
-
const populate = await getService$
|
1670
|
-
const { locale, status
|
1972
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
1973
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1671
1974
|
const version = await documentManager2.findOne(id, model, {
|
1672
1975
|
populate,
|
1673
1976
|
locale,
|
@@ -1678,9 +1981,11 @@ const collectionTypes = {
|
|
1678
1981
|
if (!exists) {
|
1679
1982
|
return ctx.notFound();
|
1680
1983
|
}
|
1681
|
-
const { meta } = await
|
1984
|
+
const { meta } = await formatDocumentWithMetadata(
|
1985
|
+
permissionChecker2,
|
1682
1986
|
model,
|
1683
|
-
|
1987
|
+
// @ts-expect-error TODO: fix
|
1988
|
+
{ documentId: id, locale, publishedAt: null },
|
1684
1989
|
{ availableLocales: true, availableStatus: false }
|
1685
1990
|
);
|
1686
1991
|
ctx.body = { data: {}, meta };
|
@@ -1690,20 +1995,19 @@ const collectionTypes = {
|
|
1690
1995
|
return ctx.forbidden();
|
1691
1996
|
}
|
1692
1997
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
1693
|
-
ctx.body = await
|
1998
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1694
1999
|
},
|
1695
2000
|
async create(ctx) {
|
1696
2001
|
const { userAbility } = ctx.state;
|
1697
2002
|
const { model } = ctx.params;
|
1698
|
-
const
|
1699
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2003
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1700
2004
|
const [totalEntries, document] = await Promise.all([
|
1701
2005
|
strapi.db.query(model).count(),
|
1702
2006
|
createDocument(ctx)
|
1703
2007
|
]);
|
1704
2008
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
1705
2009
|
ctx.status = 201;
|
1706
|
-
ctx.body = await
|
2010
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1707
2011
|
// Empty metadata as it's not relevant for a new document
|
1708
2012
|
availableLocales: false,
|
1709
2013
|
availableStatus: false
|
@@ -1717,25 +2021,23 @@ const collectionTypes = {
|
|
1717
2021
|
async update(ctx) {
|
1718
2022
|
const { userAbility } = ctx.state;
|
1719
2023
|
const { model } = ctx.params;
|
1720
|
-
const
|
1721
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2024
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1722
2025
|
const updatedVersion = await updateDocument(ctx);
|
1723
2026
|
const sanitizedVersion = await permissionChecker2.sanitizeOutput(updatedVersion);
|
1724
|
-
ctx.body = await
|
2027
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedVersion);
|
1725
2028
|
},
|
1726
2029
|
async clone(ctx) {
|
1727
2030
|
const { userAbility, user } = ctx.state;
|
1728
2031
|
const { model, sourceId: id } = ctx.params;
|
1729
2032
|
const { body } = ctx.request;
|
1730
|
-
const documentManager2 = getService$
|
1731
|
-
const
|
1732
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2033
|
+
const documentManager2 = getService$2("document-manager");
|
2034
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1733
2035
|
if (permissionChecker2.cannot.create()) {
|
1734
2036
|
return ctx.forbidden();
|
1735
2037
|
}
|
1736
2038
|
const permissionQuery = await permissionChecker2.sanitizedQuery.create(ctx.query);
|
1737
|
-
const populate = await getService$
|
1738
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2039
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2040
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1739
2041
|
const document = await documentManager2.findOne(id, model, {
|
1740
2042
|
populate,
|
1741
2043
|
locale,
|
@@ -1751,7 +2053,7 @@ const collectionTypes = {
|
|
1751
2053
|
const sanitizedBody = await sanitizeFn(body);
|
1752
2054
|
const clonedDocument = await documentManager2.clone(document.documentId, sanitizedBody, model);
|
1753
2055
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(clonedDocument);
|
1754
|
-
ctx.body = await
|
2056
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument, {
|
1755
2057
|
// Empty metadata as it's not relevant for a new document
|
1756
2058
|
availableLocales: false,
|
1757
2059
|
availableStatus: false
|
@@ -1773,14 +2075,14 @@ const collectionTypes = {
|
|
1773
2075
|
async delete(ctx) {
|
1774
2076
|
const { userAbility } = ctx.state;
|
1775
2077
|
const { id, model } = ctx.params;
|
1776
|
-
const documentManager2 = getService$
|
1777
|
-
const permissionChecker2 = getService$
|
2078
|
+
const documentManager2 = getService$2("document-manager");
|
2079
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1778
2080
|
if (permissionChecker2.cannot.delete()) {
|
1779
2081
|
return ctx.forbidden();
|
1780
2082
|
}
|
1781
2083
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(ctx.query);
|
1782
|
-
const populate = await getService$
|
1783
|
-
const { locale } = getDocumentLocaleAndStatus(ctx.query);
|
2084
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2085
|
+
const { locale } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1784
2086
|
const documentLocales = await documentManager2.findLocales(id, model, { populate, locale });
|
1785
2087
|
if (documentLocales.length === 0) {
|
1786
2088
|
return ctx.notFound();
|
@@ -1801,44 +2103,75 @@ const collectionTypes = {
|
|
1801
2103
|
const { userAbility } = ctx.state;
|
1802
2104
|
const { id, model } = ctx.params;
|
1803
2105
|
const { body } = ctx.request;
|
1804
|
-
const documentManager2 = getService$
|
1805
|
-
const
|
1806
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2106
|
+
const documentManager2 = getService$2("document-manager");
|
2107
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1807
2108
|
if (permissionChecker2.cannot.publish()) {
|
1808
2109
|
return ctx.forbidden();
|
1809
2110
|
}
|
1810
2111
|
const publishedDocument = await strapi.db.transaction(async () => {
|
1811
2112
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1812
|
-
const populate = await getService$
|
1813
|
-
|
2113
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2114
|
+
let document;
|
2115
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2116
|
+
const isCreate = isNil$1(id);
|
2117
|
+
if (isCreate) {
|
2118
|
+
if (permissionChecker2.cannot.create()) {
|
2119
|
+
throw new errors.ForbiddenError();
|
2120
|
+
}
|
2121
|
+
document = await createDocument(ctx, { populate });
|
2122
|
+
}
|
2123
|
+
const isUpdate = !isCreate;
|
2124
|
+
if (isUpdate) {
|
2125
|
+
const documentExists = documentManager2.exists(model, id);
|
2126
|
+
if (!documentExists) {
|
2127
|
+
throw new errors.NotFoundError("Document not found");
|
2128
|
+
}
|
2129
|
+
document = await documentManager2.findOne(id, model, { populate, locale });
|
2130
|
+
if (!document) {
|
2131
|
+
if (permissionChecker2.cannot.create({ locale }) || permissionChecker2.cannot.publish({ locale })) {
|
2132
|
+
throw new errors.ForbiddenError();
|
2133
|
+
}
|
2134
|
+
document = await updateDocument(ctx);
|
2135
|
+
} else if (permissionChecker2.can.update(document)) {
|
2136
|
+
await updateDocument(ctx);
|
2137
|
+
}
|
2138
|
+
}
|
1814
2139
|
if (permissionChecker2.cannot.publish(document)) {
|
1815
2140
|
throw new errors.ForbiddenError();
|
1816
2141
|
}
|
1817
|
-
const
|
1818
|
-
return documentManager2.publish(document.documentId, model, {
|
2142
|
+
const publishResult = await documentManager2.publish(document.documentId, model, {
|
1819
2143
|
locale
|
1820
2144
|
// TODO: Allow setting creator fields on publish
|
1821
2145
|
// data: setCreatorFields({ user, isEdition: true })({}),
|
1822
2146
|
});
|
2147
|
+
if (!publishResult || publishResult.length === 0) {
|
2148
|
+
throw new errors.NotFoundError("Document not found or already published.");
|
2149
|
+
}
|
2150
|
+
return publishResult[0];
|
1823
2151
|
});
|
1824
2152
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
1825
|
-
ctx.body = await
|
2153
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
1826
2154
|
},
|
1827
2155
|
async bulkPublish(ctx) {
|
1828
2156
|
const { userAbility } = ctx.state;
|
1829
2157
|
const { model } = ctx.params;
|
1830
2158
|
const { body } = ctx.request;
|
1831
|
-
const {
|
2159
|
+
const { documentIds } = body;
|
1832
2160
|
await validateBulkActionInput(body);
|
1833
|
-
const documentManager2 = getService$
|
1834
|
-
const permissionChecker2 = getService$
|
2161
|
+
const documentManager2 = getService$2("document-manager");
|
2162
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1835
2163
|
if (permissionChecker2.cannot.publish()) {
|
1836
2164
|
return ctx.forbidden();
|
1837
2165
|
}
|
1838
2166
|
const permissionQuery = await permissionChecker2.sanitizedQuery.publish(ctx.query);
|
1839
|
-
const populate = await getService$
|
1840
|
-
const
|
1841
|
-
|
2167
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).populateDeep(Infinity).countRelations().build();
|
2168
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2169
|
+
allowMultipleLocales: true
|
2170
|
+
});
|
2171
|
+
const entityPromises = documentIds.map(
|
2172
|
+
(documentId) => documentManager2.findLocales(documentId, model, { populate, locale, isPublished: false })
|
2173
|
+
);
|
2174
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1842
2175
|
for (const entity of entities) {
|
1843
2176
|
if (!entity) {
|
1844
2177
|
return ctx.notFound();
|
@@ -1847,24 +2180,27 @@ const collectionTypes = {
|
|
1847
2180
|
return ctx.forbidden();
|
1848
2181
|
}
|
1849
2182
|
}
|
1850
|
-
const
|
2183
|
+
const count = await documentManager2.publishMany(model, documentIds, locale);
|
1851
2184
|
ctx.body = { count };
|
1852
2185
|
},
|
1853
2186
|
async bulkUnpublish(ctx) {
|
1854
2187
|
const { userAbility } = ctx.state;
|
1855
2188
|
const { model } = ctx.params;
|
1856
2189
|
const { body } = ctx.request;
|
1857
|
-
const {
|
2190
|
+
const { documentIds } = body;
|
1858
2191
|
await validateBulkActionInput(body);
|
1859
|
-
const documentManager2 = getService$
|
1860
|
-
const permissionChecker2 = getService$
|
2192
|
+
const documentManager2 = getService$2("document-manager");
|
2193
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1861
2194
|
if (permissionChecker2.cannot.unpublish()) {
|
1862
2195
|
return ctx.forbidden();
|
1863
2196
|
}
|
1864
|
-
const
|
1865
|
-
|
1866
|
-
|
1867
|
-
const
|
2197
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model, {
|
2198
|
+
allowMultipleLocales: true
|
2199
|
+
});
|
2200
|
+
const entityPromises = documentIds.map(
|
2201
|
+
(documentId) => documentManager2.findLocales(documentId, model, { locale, isPublished: true })
|
2202
|
+
);
|
2203
|
+
const entities = (await Promise.all(entityPromises)).flat();
|
1868
2204
|
for (const entity of entities) {
|
1869
2205
|
if (!entity) {
|
1870
2206
|
return ctx.notFound();
|
@@ -1873,7 +2209,8 @@ const collectionTypes = {
|
|
1873
2209
|
return ctx.forbidden();
|
1874
2210
|
}
|
1875
2211
|
}
|
1876
|
-
const
|
2212
|
+
const entitiesIds = entities.map((document) => document.documentId);
|
2213
|
+
const { count } = await documentManager2.unpublishMany(entitiesIds, model, { locale });
|
1877
2214
|
ctx.body = { count };
|
1878
2215
|
},
|
1879
2216
|
async unpublish(ctx) {
|
@@ -1882,9 +2219,8 @@ const collectionTypes = {
|
|
1882
2219
|
const {
|
1883
2220
|
body: { discardDraft, ...body }
|
1884
2221
|
} = ctx.request;
|
1885
|
-
const documentManager2 = getService$
|
1886
|
-
const
|
1887
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2222
|
+
const documentManager2 = getService$2("document-manager");
|
2223
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1888
2224
|
if (permissionChecker2.cannot.unpublish()) {
|
1889
2225
|
return ctx.forbidden();
|
1890
2226
|
}
|
@@ -1892,8 +2228,8 @@ const collectionTypes = {
|
|
1892
2228
|
return ctx.forbidden();
|
1893
2229
|
}
|
1894
2230
|
const permissionQuery = await permissionChecker2.sanitizedQuery.unpublish(ctx.query);
|
1895
|
-
const populate = await getService$
|
1896
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2231
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2232
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1897
2233
|
const document = await documentManager2.findOne(id, model, {
|
1898
2234
|
populate,
|
1899
2235
|
locale,
|
@@ -1915,7 +2251,7 @@ const collectionTypes = {
|
|
1915
2251
|
ctx.body = await async.pipe(
|
1916
2252
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
1917
2253
|
permissionChecker2.sanitizeOutput,
|
1918
|
-
(document2) =>
|
2254
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1919
2255
|
)(document);
|
1920
2256
|
});
|
1921
2257
|
},
|
@@ -1923,15 +2259,14 @@ const collectionTypes = {
|
|
1923
2259
|
const { userAbility } = ctx.state;
|
1924
2260
|
const { id, model } = ctx.params;
|
1925
2261
|
const { body } = ctx.request;
|
1926
|
-
const documentManager2 = getService$
|
1927
|
-
const
|
1928
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2262
|
+
const documentManager2 = getService$2("document-manager");
|
2263
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1929
2264
|
if (permissionChecker2.cannot.discard()) {
|
1930
2265
|
return ctx.forbidden();
|
1931
2266
|
}
|
1932
2267
|
const permissionQuery = await permissionChecker2.sanitizedQuery.discard(ctx.query);
|
1933
|
-
const populate = await getService$
|
1934
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2268
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2269
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
1935
2270
|
const document = await documentManager2.findOne(id, model, {
|
1936
2271
|
populate,
|
1937
2272
|
locale,
|
@@ -1946,42 +2281,50 @@ const collectionTypes = {
|
|
1946
2281
|
ctx.body = await async.pipe(
|
1947
2282
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
1948
2283
|
permissionChecker2.sanitizeOutput,
|
1949
|
-
(document2) =>
|
2284
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
1950
2285
|
)(document);
|
1951
2286
|
},
|
1952
2287
|
async bulkDelete(ctx) {
|
1953
2288
|
const { userAbility } = ctx.state;
|
1954
2289
|
const { model } = ctx.params;
|
1955
2290
|
const { query, body } = ctx.request;
|
1956
|
-
const {
|
2291
|
+
const { documentIds } = body;
|
1957
2292
|
await validateBulkActionInput(body);
|
1958
|
-
const documentManager2 = getService$
|
1959
|
-
const permissionChecker2 = getService$
|
2293
|
+
const documentManager2 = getService$2("document-manager");
|
2294
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1960
2295
|
if (permissionChecker2.cannot.delete()) {
|
1961
2296
|
return ctx.forbidden();
|
1962
2297
|
}
|
1963
2298
|
const permissionQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
1964
|
-
const
|
1965
|
-
const
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
2299
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2300
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2301
|
+
const documentLocales = await documentManager2.findLocales(documentIds, model, {
|
2302
|
+
populate,
|
2303
|
+
locale
|
2304
|
+
});
|
2305
|
+
if (documentLocales.length === 0) {
|
2306
|
+
return ctx.notFound();
|
2307
|
+
}
|
2308
|
+
for (const document of documentLocales) {
|
2309
|
+
if (permissionChecker2.cannot.delete(document)) {
|
2310
|
+
return ctx.forbidden();
|
1969
2311
|
}
|
1970
|
-
}
|
1971
|
-
const
|
2312
|
+
}
|
2313
|
+
const localeDocumentsIds = documentLocales.map((document) => document.documentId);
|
2314
|
+
const { count } = await documentManager2.deleteMany(localeDocumentsIds, model, { locale });
|
1972
2315
|
ctx.body = { count };
|
1973
2316
|
},
|
1974
2317
|
async countDraftRelations(ctx) {
|
1975
2318
|
const { userAbility } = ctx.state;
|
1976
2319
|
const { model, id } = ctx.params;
|
1977
|
-
const documentManager2 = getService$
|
1978
|
-
const permissionChecker2 = getService$
|
2320
|
+
const documentManager2 = getService$2("document-manager");
|
2321
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
1979
2322
|
if (permissionChecker2.cannot.read()) {
|
1980
2323
|
return ctx.forbidden();
|
1981
2324
|
}
|
1982
2325
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
1983
|
-
const populate = await getService$
|
1984
|
-
const { locale, status
|
2326
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2327
|
+
const { locale, status } = await getDocumentLocaleAndStatus(ctx.query, model);
|
1985
2328
|
const entity = await documentManager2.findOne(id, model, { populate, locale, status });
|
1986
2329
|
if (!entity) {
|
1987
2330
|
return ctx.notFound();
|
@@ -1996,24 +2339,24 @@ const collectionTypes = {
|
|
1996
2339
|
},
|
1997
2340
|
async countManyEntriesDraftRelations(ctx) {
|
1998
2341
|
const { userAbility } = ctx.state;
|
1999
|
-
const ids = ctx.request.query.
|
2342
|
+
const ids = ctx.request.query.documentIds;
|
2000
2343
|
const locale = ctx.request.query.locale;
|
2001
2344
|
const { model } = ctx.params;
|
2002
|
-
const documentManager2 = getService$
|
2003
|
-
const permissionChecker2 = getService$
|
2345
|
+
const documentManager2 = getService$2("document-manager");
|
2346
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2004
2347
|
if (permissionChecker2.cannot.read()) {
|
2005
2348
|
return ctx.forbidden();
|
2006
2349
|
}
|
2007
|
-
const
|
2350
|
+
const documents = await documentManager2.findMany(
|
2008
2351
|
{
|
2009
2352
|
filters: {
|
2010
|
-
|
2353
|
+
documentId: ids
|
2011
2354
|
},
|
2012
2355
|
locale
|
2013
2356
|
},
|
2014
2357
|
model
|
2015
2358
|
);
|
2016
|
-
if (!
|
2359
|
+
if (!documents) {
|
2017
2360
|
return ctx.notFound();
|
2018
2361
|
}
|
2019
2362
|
const number = await documentManager2.countManyEntriesDraftRelations(ids, model, locale);
|
@@ -2024,13 +2367,13 @@ const collectionTypes = {
|
|
2024
2367
|
};
|
2025
2368
|
const components$1 = {
|
2026
2369
|
findComponents(ctx) {
|
2027
|
-
const components2 = getService$
|
2028
|
-
const { toDto } = getService$
|
2370
|
+
const components2 = getService$2("components").findAllComponents();
|
2371
|
+
const { toDto } = getService$2("data-mapper");
|
2029
2372
|
ctx.body = { data: components2.map(toDto) };
|
2030
2373
|
},
|
2031
2374
|
async findComponentConfiguration(ctx) {
|
2032
2375
|
const { uid: uid2 } = ctx.params;
|
2033
|
-
const componentService = getService$
|
2376
|
+
const componentService = getService$2("components");
|
2034
2377
|
const component = componentService.findComponent(uid2);
|
2035
2378
|
if (!component) {
|
2036
2379
|
return ctx.notFound("component.notFound");
|
@@ -2047,7 +2390,7 @@ const components$1 = {
|
|
2047
2390
|
async updateComponentConfiguration(ctx) {
|
2048
2391
|
const { uid: uid2 } = ctx.params;
|
2049
2392
|
const { body } = ctx.request;
|
2050
|
-
const componentService = getService$
|
2393
|
+
const componentService = getService$2("components");
|
2051
2394
|
const component = componentService.findComponent(uid2);
|
2052
2395
|
if (!component) {
|
2053
2396
|
return ctx.notFound("component.notFound");
|
@@ -2081,12 +2424,12 @@ const contentTypes = {
|
|
2081
2424
|
} catch (error) {
|
2082
2425
|
return ctx.send({ error }, 400);
|
2083
2426
|
}
|
2084
|
-
const contentTypes2 = getService$
|
2085
|
-
const { toDto } = getService$
|
2427
|
+
const contentTypes2 = getService$2("content-types").findContentTypesByKind(kind);
|
2428
|
+
const { toDto } = getService$2("data-mapper");
|
2086
2429
|
ctx.body = { data: contentTypes2.map(toDto) };
|
2087
2430
|
},
|
2088
2431
|
async findContentTypesSettings(ctx) {
|
2089
|
-
const { findAllContentTypes, findConfiguration } = getService$
|
2432
|
+
const { findAllContentTypes, findConfiguration } = getService$2("content-types");
|
2090
2433
|
const contentTypes2 = await findAllContentTypes();
|
2091
2434
|
const configurations = await Promise.all(
|
2092
2435
|
contentTypes2.map(async (contentType) => {
|
@@ -2100,7 +2443,7 @@ const contentTypes = {
|
|
2100
2443
|
},
|
2101
2444
|
async findContentTypeConfiguration(ctx) {
|
2102
2445
|
const { uid: uid2 } = ctx.params;
|
2103
|
-
const contentTypeService = getService$
|
2446
|
+
const contentTypeService = getService$2("content-types");
|
2104
2447
|
const contentType = await contentTypeService.findContentType(uid2);
|
2105
2448
|
if (!contentType) {
|
2106
2449
|
return ctx.notFound("contentType.notFound");
|
@@ -2122,13 +2465,13 @@ const contentTypes = {
|
|
2122
2465
|
const { userAbility } = ctx.state;
|
2123
2466
|
const { uid: uid2 } = ctx.params;
|
2124
2467
|
const { body } = ctx.request;
|
2125
|
-
const contentTypeService = getService$
|
2126
|
-
const metricsService = getService$
|
2468
|
+
const contentTypeService = getService$2("content-types");
|
2469
|
+
const metricsService = getService$2("metrics");
|
2127
2470
|
const contentType = await contentTypeService.findContentType(uid2);
|
2128
2471
|
if (!contentType) {
|
2129
2472
|
return ctx.notFound("contentType.notFound");
|
2130
2473
|
}
|
2131
|
-
if (!getService$
|
2474
|
+
if (!getService$2("permission").canConfigureContentType({ userAbility, contentType })) {
|
2132
2475
|
return ctx.forbidden();
|
2133
2476
|
}
|
2134
2477
|
let input;
|
@@ -2161,10 +2504,10 @@ const contentTypes = {
|
|
2161
2504
|
};
|
2162
2505
|
const init = {
|
2163
2506
|
getInitData(ctx) {
|
2164
|
-
const { toDto } = getService$
|
2165
|
-
const { findAllComponents } = getService$
|
2166
|
-
const { getAllFieldSizes } = getService$
|
2167
|
-
const { findAllContentTypes } = getService$
|
2507
|
+
const { toDto } = getService$2("data-mapper");
|
2508
|
+
const { findAllComponents } = getService$2("components");
|
2509
|
+
const { getAllFieldSizes } = getService$2("field-sizes");
|
2510
|
+
const { findAllContentTypes } = getService$2("content-types");
|
2168
2511
|
ctx.body = {
|
2169
2512
|
data: {
|
2170
2513
|
fieldSizes: getAllFieldSizes(),
|
@@ -2200,36 +2543,41 @@ const addFiltersClause = (params, filtersClause) => {
|
|
2200
2543
|
params.filters.$and.push(filtersClause);
|
2201
2544
|
};
|
2202
2545
|
const sanitizeMainField = (model, mainField, userAbility) => {
|
2203
|
-
const permissionChecker2 = getService$
|
2546
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2204
2547
|
userAbility,
|
2205
2548
|
model: model.uid
|
2206
2549
|
});
|
2207
|
-
|
2550
|
+
const isMainFieldListable = isListable(model, mainField);
|
2551
|
+
const canReadMainField = permissionChecker2.can.read(null, mainField);
|
2552
|
+
if (!isMainFieldListable || !canReadMainField) {
|
2208
2553
|
return "id";
|
2209
2554
|
}
|
2210
|
-
if (
|
2211
|
-
|
2212
|
-
const userPermissionChecker = getService$1("permission-checker").create({
|
2213
|
-
userAbility,
|
2214
|
-
model: "plugin::users-permissions.user"
|
2215
|
-
});
|
2216
|
-
if (userPermissionChecker.can.read()) {
|
2217
|
-
return "name";
|
2218
|
-
}
|
2219
|
-
}
|
2220
|
-
return "id";
|
2555
|
+
if (model.uid === "plugin::users-permissions.role") {
|
2556
|
+
return "name";
|
2221
2557
|
}
|
2222
2558
|
return mainField;
|
2223
2559
|
};
|
2224
|
-
const addStatusToRelations = async (
|
2225
|
-
if (!contentTypes$1.hasDraftAndPublish(strapi.
|
2560
|
+
const addStatusToRelations = async (targetUid, relations2) => {
|
2561
|
+
if (!contentTypes$1.hasDraftAndPublish(strapi.getModel(targetUid))) {
|
2226
2562
|
return relations2;
|
2227
2563
|
}
|
2228
|
-
const documentMetadata2 = getService$
|
2229
|
-
|
2564
|
+
const documentMetadata2 = getService$2("document-metadata");
|
2565
|
+
if (!relations2.length) {
|
2566
|
+
return relations2;
|
2567
|
+
}
|
2568
|
+
const firstRelation = relations2[0];
|
2569
|
+
const filters = {
|
2570
|
+
documentId: { $in: relations2.map((r) => r.documentId) },
|
2571
|
+
// NOTE: find the "opposite" status
|
2572
|
+
publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true }
|
2573
|
+
};
|
2574
|
+
const availableStatus = await strapi.query(targetUid).findMany({
|
2575
|
+
select: ["id", "documentId", "locale", "updatedAt", "createdAt", "publishedAt"],
|
2576
|
+
filters
|
2577
|
+
});
|
2230
2578
|
return relations2.map((relation) => {
|
2231
|
-
const availableStatuses =
|
2232
|
-
(availableDocument) => availableDocument.documentId === relation.documentId
|
2579
|
+
const availableStatuses = availableStatus.filter(
|
2580
|
+
(availableDocument) => availableDocument.documentId === relation.documentId && (relation.locale ? availableDocument.locale === relation.locale : true)
|
2233
2581
|
);
|
2234
2582
|
return {
|
2235
2583
|
...relation,
|
@@ -2250,11 +2598,8 @@ const validateLocale = (sourceUid, targetUid, locale) => {
|
|
2250
2598
|
const isLocalized = strapi.plugin("i18n").service("content-types").isLocalizedContentType;
|
2251
2599
|
const isSourceLocalized = isLocalized(sourceModel);
|
2252
2600
|
const isTargetLocalized = isLocalized(targetModel);
|
2253
|
-
let validatedLocale = locale;
|
2254
|
-
if (!targetModel || !isTargetLocalized)
|
2255
|
-
validatedLocale = void 0;
|
2256
2601
|
return {
|
2257
|
-
locale
|
2602
|
+
locale,
|
2258
2603
|
isSourceLocalized,
|
2259
2604
|
isTargetLocalized
|
2260
2605
|
};
|
@@ -2294,7 +2639,7 @@ const relations = {
|
|
2294
2639
|
ctx.request?.query?.locale
|
2295
2640
|
);
|
2296
2641
|
const { status } = validateStatus(sourceUid, ctx.request?.query?.status);
|
2297
|
-
const permissionChecker2 = getService$
|
2642
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2298
2643
|
userAbility,
|
2299
2644
|
model
|
2300
2645
|
});
|
@@ -2319,7 +2664,7 @@ const relations = {
|
|
2319
2664
|
where.id = id;
|
2320
2665
|
}
|
2321
2666
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(ctx.query);
|
2322
|
-
const populate = await getService$
|
2667
|
+
const populate = await getService$2("populate-builder")(model).populateFromQuery(permissionQuery).build();
|
2323
2668
|
const currentEntity = await strapi.db.query(model).findOne({
|
2324
2669
|
where,
|
2325
2670
|
populate
|
@@ -2334,7 +2679,7 @@ const relations = {
|
|
2334
2679
|
}
|
2335
2680
|
entryId = currentEntity.id;
|
2336
2681
|
}
|
2337
|
-
const modelConfig = isComponent2 ? await getService$
|
2682
|
+
const modelConfig = isComponent2 ? await getService$2("components").findConfiguration(sourceSchema) : await getService$2("content-types").findConfiguration(sourceSchema);
|
2338
2683
|
const targetSchema = strapi.getModel(targetUid);
|
2339
2684
|
const mainField = flow(
|
2340
2685
|
prop(`metadatas.${targetField}.edit.mainField`),
|
@@ -2357,7 +2702,7 @@ const relations = {
|
|
2357
2702
|
attribute,
|
2358
2703
|
fieldsToSelect,
|
2359
2704
|
mainField,
|
2360
|
-
source: { schema: sourceSchema },
|
2705
|
+
source: { schema: sourceSchema, isLocalized: isSourceLocalized },
|
2361
2706
|
target: { schema: targetSchema, isLocalized: isTargetLocalized },
|
2362
2707
|
sourceSchema,
|
2363
2708
|
targetSchema,
|
@@ -2379,7 +2724,8 @@ const relations = {
|
|
2379
2724
|
fieldsToSelect,
|
2380
2725
|
mainField,
|
2381
2726
|
source: {
|
2382
|
-
schema: { uid: sourceUid, modelType: sourceModelType }
|
2727
|
+
schema: { uid: sourceUid, modelType: sourceModelType },
|
2728
|
+
isLocalized: isSourceLocalized
|
2383
2729
|
},
|
2384
2730
|
target: {
|
2385
2731
|
schema: { uid: targetUid },
|
@@ -2387,7 +2733,7 @@ const relations = {
|
|
2387
2733
|
}
|
2388
2734
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2389
2735
|
const { idsToOmit, idsToInclude, _q, ...query } = ctx.request.query;
|
2390
|
-
const permissionChecker2 = getService$
|
2736
|
+
const permissionChecker2 = getService$2("permission-checker").create({
|
2391
2737
|
userAbility: ctx.state.userAbility,
|
2392
2738
|
model: targetUid
|
2393
2739
|
});
|
@@ -2417,12 +2763,16 @@ const relations = {
|
|
2417
2763
|
} else {
|
2418
2764
|
where.id = id;
|
2419
2765
|
}
|
2420
|
-
|
2421
|
-
|
2766
|
+
const publishedAt = getPublishedAtClause(status, targetUid);
|
2767
|
+
if (!isEmpty(publishedAt)) {
|
2768
|
+
where[`${alias}.published_at`] = publishedAt;
|
2422
2769
|
}
|
2423
|
-
if (
|
2770
|
+
if (isTargetLocalized && locale) {
|
2424
2771
|
where[`${alias}.locale`] = locale;
|
2425
2772
|
}
|
2773
|
+
if (isSourceLocalized && locale) {
|
2774
|
+
where.locale = locale;
|
2775
|
+
}
|
2426
2776
|
if ((idsToInclude?.length ?? 0) !== 0) {
|
2427
2777
|
where[`${alias}.id`].$notIn = idsToInclude;
|
2428
2778
|
}
|
@@ -2440,7 +2790,8 @@ const relations = {
|
|
2440
2790
|
id: { $notIn: uniq(idsToOmit) }
|
2441
2791
|
});
|
2442
2792
|
}
|
2443
|
-
const
|
2793
|
+
const dbQuery = strapi.get("query-params").transform(targetUid, queryParams);
|
2794
|
+
const res = await strapi.db.query(targetUid).findPage(dbQuery);
|
2444
2795
|
ctx.body = {
|
2445
2796
|
...res,
|
2446
2797
|
results: await addStatusToRelations(targetUid, res.results)
|
@@ -2455,29 +2806,39 @@ const relations = {
|
|
2455
2806
|
attribute,
|
2456
2807
|
targetField,
|
2457
2808
|
fieldsToSelect,
|
2458
|
-
|
2459
|
-
|
2460
|
-
}
|
2461
|
-
target: {
|
2462
|
-
schema: { uid: targetUid }
|
2463
|
-
}
|
2809
|
+
status,
|
2810
|
+
source: { schema: sourceSchema },
|
2811
|
+
target: { schema: targetSchema }
|
2464
2812
|
} = await this.extractAndValidateRequestInfo(ctx, id);
|
2465
|
-
const
|
2813
|
+
const { uid: sourceUid } = sourceSchema;
|
2814
|
+
const { uid: targetUid } = targetSchema;
|
2815
|
+
const permissionQuery = await getService$2("permission-checker").create({ userAbility, model: targetUid }).sanitizedQuery.read({ fields: fieldsToSelect });
|
2466
2816
|
const dbQuery = strapi.db.query(sourceUid);
|
2467
2817
|
const loadRelations = relations$1.isAnyToMany(attribute) ? (...args) => dbQuery.loadPages(...args) : (...args) => dbQuery.load(...args).then((res2) => ({ results: res2 ? [res2] : [] }));
|
2818
|
+
const filters = {};
|
2819
|
+
if (sourceSchema?.options?.draftAndPublish) {
|
2820
|
+
if (targetSchema?.options?.draftAndPublish) {
|
2821
|
+
if (status === "published") {
|
2822
|
+
filters.publishedAt = { $notNull: true };
|
2823
|
+
} else {
|
2824
|
+
filters.publishedAt = { $null: true };
|
2825
|
+
}
|
2826
|
+
}
|
2827
|
+
} else if (targetSchema?.options?.draftAndPublish) {
|
2828
|
+
filters.publishedAt = { $null: true };
|
2829
|
+
}
|
2468
2830
|
const res = await loadRelations({ id: entryId }, targetField, {
|
2469
|
-
select: ["id", "documentId", "locale", "publishedAt"],
|
2831
|
+
select: ["id", "documentId", "locale", "publishedAt", "updatedAt"],
|
2470
2832
|
ordering: "desc",
|
2471
2833
|
page: ctx.request.query.page,
|
2472
|
-
pageSize: ctx.request.query.pageSize
|
2834
|
+
pageSize: ctx.request.query.pageSize,
|
2835
|
+
filters
|
2473
2836
|
});
|
2474
2837
|
const loadedIds = res.results.map((item) => item.id);
|
2475
2838
|
addFiltersClause(permissionQuery, { id: { $in: loadedIds } });
|
2476
2839
|
const sanitizedRes = await loadRelations({ id: entryId }, targetField, {
|
2477
2840
|
...strapi.get("query-params").transform(targetUid, permissionQuery),
|
2478
|
-
ordering: "desc"
|
2479
|
-
page: ctx.request.query.page,
|
2480
|
-
pageSize: ctx.request.query.pageSize
|
2841
|
+
ordering: "desc"
|
2481
2842
|
});
|
2482
2843
|
const relationsUnion = uniqBy("id", concat(sanitizedRes.results, res.results));
|
2483
2844
|
ctx.body = {
|
@@ -2492,10 +2853,10 @@ const relations = {
|
|
2492
2853
|
}
|
2493
2854
|
};
|
2494
2855
|
const buildPopulateFromQuery = async (query, model) => {
|
2495
|
-
return getService$
|
2856
|
+
return getService$2("populate-builder")(model).populateFromQuery(query).populateDeep(Infinity).countRelations().build();
|
2496
2857
|
};
|
2497
2858
|
const findDocument = async (query, uid2, opts = {}) => {
|
2498
|
-
const documentManager2 = getService$
|
2859
|
+
const documentManager2 = getService$2("document-manager");
|
2499
2860
|
const populate = await buildPopulateFromQuery(query, uid2);
|
2500
2861
|
return documentManager2.findMany({ ...opts, populate }, uid2).then((documents) => documents[0]);
|
2501
2862
|
};
|
@@ -2503,13 +2864,13 @@ const createOrUpdateDocument = async (ctx, opts) => {
|
|
2503
2864
|
const { user, userAbility } = ctx.state;
|
2504
2865
|
const { model } = ctx.params;
|
2505
2866
|
const { body, query } = ctx.request;
|
2506
|
-
const documentManager2 = getService$
|
2507
|
-
const permissionChecker2 = getService$
|
2867
|
+
const documentManager2 = getService$2("document-manager");
|
2868
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2508
2869
|
if (permissionChecker2.cannot.create() && permissionChecker2.cannot.update()) {
|
2509
2870
|
throw new errors.ForbiddenError();
|
2510
2871
|
}
|
2511
2872
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.update(query);
|
2512
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
2873
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2513
2874
|
const [documentVersion, otherDocumentVersion] = await Promise.all([
|
2514
2875
|
findDocument(sanitizedQuery, model, { locale, status: "draft" }),
|
2515
2876
|
// Find the first document to check if it exists
|
@@ -2545,13 +2906,12 @@ const singleTypes = {
|
|
2545
2906
|
const { userAbility } = ctx.state;
|
2546
2907
|
const { model } = ctx.params;
|
2547
2908
|
const { query = {} } = ctx.request;
|
2548
|
-
const permissionChecker2 = getService$
|
2549
|
-
const documentMetadata2 = getService$1("document-metadata");
|
2909
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2550
2910
|
if (permissionChecker2.cannot.read()) {
|
2551
2911
|
return ctx.forbidden();
|
2552
2912
|
}
|
2553
2913
|
const permissionQuery = await permissionChecker2.sanitizedQuery.read(query);
|
2554
|
-
const { locale, status } = getDocumentLocaleAndStatus(query);
|
2914
|
+
const { locale, status } = await getDocumentLocaleAndStatus(query, model);
|
2555
2915
|
const version = await findDocument(permissionQuery, model, { locale, status });
|
2556
2916
|
if (!version) {
|
2557
2917
|
if (permissionChecker2.cannot.create()) {
|
@@ -2561,9 +2921,11 @@ const singleTypes = {
|
|
2561
2921
|
if (!document) {
|
2562
2922
|
return ctx.notFound();
|
2563
2923
|
}
|
2564
|
-
const { meta } = await
|
2924
|
+
const { meta } = await formatDocumentWithMetadata(
|
2925
|
+
permissionChecker2,
|
2565
2926
|
model,
|
2566
|
-
|
2927
|
+
// @ts-expect-error - fix types
|
2928
|
+
{ documentId: document.documentId, locale, publishedAt: null },
|
2567
2929
|
{ availableLocales: true, availableStatus: false }
|
2568
2930
|
);
|
2569
2931
|
ctx.body = { data: {}, meta };
|
@@ -2573,29 +2935,28 @@ const singleTypes = {
|
|
2573
2935
|
return ctx.forbidden();
|
2574
2936
|
}
|
2575
2937
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(version);
|
2576
|
-
ctx.body = await
|
2938
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2577
2939
|
},
|
2578
2940
|
async createOrUpdate(ctx) {
|
2579
2941
|
const { userAbility } = ctx.state;
|
2580
2942
|
const { model } = ctx.params;
|
2581
|
-
const
|
2582
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2943
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2583
2944
|
const document = await createOrUpdateDocument(ctx);
|
2584
2945
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(document);
|
2585
|
-
ctx.body = await
|
2946
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2586
2947
|
},
|
2587
2948
|
async delete(ctx) {
|
2588
2949
|
const { userAbility } = ctx.state;
|
2589
2950
|
const { model } = ctx.params;
|
2590
2951
|
const { query = {} } = ctx.request;
|
2591
|
-
const documentManager2 = getService$
|
2592
|
-
const permissionChecker2 = getService$
|
2952
|
+
const documentManager2 = getService$2("document-manager");
|
2953
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2593
2954
|
if (permissionChecker2.cannot.delete()) {
|
2594
2955
|
return ctx.forbidden();
|
2595
2956
|
}
|
2596
2957
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.delete(query);
|
2597
2958
|
const populate = await buildPopulateFromQuery(sanitizedQuery, model);
|
2598
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
2959
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2599
2960
|
const documentLocales = await documentManager2.findLocales(void 0, model, {
|
2600
2961
|
populate,
|
2601
2962
|
locale
|
@@ -2617,9 +2978,8 @@ const singleTypes = {
|
|
2617
2978
|
const { userAbility } = ctx.state;
|
2618
2979
|
const { model } = ctx.params;
|
2619
2980
|
const { query = {} } = ctx.request;
|
2620
|
-
const documentManager2 = getService$
|
2621
|
-
const
|
2622
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
2981
|
+
const documentManager2 = getService$2("document-manager");
|
2982
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2623
2983
|
if (permissionChecker2.cannot.publish()) {
|
2624
2984
|
return ctx.forbidden();
|
2625
2985
|
}
|
@@ -2633,11 +2993,12 @@ const singleTypes = {
|
|
2633
2993
|
if (permissionChecker2.cannot.publish(document)) {
|
2634
2994
|
throw new errors.ForbiddenError();
|
2635
2995
|
}
|
2636
|
-
const { locale } = getDocumentLocaleAndStatus(document);
|
2637
|
-
|
2996
|
+
const { locale } = await getDocumentLocaleAndStatus(document, model);
|
2997
|
+
const publishResult = await documentManager2.publish(document.documentId, model, { locale });
|
2998
|
+
return publishResult.at(0);
|
2638
2999
|
});
|
2639
3000
|
const sanitizedDocument = await permissionChecker2.sanitizeOutput(publishedDocument);
|
2640
|
-
ctx.body = await
|
3001
|
+
ctx.body = await formatDocumentWithMetadata(permissionChecker2, model, sanitizedDocument);
|
2641
3002
|
},
|
2642
3003
|
async unpublish(ctx) {
|
2643
3004
|
const { userAbility } = ctx.state;
|
@@ -2646,9 +3007,8 @@ const singleTypes = {
|
|
2646
3007
|
body: { discardDraft, ...body },
|
2647
3008
|
query = {}
|
2648
3009
|
} = ctx.request;
|
2649
|
-
const documentManager2 = getService$
|
2650
|
-
const
|
2651
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
3010
|
+
const documentManager2 = getService$2("document-manager");
|
3011
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2652
3012
|
if (permissionChecker2.cannot.unpublish()) {
|
2653
3013
|
return ctx.forbidden();
|
2654
3014
|
}
|
@@ -2656,7 +3016,7 @@ const singleTypes = {
|
|
2656
3016
|
return ctx.forbidden();
|
2657
3017
|
}
|
2658
3018
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.unpublish(query);
|
2659
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
3019
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2660
3020
|
const document = await findDocument(sanitizedQuery, model, { locale });
|
2661
3021
|
if (!document) {
|
2662
3022
|
return ctx.notFound();
|
@@ -2674,7 +3034,7 @@ const singleTypes = {
|
|
2674
3034
|
ctx.body = await async.pipe(
|
2675
3035
|
(document2) => documentManager2.unpublish(document2.documentId, model, { locale }),
|
2676
3036
|
permissionChecker2.sanitizeOutput,
|
2677
|
-
(document2) =>
|
3037
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2678
3038
|
)(document);
|
2679
3039
|
});
|
2680
3040
|
},
|
@@ -2682,14 +3042,13 @@ const singleTypes = {
|
|
2682
3042
|
const { userAbility } = ctx.state;
|
2683
3043
|
const { model } = ctx.params;
|
2684
3044
|
const { body, query = {} } = ctx.request;
|
2685
|
-
const documentManager2 = getService$
|
2686
|
-
const
|
2687
|
-
const permissionChecker2 = getService$1("permission-checker").create({ userAbility, model });
|
3045
|
+
const documentManager2 = getService$2("document-manager");
|
3046
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
2688
3047
|
if (permissionChecker2.cannot.discard()) {
|
2689
3048
|
return ctx.forbidden();
|
2690
3049
|
}
|
2691
3050
|
const sanitizedQuery = await permissionChecker2.sanitizedQuery.discard(query);
|
2692
|
-
const { locale } = getDocumentLocaleAndStatus(body);
|
3051
|
+
const { locale } = await getDocumentLocaleAndStatus(body, model);
|
2693
3052
|
const document = await findDocument(sanitizedQuery, model, { locale, status: "published" });
|
2694
3053
|
if (!document) {
|
2695
3054
|
return ctx.notFound();
|
@@ -2700,16 +3059,16 @@ const singleTypes = {
|
|
2700
3059
|
ctx.body = await async.pipe(
|
2701
3060
|
(document2) => documentManager2.discardDraft(document2.documentId, model, { locale }),
|
2702
3061
|
permissionChecker2.sanitizeOutput,
|
2703
|
-
(document2) =>
|
3062
|
+
(document2) => formatDocumentWithMetadata(permissionChecker2, model, document2)
|
2704
3063
|
)(document);
|
2705
3064
|
},
|
2706
3065
|
async countDraftRelations(ctx) {
|
2707
3066
|
const { userAbility } = ctx.state;
|
2708
3067
|
const { model } = ctx.params;
|
2709
3068
|
const { query } = ctx.request;
|
2710
|
-
const documentManager2 = getService$
|
2711
|
-
const permissionChecker2 = getService$
|
2712
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3069
|
+
const documentManager2 = getService$2("document-manager");
|
3070
|
+
const permissionChecker2 = getService$2("permission-checker").create({ userAbility, model });
|
3071
|
+
const { locale } = await getDocumentLocaleAndStatus(query, model);
|
2713
3072
|
if (permissionChecker2.cannot.read()) {
|
2714
3073
|
return ctx.forbidden();
|
2715
3074
|
}
|
@@ -2730,9 +3089,9 @@ const uid$1 = {
|
|
2730
3089
|
async generateUID(ctx) {
|
2731
3090
|
const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body);
|
2732
3091
|
const { query = {} } = ctx.request;
|
2733
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3092
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2734
3093
|
await validateUIDField(contentTypeUID, field);
|
2735
|
-
const uidService = getService$
|
3094
|
+
const uidService = getService$2("uid");
|
2736
3095
|
ctx.body = {
|
2737
3096
|
data: await uidService.generateUIDField({ contentTypeUID, field, data, locale })
|
2738
3097
|
};
|
@@ -2742,9 +3101,9 @@ const uid$1 = {
|
|
2742
3101
|
ctx.request.body
|
2743
3102
|
);
|
2744
3103
|
const { query = {} } = ctx.request;
|
2745
|
-
const { locale } = getDocumentLocaleAndStatus(query);
|
3104
|
+
const { locale } = await getDocumentLocaleAndStatus(query, contentTypeUID);
|
2746
3105
|
await validateUIDField(contentTypeUID, field);
|
2747
|
-
const uidService = getService$
|
3106
|
+
const uidService = getService$2("uid");
|
2748
3107
|
const isAvailable = await uidService.checkUIDAvailability({
|
2749
3108
|
contentTypeUID,
|
2750
3109
|
field,
|
@@ -2765,7 +3124,8 @@ const controllers = {
|
|
2765
3124
|
relations,
|
2766
3125
|
"single-types": singleTypes,
|
2767
3126
|
uid: uid$1,
|
2768
|
-
...history.controllers ? history.controllers : {}
|
3127
|
+
...history.controllers ? history.controllers : {},
|
3128
|
+
...preview.controllers ? preview.controllers : {}
|
2769
3129
|
};
|
2770
3130
|
const keys = {
|
2771
3131
|
CONFIGURATION: "configuration"
|
@@ -2916,12 +3276,12 @@ async function syncMetadatas(configuration, schema) {
|
|
2916
3276
|
return _.assign(metasWithDefaults, updatedMetas);
|
2917
3277
|
}
|
2918
3278
|
const getTargetSchema = (targetModel) => {
|
2919
|
-
return getService$
|
3279
|
+
return getService$2("content-types").findContentType(targetModel);
|
2920
3280
|
};
|
2921
3281
|
const DEFAULT_LIST_LENGTH = 4;
|
2922
3282
|
const MAX_ROW_SIZE = 12;
|
2923
3283
|
const isAllowedFieldSize = (type, size) => {
|
2924
|
-
const { getFieldSize } = getService$
|
3284
|
+
const { getFieldSize } = getService$2("field-sizes");
|
2925
3285
|
const fieldSize = getFieldSize(type);
|
2926
3286
|
if (!fieldSize.isResizable && size !== fieldSize.default) {
|
2927
3287
|
return false;
|
@@ -2929,7 +3289,7 @@ const isAllowedFieldSize = (type, size) => {
|
|
2929
3289
|
return size <= MAX_ROW_SIZE;
|
2930
3290
|
};
|
2931
3291
|
const getDefaultFieldSize = (attribute) => {
|
2932
|
-
const { hasFieldSize, getFieldSize } = getService$
|
3292
|
+
const { hasFieldSize, getFieldSize } = getService$2("field-sizes");
|
2933
3293
|
return getFieldSize(hasFieldSize(attribute.customField) ? attribute.customField : attribute.type).default;
|
2934
3294
|
};
|
2935
3295
|
async function createDefaultLayouts(schema) {
|
@@ -2964,7 +3324,7 @@ function syncLayouts(configuration, schema) {
|
|
2964
3324
|
for (const el of row) {
|
2965
3325
|
if (!hasEditableAttribute(schema, el.name))
|
2966
3326
|
continue;
|
2967
|
-
const { hasFieldSize } = getService$
|
3327
|
+
const { hasFieldSize } = getService$2("field-sizes");
|
2968
3328
|
const fieldType = hasFieldSize(schema.attributes[el.name].customField) ? schema.attributes[el.name].customField : schema.attributes[el.name].type;
|
2969
3329
|
if (!isAllowedFieldSize(fieldType, el.size)) {
|
2970
3330
|
elementsToReAppend.push(el.name);
|
@@ -3104,17 +3464,17 @@ const configurationService$1 = createConfigurationService({
|
|
3104
3464
|
isComponent: true,
|
3105
3465
|
prefix: STORE_KEY_PREFIX,
|
3106
3466
|
getModels() {
|
3107
|
-
const { toContentManagerModel } = getService$
|
3467
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3108
3468
|
return mapValues(toContentManagerModel, strapi.components);
|
3109
3469
|
}
|
3110
3470
|
});
|
3111
3471
|
const components = ({ strapi: strapi2 }) => ({
|
3112
3472
|
findAllComponents() {
|
3113
|
-
const { toContentManagerModel } = getService$
|
3473
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3114
3474
|
return Object.values(strapi2.components).map(toContentManagerModel);
|
3115
3475
|
},
|
3116
3476
|
findComponent(uid2) {
|
3117
|
-
const { toContentManagerModel } = getService$
|
3477
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3118
3478
|
const component = strapi2.components[uid2];
|
3119
3479
|
return isNil$1(component) ? component : toContentManagerModel(component);
|
3120
3480
|
},
|
@@ -3165,17 +3525,17 @@ const configurationService = createConfigurationService({
|
|
3165
3525
|
storeUtils,
|
3166
3526
|
prefix: "content_types",
|
3167
3527
|
getModels() {
|
3168
|
-
const { toContentManagerModel } = getService$
|
3528
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3169
3529
|
return mapValues(toContentManagerModel, strapi.contentTypes);
|
3170
3530
|
}
|
3171
3531
|
});
|
3172
3532
|
const service = ({ strapi: strapi2 }) => ({
|
3173
3533
|
findAllContentTypes() {
|
3174
|
-
const { toContentManagerModel } = getService$
|
3534
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3175
3535
|
return Object.values(strapi2.contentTypes).map(toContentManagerModel);
|
3176
3536
|
},
|
3177
3537
|
findContentType(uid2) {
|
3178
|
-
const { toContentManagerModel } = getService$
|
3538
|
+
const { toContentManagerModel } = getService$2("data-mapper");
|
3179
3539
|
const contentType = strapi2.contentTypes[uid2];
|
3180
3540
|
return isNil$1(contentType) ? contentType : toContentManagerModel(contentType);
|
3181
3541
|
},
|
@@ -3204,7 +3564,7 @@ const service = ({ strapi: strapi2 }) => ({
|
|
3204
3564
|
return this.findConfiguration(contentType);
|
3205
3565
|
},
|
3206
3566
|
findComponentsConfigurations(contentType) {
|
3207
|
-
return getService$
|
3567
|
+
return getService$2("components").findComponentsConfigurations(contentType);
|
3208
3568
|
},
|
3209
3569
|
syncConfigurations() {
|
3210
3570
|
return configurationService.syncConfigurations();
|
@@ -3385,12 +3745,27 @@ const createPermissionChecker = (strapi2) => ({ userAbility, model }) => {
|
|
3385
3745
|
ability: userAbility,
|
3386
3746
|
model
|
3387
3747
|
});
|
3388
|
-
const
|
3748
|
+
const { actionProvider } = strapi2.service("admin::permission");
|
3749
|
+
const toSubject = (entity) => {
|
3750
|
+
return entity ? permissionsManager.toSubject(entity, model) : model;
|
3751
|
+
};
|
3389
3752
|
const can = (action, entity, field) => {
|
3390
|
-
|
3753
|
+
const subject = toSubject(entity);
|
3754
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3755
|
+
return (
|
3756
|
+
// Test the original action to see if it passes
|
3757
|
+
userAbility.can(action, subject, field) || // Else try every known alias if at least one of them succeed, then the user "can"
|
3758
|
+
aliases.some((alias) => userAbility.can(alias, subject, field))
|
3759
|
+
);
|
3391
3760
|
};
|
3392
3761
|
const cannot = (action, entity, field) => {
|
3393
|
-
|
3762
|
+
const subject = toSubject(entity);
|
3763
|
+
const aliases = actionProvider.unstable_aliases(action, model);
|
3764
|
+
return (
|
3765
|
+
// Test both the original action
|
3766
|
+
userAbility.cannot(action, subject, field) && // and every known alias, if all of them fail (cannot), then the user truly "cannot"
|
3767
|
+
aliases.every((alias) => userAbility.cannot(alias, subject, field))
|
3768
|
+
);
|
3394
3769
|
};
|
3395
3770
|
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
3396
3771
|
return permissionsManager.sanitizeOutput(data, { subject: toSubject(data), action });
|
@@ -3461,7 +3836,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3461
3836
|
return userAbility.can(action);
|
3462
3837
|
},
|
3463
3838
|
async registerPermissions() {
|
3464
|
-
const displayedContentTypes = getService$
|
3839
|
+
const displayedContentTypes = getService$2("content-types").findDisplayedContentTypes();
|
3465
3840
|
const contentTypesUids = displayedContentTypes.map(prop("uid"));
|
3466
3841
|
const actions = [
|
3467
3842
|
{
|
@@ -3533,7 +3908,7 @@ const permission = ({ strapi: strapi2 }) => ({
|
|
3533
3908
|
await strapi2.service("admin::permission").actionProvider.registerMany(actions);
|
3534
3909
|
}
|
3535
3910
|
});
|
3536
|
-
const { isVisibleAttribute: isVisibleAttribute$1 } = strapiUtils.contentTypes;
|
3911
|
+
const { isVisibleAttribute: isVisibleAttribute$1, isScalarAttribute, getDoesAttributeRequireValidation } = strapiUtils.contentTypes;
|
3537
3912
|
const { isAnyToMany } = strapiUtils.relations;
|
3538
3913
|
const { PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1 } = strapiUtils.contentTypes.constants;
|
3539
3914
|
const isMorphToRelation = (attribute) => isRelation(attribute) && attribute.relation.includes("morphTo");
|
@@ -3624,6 +3999,42 @@ const getDeepPopulate = (uid2, {
|
|
3624
3999
|
{}
|
3625
4000
|
);
|
3626
4001
|
};
|
4002
|
+
const getValidatableFieldsPopulate = (uid2, {
|
4003
|
+
initialPopulate = {},
|
4004
|
+
countMany = false,
|
4005
|
+
countOne = false,
|
4006
|
+
maxLevel = Infinity
|
4007
|
+
} = {}, level = 1) => {
|
4008
|
+
if (level > maxLevel) {
|
4009
|
+
return {};
|
4010
|
+
}
|
4011
|
+
const model = strapi.getModel(uid2);
|
4012
|
+
return Object.entries(model.attributes).reduce((populateAcc, [attributeName, attribute]) => {
|
4013
|
+
if (!getDoesAttributeRequireValidation(attribute)) {
|
4014
|
+
return populateAcc;
|
4015
|
+
}
|
4016
|
+
if (isScalarAttribute(attribute)) {
|
4017
|
+
return merge(populateAcc, {
|
4018
|
+
[attributeName]: true
|
4019
|
+
});
|
4020
|
+
}
|
4021
|
+
return merge(
|
4022
|
+
populateAcc,
|
4023
|
+
getPopulateFor(
|
4024
|
+
attributeName,
|
4025
|
+
model,
|
4026
|
+
{
|
4027
|
+
// @ts-expect-error - improve types
|
4028
|
+
initialPopulate: initialPopulate?.[attributeName],
|
4029
|
+
countMany,
|
4030
|
+
countOne,
|
4031
|
+
maxLevel
|
4032
|
+
},
|
4033
|
+
level
|
4034
|
+
)
|
4035
|
+
);
|
4036
|
+
}, {});
|
4037
|
+
};
|
3627
4038
|
const getDeepPopulateDraftCount = (uid2) => {
|
3628
4039
|
const model = strapi.getModel(uid2);
|
3629
4040
|
let hasRelations = false;
|
@@ -3631,6 +4042,10 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3631
4042
|
const attribute = model.attributes[attributeName];
|
3632
4043
|
switch (attribute.type) {
|
3633
4044
|
case "relation": {
|
4045
|
+
const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
|
4046
|
+
if (isMorphRelation) {
|
4047
|
+
break;
|
4048
|
+
}
|
3634
4049
|
if (isVisibleAttribute$1(model, attributeName)) {
|
3635
4050
|
populateAcc[attributeName] = {
|
3636
4051
|
count: true,
|
@@ -3645,22 +4060,24 @@ const getDeepPopulateDraftCount = (uid2) => {
|
|
3645
4060
|
attribute.component
|
3646
4061
|
);
|
3647
4062
|
if (childHasRelations) {
|
3648
|
-
populateAcc[attributeName] = {
|
4063
|
+
populateAcc[attributeName] = {
|
4064
|
+
populate: populate2
|
4065
|
+
};
|
3649
4066
|
hasRelations = true;
|
3650
4067
|
}
|
3651
4068
|
break;
|
3652
4069
|
}
|
3653
4070
|
case "dynamiczone": {
|
3654
|
-
const
|
3655
|
-
const { populate:
|
3656
|
-
if (
|
4071
|
+
const dzPopulateFragment = attribute.components?.reduce((acc, componentUID) => {
|
4072
|
+
const { populate: componentPopulate, hasRelations: componentHasRelations } = getDeepPopulateDraftCount(componentUID);
|
4073
|
+
if (componentHasRelations) {
|
3657
4074
|
hasRelations = true;
|
3658
|
-
return
|
4075
|
+
return { ...acc, [componentUID]: { populate: componentPopulate } };
|
3659
4076
|
}
|
3660
4077
|
return acc;
|
3661
4078
|
}, {});
|
3662
|
-
if (!isEmpty(
|
3663
|
-
populateAcc[attributeName] = {
|
4079
|
+
if (!isEmpty(dzPopulateFragment)) {
|
4080
|
+
populateAcc[attributeName] = { on: dzPopulateFragment };
|
3664
4081
|
}
|
3665
4082
|
break;
|
3666
4083
|
}
|
@@ -3695,7 +4112,7 @@ const getQueryPopulate = async (uid2, query) => {
|
|
3695
4112
|
return populateQuery;
|
3696
4113
|
};
|
3697
4114
|
const buildDeepPopulate = (uid2) => {
|
3698
|
-
return getService$
|
4115
|
+
return getService$2("populate-builder")(uid2).populateDeep(Infinity).countRelations().build();
|
3699
4116
|
};
|
3700
4117
|
const populateBuilder = (uid2) => {
|
3701
4118
|
let getInitialPopulate = async () => {
|
@@ -3852,41 +4269,72 @@ const AVAILABLE_STATUS_FIELDS = [
|
|
3852
4269
|
"updatedBy",
|
3853
4270
|
"status"
|
3854
4271
|
];
|
3855
|
-
const AVAILABLE_LOCALES_FIELDS = [
|
4272
|
+
const AVAILABLE_LOCALES_FIELDS = [
|
4273
|
+
"id",
|
4274
|
+
"locale",
|
4275
|
+
"updatedAt",
|
4276
|
+
"createdAt",
|
4277
|
+
"status",
|
4278
|
+
"publishedAt",
|
4279
|
+
"documentId"
|
4280
|
+
];
|
3856
4281
|
const CONTENT_MANAGER_STATUS = {
|
3857
4282
|
PUBLISHED: "published",
|
3858
4283
|
DRAFT: "draft",
|
3859
4284
|
MODIFIED: "modified"
|
3860
4285
|
};
|
3861
|
-
const
|
3862
|
-
if (!
|
4286
|
+
const getIsVersionLatestModification = (version, otherVersion) => {
|
4287
|
+
if (!version || !version.updatedAt) {
|
3863
4288
|
return false;
|
3864
4289
|
}
|
3865
|
-
const
|
3866
|
-
const
|
3867
|
-
|
3868
|
-
return difference2 <= threshold;
|
4290
|
+
const versionUpdatedAt = version?.updatedAt ? new Date(version.updatedAt).getTime() : 0;
|
4291
|
+
const otherUpdatedAt = otherVersion?.updatedAt ? new Date(otherVersion.updatedAt).getTime() : 0;
|
4292
|
+
return versionUpdatedAt > otherUpdatedAt;
|
3869
4293
|
};
|
3870
4294
|
const documentMetadata = ({ strapi: strapi2 }) => ({
|
3871
4295
|
/**
|
3872
4296
|
* Returns available locales of a document for the current status
|
3873
4297
|
*/
|
3874
|
-
getAvailableLocales(uid2, version, allVersions) {
|
4298
|
+
async getAvailableLocales(uid2, version, allVersions, validatableFields = []) {
|
3875
4299
|
const versionsByLocale = groupBy("locale", allVersions);
|
3876
|
-
|
3877
|
-
|
3878
|
-
|
3879
|
-
|
4300
|
+
if (version.locale) {
|
4301
|
+
delete versionsByLocale[version.locale];
|
4302
|
+
}
|
4303
|
+
const model = strapi2.getModel(uid2);
|
4304
|
+
const keysToKeep = [...AVAILABLE_LOCALES_FIELDS, ...validatableFields];
|
4305
|
+
const traversalFunction = async (localeVersion) => traverseEntity(
|
4306
|
+
({ key }, { remove }) => {
|
4307
|
+
if (keysToKeep.includes(key)) {
|
4308
|
+
return;
|
4309
|
+
}
|
4310
|
+
remove(key);
|
4311
|
+
},
|
4312
|
+
{ schema: model, getModel: strapi2.getModel.bind(strapi2) },
|
4313
|
+
// @ts-expect-error fix types DocumentVersion incompatible with Data
|
4314
|
+
localeVersion
|
4315
|
+
);
|
4316
|
+
const mappingResult = await async.map(
|
4317
|
+
Object.values(versionsByLocale),
|
4318
|
+
async (localeVersions) => {
|
4319
|
+
const mappedLocaleVersions = await async.map(
|
4320
|
+
localeVersions,
|
4321
|
+
traversalFunction
|
4322
|
+
);
|
4323
|
+
if (!contentTypes$1.hasDraftAndPublish(model)) {
|
4324
|
+
return mappedLocaleVersions[0];
|
4325
|
+
}
|
4326
|
+
const draftVersion = mappedLocaleVersions.find((v) => v.publishedAt === null);
|
4327
|
+
const otherVersions = mappedLocaleVersions.filter((v) => v.id !== draftVersion?.id);
|
4328
|
+
if (!draftVersion) {
|
4329
|
+
return;
|
4330
|
+
}
|
4331
|
+
return {
|
4332
|
+
...draftVersion,
|
4333
|
+
status: this.getStatus(draftVersion, otherVersions)
|
4334
|
+
};
|
3880
4335
|
}
|
3881
|
-
|
3882
|
-
|
3883
|
-
if (!draftVersion)
|
3884
|
-
return;
|
3885
|
-
return {
|
3886
|
-
...pick(AVAILABLE_LOCALES_FIELDS, draftVersion),
|
3887
|
-
status: this.getStatus(draftVersion, otherVersions)
|
3888
|
-
};
|
3889
|
-
}).filter(Boolean);
|
4336
|
+
);
|
4337
|
+
return mappingResult.filter(Boolean);
|
3890
4338
|
},
|
3891
4339
|
/**
|
3892
4340
|
* Returns available status of a document for the current locale
|
@@ -3924,26 +4372,37 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3924
4372
|
});
|
3925
4373
|
},
|
3926
4374
|
getStatus(version, otherDocumentStatuses) {
|
3927
|
-
|
3928
|
-
|
3929
|
-
|
3930
|
-
|
3931
|
-
|
3932
|
-
|
3933
|
-
if (!publishedVersion) {
|
3934
|
-
return CONTENT_MANAGER_STATUS.DRAFT;
|
3935
|
-
}
|
4375
|
+
let draftVersion;
|
4376
|
+
let publishedVersion;
|
4377
|
+
if (version.publishedAt) {
|
4378
|
+
publishedVersion = version;
|
4379
|
+
} else {
|
4380
|
+
draftVersion = version;
|
3936
4381
|
}
|
3937
|
-
|
3938
|
-
|
4382
|
+
const otherVersion = otherDocumentStatuses?.at(0);
|
4383
|
+
if (otherVersion?.publishedAt) {
|
4384
|
+
publishedVersion = otherVersion;
|
4385
|
+
} else if (otherVersion) {
|
4386
|
+
draftVersion = otherVersion;
|
3939
4387
|
}
|
3940
|
-
|
4388
|
+
if (!draftVersion)
|
4389
|
+
return CONTENT_MANAGER_STATUS.PUBLISHED;
|
4390
|
+
if (!publishedVersion)
|
4391
|
+
return CONTENT_MANAGER_STATUS.DRAFT;
|
4392
|
+
const isDraftModified = getIsVersionLatestModification(draftVersion, publishedVersion);
|
4393
|
+
return isDraftModified ? CONTENT_MANAGER_STATUS.MODIFIED : CONTENT_MANAGER_STATUS.PUBLISHED;
|
3941
4394
|
},
|
4395
|
+
// TODO is it necessary to return metadata on every page of the CM
|
4396
|
+
// We could refactor this so the locales are only loaded when they're
|
4397
|
+
// needed. e.g. in the bulk locale action modal.
|
3942
4398
|
async getMetadata(uid2, version, { availableLocales = true, availableStatus = true } = {}) {
|
4399
|
+
const populate = getValidatableFieldsPopulate(uid2);
|
3943
4400
|
const versions = await strapi2.db.query(uid2).findMany({
|
3944
4401
|
where: { documentId: version.documentId },
|
3945
|
-
select: ["createdAt", "updatedAt", "locale", "publishedAt", "documentId"],
|
3946
4402
|
populate: {
|
4403
|
+
// Populate only fields that require validation for bulk locale actions
|
4404
|
+
...populate,
|
4405
|
+
// NOTE: creator fields are selected in this way to avoid exposing sensitive data
|
3947
4406
|
createdBy: {
|
3948
4407
|
select: ["id", "firstname", "lastname", "email"]
|
3949
4408
|
},
|
@@ -3952,7 +4411,7 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3952
4411
|
}
|
3953
4412
|
}
|
3954
4413
|
});
|
3955
|
-
const availableLocalesResult = availableLocales ? this.getAvailableLocales(uid2, version, versions) : [];
|
4414
|
+
const availableLocalesResult = availableLocales ? await this.getAvailableLocales(uid2, version, versions, Object.keys(populate)) : [];
|
3956
4415
|
const availableStatusResult = availableStatus ? this.getAvailableStatus(version, versions) : null;
|
3957
4416
|
return {
|
3958
4417
|
availableLocales: availableLocalesResult,
|
@@ -3965,8 +4424,15 @@ const documentMetadata = ({ strapi: strapi2 }) => ({
|
|
3965
4424
|
* - Available status of the document for the current locale
|
3966
4425
|
*/
|
3967
4426
|
async formatDocumentWithMetadata(uid2, document, opts = {}) {
|
3968
|
-
if (!document)
|
3969
|
-
return
|
4427
|
+
if (!document) {
|
4428
|
+
return {
|
4429
|
+
data: document,
|
4430
|
+
meta: {
|
4431
|
+
availableLocales: [],
|
4432
|
+
availableStatus: []
|
4433
|
+
}
|
4434
|
+
};
|
4435
|
+
}
|
3970
4436
|
const hasDraftAndPublish = contentTypes$1.hasDraftAndPublish(strapi2.getModel(uid2));
|
3971
4437
|
if (!hasDraftAndPublish) {
|
3972
4438
|
opts.availableStatus = false;
|
@@ -4016,26 +4482,9 @@ const sumDraftCounts = (entity, uid2) => {
|
|
4016
4482
|
}, 0);
|
4017
4483
|
};
|
4018
4484
|
const { ApplicationError } = errors;
|
4019
|
-
const { ENTRY_PUBLISH, ENTRY_UNPUBLISH } = ALLOWED_WEBHOOK_EVENTS;
|
4020
4485
|
const { PUBLISHED_AT_ATTRIBUTE } = contentTypes$1.constants;
|
4021
4486
|
const omitPublishedAtField = omit(PUBLISHED_AT_ATTRIBUTE);
|
4022
4487
|
const omitIdField = omit("id");
|
4023
|
-
const emitEvent = async (uid2, event, document) => {
|
4024
|
-
const modelDef = strapi.getModel(uid2);
|
4025
|
-
const sanitizedDocument = await sanitize.sanitizers.defaultSanitizeOutput(
|
4026
|
-
{
|
4027
|
-
schema: modelDef,
|
4028
|
-
getModel(uid22) {
|
4029
|
-
return strapi.getModel(uid22);
|
4030
|
-
}
|
4031
|
-
},
|
4032
|
-
document
|
4033
|
-
);
|
4034
|
-
strapi.eventHub.emit(event, {
|
4035
|
-
model: modelDef.modelName,
|
4036
|
-
entry: sanitizedDocument
|
4037
|
-
});
|
4038
|
-
};
|
4039
4488
|
const documentManager = ({ strapi: strapi2 }) => {
|
4040
4489
|
return {
|
4041
4490
|
async findOne(id, uid2, opts = {}) {
|
@@ -4054,6 +4503,9 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4054
4503
|
} else if (opts.locale && opts.locale !== "*") {
|
4055
4504
|
where.locale = opts.locale;
|
4056
4505
|
}
|
4506
|
+
if (typeof opts.isPublished === "boolean") {
|
4507
|
+
where.publishedAt = { $notNull: opts.isPublished };
|
4508
|
+
}
|
4057
4509
|
return strapi2.db.query(uid2).findMany({ populate: opts.populate, where });
|
4058
4510
|
},
|
4059
4511
|
async findMany(opts, uid2) {
|
@@ -4061,20 +4513,16 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4061
4513
|
return strapi2.documents(uid2).findMany(params);
|
4062
4514
|
},
|
4063
4515
|
async findPage(opts, uid2) {
|
4064
|
-
const
|
4065
|
-
|
4516
|
+
const params = pagination.withDefaultPagination(opts || {}, {
|
4517
|
+
maxLimit: 1e3
|
4518
|
+
});
|
4066
4519
|
const [documents, total = 0] = await Promise.all([
|
4067
|
-
strapi2.documents(uid2).findMany(
|
4068
|
-
strapi2.documents(uid2).count(
|
4520
|
+
strapi2.documents(uid2).findMany(params),
|
4521
|
+
strapi2.documents(uid2).count(params)
|
4069
4522
|
]);
|
4070
4523
|
return {
|
4071
4524
|
results: documents,
|
4072
|
-
pagination:
|
4073
|
-
page,
|
4074
|
-
pageSize,
|
4075
|
-
pageCount: Math.ceil(total / pageSize),
|
4076
|
-
total
|
4077
|
-
}
|
4525
|
+
pagination: pagination.transformPagedPaginationInfo(params, total)
|
4078
4526
|
};
|
4079
4527
|
},
|
4080
4528
|
async create(uid2, opts = {}) {
|
@@ -4091,10 +4539,7 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4091
4539
|
async clone(id, body, uid2) {
|
4092
4540
|
const populate = await buildDeepPopulate(uid2);
|
4093
4541
|
const params = {
|
4094
|
-
data:
|
4095
|
-
...omitIdField(body),
|
4096
|
-
[PUBLISHED_AT_ATTRIBUTE]: null
|
4097
|
-
},
|
4542
|
+
data: omitIdField(body),
|
4098
4543
|
populate
|
4099
4544
|
};
|
4100
4545
|
return strapi2.documents(uid2).clone({ ...params, documentId: id }).then((result) => result?.entries.at(0));
|
@@ -4120,70 +4565,36 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4120
4565
|
return {};
|
4121
4566
|
},
|
4122
4567
|
// FIXME: handle relations
|
4123
|
-
async deleteMany(
|
4124
|
-
const
|
4125
|
-
|
4126
|
-
|
4127
|
-
}
|
4128
|
-
return { count: docs.length };
|
4568
|
+
async deleteMany(documentIds, uid2, opts = {}) {
|
4569
|
+
const deletedEntries = await strapi2.db.transaction(async () => {
|
4570
|
+
return Promise.all(documentIds.map(async (id) => this.delete(id, uid2, opts)));
|
4571
|
+
});
|
4572
|
+
return { count: deletedEntries.length };
|
4129
4573
|
},
|
4130
4574
|
async publish(id, uid2, opts = {}) {
|
4131
4575
|
const populate = await buildDeepPopulate(uid2);
|
4132
4576
|
const params = { ...opts, populate };
|
4133
|
-
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries
|
4577
|
+
return strapi2.documents(uid2).publish({ ...params, documentId: id }).then((result) => result?.entries);
|
4134
4578
|
},
|
4135
|
-
async publishMany(
|
4136
|
-
|
4137
|
-
|
4138
|
-
|
4139
|
-
|
4140
|
-
|
4141
|
-
|
4142
|
-
strapi2.getModel(uid2),
|
4143
|
-
document,
|
4144
|
-
void 0,
|
4145
|
-
// @ts-expect-error - FIXME: entity here is unnecessary
|
4146
|
-
document
|
4147
|
-
);
|
4148
|
-
})
|
4149
|
-
);
|
4150
|
-
const entitiesToPublish = entities.filter((doc) => !doc[PUBLISHED_AT_ATTRIBUTE]).map((doc) => doc.id);
|
4151
|
-
const filters = { id: { $in: entitiesToPublish } };
|
4152
|
-
const data = { [PUBLISHED_AT_ATTRIBUTE]: /* @__PURE__ */ new Date() };
|
4153
|
-
const populate = await buildDeepPopulate(uid2);
|
4154
|
-
const publishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4155
|
-
where: filters,
|
4156
|
-
data
|
4157
|
-
});
|
4158
|
-
const publishedEntities = await strapi2.db.query(uid2).findMany({
|
4159
|
-
where: filters,
|
4160
|
-
populate
|
4579
|
+
async publishMany(uid2, documentIds, locale) {
|
4580
|
+
return strapi2.db.transaction(async () => {
|
4581
|
+
const results = await Promise.all(
|
4582
|
+
documentIds.map((documentId) => this.publish(documentId, uid2, { locale }))
|
4583
|
+
);
|
4584
|
+
const publishedEntitiesCount = results.flat().filter(Boolean).length;
|
4585
|
+
return publishedEntitiesCount;
|
4161
4586
|
});
|
4162
|
-
await Promise.all(
|
4163
|
-
publishedEntities.map((doc) => emitEvent(uid2, ENTRY_PUBLISH, doc))
|
4164
|
-
);
|
4165
|
-
return publishedEntitiesCount;
|
4166
4587
|
},
|
4167
|
-
async unpublishMany(
|
4168
|
-
|
4169
|
-
return
|
4170
|
-
|
4171
|
-
|
4172
|
-
|
4173
|
-
|
4174
|
-
const populate = await buildDeepPopulate(uid2);
|
4175
|
-
const unpublishedEntitiesCount = await strapi2.db.query(uid2).updateMany({
|
4176
|
-
where: filters,
|
4177
|
-
data
|
4178
|
-
});
|
4179
|
-
const unpublishedEntities = await strapi2.db.query(uid2).findMany({
|
4180
|
-
where: filters,
|
4181
|
-
populate
|
4588
|
+
async unpublishMany(documentIds, uid2, opts = {}) {
|
4589
|
+
const unpublishedEntries = await strapi2.db.transaction(async () => {
|
4590
|
+
return Promise.all(
|
4591
|
+
documentIds.map(
|
4592
|
+
(id) => strapi2.documents(uid2).unpublish({ ...opts, documentId: id }).then((result) => result?.entries)
|
4593
|
+
)
|
4594
|
+
);
|
4182
4595
|
});
|
4183
|
-
|
4184
|
-
|
4185
|
-
);
|
4186
|
-
return unpublishedEntitiesCount;
|
4596
|
+
const unpublishedEntitiesCount = unpublishedEntries.flat().filter(Boolean).length;
|
4597
|
+
return { count: unpublishedEntitiesCount };
|
4187
4598
|
},
|
4188
4599
|
async unpublish(id, uid2, opts = {}) {
|
4189
4600
|
const populate = await buildDeepPopulate(uid2);
|
@@ -4208,16 +4619,20 @@ const documentManager = ({ strapi: strapi2 }) => {
|
|
4208
4619
|
}
|
4209
4620
|
return sumDraftCounts(document, uid2);
|
4210
4621
|
},
|
4211
|
-
async countManyEntriesDraftRelations(
|
4622
|
+
async countManyEntriesDraftRelations(documentIds, uid2, locale) {
|
4212
4623
|
const { populate, hasRelations } = getDeepPopulateDraftCount(uid2);
|
4213
4624
|
if (!hasRelations) {
|
4214
4625
|
return 0;
|
4215
4626
|
}
|
4627
|
+
let localeFilter = {};
|
4628
|
+
if (locale) {
|
4629
|
+
localeFilter = Array.isArray(locale) ? { locale: { $in: locale } } : { locale };
|
4630
|
+
}
|
4216
4631
|
const entities = await strapi2.db.query(uid2).findMany({
|
4217
4632
|
populate,
|
4218
4633
|
where: {
|
4219
|
-
|
4220
|
-
...
|
4634
|
+
documentId: { $in: documentIds },
|
4635
|
+
...localeFilter
|
4221
4636
|
}
|
4222
4637
|
});
|
4223
4638
|
const totalNumberDraftRelations = entities.reduce(
|
@@ -4240,7 +4655,8 @@ const services = {
|
|
4240
4655
|
permission,
|
4241
4656
|
"populate-builder": populateBuilder$1,
|
4242
4657
|
uid,
|
4243
|
-
...history.services ? history.services : {}
|
4658
|
+
...history.services ? history.services : {},
|
4659
|
+
...preview.services ? preview.services : {}
|
4244
4660
|
};
|
4245
4661
|
const index = () => {
|
4246
4662
|
return {
|