@strapi/content-manager 5.48.1 → 5.50.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 +3 -2
- package/dist/admin/features/DocumentRBAC.js.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 +3 -2
- package/dist/admin/hooks/useContentTypeSchema.js.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 +3 -2
- package/dist/admin/hooks/useDocumentLayout.js.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/layout.js +3 -1
- package/dist/admin/layout.js.map +1 -1
- package/dist/admin/layout.mjs +5 -3
- package/dist/admin/layout.mjs.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.js +3 -2
- package/dist/admin/pages/ComponentConfigurationPage.js.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 +238 -108
- package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
- package/dist/admin/pages/EditView/components/DocumentActions.mjs +225 -103
- 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 +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.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/ComponentCategory.js +6 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs +2 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/ComponentCategory.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +9 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js +13 -4
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/Field.mjs +6 -1
- 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 +3 -2
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/PreviewWysiwyg.js.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 +5 -1
- package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/utils/sanitizer.js.map +1 -1
- 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/draftRelationCounts.js +117 -0
- package/dist/admin/pages/EditView/utils/draftRelationCounts.js.map +1 -0
- package/dist/admin/pages/EditView/utils/draftRelationCounts.mjs +109 -0
- package/dist/admin/pages/EditView/utils/draftRelationCounts.mjs.map +1 -0
- 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 +3 -2
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js.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 +3 -2
- package/dist/admin/pages/ListConfiguration/components/SortDisplayedFields.js.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 +4 -3
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js.map +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs +1 -1
- package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs.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 +3 -2
- package/dist/admin/pages/ListView/components/Filters.js.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 +9 -5
- package/dist/admin/pages/ListView/components/TableCells/CellContent.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/CellContent.mjs +2 -2
- package/dist/admin/pages/ListView/components/TableCells/CellContent.mjs.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/Relations.js +4 -3
- package/dist/admin/pages/ListView/components/TableCells/Relations.js.map +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Relations.mjs +1 -1
- package/dist/admin/pages/ListView/components/TableCells/Relations.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 +41 -13
- package/dist/admin/preview/pages/Preview.js.map +1 -1
- package/dist/admin/preview/pages/Preview.mjs +39 -12
- package/dist/admin/preview/pages/Preview.mjs.map +1 -1
- package/dist/admin/preview/routes.js +3 -2
- package/dist/admin/preview/routes.js.map +1 -1
- package/dist/admin/preview/utils/constants.js +9 -15
- package/dist/admin/preview/utils/constants.js.map +1 -1
- package/dist/admin/preview/utils/constants.mjs +10 -15
- package/dist/admin/preview/utils/constants.mjs.map +1 -1
- package/dist/admin/src/components/InjectionZone.d.ts +1 -2
- package/dist/admin/src/content-manager.d.ts +15 -15
- package/dist/admin/src/history/services/historyVersion.d.ts +2 -2
- package/dist/admin/src/hooks/useContentTypeSchema.d.ts +1 -1
- package/dist/admin/src/hooks/useDocument.d.ts +8 -9
- package/dist/admin/src/hooks/useDocumentLayout.d.ts +3 -3
- package/dist/admin/src/hooks/useDragAndDrop.d.ts +4 -4
- package/dist/admin/src/hooks/useKeyboardDragAndDrop.d.ts +1 -1
- package/dist/admin/src/hooks/usePersistentQueryParams.d.ts +0 -1
- package/dist/admin/src/modules/app.d.ts +5 -5
- package/dist/admin/src/pages/EditView/EditViewPage.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +12 -1
- package/dist/admin/src/pages/EditView/components/EditorToolbarObserver.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.d.ts +1 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/conversions.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/ComponentContext.d.ts +1 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations/Relations.d.ts +4 -4
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +2 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +19 -20
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +12 -12
- package/dist/admin/src/pages/EditView/utils/draftRelationCounts.d.ts +26 -0
- package/dist/admin/src/pages/EditView/utils/keyboardShortcuts.d.ts +18 -0
- package/dist/admin/src/pages/ListView/components/BulkActions/PublishAction.d.ts +1 -1
- package/dist/admin/src/pages/ListView/components/Filters.d.ts +1 -1
- package/dist/admin/src/pages/formatComponentConfigurationEditLayout.d.ts +1 -1
- package/dist/admin/src/preview/utils/constants.d.ts +1 -7
- package/dist/admin/src/preview/utils/getSendMessage.d.ts +0 -1
- package/dist/admin/src/services/documents.d.ts +30 -70
- package/dist/admin/src/services/relations.d.ts +6 -20
- package/dist/admin/src/services/uid.d.ts +5 -5
- package/dist/admin/src/utils/layouts/normalizeContentManagerLayout.d.ts +4 -4
- package/dist/admin/src/utils/users.d.ts +1 -1
- package/dist/admin/src/utils/validation.d.ts +1 -1
- 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 +7 -3
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +7 -3
- 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/ja.json.js +262 -87
- package/dist/admin/translations/ja.json.js.map +1 -1
- package/dist/admin/translations/ja.json.mjs +262 -87
- package/dist/admin/translations/ja.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/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 +2 -2
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +2 -2
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/controllers/single-types.js +2 -2
- package/dist/server/controllers/single-types.js.map +1 -1
- package/dist/server/controllers/single-types.mjs +2 -2
- package/dist/server/controllers/single-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/preview/controllers/preview.js +9 -0
- package/dist/server/preview/controllers/preview.js.map +1 -1
- package/dist/server/preview/controllers/preview.mjs +9 -0
- package/dist/server/preview/controllers/preview.mjs.map +1 -1
- package/dist/server/preview/controllers/previewScript.js +1450 -0
- package/dist/server/preview/routes/preview.js +11 -0
- package/dist/server/preview/routes/preview.js.map +1 -1
- package/dist/server/preview/routes/preview.mjs +11 -0
- package/dist/server/preview/routes/preview.mjs.map +1 -1
- package/dist/server/services/document-manager.js +13 -19
- package/dist/server/services/document-manager.js.map +1 -1
- package/dist/server/services/document-manager.mjs +13 -19
- package/dist/server/services/document-manager.mjs.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-relations.js +9 -0
- package/dist/server/services/utils/draft-relations.js.map +1 -0
- package/dist/server/services/utils/draft-relations.mjs +7 -0
- package/dist/server/services/utils/draft-relations.mjs.map +1 -0
- package/dist/server/services/utils/draft.js +123 -26
- package/dist/server/services/utils/draft.js.map +1 -1
- package/dist/server/services/utils/draft.mjs +118 -25
- package/dist/server/services/utils/draft.mjs.map +1 -1
- package/dist/server/services/utils/populate.js +23 -5
- package/dist/server/services/utils/populate.js.map +1 -1
- package/dist/server/services/utils/populate.mjs +15 -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/index.d.ts +1 -1
- package/dist/server/src/controllers/relations.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/controllers/utils/document-status.d.ts +1 -1
- package/dist/server/src/controllers/utils/document-status.d.ts.map +1 -1
- package/dist/server/src/controllers/utils/metadata.d.ts +5 -5
- package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/dimensions.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/index.d.ts +3 -3
- package/dist/server/src/controllers/validation/index.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/model-configuration.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/relations.d.ts +2 -2
- package/dist/server/src/history/controllers/history-version.d.ts +1 -7
- package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
- package/dist/server/src/history/controllers/index.d.ts +2 -1
- package/dist/server/src/history/controllers/index.d.ts.map +1 -1
- package/dist/server/src/history/controllers/validation/history-version.d.ts +1 -1
- package/dist/server/src/history/services/history.d.ts +0 -2
- package/dist/server/src/history/services/history.d.ts.map +1 -1
- package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
- package/dist/server/src/history/services/utils.d.ts +3 -3
- package/dist/server/src/history/services/utils.d.ts.map +1 -1
- package/dist/server/src/history/utils.d.ts +1 -18
- package/dist/server/src/history/utils.d.ts.map +1 -1
- package/dist/server/src/homepage/controllers/homepage.d.ts +0 -1
- package/dist/server/src/homepage/controllers/homepage.d.ts.map +1 -1
- package/dist/server/src/homepage/controllers/index.d.ts +2 -1
- package/dist/server/src/homepage/controllers/index.d.ts.map +1 -1
- package/dist/server/src/homepage/index.d.ts +4 -8
- package/dist/server/src/homepage/index.d.ts.map +1 -1
- package/dist/server/src/homepage/services/homepage-query-utils.d.ts.map +1 -1
- package/dist/server/src/homepage/services/homepage.d.ts +3 -4
- package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
- package/dist/server/src/homepage/services/index.d.ts +4 -8
- package/dist/server/src/homepage/services/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +82 -86
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/mcp/derive-content-type-mcp-tools.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/permissions.d.ts +1 -1
- package/dist/server/src/mcp/permissions.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/blocks-schema.d.ts.map +1 -1
- 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/filters-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/schemas/sort-schema.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/middlewares/routing.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/policies/index.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/index.d.ts +2 -1
- package/dist/server/src/preview/controllers/index.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/preview.d.ts +5 -0
- package/dist/server/src/preview/controllers/preview.d.ts.map +1 -1
- package/dist/server/src/preview/controllers/validation/preview.d.ts +1 -2
- package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -1
- package/dist/server/src/preview/routes/preview.d.ts.map +1 -1
- package/dist/server/src/preview/services/index.d.ts +1 -1
- package/dist/server/src/preview/services/index.d.ts.map +1 -1
- package/dist/server/src/preview/services/preview-config.d.ts +1 -1
- package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
- package/dist/server/src/preview/services/preview.d.ts.map +1 -1
- package/dist/server/src/preview/utils.d.ts +1 -16
- package/dist/server/src/preview/utils.d.ts.map +1 -1
- package/dist/server/src/services/components.d.ts +2 -2
- package/dist/server/src/services/components.d.ts.map +1 -1
- package/dist/server/src/services/configuration.d.ts.map +1 -1
- package/dist/server/src/services/content-types.d.ts.map +1 -1
- package/dist/server/src/services/data-mapper.d.ts +5 -5
- package/dist/server/src/services/data-mapper.d.ts.map +1 -1
- package/dist/server/src/services/document-manager.d.ts +14 -14
- package/dist/server/src/services/document-manager.d.ts.map +1 -1
- package/dist/server/src/services/document-metadata.d.ts +6 -6
- package/dist/server/src/services/document-metadata.d.ts.map +1 -1
- package/dist/server/src/services/field-sizes.d.ts +2 -2
- package/dist/server/src/services/field-sizes.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +81 -85
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics.d.ts.map +1 -1
- package/dist/server/src/services/permission-checker.d.ts +12 -31
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/permission.d.ts.map +1 -1
- package/dist/server/src/services/populate-builder.d.ts +7 -5
- package/dist/server/src/services/populate-builder.d.ts.map +1 -1
- package/dist/server/src/services/uid.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/attributes.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/settings.d.ts.map +1 -1
- package/dist/server/src/services/utils/count.d.ts.map +1 -1
- package/dist/server/src/services/utils/draft-relations.d.ts +19 -0
- package/dist/server/src/services/utils/draft-relations.d.ts.map +1 -0
- package/dist/server/src/services/utils/draft.d.ts +8 -7
- package/dist/server/src/services/utils/draft.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/dist/server/src/services/utils/store.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/src/validation/policies/hasPermissions.d.ts +1 -1
- package/dist/server/src/validation/zod.d.ts +1 -1
- package/dist/server/src/validation/zod.d.ts.map +1 -1
- package/dist/shared/contracts/collection-types.d.ts +4 -1
- package/dist/shared/contracts/collection-types.d.ts.map +1 -1
- package/dist/shared/contracts/single-types.d.ts +4 -1
- package/dist/shared/contracts/single-types.d.ts.map +1 -1
- package/package.json +10 -10
- package/dist/admin/preview/utils/previewScript.js +0 -1068
- package/dist/admin/preview/utils/previewScript.js.map +0 -1
- package/dist/admin/preview/utils/previewScript.mjs +0 -1066
- package/dist/admin/preview/utils/previewScript.mjs.map +0 -1
- package/dist/admin/src/preview/utils/previewScript.d.ts +0 -32
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"single-types.mjs","sources":["../../../server/src/controllers/single-types.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { setCreatorFields, async, errors } from '@strapi/utils';\n\nimport { getDocumentLocaleAndStatus } from './validation/dimensions';\nimport { getService } from '../utils';\nimport { formatDocumentWithMetadata } from './utils/metadata';\nimport { getPopulateForLocalizations } from '../services/utils/populate';\n\ntype OptionsWithPopulate = Modules.Documents.Params.Pick<UID.ContentType, 'populate:object'>;\n\nconst buildPopulateFromQuery = async (query: any, model: any) => {\n return getService('populate-builder')(model)\n .populateFromQuery(query)\n .populateDeep(Infinity)\n .countRelations()\n .withPopulateOverride(getPopulateForLocalizations(model))\n .build();\n};\n\nconst findDocument = async (query: any, uid: UID.SingleType, opts: any = {}) => {\n const documentManager = getService('document-manager');\n const populate = await buildPopulateFromQuery(query, uid);\n\n return (\n documentManager\n .findMany({ ...opts, populate }, uid)\n // Return the first document found\n .then((documents: any) => documents[0])\n );\n};\n\nconst createOrUpdateDocument = async (ctx: any, opts?: OptionsWithPopulate) => {\n const { user, userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.create() && permissionChecker.cannot.update()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.update(query);\n\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n // Load document version to update\n const [documentVersion, otherDocumentVersion] = await Promise.all([\n findDocument(sanitizedQuery, model, { locale, status: 'draft' }),\n // Find the first document to check if it exists\n strapi.db.query(model).findOne({ select: ['documentId'] }),\n ]);\n\n const documentId = otherDocumentVersion?.documentId;\n\n const pickPermittedFields = documentVersion\n ? permissionChecker.sanitizeUpdateInput(documentVersion)\n : permissionChecker.sanitizeCreateInput;\n\n const setCreator = documentVersion\n ? setCreatorFields({ user, isEdition: true })\n : setCreatorFields({ user });\n\n const sanitizeFn = async.pipe(pickPermittedFields, setCreator as any);\n\n // If version is not found, but document exists,\n // the intent is to create a new document 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 sanitizedBody = await sanitizeFn(body);\n\n if (!documentId) {\n return documentManager.create(model, {\n data: sanitizedBody,\n ...sanitizedQuery,\n locale,\n });\n }\n\n return documentManager.update(documentId, model, {\n data: sanitizedBody as any,\n populate: opts?.populate,\n locale,\n });\n};\n\nexport default {\n async find(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query = {} } = ctx.request;\n\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n const { locale, status } = await getDocumentLocaleAndStatus(query, model);\n\n const version = await findDocument(permissionQuery, model, { locale, status });\n\n // allow user with create permission to know a single type is not created\n if (!version) {\n if (permissionChecker.cannot.create()) {\n return ctx.forbidden();\n }\n // Check if document exists\n const document = await strapi.db.query(model).findOne({});\n\n if (!document) {\n return ctx.notFound();\n }\n\n // If the requested locale doesn't exist, return an empty response\n const { meta } = await formatDocumentWithMetadata(\n permissionChecker,\n model,\n // @ts-expect-error - fix types\n { documentId: document.documentId, locale, publishedAt: null },\n { availableLocales: true, availableStatus: false }\n );\n ctx.body = { data: {}, meta };\n return;\n }\n\n if (permissionChecker.cannot.read(version)) {\n return ctx.forbidden();\n }\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(version);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async createOrUpdate(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n const document = await createOrUpdateDocument(ctx);\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(document);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async delete(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.delete()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.delete(query);\n const populate = await buildPopulateFromQuery(sanitizedQuery, model);\n\n const { locale } = await getDocumentLocaleAndStatus(query, model);\n const documentLocales = await documentManager.findLocales(undefined, model, {\n populate,\n locale,\n });\n\n if (documentLocales.length === 0) {\n return ctx.notFound();\n }\n\n for (const document of documentLocales) {\n if (permissionChecker.cannot.delete(document)) {\n return ctx.forbidden();\n }\n }\n\n const deletedEntity = await documentManager.delete(documentLocales.at(0).documentId, model, {\n locale,\n });\n\n ctx.body = await permissionChecker.sanitizeOutput(deletedEntity);\n },\n\n async publish(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.publish()) {\n return ctx.forbidden();\n }\n\n const publishedDocument = await strapi.db.transaction(async () => {\n const sanitizedQuery = await permissionChecker.sanitizedQuery.publish(query);\n const populate = await buildPopulateFromQuery(sanitizedQuery, model);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n // Find the existing document\n let document = await findDocument(sanitizedQuery, model, { locale, status: 'draft' });\n\n // If document exists and user can update it, update it before publishing\n const shouldUpdate = document && permissionChecker.can.update(document);\n // If document doesn't exist and user can create it, create it before publishing\n const shouldCreate = !document && permissionChecker.can.create();\n if (shouldUpdate || shouldCreate) {\n document = await createOrUpdateDocument(ctx, { populate });\n } else if (!document) {\n // Document doesn't exist and user can't create it\n throw new errors.ForbiddenError();\n }\n\n // If document doesn't exist, throw an error\n if (!document) {\n throw new errors.NotFoundError();\n }\n\n if (permissionChecker.cannot.publish(document)) {\n throw new errors.ForbiddenError();\n }\n\n const publishResult = await documentManager.publish(document.documentId, model, { locale });\n\n return publishResult.at(0);\n });\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(publishedDocument);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async unpublish(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const {\n body: { discardDraft, ...body },\n query = {},\n } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.unpublish()) {\n return ctx.forbidden();\n }\n\n if (discardDraft && permissionChecker.cannot.discard()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.unpublish(query);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n const document = await findDocument(sanitizedQuery, model, { locale });\n\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.unpublish(document)) {\n return ctx.forbidden();\n }\n\n if (discardDraft && permissionChecker.cannot.discard(document)) {\n return ctx.forbidden();\n }\n\n await strapi.db.transaction(async () => {\n if (discardDraft) {\n await documentManager.discardDraft(document.documentId, model, { locale });\n }\n\n ctx.body = await async.pipe(\n (document) => documentManager.unpublish(document.documentId, model, { locale }),\n permissionChecker.sanitizeOutput,\n (document) => formatDocumentWithMetadata(permissionChecker, model, document)\n )(document);\n });\n },\n\n async discard(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.discard()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.discard(query);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n const document = await findDocument(sanitizedQuery, model, { locale, status: 'published' });\n\n // Can not discard a document that is not published\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.discard(document)) {\n return ctx.forbidden();\n }\n\n ctx.body = await async.pipe(\n (document) => documentManager.discardDraft(document.documentId, model, { locale }),\n permissionChecker.sanitizeOutput,\n (document) => formatDocumentWithMetadata(permissionChecker, model, document)\n )(document);\n },\n\n async countDraftRelations(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query } = ctx.request;\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n const { locale } = await getDocumentLocaleAndStatus(query, model);\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const document = await findDocument({}, model, { locale });\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.read(document)) {\n return ctx.forbidden();\n }\n\n const number = await documentManager.countDraftRelations(document.documentId, model, locale);\n\n return {\n data: number,\n };\n },\n};\n"],"names":["buildPopulateFromQuery","query","model","getService","populateFromQuery","populateDeep","Infinity","countRelations","withPopulateOverride","getPopulateForLocalizations","build","findDocument","uid","opts","documentManager","populate","findMany","then","documents","createOrUpdateDocument","ctx","user","userAbility","state","params","body","request","permissionChecker","create","cannot","update","errors","ForbiddenError","sanitizedQuery","locale","getDocumentLocaleAndStatus","documentVersion","otherDocumentVersion","Promise","all","status","strapi","db","findOne","select","documentId","pickPermittedFields","sanitizeUpdateInput","sanitizeCreateInput","setCreator","setCreatorFields","isEdition","sanitizeFn","async","pipe","sanitizedBody","data","find","read","forbidden","permissionQuery","version","document","notFound","meta","formatDocumentWithMetadata","publishedAt","availableLocales","availableStatus","sanitizedDocument","sanitizeOutput","createOrUpdate","delete","documentLocales","findLocales","undefined","length","deletedEntity","at","publish","publishedDocument","transaction","shouldUpdate","can","shouldCreate","NotFoundError","publishResult","unpublish","discardDraft","discard","countDraftRelations","number"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"single-types.mjs","sources":["../../../server/src/controllers/single-types.ts"],"sourcesContent":["import type { UID, Modules } from '@strapi/types';\nimport { setCreatorFields, async, errors } from '@strapi/utils';\n\nimport { getDocumentLocaleAndStatus } from './validation/dimensions';\nimport { getService } from '../utils';\nimport { formatDocumentWithMetadata } from './utils/metadata';\nimport { getPopulateForLocalizations } from '../services/utils/populate';\n\ntype OptionsWithPopulate = Modules.Documents.Params.Pick<UID.ContentType, 'populate:object'>;\n\nconst buildPopulateFromQuery = async (query: any, model: any) => {\n return getService('populate-builder')(model)\n .populateFromQuery(query)\n .populateDeep(Infinity)\n .countRelations()\n .withPopulateOverride(getPopulateForLocalizations(model))\n .build();\n};\n\nconst findDocument = async (query: any, uid: UID.SingleType, opts: any = {}) => {\n const documentManager = getService('document-manager');\n const populate = await buildPopulateFromQuery(query, uid);\n\n return (\n documentManager\n .findMany({ ...opts, populate }, uid)\n // Return the first document found\n .then((documents: any) => documents[0])\n );\n};\n\nconst createOrUpdateDocument = async (ctx: any, opts?: OptionsWithPopulate) => {\n const { user, userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.create() && permissionChecker.cannot.update()) {\n throw new errors.ForbiddenError();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.update(query);\n\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n // Load document version to update\n const [documentVersion, otherDocumentVersion] = await Promise.all([\n findDocument(sanitizedQuery, model, { locale, status: 'draft' }),\n // Find the first document to check if it exists\n strapi.db.query(model).findOne({ select: ['documentId'] }),\n ]);\n\n const documentId = otherDocumentVersion?.documentId;\n\n const pickPermittedFields = documentVersion\n ? permissionChecker.sanitizeUpdateInput(documentVersion)\n : permissionChecker.sanitizeCreateInput;\n\n const setCreator = documentVersion\n ? setCreatorFields({ user, isEdition: true })\n : setCreatorFields({ user });\n\n const sanitizeFn = async.pipe(pickPermittedFields, setCreator as any);\n\n // If version is not found, but document exists,\n // the intent is to create a new document 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 sanitizedBody = await sanitizeFn(body);\n\n if (!documentId) {\n return documentManager.create(model, {\n data: sanitizedBody,\n ...sanitizedQuery,\n locale,\n });\n }\n\n return documentManager.update(documentId, model, {\n data: sanitizedBody as any,\n populate: opts?.populate,\n locale,\n });\n};\n\nexport default {\n async find(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query = {} } = ctx.request;\n\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n const { locale, status } = await getDocumentLocaleAndStatus(query, model);\n\n const version = await findDocument(permissionQuery, model, { locale, status });\n\n // allow user with create permission to know a single type is not created\n if (!version) {\n if (permissionChecker.cannot.create()) {\n return ctx.forbidden();\n }\n // Check if document exists\n const document = await strapi.db.query(model).findOne({});\n\n if (!document) {\n return ctx.notFound();\n }\n\n // If the requested locale doesn't exist, return an empty response\n const { meta } = await formatDocumentWithMetadata(\n permissionChecker,\n model,\n // @ts-expect-error - fix types\n { documentId: document.documentId, locale, publishedAt: null },\n { availableLocales: true, availableStatus: false }\n );\n ctx.body = { data: {}, meta };\n return;\n }\n\n if (permissionChecker.cannot.read(version)) {\n return ctx.forbidden();\n }\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(version);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async createOrUpdate(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n const document = await createOrUpdateDocument(ctx);\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(document);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async delete(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.delete()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.delete(query);\n const populate = await buildPopulateFromQuery(sanitizedQuery, model);\n\n const { locale } = await getDocumentLocaleAndStatus(query, model);\n const documentLocales = await documentManager.findLocales(undefined, model, {\n populate,\n locale,\n });\n\n if (documentLocales.length === 0) {\n return ctx.notFound();\n }\n\n for (const document of documentLocales) {\n if (permissionChecker.cannot.delete(document)) {\n return ctx.forbidden();\n }\n }\n\n const deletedEntity = await documentManager.delete(documentLocales.at(0).documentId, model, {\n locale,\n });\n\n ctx.body = await permissionChecker.sanitizeOutput(deletedEntity);\n },\n\n async publish(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.publish()) {\n return ctx.forbidden();\n }\n\n const publishedDocument = await strapi.db.transaction(async () => {\n const sanitizedQuery = await permissionChecker.sanitizedQuery.publish(query);\n const populate = await buildPopulateFromQuery(sanitizedQuery, model);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n // Find the existing document\n let document = await findDocument(sanitizedQuery, model, { locale, status: 'draft' });\n\n // If document exists and user can update it, update it before publishing\n const shouldUpdate = document && permissionChecker.can.update(document);\n // If document doesn't exist and user can create it, create it before publishing\n const shouldCreate = !document && permissionChecker.can.create();\n if (shouldUpdate || shouldCreate) {\n document = await createOrUpdateDocument(ctx, { populate });\n } else if (!document) {\n // Document doesn't exist and user can't create it\n throw new errors.ForbiddenError();\n }\n\n // If document doesn't exist, throw an error\n if (!document) {\n throw new errors.NotFoundError();\n }\n\n if (permissionChecker.cannot.publish(document)) {\n throw new errors.ForbiddenError();\n }\n\n const publishResult = await documentManager.publish(document.documentId, model, { locale });\n\n return publishResult.at(0);\n });\n\n const sanitizedDocument = await permissionChecker.sanitizeOutput(publishedDocument);\n ctx.body = await formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);\n },\n\n async unpublish(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const {\n body: { discardDraft, ...body },\n query = {},\n } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.unpublish()) {\n return ctx.forbidden();\n }\n\n if (discardDraft && permissionChecker.cannot.discard()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.unpublish(query);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n const document = await findDocument(sanitizedQuery, model, { locale });\n\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.unpublish(document)) {\n return ctx.forbidden();\n }\n\n if (discardDraft && permissionChecker.cannot.discard(document)) {\n return ctx.forbidden();\n }\n\n await strapi.db.transaction(async () => {\n if (discardDraft) {\n await documentManager.discardDraft(document.documentId, model, { locale });\n }\n\n ctx.body = await async.pipe(\n (document) => documentManager.unpublish(document.documentId, model, { locale }),\n permissionChecker.sanitizeOutput,\n (document) => formatDocumentWithMetadata(permissionChecker, model, document)\n )(document);\n });\n },\n\n async discard(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { body, query = {} } = ctx.request;\n\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n if (permissionChecker.cannot.discard()) {\n return ctx.forbidden();\n }\n\n const sanitizedQuery = await permissionChecker.sanitizedQuery.discard(query);\n const { locale } = await getDocumentLocaleAndStatus(body, model);\n\n const document = await findDocument(sanitizedQuery, model, { locale, status: 'published' });\n\n // Can not discard a document that is not published\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.discard(document)) {\n return ctx.forbidden();\n }\n\n ctx.body = await async.pipe(\n (document) => documentManager.discardDraft(document.documentId, model, { locale }),\n permissionChecker.sanitizeOutput,\n (document) => formatDocumentWithMetadata(permissionChecker, model, document)\n )(document);\n },\n\n async countDraftRelations(ctx: any) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n const { query } = ctx.request;\n const documentManager = getService('document-manager');\n const permissionChecker = getService('permission-checker').create({ userAbility, model });\n\n const { locale } = await getDocumentLocaleAndStatus(query, model);\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const document = await findDocument({}, model, { locale });\n if (!document) {\n return ctx.notFound();\n }\n\n if (permissionChecker.cannot.read(document)) {\n return ctx.forbidden();\n }\n\n const counts = await documentManager.countDraftRelations(document.documentId, model, locale);\n\n return {\n data: counts,\n };\n },\n};\n"],"names":["buildPopulateFromQuery","query","model","getService","populateFromQuery","populateDeep","Infinity","countRelations","withPopulateOverride","getPopulateForLocalizations","build","findDocument","uid","opts","documentManager","populate","findMany","then","documents","createOrUpdateDocument","ctx","user","userAbility","state","params","body","request","permissionChecker","create","cannot","update","errors","ForbiddenError","sanitizedQuery","locale","getDocumentLocaleAndStatus","documentVersion","otherDocumentVersion","Promise","all","status","strapi","db","findOne","select","documentId","pickPermittedFields","sanitizeUpdateInput","sanitizeCreateInput","setCreator","setCreatorFields","isEdition","sanitizeFn","async","pipe","sanitizedBody","data","find","read","forbidden","permissionQuery","version","document","notFound","meta","formatDocumentWithMetadata","publishedAt","availableLocales","availableStatus","sanitizedDocument","sanitizeOutput","createOrUpdate","delete","documentLocales","findLocales","undefined","length","deletedEntity","at","publish","publishedDocument","transaction","shouldUpdate","can","shouldCreate","NotFoundError","publishResult","unpublish","discardDraft","discard","countDraftRelations","counts"],"mappings":"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"}
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
var fp = require('lodash/fp');
|
|
4
4
|
var strapiUtils = require('@strapi/utils');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var strapiUtils__default = /*#__PURE__*/_interopDefault(strapiUtils);
|
|
9
|
+
|
|
10
|
+
const { isVisibleAttribute } = strapiUtils__default.default.contentTypes;
|
|
7
11
|
/**
|
|
8
12
|
* Use an array of strings to represent the path to a field, so we can show breadcrumbs in the admin
|
|
9
13
|
* We can't use special characters as delimiters, because the path includes display names
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone.js","sources":["../../../../server/src/controllers/utils/clone.ts"],"sourcesContent":["import { set } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { ProhibitedCloningField } from '../../../../shared/contracts/collection-types';\n\nconst { isVisibleAttribute } = strapiUtils.contentTypes;\n\n/**\n * Use an array of strings to represent the path to a field, so we can show breadcrumbs in the admin\n * We can't use special characters as delimiters, because the path includes display names\n * for dynamic zone components, which can contain any character.\n */\n\nfunction checkRelation(model: any, attributeName: any, path: string[]): ProhibitedCloningField[] {\n // we don't care about createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n // Return empty array and not null so we can always spread the result\n return [];\n }\n\n /**\n * Only one-to-many and one-to-one (when they're reversed, not one-way) are dangerous,\n * because the other relations don't \"steal\" the relation from the entry we're cloning\n */\n const { relation, inversedBy, mappedBy } = model.attributes[attributeName];\n\n if (\n ['oneToOne', 'oneToMany'].includes(relation) &&\n [mappedBy, inversedBy].some((key) => key != null)\n ) {\n return [[[...path, attributeName], 'relation']];\n }\n\n return [];\n}\n\nconst getProhibitedCloningFields = (\n uid: any,\n pathPrefix: string[] = []\n): ProhibitedCloningField[] => {\n const model = strapi.getModel(uid);\n\n const prohibitedFields = Object.keys(model.attributes).reduce<ProhibitedCloningField[]>(\n (acc, attributeName) => {\n const attribute: any = model.attributes[attributeName];\n const attributePath = [...pathPrefix, attributeName];\n\n switch (attribute.type) {\n case 'relation':\n return [...acc, ...checkRelation(model, attributeName, pathPrefix)];\n case 'component':\n return [...acc, ...getProhibitedCloningFields(attribute.component, attributePath)];\n case 'dynamiczone':\n return [\n ...acc,\n ...(attribute.components || []).flatMap((componentUID: any) =>\n getProhibitedCloningFields(componentUID, [\n ...attributePath,\n strapi.getModel(componentUID).info.displayName,\n ])\n ),\n ];\n case 'uid':\n return [...acc, [attributePath, 'unique']];\n default:\n if (attribute?.unique) {\n return [...acc, [attributePath, 'unique']];\n }\n return acc;\n }\n },\n []\n );\n\n return prohibitedFields;\n};\n\n/**\n * Iterates all attributes of the content type, and removes the ones that are not creatable.\n * - If it's a relation, it sets the value to [] or null.\n * - If it's a regular attribute, it sets the value to null.\n * When cloning, if you don't set a field it will be copied from the original entry. So we need to\n * remove the fields that the user can't create.\n */\nconst excludeNotCreatableFields =\n (uid: any, permissionChecker: any) =>\n (body: any, path = []): any => {\n const model = strapi.getModel(uid);\n const canCreate = (path: any) => permissionChecker.can.create(null, path);\n\n return Object.keys(model.attributes).reduce((body, attributeName) => {\n const attribute = model.attributes[attributeName];\n const attributePath = [...path, attributeName].join('.');\n\n // Ignore the attribute if it's not visible\n if (!isVisibleAttribute(model, attributeName)) {\n return body;\n }\n\n switch (attribute.type) {\n // Relation should be empty if the user can't create it\n case 'relation': {\n if (canCreate(attributePath)) return body;\n return set(attributePath, { set: [] }, body);\n }\n // Go deeper into the component\n case 'component': {\n return excludeNotCreatableFields(attribute.component, permissionChecker)(body, [\n ...path,\n attributeName,\n ] as any);\n }\n // Attribute should be null if the user can't create it\n default: {\n if (canCreate(attributePath)) return body;\n return set(attributePath, null, body);\n }\n }\n }, body);\n };\n\nexport { getProhibitedCloningFields, excludeNotCreatableFields };\n"],"names":["isVisibleAttribute","strapiUtils","contentTypes","checkRelation","model","attributeName","path","relation","inversedBy","mappedBy","attributes","includes","some","key","getProhibitedCloningFields","uid","pathPrefix","strapi","getModel","prohibitedFields","Object","keys","reduce","acc","attribute","attributePath","type","component","components","flatMap","componentUID","info","displayName","unique","excludeNotCreatableFields","permissionChecker","body","canCreate","can","create","join","set"],"mappings":"
|
|
1
|
+
{"version":3,"file":"clone.js","sources":["../../../../server/src/controllers/utils/clone.ts"],"sourcesContent":["import { set } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { ProhibitedCloningField } from '../../../../shared/contracts/collection-types';\n\nconst { isVisibleAttribute } = strapiUtils.contentTypes;\n\n/**\n * Use an array of strings to represent the path to a field, so we can show breadcrumbs in the admin\n * We can't use special characters as delimiters, because the path includes display names\n * for dynamic zone components, which can contain any character.\n */\n\nfunction checkRelation(model: any, attributeName: any, path: string[]): ProhibitedCloningField[] {\n // we don't care about createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n // Return empty array and not null so we can always spread the result\n return [];\n }\n\n /**\n * Only one-to-many and one-to-one (when they're reversed, not one-way) are dangerous,\n * because the other relations don't \"steal\" the relation from the entry we're cloning\n */\n const { relation, inversedBy, mappedBy } = model.attributes[attributeName];\n\n if (\n ['oneToOne', 'oneToMany'].includes(relation) &&\n [mappedBy, inversedBy].some((key) => key != null)\n ) {\n return [[[...path, attributeName], 'relation']];\n }\n\n return [];\n}\n\nconst getProhibitedCloningFields = (\n uid: any,\n pathPrefix: string[] = []\n): ProhibitedCloningField[] => {\n const model = strapi.getModel(uid);\n\n const prohibitedFields = Object.keys(model.attributes).reduce<ProhibitedCloningField[]>(\n (acc, attributeName) => {\n const attribute: any = model.attributes[attributeName];\n const attributePath = [...pathPrefix, attributeName];\n\n switch (attribute.type) {\n case 'relation':\n return [...acc, ...checkRelation(model, attributeName, pathPrefix)];\n case 'component':\n return [...acc, ...getProhibitedCloningFields(attribute.component, attributePath)];\n case 'dynamiczone':\n return [\n ...acc,\n ...(attribute.components || []).flatMap((componentUID: any) =>\n getProhibitedCloningFields(componentUID, [\n ...attributePath,\n strapi.getModel(componentUID).info.displayName,\n ])\n ),\n ];\n case 'uid':\n return [...acc, [attributePath, 'unique']];\n default:\n if (attribute?.unique) {\n return [...acc, [attributePath, 'unique']];\n }\n return acc;\n }\n },\n []\n );\n\n return prohibitedFields;\n};\n\n/**\n * Iterates all attributes of the content type, and removes the ones that are not creatable.\n * - If it's a relation, it sets the value to [] or null.\n * - If it's a regular attribute, it sets the value to null.\n * When cloning, if you don't set a field it will be copied from the original entry. So we need to\n * remove the fields that the user can't create.\n */\nconst excludeNotCreatableFields =\n (uid: any, permissionChecker: any): ((body: any, path?: any[]) => any) =>\n (body: any, path = []): any => {\n const model = strapi.getModel(uid);\n const canCreate = (path: any) => permissionChecker.can.create(null, path);\n\n return Object.keys(model.attributes).reduce((body, attributeName) => {\n const attribute = model.attributes[attributeName];\n const attributePath = [...path, attributeName].join('.');\n\n // Ignore the attribute if it's not visible\n if (!isVisibleAttribute(model, attributeName)) {\n return body;\n }\n\n switch (attribute.type) {\n // Relation should be empty if the user can't create it\n case 'relation': {\n if (canCreate(attributePath)) return body;\n return set(attributePath, { set: [] }, body);\n }\n // Go deeper into the component\n case 'component': {\n return excludeNotCreatableFields(attribute.component, permissionChecker)(body, [\n ...path,\n attributeName,\n ] as any);\n }\n // Attribute should be null if the user can't create it\n default: {\n if (canCreate(attributePath)) return body;\n return set(attributePath, null, body);\n }\n }\n }, body);\n };\n\nexport { getProhibitedCloningFields, excludeNotCreatableFields };\n"],"names":["isVisibleAttribute","strapiUtils","contentTypes","checkRelation","model","attributeName","path","relation","inversedBy","mappedBy","attributes","includes","some","key","getProhibitedCloningFields","uid","pathPrefix","strapi","getModel","prohibitedFields","Object","keys","reduce","acc","attribute","attributePath","type","component","components","flatMap","componentUID","info","displayName","unique","excludeNotCreatableFields","permissionChecker","body","canCreate","can","create","join","set"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone.mjs","sources":["../../../../server/src/controllers/utils/clone.ts"],"sourcesContent":["import { set } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { ProhibitedCloningField } from '../../../../shared/contracts/collection-types';\n\nconst { isVisibleAttribute } = strapiUtils.contentTypes;\n\n/**\n * Use an array of strings to represent the path to a field, so we can show breadcrumbs in the admin\n * We can't use special characters as delimiters, because the path includes display names\n * for dynamic zone components, which can contain any character.\n */\n\nfunction checkRelation(model: any, attributeName: any, path: string[]): ProhibitedCloningField[] {\n // we don't care about createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n // Return empty array and not null so we can always spread the result\n return [];\n }\n\n /**\n * Only one-to-many and one-to-one (when they're reversed, not one-way) are dangerous,\n * because the other relations don't \"steal\" the relation from the entry we're cloning\n */\n const { relation, inversedBy, mappedBy } = model.attributes[attributeName];\n\n if (\n ['oneToOne', 'oneToMany'].includes(relation) &&\n [mappedBy, inversedBy].some((key) => key != null)\n ) {\n return [[[...path, attributeName], 'relation']];\n }\n\n return [];\n}\n\nconst getProhibitedCloningFields = (\n uid: any,\n pathPrefix: string[] = []\n): ProhibitedCloningField[] => {\n const model = strapi.getModel(uid);\n\n const prohibitedFields = Object.keys(model.attributes).reduce<ProhibitedCloningField[]>(\n (acc, attributeName) => {\n const attribute: any = model.attributes[attributeName];\n const attributePath = [...pathPrefix, attributeName];\n\n switch (attribute.type) {\n case 'relation':\n return [...acc, ...checkRelation(model, attributeName, pathPrefix)];\n case 'component':\n return [...acc, ...getProhibitedCloningFields(attribute.component, attributePath)];\n case 'dynamiczone':\n return [\n ...acc,\n ...(attribute.components || []).flatMap((componentUID: any) =>\n getProhibitedCloningFields(componentUID, [\n ...attributePath,\n strapi.getModel(componentUID).info.displayName,\n ])\n ),\n ];\n case 'uid':\n return [...acc, [attributePath, 'unique']];\n default:\n if (attribute?.unique) {\n return [...acc, [attributePath, 'unique']];\n }\n return acc;\n }\n },\n []\n );\n\n return prohibitedFields;\n};\n\n/**\n * Iterates all attributes of the content type, and removes the ones that are not creatable.\n * - If it's a relation, it sets the value to [] or null.\n * - If it's a regular attribute, it sets the value to null.\n * When cloning, if you don't set a field it will be copied from the original entry. So we need to\n * remove the fields that the user can't create.\n */\nconst excludeNotCreatableFields =\n (uid: any, permissionChecker: any) =>\n (body: any, path = []): any => {\n const model = strapi.getModel(uid);\n const canCreate = (path: any) => permissionChecker.can.create(null, path);\n\n return Object.keys(model.attributes).reduce((body, attributeName) => {\n const attribute = model.attributes[attributeName];\n const attributePath = [...path, attributeName].join('.');\n\n // Ignore the attribute if it's not visible\n if (!isVisibleAttribute(model, attributeName)) {\n return body;\n }\n\n switch (attribute.type) {\n // Relation should be empty if the user can't create it\n case 'relation': {\n if (canCreate(attributePath)) return body;\n return set(attributePath, { set: [] }, body);\n }\n // Go deeper into the component\n case 'component': {\n return excludeNotCreatableFields(attribute.component, permissionChecker)(body, [\n ...path,\n attributeName,\n ] as any);\n }\n // Attribute should be null if the user can't create it\n default: {\n if (canCreate(attributePath)) return body;\n return set(attributePath, null, body);\n }\n }\n }, body);\n };\n\nexport { getProhibitedCloningFields, excludeNotCreatableFields };\n"],"names":["isVisibleAttribute","strapiUtils","contentTypes","checkRelation","model","attributeName","path","relation","inversedBy","mappedBy","attributes","includes","some","key","getProhibitedCloningFields","uid","pathPrefix","strapi","getModel","prohibitedFields","Object","keys","reduce","acc","attribute","attributePath","type","component","components","flatMap","componentUID","info","displayName","unique","excludeNotCreatableFields","permissionChecker","body","canCreate","can","create","join","set"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clone.mjs","sources":["../../../../server/src/controllers/utils/clone.ts"],"sourcesContent":["import { set } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { ProhibitedCloningField } from '../../../../shared/contracts/collection-types';\n\nconst { isVisibleAttribute } = strapiUtils.contentTypes;\n\n/**\n * Use an array of strings to represent the path to a field, so we can show breadcrumbs in the admin\n * We can't use special characters as delimiters, because the path includes display names\n * for dynamic zone components, which can contain any character.\n */\n\nfunction checkRelation(model: any, attributeName: any, path: string[]): ProhibitedCloningField[] {\n // we don't care about createdBy, updatedBy, localizations etc.\n if (!isVisibleAttribute(model, attributeName)) {\n // Return empty array and not null so we can always spread the result\n return [];\n }\n\n /**\n * Only one-to-many and one-to-one (when they're reversed, not one-way) are dangerous,\n * because the other relations don't \"steal\" the relation from the entry we're cloning\n */\n const { relation, inversedBy, mappedBy } = model.attributes[attributeName];\n\n if (\n ['oneToOne', 'oneToMany'].includes(relation) &&\n [mappedBy, inversedBy].some((key) => key != null)\n ) {\n return [[[...path, attributeName], 'relation']];\n }\n\n return [];\n}\n\nconst getProhibitedCloningFields = (\n uid: any,\n pathPrefix: string[] = []\n): ProhibitedCloningField[] => {\n const model = strapi.getModel(uid);\n\n const prohibitedFields = Object.keys(model.attributes).reduce<ProhibitedCloningField[]>(\n (acc, attributeName) => {\n const attribute: any = model.attributes[attributeName];\n const attributePath = [...pathPrefix, attributeName];\n\n switch (attribute.type) {\n case 'relation':\n return [...acc, ...checkRelation(model, attributeName, pathPrefix)];\n case 'component':\n return [...acc, ...getProhibitedCloningFields(attribute.component, attributePath)];\n case 'dynamiczone':\n return [\n ...acc,\n ...(attribute.components || []).flatMap((componentUID: any) =>\n getProhibitedCloningFields(componentUID, [\n ...attributePath,\n strapi.getModel(componentUID).info.displayName,\n ])\n ),\n ];\n case 'uid':\n return [...acc, [attributePath, 'unique']];\n default:\n if (attribute?.unique) {\n return [...acc, [attributePath, 'unique']];\n }\n return acc;\n }\n },\n []\n );\n\n return prohibitedFields;\n};\n\n/**\n * Iterates all attributes of the content type, and removes the ones that are not creatable.\n * - If it's a relation, it sets the value to [] or null.\n * - If it's a regular attribute, it sets the value to null.\n * When cloning, if you don't set a field it will be copied from the original entry. So we need to\n * remove the fields that the user can't create.\n */\nconst excludeNotCreatableFields =\n (uid: any, permissionChecker: any): ((body: any, path?: any[]) => any) =>\n (body: any, path = []): any => {\n const model = strapi.getModel(uid);\n const canCreate = (path: any) => permissionChecker.can.create(null, path);\n\n return Object.keys(model.attributes).reduce((body, attributeName) => {\n const attribute = model.attributes[attributeName];\n const attributePath = [...path, attributeName].join('.');\n\n // Ignore the attribute if it's not visible\n if (!isVisibleAttribute(model, attributeName)) {\n return body;\n }\n\n switch (attribute.type) {\n // Relation should be empty if the user can't create it\n case 'relation': {\n if (canCreate(attributePath)) return body;\n return set(attributePath, { set: [] }, body);\n }\n // Go deeper into the component\n case 'component': {\n return excludeNotCreatableFields(attribute.component, permissionChecker)(body, [\n ...path,\n attributeName,\n ] as any);\n }\n // Attribute should be null if the user can't create it\n default: {\n if (canCreate(attributePath)) return body;\n return set(attributePath, null, body);\n }\n }\n }, body);\n };\n\nexport { getProhibitedCloningFields, excludeNotCreatableFields };\n"],"names":["isVisibleAttribute","strapiUtils","contentTypes","checkRelation","model","attributeName","path","relation","inversedBy","mappedBy","attributes","includes","some","key","getProhibitedCloningFields","uid","pathPrefix","strapi","getModel","prohibitedFields","Object","keys","reduce","acc","attribute","attributePath","type","component","components","flatMap","componentUID","info","displayName","unique","excludeNotCreatableFields","permissionChecker","body","canCreate","can","create","join","set"],"mappings":"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"}
|
|
@@ -7,6 +7,10 @@ require('@strapi/types');
|
|
|
7
7
|
require('../../services/utils/configuration/attributes.js');
|
|
8
8
|
require('../../services/utils/configuration/settings.js');
|
|
9
9
|
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var ___default = /*#__PURE__*/_interopDefault(_);
|
|
13
|
+
|
|
10
14
|
const { PaginationError, ValidationError } = strapiUtils.errors;
|
|
11
15
|
const TYPES = [
|
|
12
16
|
'singleType',
|
|
@@ -38,10 +42,10 @@ const validateUIDField = (contentTypeUID, field)=>{
|
|
|
38
42
|
if (!model) {
|
|
39
43
|
throw new ValidationError('ContentType not found');
|
|
40
44
|
}
|
|
41
|
-
if (!
|
|
45
|
+
if (!___default.default.has(model, [
|
|
42
46
|
'attributes',
|
|
43
47
|
field
|
|
44
|
-
]) ||
|
|
48
|
+
]) || ___default.default.get(model, [
|
|
45
49
|
'attributes',
|
|
46
50
|
field,
|
|
47
51
|
'type'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { Schema, UID } from '@strapi/types';\nimport { z, errors } from '@strapi/utils';\nimport { validateZodAsync, strapiID } from '../../validation/zod';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'] as const;\n\n/**\n * Validates type kind\n */\nconst kindSchema = z.enum(TYPES).nullable().optional();\n\nconst bulkActionInputSchema = z.object({\n documentIds: z.array(strapiID).min(1),\n});\n\nconst generateUIDInputSchema = z.object({\n contentTypeUID: z.string(),\n field: z.string(),\n data: z.looseObject({}),\n});\n\nconst createCheckUIDAvailabilityInputSchema = (regex?: string) => {\n const pattern = regex ? new RegExp(regex) : /^[A-Za-z0-9-_.~]*$/;\n return z.object({\n contentTypeUID: z.string(),\n field: z.string(),\n value: z.string().refine((value) => value === '' || pattern.test(value), {\n error: `Must match the custom regex or the default one \"/^[A-Za-z0-9-_.~]*$/\"`,\n }),\n });\n};\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateZodAsync(kindSchema);\nconst validateBulkActionInput = validateZodAsync(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateZodAsync(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = (body: {\n contentTypeUID: UID.ContentType;\n field: string;\n value: string;\n}) => {\n let regex: string | undefined;\n\n const contentType =\n body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;\n\n if (\n contentType?.attributes[body.field] &&\n `regex` in contentType.attributes[body.field] &&\n (contentType.attributes[body.field] as Schema.Attribute.UID).regex\n ) {\n regex = (contentType?.attributes[body.field] as Schema.Attribute.UID).regex;\n }\n\n const schema = createCheckUIDAvailabilityInputSchema(regex);\n return validateZodAsync(schema)(body);\n};\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","z","enum","nullable","optional","bulkActionInputSchema","object","documentIds","array","strapiID","min","generateUIDInputSchema","contentTypeUID","string","field","data","looseObject","createCheckUIDAvailabilityInputSchema","regex","pattern","RegExp","value","refine","test","error","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateZodAsync","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput","body","contentType","attributes","schema"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { Schema, UID } from '@strapi/types';\nimport { z, errors } from '@strapi/utils';\nimport { validateZodAsync, strapiID } from '../../validation/zod';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'] as const;\n\n/**\n * Validates type kind\n */\nconst kindSchema = z.enum(TYPES).nullable().optional();\n\nconst bulkActionInputSchema = z.object({\n documentIds: z.array(strapiID).min(1),\n});\n\nconst generateUIDInputSchema = z.object({\n contentTypeUID: z.string(),\n field: z.string(),\n data: z.looseObject({}),\n});\n\nconst createCheckUIDAvailabilityInputSchema = (regex?: string) => {\n const pattern = regex ? new RegExp(regex) : /^[A-Za-z0-9-_.~]*$/;\n return z.object({\n contentTypeUID: z.string(),\n field: z.string(),\n value: z.string().refine((value) => value === '' || pattern.test(value), {\n error: `Must match the custom regex or the default one \"/^[A-Za-z0-9-_.~]*$/\"`,\n }),\n });\n};\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateZodAsync(kindSchema);\nconst validateBulkActionInput = validateZodAsync(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateZodAsync(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = (body: {\n contentTypeUID: UID.ContentType;\n field: string;\n value: string;\n}) => {\n let regex: string | undefined;\n\n const contentType =\n body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;\n\n if (\n contentType?.attributes[body.field] &&\n `regex` in contentType.attributes[body.field] &&\n (contentType.attributes[body.field] as Schema.Attribute.UID).regex\n ) {\n regex = (contentType?.attributes[body.field] as Schema.Attribute.UID).regex;\n }\n\n const schema = createCheckUIDAvailabilityInputSchema(regex);\n return validateZodAsync(schema)(body);\n};\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","z","enum","nullable","optional","bulkActionInputSchema","object","documentIds","array","strapiID","min","generateUIDInputSchema","contentTypeUID","string","field","data","looseObject","createCheckUIDAvailabilityInputSchema","regex","pattern","RegExp","value","refine","test","error","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateZodAsync","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput","body","contentType","attributes","schema"],"mappings":"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"}
|
|
@@ -34,7 +34,12 @@ const createHomepageService = ({ strapi })=>{
|
|
|
34
34
|
action: 'plugin::content-manager.explorer.read'
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
-
|
|
37
|
+
// Deduplicate subjects using a Set: the JOIN across permission -> role -> users produces one row
|
|
38
|
+
// per role the user belongs to, so a multi-role user gets duplicate subjects.
|
|
39
|
+
// Using a Set collapses them to unique content type UID.
|
|
40
|
+
return [
|
|
41
|
+
...new Set(readPermissions.map((permission)=>permission.subject).filter(Boolean))
|
|
42
|
+
];
|
|
38
43
|
};
|
|
39
44
|
const permissionCheckerService = strapi.plugin('content-manager').service('permission-checker');
|
|
40
45
|
const getPermissionChecker = (uid)=>permissionCheckerService.create({
|
|
@@ -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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"}
|