@strapi/upload 5.37.1 → 5.38.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/ai/components/AIAssetCard.js.map +1 -1
- package/dist/admin/ai/components/AIAssetCard.mjs +1 -1
- package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.js.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.mjs +1 -1
- package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AudioAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/AudioAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AudioPreview.js.map +1 -1
- package/dist/admin/components/AssetCard/AudioPreview.mjs.map +1 -1
- package/dist/admin/components/AssetCard/DocAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/DocAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
- package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js.map +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PageSize.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PageSize.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/Pagination.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/PaginationFooter.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/PaginationFooter/PaginationFooter.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/utils/isSelectable.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/utils/isSelectable.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/DialogFooter.js.map +1 -1
- package/dist/admin/components/AssetDialog/DialogFooter.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs.map +1 -1
- package/dist/admin/components/AssetGridList/AssetGridList.js.map +1 -1
- package/dist/admin/components/AssetGridList/AssetGridList.mjs.map +1 -1
- package/dist/admin/components/AssetGridList/Draggable.js.map +1 -1
- package/dist/admin/components/AssetGridList/Draggable.mjs.map +1 -1
- package/dist/admin/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/admin/components/Breadcrumbs/Breadcrumbs.mjs.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.js.map +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js.map +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs.map +1 -1
- package/dist/admin/components/ContextInfo/ContextInfo.js.map +1 -1
- package/dist/admin/components/ContextInfo/ContextInfo.mjs.map +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.js.map +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/DialogHeader.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/DialogHeader.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/FocalPointActions.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +1 -4
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +1 -4
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewComponents.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewComponents.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/RemoveAssetDialog.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/RemoveAssetDialog.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/RemoveFolderDialog.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/RemoveFolderDialog.mjs.map +1 -1
- package/dist/admin/components/EmptyAssets/EmptyAssetGrid.js.map +1 -1
- package/dist/admin/components/EmptyAssets/EmptyAssetGrid.mjs.map +1 -1
- package/dist/admin/components/EmptyAssets/EmptyAssets.js.map +1 -1
- package/dist/admin/components/EmptyAssets/EmptyAssets.mjs.map +1 -1
- package/dist/admin/components/FilterList/FilterList.js.map +1 -1
- package/dist/admin/components/FilterList/FilterList.mjs.map +1 -1
- package/dist/admin/components/FilterList/FilterTag.js.map +1 -1
- package/dist/admin/components/FilterList/FilterTag.mjs.map +1 -1
- package/dist/admin/components/FilterPopover/FilterPopover.js.map +1 -1
- package/dist/admin/components/FilterPopover/FilterPopover.mjs.map +1 -1
- package/dist/admin/components/FilterPopover/FilterValueInput.js.map +1 -1
- package/dist/admin/components/FilterPopover/FilterValueInput.mjs.map +1 -1
- package/dist/admin/components/FilterPopover/utils/getFilterList.js.map +1 -1
- package/dist/admin/components/FilterPopover/utils/getFilterList.mjs.map +1 -1
- package/dist/admin/components/FolderCard/FolderCard/FolderCard.js.map +1 -1
- package/dist/admin/components/FolderCard/FolderCard/FolderCard.mjs.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardBody/FolderCardBody.js.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardBody/FolderCardBody.mjs.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardBodyAction/FolderCardBodyAction.js.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardBodyAction/FolderCardBodyAction.mjs.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardCheckbox/FolderCardCheckbox.js.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardCheckbox/FolderCardCheckbox.mjs.map +1 -1
- package/dist/admin/components/FolderCard/contexts/FolderCard.js.map +1 -1
- package/dist/admin/components/FolderCard/contexts/FolderCard.mjs.map +1 -1
- package/dist/admin/components/FolderGridList/FolderGridList.js.map +1 -1
- package/dist/admin/components/FolderGridList/FolderGridList.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssets.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs.map +1 -1
- package/dist/admin/components/SelectTree/Option.js.map +1 -1
- package/dist/admin/components/SelectTree/Option.mjs.map +1 -1
- package/dist/admin/components/SelectTree/SelectTree.js.map +1 -1
- package/dist/admin/components/SelectTree/SelectTree.mjs +1 -1
- package/dist/admin/components/SelectTree/SelectTree.mjs.map +1 -1
- package/dist/admin/components/SelectTree/utils/flattenTree.js.map +1 -1
- package/dist/admin/components/SelectTree/utils/flattenTree.mjs.map +1 -1
- package/dist/admin/components/SelectTree/utils/getOpenValues.js.map +1 -1
- package/dist/admin/components/SelectTree/utils/getOpenValues.mjs.map +1 -1
- package/dist/admin/components/SelectTree/utils/getValuesToClose.js.map +1 -1
- package/dist/admin/components/SelectTree/utils/getValuesToClose.mjs.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
- package/dist/admin/components/TableList/CellContent.js.map +1 -1
- package/dist/admin/components/TableList/CellContent.mjs.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.mjs +1 -1
- package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -1
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/TableList/TableRows.js.map +1 -1
- package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/UploadAssetDialog.mjs.map +1 -1
- package/dist/admin/components/UploadProgress/UploadProgress.js.map +1 -1
- package/dist/admin/components/UploadProgress/UploadProgress.mjs.map +1 -1
- package/dist/admin/constants.js.map +1 -1
- package/dist/admin/constants.mjs.map +1 -1
- package/dist/admin/future/App.js.map +1 -1
- package/dist/admin/future/App.mjs.map +1 -1
- package/dist/admin/future/components/Drawer.js +189 -0
- package/dist/admin/future/components/Drawer.js.map +1 -0
- package/dist/admin/future/components/Drawer.mjs +166 -0
- package/dist/admin/future/components/Drawer.mjs.map +1 -0
- package/dist/admin/future/components/UploadProgressDialog.js +60 -101
- package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
- package/dist/admin/future/components/UploadProgressDialog.mjs +62 -84
- package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.js +155 -100
- package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
- package/dist/admin/future/pages/Assets/AssetsPage.mjs +160 -105
- package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +406 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +384 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js +215 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs +194 -0
- package/dist/admin/future/pages/Assets/components/AssetDetails/AssetPreview.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js +37 -8
- package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +38 -9
- package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.js +35 -5
- package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +37 -7
- package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js +143 -0
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs +141 -0
- package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZone.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
- package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js +127 -0
- package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.js.map +1 -0
- package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.mjs +106 -0
- package/dist/admin/future/pages/Assets/components/ImportFromUrlDialog.mjs.map +1 -0
- package/dist/admin/future/pages/Assets/constants.js.map +1 -1
- package/dist/admin/future/pages/Assets/constants.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderInfo.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderInfo.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
- package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
- package/dist/admin/future/services/api.js +181 -97
- package/dist/admin/future/services/api.js.map +1 -1
- package/dist/admin/future/services/api.mjs +181 -98
- package/dist/admin/future/services/api.mjs.map +1 -1
- package/dist/admin/future/services/assets.js +14 -1
- package/dist/admin/future/services/assets.js.map +1 -1
- package/dist/admin/future/services/assets.mjs +14 -2
- package/dist/admin/future/services/assets.mjs.map +1 -1
- package/dist/admin/future/services/folders.js +16 -1
- package/dist/admin/future/services/folders.js.map +1 -1
- package/dist/admin/future/services/folders.mjs +16 -2
- package/dist/admin/future/services/folders.mjs.map +1 -1
- package/dist/admin/future/store/hooks.js.map +1 -1
- package/dist/admin/future/store/hooks.mjs.map +1 -1
- package/dist/admin/future/store/uploadProgress.js +7 -4
- package/dist/admin/future/store/uploadProgress.js.map +1 -1
- package/dist/admin/future/store/uploadProgress.mjs +7 -4
- package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
- package/dist/admin/future/utils/files.js +105 -3
- package/dist/admin/future/utils/files.js.map +1 -1
- package/dist/admin/future/utils/files.mjs +104 -4
- package/dist/admin/future/utils/files.mjs.map +1 -1
- package/dist/admin/future/utils/getAssetIcon.js +3 -3
- package/dist/admin/future/utils/getAssetIcon.js.map +1 -1
- package/dist/admin/future/utils/getAssetIcon.mjs +4 -4
- package/dist/admin/future/utils/getAssetIcon.mjs.map +1 -1
- package/dist/admin/future/utils/translations.js.map +1 -1
- package/dist/admin/future/utils/translations.mjs.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -1
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -1
- package/dist/admin/hooks/useAiAvailability.js.map +1 -1
- package/dist/admin/hooks/useAiAvailability.mjs.map +1 -1
- package/dist/admin/hooks/useAssets.js.map +1 -1
- package/dist/admin/hooks/useAssets.mjs.map +1 -1
- package/dist/admin/hooks/useBulkEdit.js.map +1 -1
- package/dist/admin/hooks/useBulkEdit.mjs.map +1 -1
- package/dist/admin/hooks/useBulkMove.js.map +1 -1
- package/dist/admin/hooks/useBulkMove.mjs.map +1 -1
- package/dist/admin/hooks/useBulkRemove.js.map +1 -1
- package/dist/admin/hooks/useBulkRemove.mjs.map +1 -1
- package/dist/admin/hooks/useConfig.js.map +1 -1
- package/dist/admin/hooks/useConfig.mjs.map +1 -1
- package/dist/admin/hooks/useCropImg.js.map +1 -1
- package/dist/admin/hooks/useCropImg.mjs.map +1 -1
- package/dist/admin/hooks/useEditAsset.js.map +1 -1
- package/dist/admin/hooks/useEditAsset.mjs.map +1 -1
- package/dist/admin/hooks/useEditFolder.js.map +1 -1
- package/dist/admin/hooks/useEditFolder.mjs.map +1 -1
- package/dist/admin/hooks/useFolder.js.map +1 -1
- package/dist/admin/hooks/useFolder.mjs.map +1 -1
- package/dist/admin/hooks/useFolderStructure.js.map +1 -1
- package/dist/admin/hooks/useFolderStructure.mjs.map +1 -1
- package/dist/admin/hooks/useFolders.js.map +1 -1
- package/dist/admin/hooks/useFolders.mjs.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.js.map +1 -1
- package/dist/admin/hooks/useMediaLibraryPermissions.mjs.map +1 -1
- package/dist/admin/hooks/useModalQueryParams.js.map +1 -1
- package/dist/admin/hooks/useModalQueryParams.mjs.map +1 -1
- package/dist/admin/hooks/usePersistentState.js.map +1 -1
- package/dist/admin/hooks/usePersistentState.mjs.map +1 -1
- package/dist/admin/hooks/useRemoveAsset.js.map +1 -1
- package/dist/admin/hooks/useRemoveAsset.mjs.map +1 -1
- package/dist/admin/hooks/useSelectionState.js.map +1 -1
- package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
- package/dist/admin/hooks/useSettings.js.map +1 -1
- package/dist/admin/hooks/useSettings.mjs.map +1 -1
- package/dist/admin/hooks/useTracking.js.map +1 -1
- package/dist/admin/hooks/useTracking.mjs.map +1 -1
- package/dist/admin/hooks/useUpload.js.map +1 -1
- package/dist/admin/hooks/useUpload.mjs.map +1 -1
- package/dist/admin/hooks/utils/renameKeys.js.map +1 -1
- package/dist/admin/hooks/utils/renameKeys.mjs.map +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/package.json.js +1 -152
- package/dist/admin/package.json.js.map +1 -1
- package/dist/admin/package.json.mjs +2 -141
- package/dist/admin/package.json.mjs.map +1 -1
- package/dist/admin/pages/App/App.js.map +1 -1
- package/dist/admin/pages/App/App.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +3 -3
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/actionTypes.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/actionTypes.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/actions.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/actions.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/init.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/init.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/reducer.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/reducer.mjs +1 -1
- package/dist/admin/pages/App/ConfigureTheView/state/reducer.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.js +1 -1
- package/dist/admin/pages/App/MediaLibrary.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary.mjs +2 -2
- package/dist/admin/pages/App/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.js.map +1 -1
- package/dist/admin/pages/App/components/BulkActions.mjs.map +1 -1
- package/dist/admin/pages/App/components/BulkDeleteButton.js.map +1 -1
- package/dist/admin/pages/App/components/BulkDeleteButton.mjs.map +1 -1
- package/dist/admin/pages/App/components/BulkMoveButton.js.map +1 -1
- package/dist/admin/pages/App/components/BulkMoveButton.mjs.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.js.map +1 -1
- package/dist/admin/pages/App/components/EmptyOrNoPermissions.mjs.map +1 -1
- package/dist/admin/pages/App/components/Filters.js.map +1 -1
- package/dist/admin/pages/App/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/App/components/Header.js.map +1 -1
- package/dist/admin/pages/App/components/Header.mjs +2 -2
- package/dist/admin/pages/App/components/Header.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/reducer.js.map +1 -1
- package/dist/admin/pages/SettingsPage/reducer.mjs.map +1 -1
- package/dist/admin/pluginId.js.map +1 -1
- package/dist/admin/pluginId.mjs.map +1 -1
- package/dist/admin/src/future/components/Drawer.d.ts +32 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetPreview.d.ts +6 -0
- package/dist/admin/src/future/pages/Assets/components/AssetsGrid.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/AssetsTable.d.ts +2 -1
- package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +8 -0
- package/dist/admin/src/future/pages/Assets/components/ImportFromUrlDialog.d.ts +7 -0
- package/dist/admin/src/future/services/api.d.ts +10 -1
- package/dist/admin/src/future/services/assets.d.ts +2 -2
- package/dist/admin/src/future/services/folders.d.ts +1 -1
- package/dist/admin/src/future/store/uploadProgress.d.ts +1 -1
- package/dist/admin/src/future/utils/files.d.ts +70 -0
- package/dist/admin/translations/en.json.js +35 -3
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +35 -3
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/es.json.js +1 -1
- package/dist/admin/translations/es.json.mjs +1 -1
- package/dist/admin/utils/appendSearchParamsToUrl.js.map +1 -1
- package/dist/admin/utils/appendSearchParamsToUrl.mjs.map +1 -1
- package/dist/admin/utils/containsAssetFilter.js.map +1 -1
- package/dist/admin/utils/containsAssetFilter.mjs.map +1 -1
- package/dist/admin/utils/createAssetUrl.js.map +1 -1
- package/dist/admin/utils/createAssetUrl.mjs.map +1 -1
- package/dist/admin/utils/displayedFilters.js.map +1 -1
- package/dist/admin/utils/displayedFilters.mjs.map +1 -1
- package/dist/admin/utils/downloadFile.js.map +1 -1
- package/dist/admin/utils/downloadFile.mjs.map +1 -1
- package/dist/admin/utils/findRecursiveFolderByValue.js.map +1 -1
- package/dist/admin/utils/findRecursiveFolderByValue.mjs.map +1 -1
- package/dist/admin/utils/formatBytes.js.map +1 -1
- package/dist/admin/utils/formatBytes.mjs.map +1 -1
- package/dist/admin/utils/formatDuration.js.map +1 -1
- package/dist/admin/utils/formatDuration.mjs.map +1 -1
- package/dist/admin/utils/getAPIInnerErrors.js.map +1 -1
- package/dist/admin/utils/getAPIInnerErrors.mjs.map +1 -1
- package/dist/admin/utils/getAllowedFiles.js.map +1 -1
- package/dist/admin/utils/getAllowedFiles.mjs.map +1 -1
- package/dist/admin/utils/getBreadcrumbDataCM.js.map +1 -1
- package/dist/admin/utils/getBreadcrumbDataCM.mjs.map +1 -1
- package/dist/admin/utils/getBreadcrumbDataML.js.map +1 -1
- package/dist/admin/utils/getBreadcrumbDataML.mjs.map +1 -1
- package/dist/admin/utils/getFileExtension.js.map +1 -1
- package/dist/admin/utils/getFileExtension.mjs.map +1 -1
- package/dist/admin/utils/getFolderParents.js.map +1 -1
- package/dist/admin/utils/getFolderParents.mjs.map +1 -1
- package/dist/admin/utils/getFolderURL.js.map +1 -1
- package/dist/admin/utils/getFolderURL.mjs.map +1 -1
- package/dist/admin/utils/getTrad.js.map +1 -1
- package/dist/admin/utils/getTrad.mjs.map +1 -1
- package/dist/admin/utils/icons.js.map +1 -1
- package/dist/admin/utils/icons.mjs +1 -1
- package/dist/admin/utils/icons.mjs.map +1 -1
- package/dist/admin/utils/moveElement.js.map +1 -1
- package/dist/admin/utils/moveElement.mjs.map +1 -1
- package/dist/admin/utils/normalizeAPIError.js.map +1 -1
- package/dist/admin/utils/normalizeAPIError.mjs.map +1 -1
- package/dist/admin/utils/prefixFileUrlWithBackendUrl.js.map +1 -1
- package/dist/admin/utils/prefixFileUrlWithBackendUrl.mjs.map +1 -1
- package/dist/admin/utils/prefixPluginTranslations.js.map +1 -1
- package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -1
- package/dist/admin/utils/rawFileToAsset.js.map +1 -1
- package/dist/admin/utils/rawFileToAsset.mjs.map +1 -1
- package/dist/admin/utils/toSingularTypes.js.map +1 -1
- package/dist/admin/utils/toSingularTypes.mjs.map +1 -1
- package/dist/admin/utils/typeFromMime.js.map +1 -1
- package/dist/admin/utils/typeFromMime.mjs.map +1 -1
- package/dist/admin/utils/urlYupSchema.js.map +1 -1
- package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
- package/dist/admin/utils/urlsToAssets.js.map +1 -1
- package/dist/admin/utils/urlsToAssets.mjs.map +1 -1
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/config.mjs.map +1 -1
- package/dist/server/constants.js.map +1 -1
- package/dist/server/constants.mjs.map +1 -1
- package/dist/server/content-types/file.js.map +1 -1
- package/dist/server/content-types/file.mjs.map +1 -1
- package/dist/server/content-types/folder.js.map +1 -1
- package/dist/server/content-types/folder.mjs +1 -1
- package/dist/server/content-types/folder.mjs.map +1 -1
- package/dist/server/content-types/index.js.map +1 -1
- package/dist/server/content-types/index.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +1 -1
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-folder-file.js.map +1 -1
- package/dist/server/controllers/admin-folder-file.mjs +2 -2
- package/dist/server/controllers/admin-folder-file.mjs.map +1 -1
- package/dist/server/controllers/admin-folder.js.map +1 -1
- package/dist/server/controllers/admin-folder.mjs +1 -1
- package/dist/server/controllers/admin-folder.mjs.map +1 -1
- package/dist/server/controllers/admin-settings.js.map +1 -1
- package/dist/server/controllers/admin-settings.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +144 -0
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +147 -3
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/controllers/content-api.js.map +1 -1
- package/dist/server/controllers/content-api.mjs.map +1 -1
- package/dist/server/controllers/index.js.map +1 -1
- package/dist/server/controllers/index.mjs.map +1 -1
- package/dist/server/controllers/utils/find-entity-and-check-permissions.js.map +1 -1
- package/dist/server/controllers/utils/find-entity-and-check-permissions.mjs.map +1 -1
- package/dist/server/controllers/utils/folders.js.map +1 -1
- package/dist/server/controllers/utils/folders.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/configureView.js.map +1 -1
- package/dist/server/controllers/validation/admin/configureView.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder-file.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/folder.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/settings.js.map +1 -1
- package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/upload.js.map +1 -1
- package/dist/server/controllers/validation/admin/upload.mjs.map +1 -1
- package/dist/server/controllers/validation/admin/utils.js.map +1 -1
- package/dist/server/controllers/validation/admin/utils.mjs.map +1 -1
- package/dist/server/controllers/validation/content-api/upload.js.map +1 -1
- package/dist/server/controllers/validation/content-api/upload.mjs.map +1 -1
- package/dist/server/controllers/view-configuration.js.map +1 -1
- package/dist/server/controllers/view-configuration.mjs.map +1 -1
- package/dist/server/graphql.js.map +1 -1
- package/dist/server/graphql.mjs.map +1 -1
- package/dist/server/index.js +8 -8
- package/dist/server/middlewares/upload.js.map +1 -1
- package/dist/server/middlewares/upload.mjs.map +1 -1
- package/dist/server/models/ai-metadata-job.js.map +1 -1
- package/dist/server/models/ai-metadata-job.mjs.map +1 -1
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/routes/admin.js +10 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +10 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/routes/content-api.js.map +1 -1
- package/dist/server/routes/content-api.mjs.map +1 -1
- package/dist/server/routes/index.js.map +1 -1
- package/dist/server/routes/index.mjs +4 -4
- package/dist/server/routes/index.mjs.map +1 -1
- package/dist/server/routes/validation/upload.js.map +1 -1
- package/dist/server/routes/validation/upload.mjs.map +1 -1
- package/dist/server/routes/view-configuration.js.map +1 -1
- package/dist/server/routes/view-configuration.mjs.map +1 -1
- package/dist/server/services/ai-metadata-jobs.js.map +1 -1
- package/dist/server/services/ai-metadata-jobs.mjs.map +1 -1
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/api-upload-folder.js.map +1 -1
- package/dist/server/services/api-upload-folder.mjs.map +1 -1
- package/dist/server/services/extensions/index.js.map +1 -1
- package/dist/server/services/extensions/index.mjs.map +1 -1
- package/dist/server/services/extensions/utils.js.map +1 -1
- package/dist/server/services/extensions/utils.mjs.map +1 -1
- package/dist/server/services/file.js +120 -1
- package/dist/server/services/file.js.map +1 -1
- package/dist/server/services/file.mjs +122 -3
- package/dist/server/services/file.mjs.map +1 -1
- package/dist/server/services/folder.js.map +1 -1
- package/dist/server/services/folder.mjs +1 -1
- package/dist/server/services/folder.mjs.map +1 -1
- package/dist/server/services/image-manipulation.js.map +1 -1
- package/dist/server/services/image-manipulation.mjs +1 -1
- package/dist/server/services/image-manipulation.mjs.map +1 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/services/metrics.js.map +1 -1
- package/dist/server/services/metrics.mjs.map +1 -1
- package/dist/server/services/provider.js.map +1 -1
- package/dist/server/services/provider.mjs.map +1 -1
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +1 -1
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/services/weekly-metrics.js.map +1 -1
- package/dist/server/services/weekly-metrics.mjs.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts +13 -0
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +2 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/file.d.ts +15 -0
- package/dist/server/src/services/file.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +1 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/utils/cron.js.map +1 -1
- package/dist/server/utils/cron.mjs.map +1 -1
- package/dist/server/utils/images.js.map +1 -1
- package/dist/server/utils/images.mjs.map +1 -1
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/server/utils/mime-validation.js.map +1 -1
- package/dist/server/utils/mime-validation.mjs.map +1 -1
- package/dist/shared/contracts/files.d.ts +11 -0
- package/dist/shared/contracts/files.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-folder-file.mjs","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const deletedFiles = await fileService.deleteByIds(body.fileIds);\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(body.folderIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","read","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","deletedFiles","deleteByIds","fileIds","folders","deletedFolders","totalFolderNumber","totalFileNumber","folderIds","length","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","files","sanitizeOutput","moveMany","validateMoveManyFoldersFiles","destinationFolderId","trx","db","transaction","existingFolders","queryBuilder","select","where","id","$in","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","joinTable","parent","name","delete","joinColumn","insert","map","folder","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","getConnection","orWhere","update","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","updatedFolders","query","findMany","updatedFiles"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-folder-file.mjs","sources":["../../../server/src/controllers/admin-folder-file.ts"],"sourcesContent":["import { strings } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport {\n validateDeleteManyFoldersFiles,\n validateMoveManyFoldersFiles,\n} from './validation/admin/folder-file';\n\nimport type { File, Folder } from '../types';\n\nexport default {\n async deleteMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateDeleteManyFoldersFiles(body);\n\n const fileService = getService('file');\n const folderService = getService('folder');\n\n const deletedFiles = await fileService.deleteByIds(body.fileIds);\n const {\n folders: deletedFolders,\n totalFolderNumber,\n totalFileNumber,\n } = await folderService.deleteByIds(body.folderIds);\n\n if (deletedFiles.length + deletedFolders.length > 1) {\n await getService('metrics').trackUsage('didBulkDeleteMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: deletedFolders.length,\n rootAssetNumber: deletedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + deletedFiles.length,\n },\n });\n }\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(deletedFiles),\n folders: await pmFolder.sanitizeOutput(deletedFolders),\n },\n };\n },\n async moveMany(ctx: Context) {\n const { body } = ctx.request;\n const {\n state: { userAbility },\n } = ctx;\n\n const pmFolder = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n const pmFile = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.read,\n model: FILE_MODEL_UID,\n });\n\n await validateMoveManyFoldersFiles(body);\n const { folderIds = [], fileIds = [], destinationFolderId } = body;\n\n let totalFolderNumber = 0;\n let totalFileNumber = 0;\n\n const trx = await strapi.db.transaction();\n try {\n // fetch folders\n const existingFolders = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['id', 'pathId', 'path'])\n .where({ id: { $in: folderIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<Folder[]>();\n\n // fetch files\n const existingFiles = await strapi.db\n .queryBuilder(FILE_MODEL_UID)\n .select(['id'])\n .where({ id: { $in: fileIds } })\n .transacting(trx.get())\n .forUpdate()\n .execute<File[]>();\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (destinationFolderId !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: destinationFolderId })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const folderPathColName =\n // @ts-expect-error - no dynamic typings for the models\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic typings for the models\n const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n if (existingFolders.length > 0) {\n // update folders' parent relation\n // @ts-expect-error - no dynamic typings for the models\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [joinTable.joinColumn.name]: { $in: folderIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert(\n existingFolders.map((folder) => ({\n [joinTable.inverseJoinColumn.name]: destinationFolderId,\n [joinTable.joinColumn.name]: folder.id,\n }))\n )\n .execute();\n }\n\n for (const existingFolder of existingFolders) {\n let replaceQuery;\n switch (strapi.db.dialect.client) {\n case 'sqlite':\n replaceQuery = '? || SUBSTRING(??, ?)';\n break;\n case 'postgres':\n replaceQuery = 'CONCAT(?::TEXT, SUBSTRING(??, ?::INTEGER))';\n break;\n default:\n replaceQuery = 'CONCAT(?, SUBSTRING(??, ?))';\n }\n\n // update path for folders themselves & folders below\n totalFolderNumber = await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColName, existingFolder.path)\n .orWhere(pathColName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n pathColName,\n existingFolder.path.length + 1,\n ])\n );\n\n // update path of files below\n totalFileNumber = await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColName, existingFolder.path)\n .orWhere(folderPathColName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColName,\n strapi.db.connection.raw(replaceQuery, [\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n folderPathColName,\n existingFolder.path.length + 1,\n ])\n );\n }\n }\n\n if (existingFiles.length > 0) {\n // update files' folder relation (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic typings for the models\n const fileJoinTable = strapi.db.metadata.get(FILE_MODEL_UID).attributes.folder.joinTable;\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .delete()\n .where({ [fileJoinTable.joinColumn.name]: { $in: fileIds } })\n .execute();\n\n if (destinationFolderId !== null) {\n await strapi.db\n .queryBuilder(fileJoinTable.name)\n .transacting(trx.get())\n .insert(\n existingFiles.map((file) => ({\n [fileJoinTable.inverseJoinColumn.name]: destinationFolderId,\n [fileJoinTable.joinColumn.name]: file.id,\n }))\n )\n .execute();\n }\n\n // update files main fields (path + updatedBy)\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .whereIn('id', fileIds)\n .update(folderPathColName, destinationFolderPath);\n }\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n const updatedFolders = await strapi.db.query(FOLDER_MODEL_UID).findMany({\n where: { id: { $in: folderIds } },\n });\n\n const updatedFiles = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: { id: { $in: fileIds } },\n });\n\n await getService('metrics').trackUsage('didBulkMoveMediaLibraryElements', {\n eventProperties: {\n rootFolderNumber: updatedFolders.length,\n rootAssetNumber: updatedFiles.length,\n totalFolderNumber,\n totalAssetNumber: totalFileNumber + updatedFiles.length,\n },\n });\n\n ctx.body = {\n data: {\n files: await pmFile.sanitizeOutput(updatedFiles),\n folders: await pmFolder.sanitizeOutput(updatedFolders),\n },\n };\n },\n};\n"],"names":["deleteMany","ctx","body","request","state","userAbility","pmFolder","strapi","service","createPermissionsManager","ability","model","FOLDER_MODEL_UID","pmFile","action","ACTIONS","read","FILE_MODEL_UID","validateDeleteManyFoldersFiles","fileService","getService","folderService","deletedFiles","deleteByIds","fileIds","folders","deletedFolders","totalFolderNumber","totalFileNumber","folderIds","length","trackUsage","eventProperties","rootFolderNumber","rootAssetNumber","totalAssetNumber","data","files","sanitizeOutput","moveMany","validateMoveManyFoldersFiles","destinationFolderId","trx","db","transaction","existingFolders","queryBuilder","select","where","id","$in","transacting","get","forUpdate","execute","existingFiles","destinationFolderPath","destinationFolder","first","path","fileTable","getModel","collectionName","folderTable","folderPathColName","metadata","attributes","folderPath","columnName","pathColName","joinTable","parent","name","delete","joinColumn","insert","map","folder","inverseJoinColumn","existingFolder","replaceQuery","dialect","client","getConnection","orWhere","update","connection","raw","strings","joinBy","pathId","fileJoinTable","file","whereIn","commit","e","rollback","updatedFolders","query","findMany","updatedFiles"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-folder.js","sources":["../../../server/src/controllers/admin-folder.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID } from '../constants';\nimport { validateCreateFolder, validateUpdateFolder } from './validation/admin/folder';\n\nexport default {\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const { results } = await strapi.db.query(FOLDER_MODEL_UID).findPage(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n filters: { id },\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n if (results.length === 0) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results[0]),\n };\n },\n\n async find(ctx: Context) {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const results = await strapi.db.query(FOLDER_MODEL_UID).findMany(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results),\n };\n },\n async create(ctx: Context) {\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n await validateCreateFolder(body);\n\n const folderService = getService('folder');\n\n const folder = await folderService.create(body, { user });\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n ctx.created({\n data: await permissionsManager.sanitizeOutput(folder),\n });\n },\n\n async update(ctx: Context) {\n const { id } = ctx.params;\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await validateUpdateFolder(id)(body);\n\n const folderService = getService('folder');\n\n const updatedFolder = await folderService.update(id, body, { user });\n\n if (!updatedFolder) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(updatedFolder),\n };\n },\n\n async getStructure(ctx: Context) {\n const { getStructure } = getService('folder');\n\n const structure = await getStructure();\n\n ctx.body = {\n data: structure,\n };\n },\n};\n"],"names":["findOne","ctx","id","params","permissionsManager","strapi","service","createPermissionsManager","ability","state","userAbility","model","FOLDER_MODEL_UID","validateQuery","query","sanitizeQuery","results","db","findPage","get","transform","defaultsDeep","filters","populate","children","count","files","length","notFound","body","data","sanitizeOutput","find","findMany","create","user","request","validateCreateFolder","folderService","getService","folder","created","update","validateUpdateFolder","updatedFolder","getStructure","structure"],"mappings":";;;;;;;AAQA,kBAAe;AACb,IAAA,MAAMA,SAAQC,GAAY,EAAA;AACxB,QAAA,MAAM,EAAEC,EAAE,EAAE,GAAGD,IAAIE,MAAM;AAEzB,QAAA,MAAMC,qBAAqBC,
|
|
1
|
+
{"version":3,"file":"admin-folder.js","sources":["../../../server/src/controllers/admin-folder.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID } from '../constants';\nimport { validateCreateFolder, validateUpdateFolder } from './validation/admin/folder';\n\nexport default {\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const { results } = await strapi.db.query(FOLDER_MODEL_UID).findPage(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n filters: { id },\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n if (results.length === 0) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results[0]),\n };\n },\n\n async find(ctx: Context) {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const results = await strapi.db.query(FOLDER_MODEL_UID).findMany(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results),\n };\n },\n async create(ctx: Context) {\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n await validateCreateFolder(body);\n\n const folderService = getService('folder');\n\n const folder = await folderService.create(body, { user });\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n ctx.created({\n data: await permissionsManager.sanitizeOutput(folder),\n });\n },\n\n async update(ctx: Context) {\n const { id } = ctx.params;\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await validateUpdateFolder(id)(body);\n\n const folderService = getService('folder');\n\n const updatedFolder = await folderService.update(id, body, { user });\n\n if (!updatedFolder) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(updatedFolder),\n };\n },\n\n async getStructure(ctx: Context) {\n const { getStructure } = getService('folder');\n\n const structure = await getStructure();\n\n ctx.body = {\n data: structure,\n };\n },\n};\n"],"names":["findOne","ctx","id","params","permissionsManager","strapi","service","createPermissionsManager","ability","state","userAbility","model","FOLDER_MODEL_UID","validateQuery","query","sanitizeQuery","results","db","findPage","get","transform","defaultsDeep","filters","populate","children","count","files","length","notFound","body","data","sanitizeOutput","find","findMany","create","user","request","validateCreateFolder","folderService","getService","folder","created","update","validateUpdateFolder","updatedFolder","getStructure","structure"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defaultsDeep } from 'lodash/fp';
|
|
2
2
|
import { getService } from '../utils/index.mjs';
|
|
3
3
|
import { FOLDER_MODEL_UID } from '../constants.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import { validateUpdateFolder, validateCreateFolder } from './validation/admin/folder.mjs';
|
|
5
5
|
|
|
6
6
|
var adminFolder = {
|
|
7
7
|
async findOne (ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-folder.mjs","sources":["../../../server/src/controllers/admin-folder.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID } from '../constants';\nimport { validateCreateFolder, validateUpdateFolder } from './validation/admin/folder';\n\nexport default {\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const { results } = await strapi.db.query(FOLDER_MODEL_UID).findPage(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n filters: { id },\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n if (results.length === 0) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results[0]),\n };\n },\n\n async find(ctx: Context) {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const results = await strapi.db.query(FOLDER_MODEL_UID).findMany(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results),\n };\n },\n async create(ctx: Context) {\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n await validateCreateFolder(body);\n\n const folderService = getService('folder');\n\n const folder = await folderService.create(body, { user });\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n ctx.created({\n data: await permissionsManager.sanitizeOutput(folder),\n });\n },\n\n async update(ctx: Context) {\n const { id } = ctx.params;\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await validateUpdateFolder(id)(body);\n\n const folderService = getService('folder');\n\n const updatedFolder = await folderService.update(id, body, { user });\n\n if (!updatedFolder) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(updatedFolder),\n };\n },\n\n async getStructure(ctx: Context) {\n const { getStructure } = getService('folder');\n\n const structure = await getStructure();\n\n ctx.body = {\n data: structure,\n };\n },\n};\n"],"names":["findOne","ctx","id","params","permissionsManager","strapi","service","createPermissionsManager","ability","state","userAbility","model","FOLDER_MODEL_UID","validateQuery","query","sanitizeQuery","results","db","findPage","get","transform","defaultsDeep","filters","populate","children","count","files","length","notFound","body","data","sanitizeOutput","find","findMany","create","user","request","validateCreateFolder","folderService","getService","folder","created","update","validateUpdateFolder","updatedFolder","getStructure","structure"],"mappings":";;;;;AAQA,kBAAe;AACb,IAAA,MAAMA,SAAQC,GAAY,EAAA;AACxB,QAAA,MAAM,EAAEC,EAAE,EAAE,GAAGD,IAAIE,MAAM;AAEzB,QAAA,MAAMC,qBAAqBC,
|
|
1
|
+
{"version":3,"file":"admin-folder.mjs","sources":["../../../server/src/controllers/admin-folder.ts"],"sourcesContent":["import { defaultsDeep } from 'lodash/fp';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID } from '../constants';\nimport { validateCreateFolder, validateUpdateFolder } from './validation/admin/folder';\n\nexport default {\n async findOne(ctx: Context) {\n const { id } = ctx.params;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const { results } = await strapi.db.query(FOLDER_MODEL_UID).findPage(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n filters: { id },\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n if (results.length === 0) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results[0]),\n };\n },\n\n async find(ctx: Context) {\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await permissionsManager.validateQuery(ctx.query);\n const query = await permissionsManager.sanitizeQuery(ctx.query);\n\n const results = await strapi.db.query(FOLDER_MODEL_UID).findMany(\n strapi.get('query-params').transform(\n FOLDER_MODEL_UID,\n defaultsDeep(\n {\n populate: {\n children: {\n count: true,\n },\n files: {\n count: true,\n },\n },\n },\n query\n )\n )\n );\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(results),\n };\n },\n async create(ctx: Context) {\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n await validateCreateFolder(body);\n\n const folderService = getService('folder');\n\n const folder = await folderService.create(body, { user });\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n ctx.created({\n data: await permissionsManager.sanitizeOutput(folder),\n });\n },\n\n async update(ctx: Context) {\n const { id } = ctx.params;\n const { user } = ctx.state;\n const { body } = ctx.request;\n\n const permissionsManager = strapi.service('admin::permission').createPermissionsManager({\n ability: ctx.state.userAbility,\n model: FOLDER_MODEL_UID,\n });\n\n await validateUpdateFolder(id)(body);\n\n const folderService = getService('folder');\n\n const updatedFolder = await folderService.update(id, body, { user });\n\n if (!updatedFolder) {\n return ctx.notFound('folder not found');\n }\n\n ctx.body = {\n data: await permissionsManager.sanitizeOutput(updatedFolder),\n };\n },\n\n async getStructure(ctx: Context) {\n const { getStructure } = getService('folder');\n\n const structure = await getStructure();\n\n ctx.body = {\n data: structure,\n };\n },\n};\n"],"names":["findOne","ctx","id","params","permissionsManager","strapi","service","createPermissionsManager","ability","state","userAbility","model","FOLDER_MODEL_UID","validateQuery","query","sanitizeQuery","results","db","findPage","get","transform","defaultsDeep","filters","populate","children","count","files","length","notFound","body","data","sanitizeOutput","find","findMany","create","user","request","validateCreateFolder","folderService","getService","folder","created","update","validateUpdateFolder","updatedFolder","getStructure","structure"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-settings.js","sources":["../../../server/src/controllers/admin-settings.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport validateSettings from './validation/admin/settings';\n\nexport default {\n async updateSettings(ctx: Context) {\n const {\n request: { body },\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await validateSettings(body);\n\n await getService('upload').setSettings(data);\n\n ctx.body = { data };\n },\n\n async getSettings(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await getService('upload').getSettings();\n\n ctx.body = { data };\n },\n};\n"],"names":["updateSettings","ctx","request","body","state","userAbility","cannot","ACTIONS","readSettings","FILE_MODEL_UID","forbidden","data","validateSettings","getService","setSettings","getSettings"],"mappings":";;;;;;AAMA,oBAAe;AACb,IAAA,MAAMA,gBAAeC,GAAY,EAAA;QAC/B,MAAM,EACJC,
|
|
1
|
+
{"version":3,"file":"admin-settings.js","sources":["../../../server/src/controllers/admin-settings.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport validateSettings from './validation/admin/settings';\n\nexport default {\n async updateSettings(ctx: Context) {\n const {\n request: { body },\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await validateSettings(body);\n\n await getService('upload').setSettings(data);\n\n ctx.body = { data };\n },\n\n async getSettings(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await getService('upload').getSettings();\n\n ctx.body = { data };\n },\n};\n"],"names":["updateSettings","ctx","request","body","state","userAbility","cannot","ACTIONS","readSettings","FILE_MODEL_UID","forbidden","data","validateSettings","getService","setSettings","getSettings"],"mappings":";;;;;;AAMA,oBAAe;AACb,IAAA,MAAMA,gBAAeC,GAAY,EAAA;QAC/B,MAAM,EACJC,OAAAA,EAAS,EAAEC,IAAI,EAAE,EACjBC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGJ,GAAAA;AAEJ,QAAA,IAAII,YAAYC,MAAM,CAACC,iBAAAA,CAAQC,YAAY,EAAEC,wBAAAA,CAAAA,EAAiB;AAC5D,YAAA,OAAOR,IAAIS,SAAS,EAAA;AACtB,QAAA;QAEA,MAAMC,IAAAA,GAAO,MAAMC,QAAAA,CAAiBT,IAAAA,CAAAA;QAEpC,MAAMU,gBAAAA,CAAW,QAAA,CAAA,CAAUC,WAAW,CAACH,IAAAA,CAAAA;AAEvCV,QAAAA,GAAAA,CAAIE,IAAI,GAAG;AAAEQ,YAAAA;AAAK,SAAA;AACpB,IAAA,CAAA;AAEA,IAAA,MAAMI,aAAYd,GAAY,EAAA;AAC5B,QAAA,MAAM,EACJG,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGJ,GAAAA;AAEJ,QAAA,IAAII,YAAYC,MAAM,CAACC,iBAAAA,CAAQC,YAAY,EAAEC,wBAAAA,CAAAA,EAAiB;AAC5D,YAAA,OAAOR,IAAIS,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMC,IAAAA,GAAO,MAAME,gBAAAA,CAAW,QAAA,CAAA,CAAUE,WAAW,EAAA;AAEnDd,QAAAA,GAAAA,CAAIE,IAAI,GAAG;AAAEQ,YAAAA;AAAK,SAAA;AACpB,IAAA;AACF,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-settings.mjs","sources":["../../../server/src/controllers/admin-settings.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport validateSettings from './validation/admin/settings';\n\nexport default {\n async updateSettings(ctx: Context) {\n const {\n request: { body },\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await validateSettings(body);\n\n await getService('upload').setSettings(data);\n\n ctx.body = { data };\n },\n\n async getSettings(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await getService('upload').getSettings();\n\n ctx.body = { data };\n },\n};\n"],"names":["updateSettings","ctx","request","body","state","userAbility","cannot","ACTIONS","readSettings","FILE_MODEL_UID","forbidden","data","validateSettings","getService","setSettings","getSettings"],"mappings":";;;;AAMA,oBAAe;AACb,IAAA,MAAMA,gBAAeC,GAAY,EAAA;QAC/B,MAAM,EACJC,
|
|
1
|
+
{"version":3,"file":"admin-settings.mjs","sources":["../../../server/src/controllers/admin-settings.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport validateSettings from './validation/admin/settings';\n\nexport default {\n async updateSettings(ctx: Context) {\n const {\n request: { body },\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await validateSettings(body);\n\n await getService('upload').setSettings(data);\n\n ctx.body = { data };\n },\n\n async getSettings(ctx: Context) {\n const {\n state: { userAbility },\n } = ctx;\n\n if (userAbility.cannot(ACTIONS.readSettings, FILE_MODEL_UID)) {\n return ctx.forbidden();\n }\n\n const data = await getService('upload').getSettings();\n\n ctx.body = { data };\n },\n};\n"],"names":["updateSettings","ctx","request","body","state","userAbility","cannot","ACTIONS","readSettings","FILE_MODEL_UID","forbidden","data","validateSettings","getService","setSettings","getSettings"],"mappings":";;;;AAMA,oBAAe;AACb,IAAA,MAAMA,gBAAeC,GAAY,EAAA;QAC/B,MAAM,EACJC,OAAAA,EAAS,EAAEC,IAAI,EAAE,EACjBC,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGJ,GAAAA;AAEJ,QAAA,IAAII,YAAYC,MAAM,CAACC,OAAAA,CAAQC,YAAY,EAAEC,cAAAA,CAAAA,EAAiB;AAC5D,YAAA,OAAOR,IAAIS,SAAS,EAAA;AACtB,QAAA;QAEA,MAAMC,IAAAA,GAAO,MAAMC,gBAAAA,CAAiBT,IAAAA,CAAAA;QAEpC,MAAMU,UAAAA,CAAW,QAAA,CAAA,CAAUC,WAAW,CAACH,IAAAA,CAAAA;AAEvCV,QAAAA,GAAAA,CAAIE,IAAI,GAAG;AAAEQ,YAAAA;AAAK,SAAA;AACpB,IAAA,CAAA;AAEA,IAAA,MAAMI,aAAYd,GAAY,EAAA;AAC5B,QAAA,MAAM,EACJG,KAAAA,EAAO,EAAEC,WAAW,EAAE,EACvB,GAAGJ,GAAAA;AAEJ,QAAA,IAAII,YAAYC,MAAM,CAACC,OAAAA,CAAQC,YAAY,EAAEC,cAAAA,CAAAA,EAAiB;AAC5D,YAAA,OAAOR,IAAIS,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMC,IAAAA,GAAO,MAAME,UAAAA,CAAW,QAAA,CAAA,CAAUE,WAAW,EAAA;AAEnDd,QAAAA,GAAAA,CAAIE,IAAI,GAAG;AAAEQ,YAAAA;AAAK,SAAA;AACpB,IAAA;AACF,CAAA;;;;"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var os = require('os');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var fse = require('fs-extra');
|
|
3
6
|
var _ = require('lodash');
|
|
4
7
|
var utils = require('@strapi/utils');
|
|
5
8
|
var index = require('../utils/index.js');
|
|
@@ -264,6 +267,147 @@ var adminUpload = {
|
|
|
264
267
|
});
|
|
265
268
|
res.end();
|
|
266
269
|
},
|
|
270
|
+
/**
|
|
271
|
+
* @experimental
|
|
272
|
+
* Upload files from URLs with SSE streaming for per-file progress
|
|
273
|
+
*
|
|
274
|
+
* Accepts JSON body with URLs and fetches them server-side.
|
|
275
|
+
* Streams Server-Sent Events as each URL is fetched and uploaded:
|
|
276
|
+
* - file:fetching — when starting to fetch a URL
|
|
277
|
+
* - file:uploading — when upload starts for a fetched file
|
|
278
|
+
* - file:complete — when a file is successfully uploaded
|
|
279
|
+
* - file:error — when a URL fetch or upload fails
|
|
280
|
+
* - stream:complete — final summary with all results
|
|
281
|
+
*/ async unstable_uploadFromUrls (ctx) {
|
|
282
|
+
const { state: { userAbility, user }, request: { body } } = ctx;
|
|
283
|
+
const uploadService = index.getService('upload');
|
|
284
|
+
const fileService = index.getService('file');
|
|
285
|
+
const pm = strapi.service('admin::permission').createPermissionsManager({
|
|
286
|
+
ability: userAbility,
|
|
287
|
+
action: constants.ACTIONS.create,
|
|
288
|
+
model: constants.FILE_MODEL_UID
|
|
289
|
+
});
|
|
290
|
+
if (!pm.isAllowed) {
|
|
291
|
+
return ctx.forbidden();
|
|
292
|
+
}
|
|
293
|
+
// Parse and validate request body
|
|
294
|
+
const { urls, folderId } = body;
|
|
295
|
+
if (!urls || !Array.isArray(urls) || urls.length === 0) {
|
|
296
|
+
throw new utils.errors.ApplicationError('URLs are required');
|
|
297
|
+
}
|
|
298
|
+
if (urls.length > 20) {
|
|
299
|
+
throw new utils.errors.ApplicationError('Maximum 20 URLs allowed per request');
|
|
300
|
+
}
|
|
301
|
+
// Take manual control of the response for SSE streaming
|
|
302
|
+
ctx.respond = false;
|
|
303
|
+
const res = ctx.res;
|
|
304
|
+
res.writeHead(200, {
|
|
305
|
+
'Content-Type': 'text/event-stream',
|
|
306
|
+
'Cache-Control': 'no-cache',
|
|
307
|
+
Connection: 'keep-alive'
|
|
308
|
+
});
|
|
309
|
+
const writeSSE = (event, data)=>{
|
|
310
|
+
res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
311
|
+
};
|
|
312
|
+
const total = urls.length;
|
|
313
|
+
const uploadErrors = [];
|
|
314
|
+
const successfulFiles = [];
|
|
315
|
+
// Create temp directory for fetched files
|
|
316
|
+
const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-url-upload-'));
|
|
317
|
+
const { sizeLimit } = strapi.config.get('plugin::upload');
|
|
318
|
+
try {
|
|
319
|
+
// Process each URL sequentially
|
|
320
|
+
for(let i = 0; i < urls.length; i += 1){
|
|
321
|
+
const url = urls[i];
|
|
322
|
+
writeSSE('file:fetching', {
|
|
323
|
+
url,
|
|
324
|
+
index: i,
|
|
325
|
+
total
|
|
326
|
+
});
|
|
327
|
+
try {
|
|
328
|
+
// Fetch URL to temp file
|
|
329
|
+
const { file } = await fileService.fetchUrlToInputFile(url, tmpWorkingDirectory, sizeLimit);
|
|
330
|
+
const fileName = file.originalFilename;
|
|
331
|
+
writeSSE('file:uploading', {
|
|
332
|
+
name: fileName,
|
|
333
|
+
index: i,
|
|
334
|
+
total,
|
|
335
|
+
size: file.size
|
|
336
|
+
});
|
|
337
|
+
// Validate using security checks
|
|
338
|
+
const fileInfo = {
|
|
339
|
+
name: fileName,
|
|
340
|
+
caption: null,
|
|
341
|
+
alternativeText: null,
|
|
342
|
+
folder: folderId ?? null
|
|
343
|
+
};
|
|
344
|
+
const { validFiles, errors: validationErrors } = await mimeValidation.prepareUploadRequest(file, {
|
|
345
|
+
fileInfo: JSON.stringify(fileInfo)
|
|
346
|
+
}, strapi);
|
|
347
|
+
if (validFiles.length === 0) {
|
|
348
|
+
const errorMessage = validationErrors[0]?.message || 'Validation failed';
|
|
349
|
+
uploadErrors.push({
|
|
350
|
+
name: fileName,
|
|
351
|
+
message: errorMessage
|
|
352
|
+
});
|
|
353
|
+
writeSSE('file:error', {
|
|
354
|
+
name: fileName,
|
|
355
|
+
url,
|
|
356
|
+
index: i,
|
|
357
|
+
message: errorMessage
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
// Upload the file
|
|
361
|
+
const data = await upload.validateUploadBody({
|
|
362
|
+
fileInfo
|
|
363
|
+
}, false);
|
|
364
|
+
const [uploadedFile] = await uploadService.upload({
|
|
365
|
+
data,
|
|
366
|
+
files: [
|
|
367
|
+
validFiles[0]
|
|
368
|
+
]
|
|
369
|
+
}, {
|
|
370
|
+
user
|
|
371
|
+
});
|
|
372
|
+
// Sign file url
|
|
373
|
+
const signedFile = await fileService.signFileUrls(uploadedFile);
|
|
374
|
+
successfulFiles.push(signedFile);
|
|
375
|
+
writeSSE('file:complete', {
|
|
376
|
+
name: fileName,
|
|
377
|
+
index: i,
|
|
378
|
+
file: signedFile
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
} catch (error) {
|
|
382
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
383
|
+
uploadErrors.push({
|
|
384
|
+
name: url,
|
|
385
|
+
message: errorMessage
|
|
386
|
+
});
|
|
387
|
+
writeSSE('file:error', {
|
|
388
|
+
url,
|
|
389
|
+
index: i,
|
|
390
|
+
message: errorMessage
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// Track image upload metric once if any images were uploaded
|
|
395
|
+
if (successfulFiles.some((file)=>file.mime?.startsWith('image/'))) {
|
|
396
|
+
await index.getService('metrics').trackUsage('didUploadImage');
|
|
397
|
+
}
|
|
398
|
+
// Send final stream summary
|
|
399
|
+
writeSSE('stream:complete', {
|
|
400
|
+
data: await pm.sanitizeOutput(successfulFiles, {
|
|
401
|
+
action: constants.ACTIONS.read
|
|
402
|
+
}),
|
|
403
|
+
errors: uploadErrors
|
|
404
|
+
});
|
|
405
|
+
} finally{
|
|
406
|
+
// Clean up temp directory
|
|
407
|
+
await fse.remove(tmpWorkingDirectory);
|
|
408
|
+
}
|
|
409
|
+
res.end();
|
|
410
|
+
},
|
|
267
411
|
// TODO: split into multiple endpoints
|
|
268
412
|
async upload (ctx) {
|
|
269
413
|
const { query: { id }, request: { files: { files } = {} } } = ctx;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-upload.js","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { FileInfo } from '../types';\nimport { prepareUploadRequest, type FileUploadError } from '../utils/mime-validation';\nimport type { UploadFileInfo } from '../../../shared/contracts/files';\n\nexport default {\n async bulkUpdateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const { updates } = await validateBulkUpdateBody(body);\n const uploadService = getService('upload');\n\n const results = await async.map(\n updates,\n async ({ id, fileInfo }: { id: number; fileInfo: FileInfo }) => {\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const updated = await uploadService.updateFileInfo(id, fileInfo as any, { user });\n return pm.sanitizeOutput(updated, { action: ACTIONS.read });\n }\n );\n\n ctx.body = results;\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: validFiles[0] }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data = await validateUploadBody(filteredBody, isMultipleFiles);\n\n let filesArray = validFiles;\n\n if (\n data.fileInfo &&\n Array.isArray(data.fileInfo) &&\n filesArray.length === data.fileInfo.length\n ) {\n // Reorder filesArray to match data.fileInfo order\n const alignedFilesArray = data.fileInfo\n .map((info) => {\n return filesArray.find((file) => file.originalFilename === info.name);\n })\n .filter(Boolean) as any[];\n\n filesArray = alignedFilesArray;\n }\n\n // Upload files first to get thumbnails\n const uploadedFiles = await uploadService.upload({ data, files: filesArray }, { user });\n if (uploadedFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // AFTER upload - generate AI metadata for images\n if (await aiMetadataService.isEnabled()) {\n try {\n const metadataResults = await aiMetadataService.processFiles(uploadedFiles);\n // Update the uploaded files with AI metadata\n await aiMetadataService.updateFilesWithAIMetadata(uploadedFiles, metadataResults, user);\n } catch (error) {\n strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n /**\n * @experimental\n * Stream upload files with SSE streaming for per-file progress\n *\n * Streams Server-Sent Events as each file is validated and uploaded:\n * - file:uploading — when processing starts for a file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a file fails validation or upload\n * - stream:complete — final summary with all results\n *\n */\n async unstable_uploadFilesStream(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n throw new errors.ApplicationError('Files are empty');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n // Normalize files to an array\n const filesArray = Array.isArray(files) ? files : [files];\n const total = filesArray.length;\n\n // Parse fileInfo from body\n // Multipart forms send fileInfo as either:\n // - An array of JSON strings (one per file)\n // - A single JSON string (one file, or a JSON-encoded array)\n let parsedFileInfo: UploadFileInfo[] = [];\n if (body?.fileInfo) {\n const raw = body.fileInfo;\n if (Array.isArray(raw)) {\n parsedFileInfo = raw.map((fi: unknown) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n ) as UploadFileInfo[];\n } else if (typeof raw === 'string') {\n const parsed = JSON.parse(raw);\n // Handle case where a single string contains a JSON array\n parsedFileInfo = (Array.isArray(parsed) ? parsed : [parsed]) as UploadFileInfo[];\n } else {\n parsedFileInfo = [raw as UploadFileInfo];\n }\n }\n\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Process each file sequentially with inline validation\n for (let i = 0; i < filesArray.length; i += 1) {\n const file = filesArray[i];\n const fileName = file.originalFilename || 'unknown';\n const fileInfo: UploadFileInfo = parsedFileInfo[i] || {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: null,\n };\n\n writeSSE('file:uploading', { name: fileName, index: i, total, size: file.size || 0 });\n\n try {\n // Validate this single file using security checks\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n } else {\n // Validate using the already-parsed single fileInfo object directly\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await getService('file').signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n\n res.end();\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["bulkUpdateFileInfo","ctx","state","userAbility","user","request","body","updates","validateBulkUpdateBody","uploadService","getService","results","async","map","id","fileInfo","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","updated","updateFileInfo","sanitizeOutput","action","read","query","errors","ValidationError","data","validateUploadBody","file","replaceFile","files","Array","isArray","ApplicationError","validFiles","filteredBody","validationErrors","prepareUploadRequest","strapi","length","message","replacedFile","replace","signedFile","signFileUrls","uploadFiles","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","isMultipleFiles","filesArray","alignedFilesArray","info","find","originalFilename","name","filter","Boolean","uploadedFiles","upload","some","mime","startsWith","trackUsage","aiMetadataService","isEnabled","metadataResults","processFiles","updateFilesWithAIMetadata","error","log","warn","Error","String","signedFiles","status","unstable_uploadFilesStream","_","isEmpty","size","respond","res","writeHead","Connection","writeSSE","event","write","JSON","stringify","total","parsedFileInfo","raw","fi","parse","parsed","uploadErrors","successfulFiles","i","fileName","caption","alternativeText","folder","index","errorMessage","push","uploadedFile","end"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-upload.js","sources":["../../../server/src/controllers/admin-upload.ts"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fse from 'fs-extra';\nimport _ from 'lodash';\nimport { errors, async } from '@strapi/utils';\n\nimport type { Context } from 'koa';\n\nimport { getService } from '../utils';\nimport { ACTIONS, FILE_MODEL_UID } from '../constants';\nimport { validateBulkUpdateBody, validateUploadBody } from './validation/admin/upload';\nimport { findEntityAndCheckPermissions } from './utils/find-entity-and-check-permissions';\nimport { Config, FileInfo } from '../types';\nimport { prepareUploadRequest, type FileUploadError } from '../utils/mime-validation';\nimport type { UploadFileInfo } from '../../../shared/contracts/files';\n\nexport default {\n async bulkUpdateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const { updates } = await validateBulkUpdateBody(body);\n const uploadService = getService('upload');\n\n const results = await async.map(\n updates,\n async ({ id, fileInfo }: { id: number; fileInfo: FileInfo }) => {\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const updated = await uploadService.updateFileInfo(id, fileInfo as any, { user });\n return pm.sanitizeOutput(updated, { action: ACTIONS.read });\n }\n );\n\n ctx.body = results;\n },\n\n async updateFileInfo(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n const data = await validateUploadBody(body);\n\n const file = await uploadService.updateFileInfo(id, data.fileInfo as any, { user });\n\n ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read });\n },\n\n async replaceFile(ctx: Context) {\n const {\n state: { userAbility, user },\n query: { id },\n request: { body, files: { files } = {} },\n } = ctx;\n\n if (typeof id !== 'string') {\n throw new errors.ValidationError('File id is required');\n }\n\n const uploadService = getService('upload');\n const { pm } = await findEntityAndCheckPermissions(\n userAbility,\n ACTIONS.update,\n FILE_MODEL_UID,\n id\n );\n\n if (Array.isArray(files)) {\n throw new errors.ApplicationError('Cannot replace a file with multiple ones');\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const data = (await validateUploadBody(filteredBody)) as { fileInfo: FileInfo };\n const replacedFile = await uploadService.replace(id, { data, file: validFiles[0] }, { user });\n\n // Sign file urls for private providers\n const signedFile = await getService('file').signFileUrls(replacedFile);\n\n ctx.body = await pm.sanitizeOutput(signedFile, { action: ACTIONS.read });\n },\n\n async uploadFiles(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n const {\n validFiles,\n filteredBody,\n errors: validationErrors,\n } = await prepareUploadRequest(files, body, strapi);\n if (validFiles.length === 0) {\n throw new errors.ValidationError(validationErrors[0].message);\n }\n\n const isMultipleFiles = validFiles.length > 1;\n const data = await validateUploadBody(filteredBody, isMultipleFiles);\n\n let filesArray = validFiles;\n\n if (\n data.fileInfo &&\n Array.isArray(data.fileInfo) &&\n filesArray.length === data.fileInfo.length\n ) {\n // Reorder filesArray to match data.fileInfo order\n const alignedFilesArray = data.fileInfo\n .map((info) => {\n return filesArray.find((file) => file.originalFilename === info.name);\n })\n .filter(Boolean) as any[];\n\n filesArray = alignedFilesArray;\n }\n\n // Upload files first to get thumbnails\n const uploadedFiles = await uploadService.upload({ data, files: filesArray }, { user });\n if (uploadedFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n const aiMetadataService = getService('aiMetadata');\n\n // AFTER upload - generate AI metadata for images\n if (await aiMetadataService.isEnabled()) {\n try {\n const metadataResults = await aiMetadataService.processFiles(uploadedFiles);\n // Update the uploaded files with AI metadata\n await aiMetadataService.updateFilesWithAIMetadata(uploadedFiles, metadataResults, user);\n } catch (error) {\n strapi.log.warn('AI metadata generation failed, proceeding without AI enhancements', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Sign file urls for private providers\n const signedFiles = await async.map(uploadedFiles, getService('file').signFileUrls);\n\n ctx.body = await pm.sanitizeOutput(signedFiles, { action: ACTIONS.read });\n ctx.status = 201;\n },\n\n /**\n * @experimental\n * Stream upload files with SSE streaming for per-file progress\n *\n * Streams Server-Sent Events as each file is validated and uploaded:\n * - file:uploading — when processing starts for a file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a file fails validation or upload\n * - stream:complete — final summary with all results\n *\n */\n async unstable_uploadFilesStream(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body, files: { files } = {} },\n } = ctx;\n\n const uploadService = getService('upload');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n throw new errors.ApplicationError('Files are empty');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n // Normalize files to an array\n const filesArray = Array.isArray(files) ? files : [files];\n const total = filesArray.length;\n\n // Parse fileInfo from body\n // Multipart forms send fileInfo as either:\n // - An array of JSON strings (one per file)\n // - A single JSON string (one file, or a JSON-encoded array)\n let parsedFileInfo: UploadFileInfo[] = [];\n if (body?.fileInfo) {\n const raw = body.fileInfo;\n if (Array.isArray(raw)) {\n parsedFileInfo = raw.map((fi: unknown) =>\n typeof fi === 'string' ? JSON.parse(fi) : fi\n ) as UploadFileInfo[];\n } else if (typeof raw === 'string') {\n const parsed = JSON.parse(raw);\n // Handle case where a single string contains a JSON array\n parsedFileInfo = (Array.isArray(parsed) ? parsed : [parsed]) as UploadFileInfo[];\n } else {\n parsedFileInfo = [raw as UploadFileInfo];\n }\n }\n\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Process each file sequentially with inline validation\n for (let i = 0; i < filesArray.length; i += 1) {\n const file = filesArray[i];\n const fileName = file.originalFilename || 'unknown';\n const fileInfo: UploadFileInfo = parsedFileInfo[i] || {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: null,\n };\n\n writeSSE('file:uploading', { name: fileName, index: i, total, size: file.size || 0 });\n\n try {\n // Validate this single file using security checks\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n } else {\n // Validate using the already-parsed single fileInfo object directly\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await getService('file').signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n\n res.end();\n },\n\n /**\n * @experimental\n * Upload files from URLs with SSE streaming for per-file progress\n *\n * Accepts JSON body with URLs and fetches them server-side.\n * Streams Server-Sent Events as each URL is fetched and uploaded:\n * - file:fetching — when starting to fetch a URL\n * - file:uploading — when upload starts for a fetched file\n * - file:complete — when a file is successfully uploaded\n * - file:error — when a URL fetch or upload fails\n * - stream:complete — final summary with all results\n */\n async unstable_uploadFromUrls(ctx: Context) {\n const {\n state: { userAbility, user },\n request: { body },\n } = ctx;\n\n const uploadService = getService('upload');\n const fileService = getService('file');\n const pm = strapi.service('admin::permission').createPermissionsManager({\n ability: userAbility,\n action: ACTIONS.create,\n model: FILE_MODEL_UID,\n });\n\n if (!pm.isAllowed) {\n return ctx.forbidden();\n }\n\n // Parse and validate request body\n const { urls, folderId } = body as { urls?: string[]; folderId?: number | null };\n\n if (!urls || !Array.isArray(urls) || urls.length === 0) {\n throw new errors.ApplicationError('URLs are required');\n }\n\n if (urls.length > 20) {\n throw new errors.ApplicationError('Maximum 20 URLs allowed per request');\n }\n\n // Take manual control of the response for SSE streaming\n ctx.respond = false;\n const res = ctx.res;\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n });\n\n const writeSSE = (event: string, data: Record<string, unknown>) => {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n };\n\n const total = urls.length;\n const uploadErrors: FileUploadError[] = [];\n const successfulFiles: any[] = [];\n\n // Create temp directory for fetched files\n const tmpWorkingDirectory = await fse.mkdtemp(path.join(os.tmpdir(), 'strapi-url-upload-'));\n const { sizeLimit } = strapi.config.get<Config>('plugin::upload');\n\n try {\n // Process each URL sequentially\n for (let i = 0; i < urls.length; i += 1) {\n const url = urls[i];\n\n writeSSE('file:fetching', { url, index: i, total });\n\n try {\n // Fetch URL to temp file\n const { file } = await fileService.fetchUrlToInputFile(\n url,\n tmpWorkingDirectory,\n sizeLimit\n );\n const fileName = file.originalFilename;\n\n writeSSE('file:uploading', {\n name: fileName,\n index: i,\n total,\n size: file.size,\n });\n\n // Validate using security checks\n const fileInfo: UploadFileInfo = {\n name: fileName,\n caption: null,\n alternativeText: null,\n folder: folderId ?? null,\n };\n\n const { validFiles, errors: validationErrors } = await prepareUploadRequest(\n file,\n { fileInfo: JSON.stringify(fileInfo) },\n strapi\n );\n\n if (validFiles.length === 0) {\n const errorMessage = validationErrors[0]?.message || 'Validation failed';\n uploadErrors.push({ name: fileName, message: errorMessage });\n writeSSE('file:error', { name: fileName, url, index: i, message: errorMessage });\n } else {\n // Upload the file\n const data = await validateUploadBody({ fileInfo }, false);\n const [uploadedFile] = await uploadService.upload(\n { data, files: [validFiles[0]] },\n { user }\n );\n\n // Sign file url\n const signedFile = await fileService.signFileUrls(uploadedFile);\n successfulFiles.push(signedFile);\n\n writeSSE('file:complete', { name: fileName, index: i, file: signedFile });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n uploadErrors.push({ name: url, message: errorMessage });\n writeSSE('file:error', { url, index: i, message: errorMessage });\n }\n }\n\n // Track image upload metric once if any images were uploaded\n if (successfulFiles.some((file) => file.mime?.startsWith('image/'))) {\n await getService('metrics').trackUsage('didUploadImage');\n }\n\n // Send final stream summary\n writeSSE('stream:complete', {\n data: await pm.sanitizeOutput(successfulFiles, { action: ACTIONS.read }),\n errors: uploadErrors,\n });\n } finally {\n // Clean up temp directory\n await fse.remove(tmpWorkingDirectory);\n }\n\n res.end();\n },\n\n // TODO: split into multiple endpoints\n async upload(ctx: Context) {\n const {\n query: { id },\n request: { files: { files } = {} },\n } = ctx;\n\n if (_.isEmpty(files) || (!Array.isArray(files) && files.size === 0)) {\n if (id) {\n return this.updateFileInfo(ctx);\n }\n\n throw new errors.ApplicationError('Files are empty');\n }\n\n await (id ? this.replaceFile : this.uploadFiles)(ctx);\n },\n};\n"],"names":["bulkUpdateFileInfo","ctx","state","userAbility","user","request","body","updates","validateBulkUpdateBody","uploadService","getService","results","async","map","id","fileInfo","pm","findEntityAndCheckPermissions","ACTIONS","update","FILE_MODEL_UID","updated","updateFileInfo","sanitizeOutput","action","read","query","errors","ValidationError","data","validateUploadBody","file","replaceFile","files","Array","isArray","ApplicationError","validFiles","filteredBody","validationErrors","prepareUploadRequest","strapi","length","message","replacedFile","replace","signedFile","signFileUrls","uploadFiles","service","createPermissionsManager","ability","create","model","isAllowed","forbidden","isMultipleFiles","filesArray","alignedFilesArray","info","find","originalFilename","name","filter","Boolean","uploadedFiles","upload","some","mime","startsWith","trackUsage","aiMetadataService","isEnabled","metadataResults","processFiles","updateFilesWithAIMetadata","error","log","warn","Error","String","signedFiles","status","unstable_uploadFilesStream","_","isEmpty","size","respond","res","writeHead","Connection","writeSSE","event","write","JSON","stringify","total","parsedFileInfo","raw","fi","parse","parsed","uploadErrors","successfulFiles","i","fileName","caption","alternativeText","folder","index","errorMessage","push","uploadedFile","end","unstable_uploadFromUrls","fileService","urls","folderId","tmpWorkingDirectory","fse","mkdtemp","path","join","os","tmpdir","sizeLimit","config","get","url","fetchUrlToInputFile","remove"],"mappings":"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"}
|