@strapi/content-manager 5.48.0 → 5.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/ActionsDrawer.js +3 -2
- package/dist/admin/components/ActionsDrawer.js.map +1 -1
- package/dist/admin/components/ComponentIcon.js +4 -3
- package/dist/admin/components/ComponentIcon.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/EditFieldForm.js +3 -2
- package/dist/admin/components/ConfigurationForm/EditFieldForm.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Fields.js +3 -2
- package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
- package/dist/admin/components/ConfigurationForm/Form.js +7 -3
- package/dist/admin/components/ConfigurationForm/Form.js.map +1 -1
- package/dist/admin/components/LeftMenu.js +3 -2
- package/dist/admin/components/LeftMenu.js.map +1 -1
- package/dist/admin/components/RelativeTime.js +3 -2
- package/dist/admin/components/RelativeTime.js.map +1 -1
- package/dist/admin/components/Widgets.js +3 -2
- package/dist/admin/components/Widgets.js.map +1 -1
- package/dist/admin/features/DocumentRBAC.js +12 -3
- package/dist/admin/features/DocumentRBAC.js.map +1 -1
- package/dist/admin/features/DocumentRBAC.mjs +9 -1
- package/dist/admin/features/DocumentRBAC.mjs.map +1 -1
- package/dist/admin/history/components/VersionContent.js +7 -3
- package/dist/admin/history/components/VersionContent.js.map +1 -1
- package/dist/admin/history/components/VersionHeader.js +3 -2
- package/dist/admin/history/components/VersionHeader.js.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.js +3 -2
- package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
- package/dist/admin/history/pages/History.js +3 -2
- package/dist/admin/history/pages/History.js.map +1 -1
- package/dist/admin/history/routes.js +3 -2
- package/dist/admin/history/routes.js.map +1 -1
- package/dist/admin/hooks/useContentTypeSchema.js +40 -19
- package/dist/admin/hooks/useContentTypeSchema.js.map +1 -1
- package/dist/admin/hooks/useContentTypeSchema.mjs +37 -17
- package/dist/admin/hooks/useContentTypeSchema.mjs.map +1 -1
- package/dist/admin/hooks/useDocument.js +3 -2
- package/dist/admin/hooks/useDocument.js.map +1 -1
- package/dist/admin/hooks/useDocumentActions.js +3 -2
- package/dist/admin/hooks/useDocumentActions.js.map +1 -1
- package/dist/admin/hooks/useDocumentContext.js +3 -2
- package/dist/admin/hooks/useDocumentContext.js.map +1 -1
- package/dist/admin/hooks/useDocumentLayout.js +46 -6
- package/dist/admin/hooks/useDocumentLayout.js.map +1 -1
- package/dist/admin/hooks/useDocumentLayout.mjs +43 -4
- package/dist/admin/hooks/useDocumentLayout.mjs.map +1 -1
- package/dist/admin/hooks/useDragAndDrop.js +3 -2
- package/dist/admin/hooks/useDragAndDrop.js.map +1 -1
- package/dist/admin/hooks/useKeyboardDragAndDrop.js +3 -2
- package/dist/admin/hooks/useKeyboardDragAndDrop.js.map +1 -1
- package/dist/admin/hooks/useOnce.js +3 -2
- package/dist/admin/hooks/useOnce.js.map +1 -1
- package/dist/admin/hooks/usePersistentQueryParams.js +7 -2
- package/dist/admin/hooks/usePersistentQueryParams.js.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.js +9 -5
- package/dist/admin/pages/ComponentConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.mjs +6 -3
- package/dist/admin/pages/ComponentConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/EditConfigurationPage.js +3 -2
- package/dist/admin/pages/EditConfigurationPage.js.map +1 -1
- package/dist/admin/pages/EditView/EditViewPage.js +3 -2
- package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.js +80 -39
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +67 -33
- package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/EditorToolbarObserver.js +3 -2
- package/dist/admin/pages/EditView/components/EditorToolbarObserver.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.js +4 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Link.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +8 -4
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +5 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksInput.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +4 -3
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/Input.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +14 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +11 -2
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js +16 -7
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs +9 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +7 -3
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/UID.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/UID.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js +8 -4
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.js +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.js +5 -28
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.mjs +2 -26
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/continueList.js +5 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/continueList.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/mdRenderer.js +15 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/mdRenderer.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.js +76 -0
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.js.map +1 -0
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.mjs +70 -0
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.mjs.map +1 -0
- package/dist/admin/pages/EditView/components/FormLayout.js +3 -2
- package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
- package/dist/admin/pages/EditView/components/Header.js +3 -2
- package/dist/admin/pages/EditView/components/Header.js.map +1 -1
- package/dist/admin/pages/EditView/components/InputRenderer.js +3 -2
- package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
- package/dist/admin/pages/EditView/components/Panels.js +3 -2
- package/dist/admin/pages/EditView/components/Panels.js.map +1 -1
- package/dist/admin/pages/EditView/utils/data.js +5 -1
- package/dist/admin/pages/EditView/utils/data.js.map +1 -1
- package/dist/admin/pages/EditView/utils/keyboardShortcuts.js +35 -0
- package/dist/admin/pages/EditView/utils/keyboardShortcuts.js.map +1 -0
- package/dist/admin/pages/EditView/utils/keyboardShortcuts.mjs +33 -0
- package/dist/admin/pages/EditView/utils/keyboardShortcuts.mjs.map +1 -0
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js +7 -10
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs +5 -9
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/DraggableCard.js +3 -2
- package/dist/admin/pages/ListConfiguration/components/DraggableCard.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/EditFieldForm.js +3 -2
- package/dist/admin/pages/ListConfiguration/components/EditFieldForm.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/Settings.js +3 -2
- package/dist/admin/pages/ListConfiguration/components/Settings.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.js +9 -12
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.mjs +6 -10
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +3 -2
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/Actions.js +3 -2
- package/dist/admin/pages/ListView/components/BulkActions/Actions.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js +3 -2
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js +3 -2
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/PublishAction.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.js +10 -11
- package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.mjs +7 -9
- package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableActions.js +3 -2
- package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellContent.js +7 -3
- package/dist/admin/pages/ListView/components/TableCells/CellContent.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellValue.js +7 -2
- package/dist/admin/pages/ListView/components/TableCells/CellValue.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Media.js +5 -4
- package/dist/admin/pages/ListView/components/TableCells/Media.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Media.mjs +5 -4
- package/dist/admin/pages/ListView/components/TableCells/Media.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Relations.js +3 -2
- package/dist/admin/pages/ListView/components/TableCells/Relations.js.map +1 -1
- package/dist/admin/pages/formatComponentConfigurationEditLayout.js +15 -9
- package/dist/admin/pages/formatComponentConfigurationEditLayout.js.map +1 -1
- package/dist/admin/pages/formatComponentConfigurationEditLayout.mjs +15 -9
- package/dist/admin/pages/formatComponentConfigurationEditLayout.mjs.map +1 -1
- package/dist/admin/preview/components/InputPopover.js +3 -2
- package/dist/admin/preview/components/InputPopover.js.map +1 -1
- package/dist/admin/preview/hooks/usePreviewInputManager.js +3 -2
- package/dist/admin/preview/hooks/usePreviewInputManager.js.map +1 -1
- package/dist/admin/preview/pages/Preview.js +3 -2
- package/dist/admin/preview/pages/Preview.js.map +1 -1
- package/dist/admin/preview/routes.js +3 -2
- package/dist/admin/preview/routes.js.map +1 -1
- package/dist/admin/services/components.js +3 -2
- package/dist/admin/services/components.js.map +1 -1
- package/dist/admin/services/components.mjs +3 -2
- package/dist/admin/services/components.mjs.map +1 -1
- package/dist/admin/services/contentTypes.js +4 -3
- package/dist/admin/services/contentTypes.js.map +1 -1
- package/dist/admin/services/contentTypes.mjs +4 -3
- package/dist/admin/services/contentTypes.mjs.map +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.d.ts +2 -0
- package/dist/admin/src/pages/EditView/utils/keyboardShortcuts.d.ts +18 -0
- package/dist/admin/src/pages/ListConfiguration/components/SortDisplayedFields.d.ts +2 -2
- package/dist/admin/src/pages/ListView/components/TableCells/Media.d.ts +2 -2
- package/dist/admin/src/pages/formatComponentConfigurationEditLayout.d.ts +3 -1
- package/dist/admin/src/utils/layouts/normalizeContentManagerLayout.d.ts +24 -0
- package/dist/admin/translations/cs.json.js +2 -1
- package/dist/admin/translations/cs.json.js.map +1 -1
- package/dist/admin/translations/cs.json.mjs +2 -1
- package/dist/admin/translations/cs.json.mjs.map +1 -1
- package/dist/admin/translations/de.json.js +2 -1
- package/dist/admin/translations/de.json.js.map +1 -1
- package/dist/admin/translations/de.json.mjs +2 -1
- package/dist/admin/translations/de.json.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +3 -1
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +3 -1
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/es.json.js +2 -1
- package/dist/admin/translations/es.json.js.map +1 -1
- package/dist/admin/translations/es.json.mjs +2 -1
- package/dist/admin/translations/es.json.mjs.map +1 -1
- package/dist/admin/translations/fr.json.js +2 -1
- package/dist/admin/translations/fr.json.js.map +1 -1
- package/dist/admin/translations/fr.json.mjs +2 -1
- package/dist/admin/translations/fr.json.mjs.map +1 -1
- package/dist/admin/translations/nl.json.js +2 -1
- package/dist/admin/translations/nl.json.js.map +1 -1
- package/dist/admin/translations/nl.json.mjs +2 -1
- package/dist/admin/translations/nl.json.mjs.map +1 -1
- package/dist/admin/translations/pl.json.js +2 -1
- package/dist/admin/translations/pl.json.js.map +1 -1
- package/dist/admin/translations/pl.json.mjs +2 -1
- package/dist/admin/translations/pl.json.mjs.map +1 -1
- package/dist/admin/translations/sk.json.js +2 -1
- package/dist/admin/translations/sk.json.js.map +1 -1
- package/dist/admin/translations/sk.json.mjs +2 -1
- package/dist/admin/translations/sk.json.mjs.map +1 -1
- package/dist/admin/utils/attributes.js +17 -2
- package/dist/admin/utils/attributes.js.map +1 -1
- package/dist/admin/utils/attributes.mjs +17 -2
- package/dist/admin/utils/attributes.mjs.map +1 -1
- package/dist/admin/utils/layouts/normalizeContentManagerLayout.js +329 -0
- package/dist/admin/utils/layouts/normalizeContentManagerLayout.js.map +1 -0
- package/dist/admin/utils/layouts/normalizeContentManagerLayout.mjs +321 -0
- package/dist/admin/utils/layouts/normalizeContentManagerLayout.mjs.map +1 -0
- package/dist/admin/utils/objects.js +9 -4
- package/dist/admin/utils/objects.js.map +1 -1
- package/dist/admin/utils/validation.js +7 -3
- package/dist/admin/utils/validation.js.map +1 -1
- package/dist/server/controllers/collection-types.js +7 -2
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +7 -2
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/utils/clone.js +5 -1
- package/dist/server/controllers/utils/clone.js.map +1 -1
- package/dist/server/controllers/utils/clone.mjs.map +1 -1
- package/dist/server/controllers/validation/index.js +6 -2
- package/dist/server/controllers/validation/index.js.map +1 -1
- package/dist/server/homepage/services/homepage.js +6 -1
- package/dist/server/homepage/services/homepage.js.map +1 -1
- package/dist/server/homepage/services/homepage.mjs +6 -1
- package/dist/server/homepage/services/homepage.mjs.map +1 -1
- package/dist/server/mcp/handlers/collection-handlers.js +15 -18
- package/dist/server/mcp/handlers/collection-handlers.js.map +1 -1
- package/dist/server/mcp/handlers/collection-handlers.mjs +16 -19
- package/dist/server/mcp/handlers/collection-handlers.mjs.map +1 -1
- package/dist/server/mcp/handlers/single-type-handlers.js +12 -12
- package/dist/server/mcp/handlers/single-type-handlers.js.map +1 -1
- package/dist/server/mcp/handlers/single-type-handlers.mjs +13 -13
- package/dist/server/mcp/handlers/single-type-handlers.mjs.map +1 -1
- package/dist/server/mcp/register-content-manager-mcp-tools.js +4 -1
- package/dist/server/mcp/register-content-manager-mcp-tools.js.map +1 -1
- package/dist/server/mcp/register-content-manager-mcp-tools.mjs +4 -1
- package/dist/server/mcp/register-content-manager-mcp-tools.mjs.map +1 -1
- package/dist/server/mcp/sanitizers/shape-relations.js +108 -0
- package/dist/server/mcp/sanitizers/shape-relations.js.map +1 -0
- package/dist/server/mcp/sanitizers/shape-relations.mjs +103 -0
- package/dist/server/mcp/sanitizers/shape-relations.mjs.map +1 -0
- package/dist/server/mcp/schemas/data-schema.js +0 -3
- package/dist/server/mcp/schemas/data-schema.js.map +1 -1
- package/dist/server/mcp/schemas/data-schema.mjs +0 -3
- package/dist/server/mcp/schemas/data-schema.mjs.map +1 -1
- package/dist/server/mcp/schemas/output-schemas.js +30 -4
- package/dist/server/mcp/schemas/output-schemas.js.map +1 -1
- package/dist/server/mcp/schemas/output-schemas.mjs +30 -4
- package/dist/server/mcp/schemas/output-schemas.mjs.map +1 -1
- package/dist/server/mcp/utils.js +30 -3
- package/dist/server/mcp/utils.js.map +1 -1
- package/dist/server/mcp/utils.mjs +30 -4
- package/dist/server/mcp/utils.mjs.map +1 -1
- package/dist/server/middlewares/routing.js +5 -1
- package/dist/server/middlewares/routing.js.map +1 -1
- package/dist/server/services/populate-builder.js.map +1 -1
- package/dist/server/services/populate-builder.mjs.map +1 -1
- package/dist/server/services/uid.js +9 -4
- package/dist/server/services/uid.js.map +1 -1
- package/dist/server/services/utils/configuration/attributes.js +14 -10
- package/dist/server/services/utils/configuration/attributes.js.map +1 -1
- package/dist/server/services/utils/configuration/layouts.js +8 -4
- package/dist/server/services/utils/configuration/layouts.js.map +1 -1
- package/dist/server/services/utils/configuration/metadatas.js +19 -15
- package/dist/server/services/utils/configuration/metadatas.js.map +1 -1
- package/dist/server/services/utils/configuration/settings.js +5 -1
- package/dist/server/services/utils/configuration/settings.js.map +1 -1
- package/dist/server/services/utils/draft.js +5 -1
- package/dist/server/services/utils/draft.js.map +1 -1
- package/dist/server/services/utils/populate.js +8 -4
- package/dist/server/services/utils/populate.js.map +1 -1
- package/dist/server/services/utils/populate.mjs.map +1 -1
- package/dist/server/services/utils/store.js +9 -5
- package/dist/server/services/utils/store.js.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/clone.d.ts +1 -1
- package/dist/server/src/controllers/utils/clone.d.ts.map +1 -1
- package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +3 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/handlers/collection-handlers.d.ts.map +1 -1
- package/dist/server/src/mcp/handlers/single-type-handlers.d.ts.map +1 -1
- package/dist/server/src/mcp/register-content-manager-mcp-tools.d.ts +2 -1
- package/dist/server/src/mcp/register-content-manager-mcp-tools.d.ts.map +1 -1
- package/dist/server/src/mcp/sanitizers/shape-relations.d.ts +38 -0
- package/dist/server/src/mcp/sanitizers/shape-relations.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/data-schema.d.ts +0 -3
- package/dist/server/src/mcp/schemas/data-schema.d.ts.map +1 -1
- package/dist/server/src/mcp/schemas/output-schemas.d.ts +2 -2
- package/dist/server/src/mcp/schemas/output-schemas.d.ts.map +1 -1
- package/dist/server/src/mcp/types.d.ts +2 -2
- package/dist/server/src/mcp/types.d.ts.map +1 -1
- package/dist/server/src/mcp/utils.d.ts +19 -1
- package/dist/server/src/mcp/utils.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +3 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/populate-builder.d.ts +3 -1
- package/dist/server/src/services/populate-builder.d.ts.map +1 -1
- package/dist/server/src/services/utils/populate.d.ts +3 -1
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homepage.js","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n return readPermissions\n .map((permission) => permission.subject)\n .filter(Boolean) as RecentDocument['contentTypeUid'][];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.map((uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = strapi.contentType(uid);\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n return {\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n };\n });\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n return contentTypes.hasDraftAndPublish(strapi.contentType(uid));\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","contentType","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","subject","filter","Boolean","permissionCheckerService","getPermissionChecker","uid","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","contentTypes","formatDocuments","documents","meta","populate","document","additionalFields","reduce","acc","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","undefined","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"homepage.js","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n // Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row\n // per role the user belongs to, so a multi-role user gets duplicate subjects.\n // Using a Set collapses them to unique content type UID.\n return [\n ...new Set(\n readPermissions\n .map((permission) => permission.subject)\n .filter(Boolean) as RecentDocument['contentTypeUid'][]\n ),\n ];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.map((uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = strapi.contentType(uid);\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n return {\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n };\n });\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n return contentTypes.hasDraftAndPublish(strapi.contentType(uid));\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","contentType","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","Set","subject","filter","Boolean","permissionCheckerService","getPermissionChecker","uid","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","contentTypes","formatDocuments","documents","meta","populate","document","additionalFields","reduce","acc","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","undefined","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
@@ -32,7 +32,12 @@ const createHomepageService = ({ strapi })=>{
|
|
|
32
32
|
action: 'plugin::content-manager.explorer.read'
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
|
-
|
|
35
|
+
// Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row
|
|
36
|
+
// per role the user belongs to, so a multi-role user gets duplicate subjects.
|
|
37
|
+
// Using a Set collapses them to unique content type UID.
|
|
38
|
+
return [
|
|
39
|
+
...new Set(readPermissions.map((permission)=>permission.subject).filter(Boolean))
|
|
40
|
+
];
|
|
36
41
|
};
|
|
37
42
|
const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');
|
|
38
43
|
const getPermissionChecker = (uid)=>permissionCheckerService.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homepage.mjs","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n return readPermissions\n .map((permission) => permission.subject)\n .filter(Boolean) as RecentDocument['contentTypeUid'][];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.map((uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = strapi.contentType(uid);\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n return {\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n };\n });\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n return contentTypes.hasDraftAndPublish(strapi.contentType(uid));\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","contentType","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","subject","filter","Boolean","permissionCheckerService","getPermissionChecker","uid","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","contentTypes","formatDocuments","documents","meta","populate","document","additionalFields","reduce","acc","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","undefined","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"homepage.mjs","sources":["../../../../server/src/homepage/services/homepage.ts"],"sourcesContent":["/* eslint-disable func-names */\nimport type { Core, Modules, Schema } from '@strapi/types';\nimport { contentTypes } from '@strapi/utils';\n\nimport type {\n GetCountDocuments,\n GetRecentDocuments,\n RecentDocument,\n} from '../../../../shared/contracts/homepage';\n\nimport {\n buildHomepageQueryFields,\n compactSanitizedFields,\n resolveReadableMainField,\n resolveTitleField,\n} from './homepage-query-utils';\n\nconst createHomepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const MAX_DOCUMENTS = 4;\n\n const metadataService = strapi.plugin('content-manager').service('document-metadata');\n const permissionService = strapi.admin.services.permission;\n\n type ContentTypeConfiguration = {\n uid: RecentDocument['contentTypeUid'];\n settings: { mainField: string };\n };\n const getConfiguration = async (\n contentTypeUids: RecentDocument['contentTypeUid'][]\n ): Promise<ContentTypeConfiguration[]> => {\n /**\n * Don't use the strapi.store util because we need to make\n * more precise queries than exact key matches, in order to make as few queries as possible.\n */\n const coreStore = strapi.db.query('strapi::core-store');\n const rawConfigurations = await coreStore.findMany({\n where: {\n key: {\n $in: contentTypeUids.map(\n (contentType) => `plugin_content_manager_configuration_content_types::${contentType}`\n ),\n },\n },\n });\n\n return rawConfigurations.map((rawConfiguration) => {\n return JSON.parse(rawConfiguration.value);\n });\n };\n\n const getPermittedContentTypes = async () => {\n const readPermissions: Modules.Permissions.PermissionRule[] = await permissionService.findMany({\n where: {\n role: { users: { id: strapi.requestContext.get()?.state?.user.id } },\n action: 'plugin::content-manager.explorer.read',\n },\n });\n\n // Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row\n // per role the user belongs to, so a multi-role user gets duplicate subjects.\n // Using a Set collapses them to unique content type UID.\n return [\n ...new Set(\n readPermissions\n .map((permission) => permission.subject)\n .filter(Boolean) as RecentDocument['contentTypeUid'][]\n ),\n ];\n };\n\n type ContentTypeMeta = {\n fields: string[];\n mainField: string;\n contentType: Schema.ContentType;\n hasDraftAndPublish: boolean;\n uid: RecentDocument['contentTypeUid'];\n };\n\n const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');\n const getPermissionChecker = (uid: string) =>\n permissionCheckerService.create({\n userAbility: strapi.requestContext.get()?.state.userAbility,\n model: uid,\n });\n\n const getContentTypesMeta = (\n allowedContentTypeUids: RecentDocument['contentTypeUid'][],\n configurations: ContentTypeConfiguration[]\n ): ContentTypeMeta[] => {\n return allowedContentTypeUids.map((uid) => {\n const configuration = configurations.find((config) => config.uid === uid);\n const contentType = strapi.contentType(uid);\n const mainField = resolveReadableMainField(\n contentType,\n configuration,\n getPermissionChecker(uid)\n );\n const fields = buildHomepageQueryFields(contentType, mainField);\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(contentType);\n\n return {\n fields,\n mainField,\n contentType,\n hasDraftAndPublish,\n uid,\n };\n });\n };\n\n const formatDocuments = (\n documents: Modules.Documents.AnyDocument[],\n meta: ContentTypeMeta,\n populate?: string[]\n ) => {\n return documents.map((document) => {\n const additionalFields =\n populate?.reduce(\n (acc, key) => {\n acc[key] = document[key];\n return acc;\n },\n {} as Record<string, any>\n ) || {};\n return {\n documentId: document.documentId,\n locale: document.locale ?? null,\n updatedAt: new Date(document.updatedAt),\n title: document[meta.mainField ?? 'documentId'],\n publishedAt:\n meta.hasDraftAndPublish && document.publishedAt ? new Date(document.publishedAt) : null,\n contentTypeUid: meta.uid,\n contentTypeDisplayName: meta.contentType.info.displayName,\n kind: meta.contentType.kind,\n ...additionalFields,\n };\n });\n };\n\n const sanitizeHomepageQuery = async (\n meta: ContentTypeMeta,\n additionalQueryParams?: Record<string, unknown>\n ) => {\n const permissionQuery = await getPermissionChecker(meta.uid).sanitizedQuery.read({\n limit: MAX_DOCUMENTS,\n fields: meta.fields,\n ...additionalQueryParams,\n locale: '*',\n });\n\n const sanitizedFields = compactSanitizedFields(permissionQuery.fields);\n if (sanitizedFields !== undefined) {\n permissionQuery.fields = sanitizedFields;\n }\n\n return {\n permissionQuery,\n titleField: resolveTitleField(meta.mainField, sanitizedFields),\n };\n };\n\n return {\n async addStatusToDocuments(documents: RecentDocument[]): Promise<RecentDocument[]> {\n return Promise.all(\n documents.map(async (recentDocument) => {\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(\n strapi.contentType(recentDocument.contentTypeUid)\n );\n /**\n * Tries to query the other version of the document if draft and publish is enabled,\n * so that we know when to give the \"modified\" status.\n */\n const { availableStatus } = await metadataService.getMetadata(\n recentDocument.contentTypeUid,\n recentDocument,\n {\n availableStatus: hasDraftAndPublish,\n availableLocales: false,\n }\n );\n const status: RecentDocument['status'] = metadataService.getStatus(\n recentDocument,\n availableStatus\n );\n\n return {\n ...recentDocument,\n status: hasDraftAndPublish ? status : undefined,\n };\n })\n );\n },\n\n async queryLastDocuments(\n additionalQueryParams?: Record<string, unknown>,\n draftAndPublishOnly?: boolean\n ): Promise<RecentDocument[]> {\n const permittedContentTypes = await getPermittedContentTypes();\n const allowedContentTypeUids = draftAndPublishOnly\n ? permittedContentTypes.filter((uid) => {\n return contentTypes.hasDraftAndPublish(strapi.contentType(uid));\n })\n : permittedContentTypes;\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(allowedContentTypeUids);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(allowedContentTypeUids, configurations);\n\n const recentDocuments = await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const { permissionQuery, titleField } = await sanitizeHomepageQuery(\n meta,\n additionalQueryParams\n );\n\n const docs = await strapi.documents(meta.uid).findMany(permissionQuery);\n const populate = additionalQueryParams?.populate as string[];\n\n return formatDocuments(docs, { ...meta, mainField: titleField }, populate);\n })\n );\n\n return recentDocuments\n .flat()\n .sort((a, b) => {\n switch (additionalQueryParams?.sort) {\n case 'publishedAt:desc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return b.publishedAt.valueOf() - a.publishedAt.valueOf();\n case 'publishedAt:asc':\n if (!a.publishedAt || !b.publishedAt) return 0;\n return a.publishedAt.valueOf() - b.publishedAt.valueOf();\n case 'updatedAt:desc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return b.updatedAt.valueOf() - a.updatedAt.valueOf();\n case 'updatedAt:asc':\n if (!a.updatedAt || !b.updatedAt) return 0;\n return a.updatedAt.valueOf() - b.updatedAt.valueOf();\n default:\n return 0;\n }\n })\n .slice(0, MAX_DOCUMENTS);\n },\n\n async getRecentlyPublishedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyPublishedDocuments = await this.queryLastDocuments(\n {\n sort: 'publishedAt:desc',\n status: 'published',\n },\n true\n );\n\n return this.addStatusToDocuments(recentlyPublishedDocuments);\n },\n\n async getRecentlyUpdatedDocuments(): Promise<GetRecentDocuments.Response['data']> {\n const recentlyUpdatedDocuments = await this.queryLastDocuments({\n sort: 'updatedAt:desc',\n });\n\n return this.addStatusToDocuments(recentlyUpdatedDocuments);\n },\n\n async getCountDocuments(): Promise<GetCountDocuments.Response['data']> {\n const permittedContentTypes = await getPermittedContentTypes();\n // Fetch the configuration for each content type in a single query\n const configurations = await getConfiguration(permittedContentTypes);\n // Get the necessary metadata for the documents\n const contentTypesMeta = getContentTypesMeta(permittedContentTypes, configurations);\n\n const countDocuments = {\n draft: 0,\n published: 0,\n modified: 0,\n };\n\n await Promise.all(\n contentTypesMeta.map(async (meta) => {\n const strapiDBConnection = strapi.db.connection;\n const tableName = strapi.contentType(meta.uid).collectionName;\n if (!tableName) return;\n\n if (!meta.hasDraftAndPublish) {\n const publishedDocuments = await strapiDBConnection(tableName)\n .countDistinct('document_id as count')\n .first();\n countDocuments.published += Number(publishedDocuments?.count) || 0;\n return;\n }\n\n // Classify each document_id into a single bucket (draft / published / modified)\n // in one pass. Replaces three separate self-join queries that scaled poorly on\n // large tables — see https://github.com/strapi/strapi/issues/25200.\n const classified = strapiDBConnection(tableName)\n .select('document_id')\n .select(\n strapiDBConnection.raw(\n `CASE\n WHEN MAX(CASE WHEN published_at IS NOT NULL THEN 1 ELSE 0 END) = 0\n THEN 'draft'\n WHEN MAX(CASE WHEN published_at IS NULL THEN updated_at END) =\n MAX(CASE WHEN published_at IS NOT NULL THEN updated_at END)\n THEN 'published'\n ELSE 'modified'\n END AS bucket`\n )\n )\n .groupBy('document_id');\n\n const counts = await strapiDBConnection\n .from(classified.as('classified'))\n .select(\n strapiDBConnection.raw(\n `COUNT(CASE WHEN bucket = 'draft' THEN 1 END) AS draft,\n COUNT(CASE WHEN bucket = 'published' THEN 1 END) AS published,\n COUNT(CASE WHEN bucket = 'modified' THEN 1 END) AS modified`\n )\n )\n .first();\n\n countDocuments.draft += Number(counts?.draft) || 0;\n countDocuments.published += Number(counts?.published) || 0;\n countDocuments.modified += Number(counts?.modified) || 0;\n })\n );\n\n return countDocuments;\n },\n };\n};\n\nexport { createHomepageService };\n"],"names":["createHomepageService","strapi","MAX_DOCUMENTS","metadataService","plugin","service","permissionService","admin","services","permission","getConfiguration","contentTypeUids","coreStore","db","query","rawConfigurations","findMany","where","key","$in","map","contentType","rawConfiguration","JSON","parse","value","getPermittedContentTypes","readPermissions","role","users","id","requestContext","get","state","user","action","Set","subject","filter","Boolean","permissionCheckerService","getPermissionChecker","uid","create","userAbility","model","getContentTypesMeta","allowedContentTypeUids","configurations","configuration","find","config","mainField","resolveReadableMainField","fields","buildHomepageQueryFields","hasDraftAndPublish","contentTypes","formatDocuments","documents","meta","populate","document","additionalFields","reduce","acc","documentId","locale","updatedAt","Date","title","publishedAt","contentTypeUid","contentTypeDisplayName","info","displayName","kind","sanitizeHomepageQuery","additionalQueryParams","permissionQuery","sanitizedQuery","read","limit","sanitizedFields","compactSanitizedFields","undefined","titleField","resolveTitleField","addStatusToDocuments","Promise","all","recentDocument","availableStatus","getMetadata","availableLocales","status","getStatus","queryLastDocuments","draftAndPublishOnly","permittedContentTypes","contentTypesMeta","recentDocuments","docs","flat","sort","a","b","valueOf","slice","getRecentlyPublishedDocuments","recentlyPublishedDocuments","getRecentlyUpdatedDocuments","recentlyUpdatedDocuments","getCountDocuments","countDocuments","draft","published","modified","strapiDBConnection","connection","tableName","collectionName","publishedDocuments","countDistinct","first","Number","count","classified","select","raw","groupBy","counts","from","as"],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ var documentStatus = require('../../controllers/utils/document-status.js');
|
|
|
8
8
|
var populate = require('../../services/utils/populate.js');
|
|
9
9
|
var constants = require('./constants.js');
|
|
10
10
|
var permissions = require('../permissions.js');
|
|
11
|
+
var shapeRelations = require('../sanitizers/shape-relations.js');
|
|
11
12
|
var utils = require('../utils.js');
|
|
12
13
|
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
@@ -43,10 +44,7 @@ var utils = require('../utils.js');
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
const permissionQuery = await permissionChecker.sanitizedQuery.read(query);
|
|
46
|
-
const populate$1 = await index.getService('populate-builder')(uid).populateFromQuery(permissionQuery).populateDeep(1).
|
|
47
|
-
toOne: false,
|
|
48
|
-
toMany: true
|
|
49
|
-
}).withPopulateOverride(populate.getPopulateForLocalizations(uid)).build();
|
|
47
|
+
const populate$1 = await index.getService('populate-builder')(uid).populateFromQuery(permissionQuery).populateDeep(1).withPopulateOverride(populate.getPopulateForLocalizations(uid)).build();
|
|
50
48
|
const { locale: resolvedLocale, status: resolvedStatus } = await dimensions.getDocumentLocaleAndStatus({
|
|
51
49
|
locale,
|
|
52
50
|
status
|
|
@@ -65,7 +63,9 @@ var utils = require('../utils.js');
|
|
|
65
63
|
document.status = documentMetadata.getStatus(document, availableStatuses);
|
|
66
64
|
return document;
|
|
67
65
|
};
|
|
68
|
-
|
|
66
|
+
// Calculate, then strip: setStatus reads top-level publishedAt/updatedAt, so it must
|
|
67
|
+
// run before relation shaping reduces the document at the output boundary.
|
|
68
|
+
const results = await strapiUtils.async.map(documents, strapiUtils.async.pipe((doc)=>permissionChecker.sanitizeOutput(doc), setStatus, (doc)=>shapeRelations.shapeRelationsForMcp(uid, doc)));
|
|
69
69
|
return utils.ok({
|
|
70
70
|
results,
|
|
71
71
|
pagination
|
|
@@ -89,7 +89,7 @@ var utils = require('../utils.js');
|
|
|
89
89
|
locale,
|
|
90
90
|
status
|
|
91
91
|
});
|
|
92
|
-
const populate$1 = await index.getService('populate-builder')(uid).populateFromQuery(permissionQuery).populateDeep(Infinity).
|
|
92
|
+
const populate$1 = await index.getService('populate-builder')(uid).populateFromQuery(permissionQuery).populateDeep(Infinity).withPopulateOverride(populate.getPopulateForLocalizations(uid)).build();
|
|
93
93
|
const { locale: resolvedLocale, status: resolvedStatus } = await dimensions.getDocumentLocaleAndStatus({
|
|
94
94
|
locale,
|
|
95
95
|
status
|
|
@@ -120,8 +120,7 @@ var utils = require('../utils.js');
|
|
|
120
120
|
if (permissionChecker.cannot.read(version)) {
|
|
121
121
|
throw new strapiUtils.errors.ForbiddenError();
|
|
122
122
|
}
|
|
123
|
-
const
|
|
124
|
-
const result = await metadata.formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);
|
|
123
|
+
const result = await utils.sanitizeFormatShape(permissionChecker, uid, version);
|
|
125
124
|
return utils.ok(result);
|
|
126
125
|
};
|
|
127
126
|
/**
|
|
@@ -150,8 +149,7 @@ var utils = require('../utils.js');
|
|
|
150
149
|
locale: resolvedLocale,
|
|
151
150
|
status
|
|
152
151
|
});
|
|
153
|
-
|
|
154
|
-
return metadata.formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument, {
|
|
152
|
+
return utils.sanitizeFormatShape(permissionChecker, uid, document, {
|
|
155
153
|
availableLocales: false,
|
|
156
154
|
availableStatus: false
|
|
157
155
|
});
|
|
@@ -210,8 +208,7 @@ var utils = require('../utils.js');
|
|
|
210
208
|
data: sanitizedData,
|
|
211
209
|
locale: resolvedLocale
|
|
212
210
|
});
|
|
213
|
-
|
|
214
|
-
return metadata.formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);
|
|
211
|
+
return utils.sanitizeFormatShape(permissionChecker, uid, updatedDocument);
|
|
215
212
|
});
|
|
216
213
|
return utils.ok(result);
|
|
217
214
|
};
|
|
@@ -253,9 +250,11 @@ var utils = require('../utils.js');
|
|
|
253
250
|
const result = await documentManager.delete(documentId, uid, {
|
|
254
251
|
locale: localeForQuery
|
|
255
252
|
});
|
|
253
|
+
// Delete returns `{ data }` without metadata — no status to compute, so sanitize + shape only.
|
|
256
254
|
const sanitizedResult = await permissionChecker.sanitizeOutput(result);
|
|
255
|
+
const shapedResult = await shapeRelations.shapeRelationsForMcp(uid, sanitizedResult);
|
|
257
256
|
return utils.ok({
|
|
258
|
-
data:
|
|
257
|
+
data: shapedResult
|
|
259
258
|
});
|
|
260
259
|
};
|
|
261
260
|
/**
|
|
@@ -298,8 +297,7 @@ var utils = require('../utils.js');
|
|
|
298
297
|
}
|
|
299
298
|
return publishResult[0];
|
|
300
299
|
});
|
|
301
|
-
const
|
|
302
|
-
const result = await metadata.formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);
|
|
300
|
+
const result = await utils.sanitizeFormatShape(permissionChecker, uid, publishedDocument);
|
|
303
301
|
return utils.ok(result);
|
|
304
302
|
};
|
|
305
303
|
/**
|
|
@@ -351,8 +349,7 @@ var utils = require('../utils.js');
|
|
|
351
349
|
locale: resolvedLocale
|
|
352
350
|
});
|
|
353
351
|
});
|
|
354
|
-
const
|
|
355
|
-
const result = await metadata.formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);
|
|
352
|
+
const result = await utils.sanitizeFormatShape(permissionChecker, uid, unpublishedDocument);
|
|
356
353
|
return utils.ok(result);
|
|
357
354
|
};
|
|
358
355
|
/**
|
|
@@ -389,7 +386,7 @@ var utils = require('../utils.js');
|
|
|
389
386
|
}
|
|
390
387
|
const discardedDocument = await strapiUtils.async.pipe((doc)=>documentManager.discardDraft(doc.documentId, uid, {
|
|
391
388
|
locale: resolvedLocale
|
|
392
|
-
}),
|
|
389
|
+
}), (doc)=>utils.sanitizeFormatShape(permissionChecker, uid, doc))(document);
|
|
393
390
|
return utils.ok(discardedDocument);
|
|
394
391
|
};
|
|
395
392
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-handlers.js","sources":["../../../../server/src/mcp/handlers/collection-handlers.ts"],"sourcesContent":["import { errors, contentTypes, async as asyncPipe, setCreatorFields } from '@strapi/utils';\nimport type { Core, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../../utils';\nimport { getDocumentLocaleAndStatus } from '../../controllers/validation/dimensions';\nimport { formatDocumentWithMetadata } from '../../controllers/utils/metadata';\nimport { indexByDocumentId } from '../../controllers/utils/document-status';\nimport { getPopulateForLocalizations } from '../../services/utils/populate';\nimport {\n MCP_NOT_FOUND_DOCUMENT,\n MCP_NOT_FOUND_LOCALE,\n MCP_NOT_FOUND_OR_PUBLISHED,\n} from './constants';\nimport { isContentTypeLocalized } from '../permissions';\nimport { ok } from '../utils';\n\ntype McpDocumentQuery = {\n populate?: unknown;\n locale?: string;\n status?: string;\n filters?: unknown;\n sort?: unknown;\n pagination?: unknown;\n [key: string]: unknown;\n};\n\ntype McpFindManyParams = Parameters<Modules.Documents.ServiceInstance['findMany']>[0];\n\n// ---------------------------------------------------------------------------\n// Arg types — type-level only; runtime validation is handled by the MCP SDK\n// ---------------------------------------------------------------------------\n\ntype CollectionListArgs = {\n locale?: string;\n status?: 'draft' | 'published';\n page?: number;\n pageSize?: number;\n sort?: unknown;\n filters?: unknown;\n};\n\ntype DocumentLocaleArgs = {\n documentId: string;\n locale?: string;\n};\n\ntype CollectionGetArgs = DocumentLocaleArgs & {\n status?: 'draft' | 'published';\n};\n\ntype CollectionCreateArgs = {\n data: Record<string, unknown>;\n locale?: string;\n};\n\ntype CollectionUpdateArgs = DocumentLocaleArgs & {\n data: Record<string, unknown>;\n};\n\ntype CollectionUnpublishArgs = DocumentLocaleArgs & {\n discardDraft?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a handler for listing (paginated) documents of a collection-type.\n * Enforces RBAC read permission and sanitizes query + output via permissionChecker.\n */\nexport const createCollectionListHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({ args }: { args: CollectionListArgs }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { locale, status, page, pageSize, sort, filters } = args;\n\n const documentMetadata = getService('document-metadata');\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.read()) {\n throw new errors.ForbiddenError();\n }\n\n const query: Record<string, unknown> = {\n ...(page !== undefined && { page }),\n ...(pageSize !== undefined && { pageSize }),\n ...(sort !== undefined && { sort }),\n ...(filters !== undefined && { filters }),\n };\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .populateDeep(1)\n .countRelations({ toOne: false, toMany: true })\n .withPopulateOverride(getPopulateForLocalizations(uid))\n .build();\n\n const { locale: resolvedLocale, status: resolvedStatus } = await getDocumentLocaleAndStatus(\n { locale, status },\n uid\n );\n\n const findPageQuery: McpDocumentQuery = {\n ...permissionQuery,\n populate,\n locale: resolvedLocale,\n status: resolvedStatus,\n };\n const { results: documents, pagination } = await documentManager.findPage(\n findPageQuery as McpFindManyParams,\n uid\n );\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n const statusByDocumentId = hasDraftAndPublish\n ? indexByDocumentId(await documentMetadata.getManyAvailableStatus(uid, documents))\n : new Map();\n\n const setStatus = (document: any) => {\n const availableStatuses = statusByDocumentId.get(document.documentId) || [];\n document.status = documentMetadata.getStatus(document, availableStatuses);\n return document;\n };\n\n const results = await asyncPipe.map(\n documents,\n asyncPipe.pipe(permissionChecker.sanitizeOutput, setStatus)\n );\n\n return ok({ results, pagination } as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for fetching a single collection-type document by `documentId`.\n * Enforces RBAC read permission; returns available locale metadata when the locale is missing.\n */\nexport const createCollectionGetHandler =\n (uid: UID.CollectionType) =>\n (_strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale, status } = args as CollectionGetArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.read()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read({ locale, status });\n\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .populateDeep(Infinity)\n .countRelations()\n .withPopulateOverride(getPopulateForLocalizations(uid))\n .build();\n\n const { locale: resolvedLocale, status: resolvedStatus } = await getDocumentLocaleAndStatus(\n { locale, status },\n uid\n );\n\n const version = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: resolvedStatus,\n });\n\n if (!version) {\n const exists = await documentManager.exists(uid, documentId);\n if (!exists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n const { meta } = await formatDocumentWithMetadata(\n permissionChecker,\n uid,\n { documentId, locale: resolvedLocale, publishedAt: null } as Parameters<\n typeof formatDocumentWithMetadata\n >[2],\n { availableLocales: true, availableStatus: false }\n );\n\n return ok({ data: {}, meta } as Record<string, unknown>);\n }\n\n if (permissionChecker.cannot.read(version)) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(version);\n const result = await formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for creating a new collection-type document.\n * Enforces RBAC create permission; sanitizes input and stamps creator fields.\n */\nexport const createCollectionCreateHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility, user } = context;\n const { data, locale } = args as CollectionCreateArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.create()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizedData = setCreatorFields({ user })(\n await permissionChecker.sanitizeCreateInput(data)\n ) as Record<string, unknown>;\n\n const { locale: resolvedLocale, status } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const result = await strapi.db.transaction(async () => {\n const document = await documentManager.create(uid, {\n data: sanitizedData,\n locale: resolvedLocale,\n status,\n });\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(document);\n return formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument, {\n availableLocales: false,\n availableStatus: false,\n });\n });\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for updating an existing collection-type document draft.\n * Creates a new locale version when the target locale does not yet exist for the document.\n * Enforces RBAC update (or create) permission accordingly.\n */\nexport const createCollectionUpdateHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility, user } = context;\n const { documentId, data, locale } = args as CollectionUpdateArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.update()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.update({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const [documentVersion, documentExists] = await Promise.all([\n documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'draft',\n }),\n documentManager.exists(uid, documentId),\n ]);\n\n if (!documentExists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n // If version is not found but document exists, the intent is to create a new locale\n if (documentVersion) {\n if (permissionChecker.cannot.update(documentVersion)) {\n throw new errors.ForbiddenError();\n }\n } else if (permissionChecker.cannot.create()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizeInput = documentVersion\n ? permissionChecker.sanitizeUpdateInput(documentVersion)\n : permissionChecker.sanitizeCreateInput;\n\n const isEdition = documentVersion !== null && documentVersion !== undefined;\n const sanitizedData = setCreatorFields({ user, isEdition })(\n await sanitizeInput(data)\n ) as Record<string, unknown>;\n\n const result = await strapi.db.transaction(async () => {\n const updatedDocument = await documentManager.update(\n documentVersion?.documentId ?? documentId,\n uid,\n { data: sanitizedData, locale: resolvedLocale }\n );\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(updatedDocument);\n return formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);\n });\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for deleting a collection-type document (or a specific locale).\n * Enforces RBAC delete permission on every locale version before deletion.\n */\nexport const createCollectionDeleteHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.delete()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.delete({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const isLocalized = isContentTypeLocalized(strapi, uid);\n\n const localeForQuery = isLocalized === true ? resolvedLocale : undefined;\n\n const documentLocales = await documentManager.findLocales(documentId, uid, {\n populate,\n locale: localeForQuery,\n });\n\n if (documentLocales.length === 0) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n for (const document of documentLocales) {\n if (permissionChecker.cannot.delete(document)) {\n throw new errors.ForbiddenError();\n }\n }\n\n const result = await documentManager.delete(documentId, uid, { locale: localeForQuery });\n const sanitizedResult = await permissionChecker.sanitizeOutput(result);\n\n return ok({ data: sanitizedResult } as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for publishing a collection-type document draft.\n * Enforces RBAC publish permission; throws NotFound when the draft or document is missing.\n */\nexport const createCollectionPublishHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.publish()) {\n throw new errors.ForbiddenError();\n }\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const publishedDocument = await strapi.db.transaction(async () => {\n const exists = await documentManager.exists(uid, documentId);\n if (!exists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n const document = await documentManager.findOne(documentId, uid, {\n locale: resolvedLocale,\n status: 'draft',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_LOCALE);\n }\n\n if (permissionChecker.cannot.publish(document)) {\n throw new errors.ForbiddenError();\n }\n\n const publishResult = await documentManager.publish(document.documentId, uid, {\n locale: resolvedLocale,\n });\n\n if (!publishResult || publishResult.length === 0) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_OR_PUBLISHED);\n }\n\n return publishResult[0];\n });\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(publishedDocument);\n const result = await formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for unpublishing a collection-type document.\n * Optionally discards the draft in the same transaction when `discardDraft` is true.\n * Enforces RBAC unpublish (and discard) permission.\n */\nexport const createCollectionUnpublishHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale, discardDraft } = args as CollectionUnpublishArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.unpublish()) {\n throw new errors.ForbiddenError();\n }\n\n if (discardDraft === true && permissionChecker.cannot.discard()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.unpublish({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const document = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'published',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n if (permissionChecker.cannot.unpublish(document)) {\n throw new errors.ForbiddenError();\n }\n\n if (discardDraft === true && permissionChecker.cannot.discard(document)) {\n throw new errors.ForbiddenError();\n }\n\n const unpublishedDocument = await strapi.db.transaction(async () => {\n if (discardDraft === true) {\n await documentManager.discardDraft(document.documentId, uid, { locale: resolvedLocale });\n }\n\n return documentManager.unpublish(document.documentId, uid, { locale: resolvedLocale });\n });\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(unpublishedDocument);\n const result = await formatDocumentWithMetadata(permissionChecker, uid, sanitizedDocument);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for discarding the draft of a collection-type document.\n * Restores the published version as the draft. Enforces RBAC discard permission.\n */\nexport const createCollectionDiscardDraftHandler =\n (uid: UID.CollectionType) =>\n (_strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.discard()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.discard({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const document = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'published',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n if (permissionChecker.cannot.discard(document)) {\n throw new errors.ForbiddenError();\n }\n\n const discardedDocument = await asyncPipe.pipe(\n (doc: any) => documentManager.discardDraft(doc.documentId, uid, { locale: resolvedLocale }),\n permissionChecker.sanitizeOutput,\n (doc: any) => formatDocumentWithMetadata(permissionChecker, uid, doc)\n )(document);\n\n return ok(discardedDocument as Record<string, unknown>);\n };\n"],"names":["createCollectionListHandler","uid","strapi","context","args","userAbility","locale","status","page","pageSize","sort","filters","documentMetadata","getService","documentManager","permissionChecker","create","model","cannot","read","errors","ForbiddenError","query","undefined","permissionQuery","sanitizedQuery","populate","populateFromQuery","populateDeep","countRelations","toOne","toMany","withPopulateOverride","getPopulateForLocalizations","build","resolvedLocale","resolvedStatus","getDocumentLocaleAndStatus","findPageQuery","results","documents","pagination","findPage","hasDraftAndPublish","contentTypes","getModel","statusByDocumentId","indexByDocumentId","getManyAvailableStatus","Map","setStatus","document","availableStatuses","get","documentId","getStatus","asyncPipe","map","pipe","sanitizeOutput","ok","createCollectionGetHandler","_strapi","Infinity","version","findOne","exists","NotFoundError","MCP_NOT_FOUND_DOCUMENT","meta","formatDocumentWithMetadata","publishedAt","availableLocales","availableStatus","data","sanitizedDocument","result","createCollectionCreateHandler","user","sanitizedData","setCreatorFields","sanitizeCreateInput","db","transaction","createCollectionUpdateHandler","update","documentVersion","documentExists","Promise","all","sanitizeInput","sanitizeUpdateInput","isEdition","updatedDocument","createCollectionDeleteHandler","delete","isLocalized","isContentTypeLocalized","localeForQuery","documentLocales","findLocales","length","sanitizedResult","createCollectionPublishHandler","publish","publishedDocument","MCP_NOT_FOUND_LOCALE","publishResult","MCP_NOT_FOUND_OR_PUBLISHED","createCollectionUnpublishHandler","discardDraft","unpublish","discard","unpublishedDocument","createCollectionDiscardDraftHandler","discardedDocument","doc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collection-handlers.js","sources":["../../../../server/src/mcp/handlers/collection-handlers.ts"],"sourcesContent":["import { errors, contentTypes, async as asyncPipe, setCreatorFields } from '@strapi/utils';\nimport type { Core, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../../utils';\nimport { getDocumentLocaleAndStatus } from '../../controllers/validation/dimensions';\nimport { formatDocumentWithMetadata } from '../../controllers/utils/metadata';\nimport { indexByDocumentId } from '../../controllers/utils/document-status';\nimport { getPopulateForLocalizations } from '../../services/utils/populate';\nimport {\n MCP_NOT_FOUND_DOCUMENT,\n MCP_NOT_FOUND_LOCALE,\n MCP_NOT_FOUND_OR_PUBLISHED,\n} from './constants';\nimport { isContentTypeLocalized } from '../permissions';\nimport { shapeRelationsForMcp } from '../sanitizers/shape-relations';\nimport { ok, sanitizeFormatShape } from '../utils';\n\ntype McpDocumentQuery = {\n populate?: unknown;\n locale?: string;\n status?: string;\n filters?: unknown;\n sort?: unknown;\n pagination?: unknown;\n [key: string]: unknown;\n};\n\ntype McpFindManyParams = Parameters<Modules.Documents.ServiceInstance['findMany']>[0];\n\n// ---------------------------------------------------------------------------\n// Arg types — type-level only; runtime validation is handled by the MCP SDK\n// ---------------------------------------------------------------------------\n\ntype CollectionListArgs = {\n locale?: string;\n status?: 'draft' | 'published';\n page?: number;\n pageSize?: number;\n sort?: unknown;\n filters?: unknown;\n};\n\ntype DocumentLocaleArgs = {\n documentId: string;\n locale?: string;\n};\n\ntype CollectionGetArgs = DocumentLocaleArgs & {\n status?: 'draft' | 'published';\n};\n\ntype CollectionCreateArgs = {\n data: Record<string, unknown>;\n locale?: string;\n};\n\ntype CollectionUpdateArgs = DocumentLocaleArgs & {\n data: Record<string, unknown>;\n};\n\ntype CollectionUnpublishArgs = DocumentLocaleArgs & {\n discardDraft?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Handler factories\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a handler for listing (paginated) documents of a collection-type.\n * Enforces RBAC read permission and sanitizes query + output via permissionChecker.\n */\nexport const createCollectionListHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({ args }: { args: CollectionListArgs }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { locale, status, page, pageSize, sort, filters } = args;\n\n const documentMetadata = getService('document-metadata');\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.read()) {\n throw new errors.ForbiddenError();\n }\n\n const query: Record<string, unknown> = {\n ...(page !== undefined && { page }),\n ...(pageSize !== undefined && { pageSize }),\n ...(sort !== undefined && { sort }),\n ...(filters !== undefined && { filters }),\n };\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .populateDeep(1)\n .withPopulateOverride(getPopulateForLocalizations(uid))\n .build();\n\n const { locale: resolvedLocale, status: resolvedStatus } = await getDocumentLocaleAndStatus(\n { locale, status },\n uid\n );\n\n const findPageQuery: McpDocumentQuery = {\n ...permissionQuery,\n populate,\n locale: resolvedLocale,\n status: resolvedStatus,\n };\n const { results: documents, pagination } = await documentManager.findPage(\n findPageQuery as McpFindManyParams,\n uid\n );\n\n const hasDraftAndPublish = contentTypes.hasDraftAndPublish(strapi.getModel(uid));\n const statusByDocumentId = hasDraftAndPublish\n ? indexByDocumentId(await documentMetadata.getManyAvailableStatus(uid, documents))\n : new Map();\n\n const setStatus = (document: any) => {\n const availableStatuses = statusByDocumentId.get(document.documentId) || [];\n document.status = documentMetadata.getStatus(document, availableStatuses);\n return document;\n };\n\n // Calculate, then strip: setStatus reads top-level publishedAt/updatedAt, so it must\n // run before relation shaping reduces the document at the output boundary.\n const results = await asyncPipe.map(\n documents,\n asyncPipe.pipe(\n (doc: unknown) => permissionChecker.sanitizeOutput(doc),\n setStatus,\n (doc: Record<string, unknown>) => shapeRelationsForMcp(uid, doc)\n )\n );\n\n return ok({ results, pagination } as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for fetching a single collection-type document by `documentId`.\n * Enforces RBAC read permission; returns available locale metadata when the locale is missing.\n */\nexport const createCollectionGetHandler =\n (uid: UID.CollectionType) =>\n (_strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale, status } = args as CollectionGetArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.read()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read({ locale, status });\n\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .populateDeep(Infinity)\n .withPopulateOverride(getPopulateForLocalizations(uid))\n .build();\n\n const { locale: resolvedLocale, status: resolvedStatus } = await getDocumentLocaleAndStatus(\n { locale, status },\n uid\n );\n\n const version = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: resolvedStatus,\n });\n\n if (!version) {\n const exists = await documentManager.exists(uid, documentId);\n if (!exists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n const { meta } = await formatDocumentWithMetadata(\n permissionChecker,\n uid,\n { documentId, locale: resolvedLocale, publishedAt: null } as Parameters<\n typeof formatDocumentWithMetadata\n >[2],\n { availableLocales: true, availableStatus: false }\n );\n\n return ok({ data: {}, meta } as Record<string, unknown>);\n }\n\n if (permissionChecker.cannot.read(version)) {\n throw new errors.ForbiddenError();\n }\n\n const result = await sanitizeFormatShape(permissionChecker, uid, version);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for creating a new collection-type document.\n * Enforces RBAC create permission; sanitizes input and stamps creator fields.\n */\nexport const createCollectionCreateHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility, user } = context;\n const { data, locale } = args as CollectionCreateArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.create()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizedData = setCreatorFields({ user })(\n await permissionChecker.sanitizeCreateInput(data)\n ) as Record<string, unknown>;\n\n const { locale: resolvedLocale, status } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const result = await strapi.db.transaction(async () => {\n const document = await documentManager.create(uid, {\n data: sanitizedData,\n locale: resolvedLocale,\n status,\n });\n\n return sanitizeFormatShape(permissionChecker, uid, document, {\n availableLocales: false,\n availableStatus: false,\n });\n });\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for updating an existing collection-type document draft.\n * Creates a new locale version when the target locale does not yet exist for the document.\n * Enforces RBAC update (or create) permission accordingly.\n */\nexport const createCollectionUpdateHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility, user } = context;\n const { documentId, data, locale } = args as CollectionUpdateArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.update()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.update({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const [documentVersion, documentExists] = await Promise.all([\n documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'draft',\n }),\n documentManager.exists(uid, documentId),\n ]);\n\n if (!documentExists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n // If version is not found but document exists, the intent is to create a new locale\n if (documentVersion) {\n if (permissionChecker.cannot.update(documentVersion)) {\n throw new errors.ForbiddenError();\n }\n } else if (permissionChecker.cannot.create()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizeInput = documentVersion\n ? permissionChecker.sanitizeUpdateInput(documentVersion)\n : permissionChecker.sanitizeCreateInput;\n\n const isEdition = documentVersion !== null && documentVersion !== undefined;\n const sanitizedData = setCreatorFields({ user, isEdition })(\n await sanitizeInput(data)\n ) as Record<string, unknown>;\n\n const result = await strapi.db.transaction(async () => {\n const updatedDocument = await documentManager.update(\n documentVersion?.documentId ?? documentId,\n uid,\n { data: sanitizedData, locale: resolvedLocale }\n );\n\n return sanitizeFormatShape(permissionChecker, uid, updatedDocument);\n });\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for deleting a collection-type document (or a specific locale).\n * Enforces RBAC delete permission on every locale version before deletion.\n */\nexport const createCollectionDeleteHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.delete()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.delete({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const isLocalized = isContentTypeLocalized(strapi, uid);\n\n const localeForQuery = isLocalized === true ? resolvedLocale : undefined;\n\n const documentLocales = await documentManager.findLocales(documentId, uid, {\n populate,\n locale: localeForQuery,\n });\n\n if (documentLocales.length === 0) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n for (const document of documentLocales) {\n if (permissionChecker.cannot.delete(document)) {\n throw new errors.ForbiddenError();\n }\n }\n\n const result = await documentManager.delete(documentId, uid, { locale: localeForQuery });\n // Delete returns `{ data }` without metadata — no status to compute, so sanitize + shape only.\n const sanitizedResult = await permissionChecker.sanitizeOutput(result);\n const shapedResult = await shapeRelationsForMcp(uid, sanitizedResult);\n\n return ok({ data: shapedResult } as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for publishing a collection-type document draft.\n * Enforces RBAC publish permission; throws NotFound when the draft or document is missing.\n */\nexport const createCollectionPublishHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.publish()) {\n throw new errors.ForbiddenError();\n }\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const publishedDocument = await strapi.db.transaction(async () => {\n const exists = await documentManager.exists(uid, documentId);\n if (!exists) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n const document = await documentManager.findOne(documentId, uid, {\n locale: resolvedLocale,\n status: 'draft',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_LOCALE);\n }\n\n if (permissionChecker.cannot.publish(document)) {\n throw new errors.ForbiddenError();\n }\n\n const publishResult = await documentManager.publish(document.documentId, uid, {\n locale: resolvedLocale,\n });\n\n if (!publishResult || publishResult.length === 0) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_OR_PUBLISHED);\n }\n\n return publishResult[0];\n });\n\n const result = await sanitizeFormatShape(permissionChecker, uid, publishedDocument);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for unpublishing a collection-type document.\n * Optionally discards the draft in the same transaction when `discardDraft` is true.\n * Enforces RBAC unpublish (and discard) permission.\n */\nexport const createCollectionUnpublishHandler =\n (uid: UID.CollectionType) =>\n (strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale, discardDraft } = args as CollectionUnpublishArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.unpublish()) {\n throw new errors.ForbiddenError();\n }\n\n if (discardDraft === true && permissionChecker.cannot.discard()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.unpublish({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const document = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'published',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n if (permissionChecker.cannot.unpublish(document)) {\n throw new errors.ForbiddenError();\n }\n\n if (discardDraft === true && permissionChecker.cannot.discard(document)) {\n throw new errors.ForbiddenError();\n }\n\n const unpublishedDocument = await strapi.db.transaction(async () => {\n if (discardDraft === true) {\n await documentManager.discardDraft(document.documentId, uid, { locale: resolvedLocale });\n }\n\n return documentManager.unpublish(document.documentId, uid, { locale: resolvedLocale });\n });\n\n const result = await sanitizeFormatShape(permissionChecker, uid, unpublishedDocument);\n\n return ok(result as Record<string, unknown>);\n };\n\n/**\n * Creates a handler for discarding the draft of a collection-type document.\n * Restores the published version as the draft. Enforces RBAC discard permission.\n */\nexport const createCollectionDiscardDraftHandler =\n (uid: UID.CollectionType) =>\n (_strapi: Core.Strapi, context: Modules.MCP.McpHandlerContext) =>\n async ({\n args,\n }: {\n args: Record<string, unknown>;\n }): Promise<Modules.MCP.McpToolHandlerReturn> => {\n const { userAbility } = context;\n const { documentId, locale } = args as DocumentLocaleArgs;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model: uid });\n\n if (permissionChecker.cannot.discard()) {\n throw new errors.ForbiddenError();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.discard({ locale });\n const populate = await getService('populate-builder')(uid)\n .populateFromQuery(permissionQuery)\n .build();\n\n const { locale: resolvedLocale } = await getDocumentLocaleAndStatus({ locale }, uid);\n\n const document = await documentManager.findOne(documentId, uid, {\n populate,\n locale: resolvedLocale,\n status: 'published',\n });\n\n if (!document) {\n throw new errors.NotFoundError(MCP_NOT_FOUND_DOCUMENT);\n }\n\n if (permissionChecker.cannot.discard(document)) {\n throw new errors.ForbiddenError();\n }\n\n const discardedDocument = await asyncPipe.pipe(\n (doc: any) => documentManager.discardDraft(doc.documentId, uid, { locale: resolvedLocale }),\n (doc: unknown) => sanitizeFormatShape(permissionChecker, uid, doc)\n )(document);\n\n return ok(discardedDocument as Record<string, unknown>);\n };\n"],"names":["createCollectionListHandler","uid","strapi","context","args","userAbility","locale","status","page","pageSize","sort","filters","documentMetadata","getService","documentManager","permissionChecker","create","model","cannot","read","errors","ForbiddenError","query","undefined","permissionQuery","sanitizedQuery","populate","populateFromQuery","populateDeep","withPopulateOverride","getPopulateForLocalizations","build","resolvedLocale","resolvedStatus","getDocumentLocaleAndStatus","findPageQuery","results","documents","pagination","findPage","hasDraftAndPublish","contentTypes","getModel","statusByDocumentId","indexByDocumentId","getManyAvailableStatus","Map","setStatus","document","availableStatuses","get","documentId","getStatus","asyncPipe","map","pipe","doc","sanitizeOutput","shapeRelationsForMcp","ok","createCollectionGetHandler","_strapi","Infinity","version","findOne","exists","NotFoundError","MCP_NOT_FOUND_DOCUMENT","meta","formatDocumentWithMetadata","publishedAt","availableLocales","availableStatus","data","result","sanitizeFormatShape","createCollectionCreateHandler","user","sanitizedData","setCreatorFields","sanitizeCreateInput","db","transaction","createCollectionUpdateHandler","update","documentVersion","documentExists","Promise","all","sanitizeInput","sanitizeUpdateInput","isEdition","updatedDocument","createCollectionDeleteHandler","delete","isLocalized","isContentTypeLocalized","localeForQuery","documentLocales","findLocales","length","sanitizedResult","shapedResult","createCollectionPublishHandler","publish","publishedDocument","MCP_NOT_FOUND_LOCALE","publishResult","MCP_NOT_FOUND_OR_PUBLISHED","createCollectionUnpublishHandler","discardDraft","unpublish","discard","unpublishedDocument","createCollectionDiscardDraftHandler","discardedDocument"],"mappings":"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"}
|