@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
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var strapiUtils = require('@strapi/utils');
|
|
4
|
+
|
|
5
|
+
// Relations whose cardinality is "many" — maps to Array output.
|
|
6
|
+
// Includes non-owning variants and morph-many.
|
|
7
|
+
const MANY_RELATION_TYPES = new Set([
|
|
8
|
+
'oneToMany',
|
|
9
|
+
'manyToMany',
|
|
10
|
+
'manyWay',
|
|
11
|
+
'morphToMany',
|
|
12
|
+
'morphMany'
|
|
13
|
+
]);
|
|
14
|
+
/**
|
|
15
|
+
* Canonical "is this relation a list" predicate for the MCP output boundary.
|
|
16
|
+
* Both the runtime shaping (reduceToIdentity) and the registered output schemas
|
|
17
|
+
* (output-schemas.ts) MUST use this single definition — the MCP SDK validates
|
|
18
|
+
* structuredContent against the schema, so any divergence fails the tool call.
|
|
19
|
+
* Intentionally broader than `relations.isAnyToMany` from @strapi/utils, which
|
|
20
|
+
* ignores `manyWay` and the morph variants.
|
|
21
|
+
*/ const isManyRelationForMcp = (attribute)=>MANY_RELATION_TYPES.has(attribute.relation ?? '');
|
|
22
|
+
/**
|
|
23
|
+
* Extracts identity fields from a single relation entry.
|
|
24
|
+
* Returns undefined when the entry has no documentId (e.g. a bare {count} object).
|
|
25
|
+
*/ const pickIdentity = (entry)=>{
|
|
26
|
+
if (entry === null || typeof entry !== 'object') {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const obj = entry;
|
|
30
|
+
if (typeof obj.documentId !== 'string') {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const identity = {
|
|
34
|
+
documentId: obj.documentId
|
|
35
|
+
};
|
|
36
|
+
if (typeof obj.locale === 'string') {
|
|
37
|
+
identity.locale = obj.locale;
|
|
38
|
+
}
|
|
39
|
+
if (typeof obj.__type === 'string') {
|
|
40
|
+
identity.__type = obj.__type;
|
|
41
|
+
}
|
|
42
|
+
// Preserve the computed publish status on `localizations` entries — it is
|
|
43
|
+
// calculated by formatDocumentWithMetadata BEFORE shaping (calculate, then strip).
|
|
44
|
+
// Non-localization relation entries never carry a string `status`, so this is a no-op for them.
|
|
45
|
+
if (typeof obj.status === 'string') {
|
|
46
|
+
identity.status = obj.status;
|
|
47
|
+
}
|
|
48
|
+
return identity;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Reduces a populated relation value to identity-only shape.
|
|
52
|
+
*
|
|
53
|
+
* to-one → { documentId, locale?, __type? } | null
|
|
54
|
+
* to-many → Array<{ documentId, locale?, __type? }> ([] when empty)
|
|
55
|
+
*/ const reduceToIdentity = (attribute, value)=>{
|
|
56
|
+
const isMany = isManyRelationForMcp(attribute);
|
|
57
|
+
if (isMany) {
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
return value.map(pickIdentity).filter((v)=>v !== undefined);
|
|
60
|
+
}
|
|
61
|
+
// defensive: { count: N } or null/undefined → empty array
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
// to-one
|
|
65
|
+
if (value === null || value === undefined) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
// should not happen, but guard: treat first element
|
|
70
|
+
return pickIdentity(value[0]) ?? null;
|
|
71
|
+
}
|
|
72
|
+
return pickIdentity(value) ?? null;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Post-sanitize shaping visitor.
|
|
76
|
+
* Reduces every relation attribute to identity-only (documentId + locale? + __type?).
|
|
77
|
+
* Skips admin::user relations — those are out of scope and preserved as-is.
|
|
78
|
+
*/ const shapeRelationToIdentity = ({ key, value, attribute }, { set })=>{
|
|
79
|
+
if (attribute?.type !== 'relation') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const target = attribute.target;
|
|
83
|
+
// Out of scope — admin user records are preserved untouched (tracked separately).
|
|
84
|
+
if (target === 'admin::user') {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// @ts-expect-error — reduceToIdentity returns a narrower type; traverseEntity Data allows unknown
|
|
88
|
+
set(key, reduceToIdentity(attribute, value));
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Applies identity shaping to all relation fields in a document, including
|
|
92
|
+
* nested fields inside components, dynamic zones, and `localizations`.
|
|
93
|
+
*
|
|
94
|
+
* This covers leak family #1 (relation targets) and #2 (localizations full draft rows)
|
|
95
|
+
* with the same single mechanism.
|
|
96
|
+
*/ const shapeRelationsForMcp = async (uid, data)=>{
|
|
97
|
+
return strapiUtils.traverseEntity(shapeRelationToIdentity, {
|
|
98
|
+
schema: strapi.getModel(uid),
|
|
99
|
+
getModel: strapi.getModel.bind(strapi)
|
|
100
|
+
}, // @ts-expect-error — traverseEntity expects Data; post-sanitize documents are compatible at runtime
|
|
101
|
+
data);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
exports.MANY_RELATION_TYPES = MANY_RELATION_TYPES;
|
|
105
|
+
exports.isManyRelationForMcp = isManyRelationForMcp;
|
|
106
|
+
exports.reduceToIdentity = reduceToIdentity;
|
|
107
|
+
exports.shapeRelationsForMcp = shapeRelationsForMcp;
|
|
108
|
+
//# sourceMappingURL=shape-relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape-relations.js","sources":["../../../../server/src/mcp/sanitizers/shape-relations.ts"],"sourcesContent":["import { traverseEntity } from '@strapi/utils';\nimport type { UID } from '@strapi/types';\n\n// Relations whose cardinality is \"many\" — maps to Array output.\n// Includes non-owning variants and morph-many.\nconst MANY_RELATION_TYPES = new Set([\n 'oneToMany',\n 'manyToMany',\n 'manyWay',\n 'morphToMany',\n 'morphMany',\n]);\n\n/**\n * Canonical \"is this relation a list\" predicate for the MCP output boundary.\n * Both the runtime shaping (reduceToIdentity) and the registered output schemas\n * (output-schemas.ts) MUST use this single definition — the MCP SDK validates\n * structuredContent against the schema, so any divergence fails the tool call.\n * Intentionally broader than `relations.isAnyToMany` from @strapi/utils, which\n * ignores `manyWay` and the morph variants.\n */\nexport const isManyRelationForMcp = (attribute: { relation?: string }): boolean =>\n MANY_RELATION_TYPES.has(attribute.relation ?? '');\n\ntype RelationIdentity = {\n documentId: string;\n locale?: string;\n __type?: string;\n status?: string;\n};\n\n/**\n * Extracts identity fields from a single relation entry.\n * Returns undefined when the entry has no documentId (e.g. a bare {count} object).\n */\nconst pickIdentity = (entry: unknown): RelationIdentity | undefined => {\n if (entry === null || typeof entry !== 'object') {\n return undefined;\n }\n\n const obj = entry as Record<string, unknown>;\n\n if (typeof obj.documentId !== 'string') {\n return undefined;\n }\n\n const identity: RelationIdentity = { documentId: obj.documentId };\n\n if (typeof obj.locale === 'string') {\n identity.locale = obj.locale;\n }\n\n if (typeof obj.__type === 'string') {\n identity.__type = obj.__type;\n }\n\n // Preserve the computed publish status on `localizations` entries — it is\n // calculated by formatDocumentWithMetadata BEFORE shaping (calculate, then strip).\n // Non-localization relation entries never carry a string `status`, so this is a no-op for them.\n if (typeof obj.status === 'string') {\n identity.status = obj.status;\n }\n\n return identity;\n};\n\n/**\n * Reduces a populated relation value to identity-only shape.\n *\n * to-one → { documentId, locale?, __type? } | null\n * to-many → Array<{ documentId, locale?, __type? }> ([] when empty)\n */\nconst reduceToIdentity = (\n attribute: { relation?: string },\n value: unknown\n): RelationIdentity | RelationIdentity[] | null => {\n const isMany = isManyRelationForMcp(attribute);\n\n if (isMany) {\n if (Array.isArray(value)) {\n return value.map(pickIdentity).filter((v): v is RelationIdentity => v !== undefined);\n }\n // defensive: { count: N } or null/undefined → empty array\n return [];\n }\n\n // to-one\n if (value === null || value === undefined) {\n return null;\n }\n\n if (Array.isArray(value)) {\n // should not happen, but guard: treat first element\n return pickIdentity(value[0]) ?? null;\n }\n\n return pickIdentity(value) ?? null;\n};\n\n/**\n * Post-sanitize shaping visitor.\n * Reduces every relation attribute to identity-only (documentId + locale? + __type?).\n * Skips admin::user relations — those are out of scope and preserved as-is.\n */\nconst shapeRelationToIdentity: Parameters<typeof traverseEntity>[0] = (\n { key, value, attribute },\n { set }\n) => {\n if (attribute?.type !== 'relation') {\n return;\n }\n\n const target = (attribute as { target?: string }).target;\n\n // Out of scope — admin user records are preserved untouched (tracked separately).\n if (target === 'admin::user') {\n return;\n }\n\n // @ts-expect-error — reduceToIdentity returns a narrower type; traverseEntity Data allows unknown\n set(key, reduceToIdentity(attribute as { relation?: string }, value));\n};\n\n/**\n * Applies identity shaping to all relation fields in a document, including\n * nested fields inside components, dynamic zones, and `localizations`.\n *\n * This covers leak family #1 (relation targets) and #2 (localizations full draft rows)\n * with the same single mechanism.\n */\nexport const shapeRelationsForMcp = async (\n uid: UID.Schema,\n data: Record<string, unknown>\n): Promise<Record<string, unknown>> => {\n return traverseEntity(\n shapeRelationToIdentity,\n {\n schema: strapi.getModel(uid),\n getModel: strapi.getModel.bind(strapi),\n },\n // @ts-expect-error — traverseEntity expects Data; post-sanitize documents are compatible at runtime\n data\n );\n};\n\n// Export for unit-testing without a full strapi instance\nexport { reduceToIdentity, MANY_RELATION_TYPES };\n"],"names":["MANY_RELATION_TYPES","Set","isManyRelationForMcp","attribute","has","relation","pickIdentity","entry","undefined","obj","documentId","identity","locale","__type","status","reduceToIdentity","value","isMany","Array","isArray","map","filter","v","shapeRelationToIdentity","key","set","type","target","shapeRelationsForMcp","uid","data","traverseEntity","schema","strapi","getModel","bind"],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { traverseEntity } from '@strapi/utils';
|
|
2
|
+
|
|
3
|
+
// Relations whose cardinality is "many" — maps to Array output.
|
|
4
|
+
// Includes non-owning variants and morph-many.
|
|
5
|
+
const MANY_RELATION_TYPES = new Set([
|
|
6
|
+
'oneToMany',
|
|
7
|
+
'manyToMany',
|
|
8
|
+
'manyWay',
|
|
9
|
+
'morphToMany',
|
|
10
|
+
'morphMany'
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Canonical "is this relation a list" predicate for the MCP output boundary.
|
|
14
|
+
* Both the runtime shaping (reduceToIdentity) and the registered output schemas
|
|
15
|
+
* (output-schemas.ts) MUST use this single definition — the MCP SDK validates
|
|
16
|
+
* structuredContent against the schema, so any divergence fails the tool call.
|
|
17
|
+
* Intentionally broader than `relations.isAnyToMany` from @strapi/utils, which
|
|
18
|
+
* ignores `manyWay` and the morph variants.
|
|
19
|
+
*/ const isManyRelationForMcp = (attribute)=>MANY_RELATION_TYPES.has(attribute.relation ?? '');
|
|
20
|
+
/**
|
|
21
|
+
* Extracts identity fields from a single relation entry.
|
|
22
|
+
* Returns undefined when the entry has no documentId (e.g. a bare {count} object).
|
|
23
|
+
*/ const pickIdentity = (entry)=>{
|
|
24
|
+
if (entry === null || typeof entry !== 'object') {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const obj = entry;
|
|
28
|
+
if (typeof obj.documentId !== 'string') {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const identity = {
|
|
32
|
+
documentId: obj.documentId
|
|
33
|
+
};
|
|
34
|
+
if (typeof obj.locale === 'string') {
|
|
35
|
+
identity.locale = obj.locale;
|
|
36
|
+
}
|
|
37
|
+
if (typeof obj.__type === 'string') {
|
|
38
|
+
identity.__type = obj.__type;
|
|
39
|
+
}
|
|
40
|
+
// Preserve the computed publish status on `localizations` entries — it is
|
|
41
|
+
// calculated by formatDocumentWithMetadata BEFORE shaping (calculate, then strip).
|
|
42
|
+
// Non-localization relation entries never carry a string `status`, so this is a no-op for them.
|
|
43
|
+
if (typeof obj.status === 'string') {
|
|
44
|
+
identity.status = obj.status;
|
|
45
|
+
}
|
|
46
|
+
return identity;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Reduces a populated relation value to identity-only shape.
|
|
50
|
+
*
|
|
51
|
+
* to-one → { documentId, locale?, __type? } | null
|
|
52
|
+
* to-many → Array<{ documentId, locale?, __type? }> ([] when empty)
|
|
53
|
+
*/ const reduceToIdentity = (attribute, value)=>{
|
|
54
|
+
const isMany = isManyRelationForMcp(attribute);
|
|
55
|
+
if (isMany) {
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
return value.map(pickIdentity).filter((v)=>v !== undefined);
|
|
58
|
+
}
|
|
59
|
+
// defensive: { count: N } or null/undefined → empty array
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
// to-one
|
|
63
|
+
if (value === null || value === undefined) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
// should not happen, but guard: treat first element
|
|
68
|
+
return pickIdentity(value[0]) ?? null;
|
|
69
|
+
}
|
|
70
|
+
return pickIdentity(value) ?? null;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Post-sanitize shaping visitor.
|
|
74
|
+
* Reduces every relation attribute to identity-only (documentId + locale? + __type?).
|
|
75
|
+
* Skips admin::user relations — those are out of scope and preserved as-is.
|
|
76
|
+
*/ const shapeRelationToIdentity = ({ key, value, attribute }, { set })=>{
|
|
77
|
+
if (attribute?.type !== 'relation') {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const target = attribute.target;
|
|
81
|
+
// Out of scope — admin user records are preserved untouched (tracked separately).
|
|
82
|
+
if (target === 'admin::user') {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// @ts-expect-error — reduceToIdentity returns a narrower type; traverseEntity Data allows unknown
|
|
86
|
+
set(key, reduceToIdentity(attribute, value));
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Applies identity shaping to all relation fields in a document, including
|
|
90
|
+
* nested fields inside components, dynamic zones, and `localizations`.
|
|
91
|
+
*
|
|
92
|
+
* This covers leak family #1 (relation targets) and #2 (localizations full draft rows)
|
|
93
|
+
* with the same single mechanism.
|
|
94
|
+
*/ const shapeRelationsForMcp = async (uid, data)=>{
|
|
95
|
+
return traverseEntity(shapeRelationToIdentity, {
|
|
96
|
+
schema: strapi.getModel(uid),
|
|
97
|
+
getModel: strapi.getModel.bind(strapi)
|
|
98
|
+
}, // @ts-expect-error — traverseEntity expects Data; post-sanitize documents are compatible at runtime
|
|
99
|
+
data);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export { MANY_RELATION_TYPES, isManyRelationForMcp, reduceToIdentity, shapeRelationsForMcp };
|
|
103
|
+
//# sourceMappingURL=shape-relations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape-relations.mjs","sources":["../../../../server/src/mcp/sanitizers/shape-relations.ts"],"sourcesContent":["import { traverseEntity } from '@strapi/utils';\nimport type { UID } from '@strapi/types';\n\n// Relations whose cardinality is \"many\" — maps to Array output.\n// Includes non-owning variants and morph-many.\nconst MANY_RELATION_TYPES = new Set([\n 'oneToMany',\n 'manyToMany',\n 'manyWay',\n 'morphToMany',\n 'morphMany',\n]);\n\n/**\n * Canonical \"is this relation a list\" predicate for the MCP output boundary.\n * Both the runtime shaping (reduceToIdentity) and the registered output schemas\n * (output-schemas.ts) MUST use this single definition — the MCP SDK validates\n * structuredContent against the schema, so any divergence fails the tool call.\n * Intentionally broader than `relations.isAnyToMany` from @strapi/utils, which\n * ignores `manyWay` and the morph variants.\n */\nexport const isManyRelationForMcp = (attribute: { relation?: string }): boolean =>\n MANY_RELATION_TYPES.has(attribute.relation ?? '');\n\ntype RelationIdentity = {\n documentId: string;\n locale?: string;\n __type?: string;\n status?: string;\n};\n\n/**\n * Extracts identity fields from a single relation entry.\n * Returns undefined when the entry has no documentId (e.g. a bare {count} object).\n */\nconst pickIdentity = (entry: unknown): RelationIdentity | undefined => {\n if (entry === null || typeof entry !== 'object') {\n return undefined;\n }\n\n const obj = entry as Record<string, unknown>;\n\n if (typeof obj.documentId !== 'string') {\n return undefined;\n }\n\n const identity: RelationIdentity = { documentId: obj.documentId };\n\n if (typeof obj.locale === 'string') {\n identity.locale = obj.locale;\n }\n\n if (typeof obj.__type === 'string') {\n identity.__type = obj.__type;\n }\n\n // Preserve the computed publish status on `localizations` entries — it is\n // calculated by formatDocumentWithMetadata BEFORE shaping (calculate, then strip).\n // Non-localization relation entries never carry a string `status`, so this is a no-op for them.\n if (typeof obj.status === 'string') {\n identity.status = obj.status;\n }\n\n return identity;\n};\n\n/**\n * Reduces a populated relation value to identity-only shape.\n *\n * to-one → { documentId, locale?, __type? } | null\n * to-many → Array<{ documentId, locale?, __type? }> ([] when empty)\n */\nconst reduceToIdentity = (\n attribute: { relation?: string },\n value: unknown\n): RelationIdentity | RelationIdentity[] | null => {\n const isMany = isManyRelationForMcp(attribute);\n\n if (isMany) {\n if (Array.isArray(value)) {\n return value.map(pickIdentity).filter((v): v is RelationIdentity => v !== undefined);\n }\n // defensive: { count: N } or null/undefined → empty array\n return [];\n }\n\n // to-one\n if (value === null || value === undefined) {\n return null;\n }\n\n if (Array.isArray(value)) {\n // should not happen, but guard: treat first element\n return pickIdentity(value[0]) ?? null;\n }\n\n return pickIdentity(value) ?? null;\n};\n\n/**\n * Post-sanitize shaping visitor.\n * Reduces every relation attribute to identity-only (documentId + locale? + __type?).\n * Skips admin::user relations — those are out of scope and preserved as-is.\n */\nconst shapeRelationToIdentity: Parameters<typeof traverseEntity>[0] = (\n { key, value, attribute },\n { set }\n) => {\n if (attribute?.type !== 'relation') {\n return;\n }\n\n const target = (attribute as { target?: string }).target;\n\n // Out of scope — admin user records are preserved untouched (tracked separately).\n if (target === 'admin::user') {\n return;\n }\n\n // @ts-expect-error — reduceToIdentity returns a narrower type; traverseEntity Data allows unknown\n set(key, reduceToIdentity(attribute as { relation?: string }, value));\n};\n\n/**\n * Applies identity shaping to all relation fields in a document, including\n * nested fields inside components, dynamic zones, and `localizations`.\n *\n * This covers leak family #1 (relation targets) and #2 (localizations full draft rows)\n * with the same single mechanism.\n */\nexport const shapeRelationsForMcp = async (\n uid: UID.Schema,\n data: Record<string, unknown>\n): Promise<Record<string, unknown>> => {\n return traverseEntity(\n shapeRelationToIdentity,\n {\n schema: strapi.getModel(uid),\n getModel: strapi.getModel.bind(strapi),\n },\n // @ts-expect-error — traverseEntity expects Data; post-sanitize documents are compatible at runtime\n data\n );\n};\n\n// Export for unit-testing without a full strapi instance\nexport { reduceToIdentity, MANY_RELATION_TYPES };\n"],"names":["MANY_RELATION_TYPES","Set","isManyRelationForMcp","attribute","has","relation","pickIdentity","entry","undefined","obj","documentId","identity","locale","__type","status","reduceToIdentity","value","isMany","Array","isArray","map","filter","v","shapeRelationToIdentity","key","set","type","target","shapeRelationsForMcp","uid","data","traverseEntity","schema","strapi","getModel","bind"],"mappings":"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"}
|
|
@@ -43,9 +43,6 @@ const isCustomFieldAttribute = (attr)=>typeof attr === 'object' && attr !== null
|
|
|
43
43
|
* here to avoid a cross-package import from @strapi/content-manager into
|
|
44
44
|
* @strapi/core (which is not a listed dependency).
|
|
45
45
|
*
|
|
46
|
-
* TODO — custom fields call `strapi.get('custom-fields')` at schema-build
|
|
47
|
-
* time; confirm with an integration test that the registry is populated when MCP
|
|
48
|
-
* tools are registered (post-bootstrap).
|
|
49
46
|
*/ const attributeToInputSchema = (strapi, attr, visited = new Set())=>{
|
|
50
47
|
switch(attr.type){
|
|
51
48
|
case 'string':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-schema.js","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n * TODO — custom fields call `strapi.get('custom-fields')` at schema-build\n * time; confirm with an integration test that the registry is populated when MCP\n * tools are registered (post-bootstrap).\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-schema.js","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|
|
@@ -41,9 +41,6 @@ const isCustomFieldAttribute = (attr)=>typeof attr === 'object' && attr !== null
|
|
|
41
41
|
* here to avoid a cross-package import from @strapi/content-manager into
|
|
42
42
|
* @strapi/core (which is not a listed dependency).
|
|
43
43
|
*
|
|
44
|
-
* TODO — custom fields call `strapi.get('custom-fields')` at schema-build
|
|
45
|
-
* time; confirm with an integration test that the registry is populated when MCP
|
|
46
|
-
* tools are registered (post-bootstrap).
|
|
47
44
|
*/ const attributeToInputSchema = (strapi, attr, visited = new Set())=>{
|
|
48
45
|
switch(attr.type){
|
|
49
46
|
case 'string':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-schema.mjs","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n * TODO — custom fields call `strapi.get('custom-fields')` at schema-build\n * time; confirm with an integration test that the registry is populated when MCP\n * tools are registered (post-bootstrap).\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data-schema.mjs","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var strapiUtils = require('@strapi/utils');
|
|
4
|
+
var shapeRelations = require('../sanitizers/shape-relations.js');
|
|
4
5
|
|
|
6
|
+
const relationIdentity = strapiUtils.z.object({
|
|
7
|
+
documentId: strapiUtils.z.string(),
|
|
8
|
+
locale: strapiUtils.z.string().optional(),
|
|
9
|
+
__type: strapiUtils.z.string().optional(),
|
|
10
|
+
// Computed publish status preserved on `localizations` entries (calculate, then strip).
|
|
11
|
+
status: strapiUtils.z.string().optional()
|
|
12
|
+
});
|
|
13
|
+
const buildAttributeSchema = (key, attributes)=>{
|
|
14
|
+
const attribute = attributes[key];
|
|
15
|
+
if (attribute?.type !== 'relation') {
|
|
16
|
+
return strapiUtils.z.unknown().optional();
|
|
17
|
+
}
|
|
18
|
+
// admin::user relations are out of scope — left as unknown
|
|
19
|
+
if (attribute.target === 'admin::user') {
|
|
20
|
+
return strapiUtils.z.unknown().optional();
|
|
21
|
+
}
|
|
22
|
+
// Must match the runtime shaping cardinality (shape-relations.ts) — the MCP SDK
|
|
23
|
+
// validates structuredContent against this schema, so a mismatch fails the tool call.
|
|
24
|
+
if (shapeRelations.isManyRelationForMcp(attribute)) {
|
|
25
|
+
return strapiUtils.z.array(relationIdentity).optional();
|
|
26
|
+
}
|
|
27
|
+
return relationIdentity.nullable().optional();
|
|
28
|
+
};
|
|
5
29
|
const buildOutputDataSchema = (attributes, permittedFields)=>{
|
|
6
30
|
const readableKeys = Object.keys(attributes).filter((key)=>permittedFields === null || permittedFields.has(key));
|
|
7
31
|
if (readableKeys.length === 0) {
|
|
@@ -9,7 +33,7 @@ const buildOutputDataSchema = (attributes, permittedFields)=>{
|
|
|
9
33
|
}
|
|
10
34
|
const shape = Object.fromEntries(readableKeys.map((key)=>[
|
|
11
35
|
key,
|
|
12
|
-
|
|
36
|
+
buildAttributeSchema(key, attributes)
|
|
13
37
|
]));
|
|
14
38
|
return strapiUtils.z.object(shape).loose();
|
|
15
39
|
};
|
|
@@ -37,9 +61,11 @@ const buildOutputDataSchema = (attributes, permittedFields)=>{
|
|
|
37
61
|
}).loose();
|
|
38
62
|
/**
|
|
39
63
|
* Builds the MCP output schema for a delete response (`{ data }`).
|
|
40
|
-
*
|
|
41
|
-
*/ const buildDeleteOutputSchema = (
|
|
42
|
-
|
|
64
|
+
* Delete handlers return an empty data object, so do not require document relation fields.
|
|
65
|
+
*/ const buildDeleteOutputSchema = (// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
66
|
+
_attributes, // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
67
|
+
_readFields)=>strapiUtils.z.object({
|
|
68
|
+
data: strapiUtils.z.object({}).loose().nullable()
|
|
43
69
|
}).loose();
|
|
44
70
|
|
|
45
71
|
exports.buildDeleteOutputSchema = buildDeleteOutputSchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-schemas.js","sources":["../../../../server/src/mcp/schemas/output-schemas.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Struct } from '@strapi/types';\n\nconst buildOutputDataSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields: Set<string> | null\n): z.ZodTypeAny => {\n const readableKeys = Object.keys(attributes).filter(\n (key) => permittedFields === null || permittedFields.has(key)\n );\n\n if (readableKeys.length === 0) {\n return z.record(z.string(), z.unknown());\n }\n\n const shape = Object.fromEntries(readableKeys.map((key) => [key,
|
|
1
|
+
{"version":3,"file":"output-schemas.js","sources":["../../../../server/src/mcp/schemas/output-schemas.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Struct } from '@strapi/types';\n\nimport { isManyRelationForMcp } from '../sanitizers/shape-relations';\n\nconst relationIdentity = z.object({\n documentId: z.string(),\n locale: z.string().optional(),\n __type: z.string().optional(),\n // Computed publish status preserved on `localizations` entries (calculate, then strip).\n status: z.string().optional(),\n});\n\nconst buildAttributeSchema = (key: string, attributes: Struct.SchemaAttributes): z.ZodTypeAny => {\n const attribute = attributes[key];\n\n if (attribute?.type !== 'relation') {\n return z.unknown().optional();\n }\n\n // admin::user relations are out of scope — left as unknown\n if ((attribute as { target?: string }).target === 'admin::user') {\n return z.unknown().optional();\n }\n\n // Must match the runtime shaping cardinality (shape-relations.ts) — the MCP SDK\n // validates structuredContent against this schema, so a mismatch fails the tool call.\n if (isManyRelationForMcp(attribute as { relation?: string })) {\n return z.array(relationIdentity).optional();\n }\n\n return relationIdentity.nullable().optional();\n};\n\nconst buildOutputDataSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields: Set<string> | null\n): z.ZodTypeAny => {\n const readableKeys = Object.keys(attributes).filter(\n (key) => permittedFields === null || permittedFields.has(key)\n );\n\n if (readableKeys.length === 0) {\n return z.record(z.string(), z.unknown());\n }\n\n const shape = Object.fromEntries(\n readableKeys.map((key) => [key, buildAttributeSchema(key, attributes)])\n );\n\n return z.object(shape).loose();\n};\n\n/**\n * Builds the MCP output schema for a single-document response (`{ data, meta }`).\n * Field shape is constrained to `readFields` when non-null (RBAC field filtering).\n */\nexport const buildDocumentOutputSchema = (\n attributes: Struct.SchemaAttributes,\n readFields: Set<string> | null\n): z.ZodObject<z.ZodRawShape> =>\n z\n .object({\n data: buildOutputDataSchema(attributes, readFields).nullable(),\n meta: z\n .object({\n availableLocales: z.array(z.record(z.string(), z.unknown())).optional(),\n availableStatus: z.array(z.record(z.string(), z.unknown())).optional(),\n })\n .optional(),\n })\n .loose();\n\n/**\n * Builds the MCP output schema for a paginated list response (`{ results, pagination }`).\n * Field shape is constrained to `readFields` when non-null (RBAC field filtering).\n */\nexport const buildListOutputSchema = (\n attributes: Struct.SchemaAttributes,\n readFields: Set<string> | null\n): z.ZodObject<z.ZodRawShape> =>\n z\n .object({\n results: z.array(buildOutputDataSchema(attributes, readFields)),\n pagination: z.object({\n page: z.number(),\n pageSize: z.number(),\n pageCount: z.number(),\n total: z.number(),\n }),\n })\n .loose();\n\n/**\n * Builds the MCP output schema for a delete response (`{ data }`).\n * Delete handlers return an empty data object, so do not require document relation fields.\n */\nexport const buildDeleteOutputSchema = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _attributes: Struct.SchemaAttributes,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _readFields: Set<string> | null\n): z.ZodObject<z.ZodRawShape> =>\n z\n .object({\n data: z.object({}).loose().nullable(),\n })\n .loose();\n"],"names":["relationIdentity","z","object","documentId","string","locale","optional","__type","status","buildAttributeSchema","key","attributes","attribute","type","unknown","target","isManyRelationForMcp","array","nullable","buildOutputDataSchema","permittedFields","readableKeys","Object","keys","filter","has","length","record","shape","fromEntries","map","loose","buildDocumentOutputSchema","readFields","data","meta","availableLocales","availableStatus","buildListOutputSchema","results","pagination","page","number","pageSize","pageCount","total","buildDeleteOutputSchema","_attributes","_readFields"],"mappings":";;;;;AAKA,MAAMA,gBAAAA,GAAmBC,aAAAA,CAAEC,MAAM,CAAC;AAChCC,IAAAA,UAAAA,EAAYF,cAAEG,MAAM,EAAA;IACpBC,MAAAA,EAAQJ,aAAAA,CAAEG,MAAM,EAAA,CAAGE,QAAQ,EAAA;IAC3BC,MAAAA,EAAQN,aAAAA,CAAEG,MAAM,EAAA,CAAGE,QAAQ,EAAA;;IAE3BE,MAAAA,EAAQP,aAAAA,CAAEG,MAAM,EAAA,CAAGE,QAAQ;AAC7B,CAAA,CAAA;AAEA,MAAMG,oBAAAA,GAAuB,CAACC,GAAAA,EAAaC,UAAAA,GAAAA;IACzC,MAAMC,SAAAA,GAAYD,UAAU,CAACD,GAAAA,CAAI;IAEjC,IAAIE,SAAAA,EAAWC,SAAS,UAAA,EAAY;QAClC,OAAOZ,aAAAA,CAAEa,OAAO,EAAA,CAAGR,QAAQ,EAAA;AAC7B,IAAA;;AAGA,IAAA,IAAI,SAACM,CAAkCG,MAAM,KAAK,aAAA,EAAe;QAC/D,OAAOd,aAAAA,CAAEa,OAAO,EAAA,CAAGR,QAAQ,EAAA;AAC7B,IAAA;;;AAIA,IAAA,IAAIU,oCAAqBJ,SAAAA,CAAAA,EAAqC;AAC5D,QAAA,OAAOX,aAAAA,CAAEgB,KAAK,CAACjB,gBAAAA,CAAAA,CAAkBM,QAAQ,EAAA;AAC3C,IAAA;IAEA,OAAON,gBAAAA,CAAiBkB,QAAQ,EAAA,CAAGZ,QAAQ,EAAA;AAC7C,CAAA;AAEA,MAAMa,qBAAAA,GAAwB,CAC5BR,UAAAA,EACAS,eAAAA,GAAAA;AAEA,IAAA,MAAMC,YAAAA,GAAeC,MAAAA,CAAOC,IAAI,CAACZ,UAAAA,CAAAA,CAAYa,MAAM,CACjD,CAACd,GAAAA,GAAQU,eAAAA,KAAoB,IAAA,IAAQA,eAAAA,CAAgBK,GAAG,CAACf,GAAAA,CAAAA,CAAAA;IAG3D,IAAIW,YAAAA,CAAaK,MAAM,KAAK,CAAA,EAAG;AAC7B,QAAA,OAAOzB,cAAE0B,MAAM,CAAC1B,cAAEG,MAAM,EAAA,EAAIH,cAAEa,OAAO,EAAA,CAAA;AACvC,IAAA;IAEA,MAAMc,KAAAA,GAAQN,OAAOO,WAAW,CAC9BR,aAAaS,GAAG,CAAC,CAACpB,GAAAA,GAAQ;AAACA,YAAAA,GAAAA;AAAKD,YAAAA,oBAAAA,CAAqBC,GAAAA,EAAKC,UAAAA;AAAY,SAAA,CAAA,CAAA;AAGxE,IAAA,OAAOV,aAAAA,CAAEC,MAAM,CAAC0B,KAAAA,CAAAA,CAAOG,KAAK,EAAA;AAC9B,CAAA;AAEA;;;UAIaC,yBAAAA,GAA4B,CACvCrB,YACAsB,UAAAA,GAEAhC,aAAAA,CACGC,MAAM,CAAC;QACNgC,IAAAA,EAAMf,qBAAAA,CAAsBR,UAAAA,EAAYsB,UAAAA,CAAAA,CAAYf,QAAQ,EAAA;QAC5DiB,IAAAA,EAAMlC,aAAAA,CACHC,MAAM,CAAC;AACNkC,YAAAA,gBAAAA,EAAkBnC,aAAAA,CAAEgB,KAAK,CAAChB,aAAAA,CAAE0B,MAAM,CAAC1B,aAAAA,CAAEG,MAAM,EAAA,EAAIH,aAAAA,CAAEa,OAAO,EAAA,CAAA,CAAA,CAAKR,QAAQ,EAAA;AACrE+B,YAAAA,eAAAA,EAAiBpC,aAAAA,CAAEgB,KAAK,CAAChB,aAAAA,CAAE0B,MAAM,CAAC1B,aAAAA,CAAEG,MAAM,EAAA,EAAIH,aAAAA,CAAEa,OAAO,EAAA,CAAA,CAAA,CAAKR,QAAQ;AACtE,SAAA,CAAA,CACCA,QAAQ;AACb,KAAA,CAAA,CACCyB,KAAK;AAEV;;;UAIaO,qBAAAA,GAAwB,CACnC3B,YACAsB,UAAAA,GAEAhC,aAAAA,CACGC,MAAM,CAAC;AACNqC,QAAAA,OAAAA,EAAStC,aAAAA,CAAEgB,KAAK,CAACE,qBAAAA,CAAsBR,UAAAA,EAAYsB,UAAAA,CAAAA,CAAAA;QACnDO,UAAAA,EAAYvC,aAAAA,CAAEC,MAAM,CAAC;AACnBuC,YAAAA,IAAAA,EAAMxC,cAAEyC,MAAM,EAAA;AACdC,YAAAA,QAAAA,EAAU1C,cAAEyC,MAAM,EAAA;AAClBE,YAAAA,SAAAA,EAAW3C,cAAEyC,MAAM,EAAA;AACnBG,YAAAA,KAAAA,EAAO5C,cAAEyC,MAAM;AACjB,SAAA;AACF,KAAA,CAAA,CACCX,KAAK;AAEV;;;AAGC,IACM,MAAMe,uBAAAA,GAA0B;AAErCC,WAAAA;AAEAC,WAAAA,GAEA/C,aAAAA,CACGC,MAAM,CAAC;AACNgC,QAAAA,IAAAA,EAAMjC,cAAEC,MAAM,CAAC,EAAC,CAAA,CAAG6B,KAAK,GAAGb,QAAQ;AACrC,KAAA,CAAA,CACCa,KAAK;;;;;;"}
|