@strapi/upload 5.29.0 → 5.30.1
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 +31 -9
- package/dist/admin/ai/components/AIAssetCard.js.map +1 -1
- package/dist/admin/ai/components/AIAssetCard.mjs +25 -3
- package/dist/admin/ai/components/AIAssetCard.mjs.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.js +3 -2
- package/dist/admin/ai/components/AIUploadModal.js.map +1 -1
- package/dist/admin/ai/components/AIUploadModal.mjs +3 -2
- package/dist/admin/ai/components/AIUploadModal.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.js +5 -4
- package/dist/admin/components/AssetCard/AssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/AssetCard.mjs +2 -1
- package/dist/admin/components/AssetCard/AssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.js +1 -1
- package/dist/admin/components/AssetCard/AssetCardBase.mjs +1 -1
- package/dist/admin/components/AssetCard/DocAssetCard.js +3 -7
- package/dist/admin/components/AssetCard/DocAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/DocAssetCard.mjs +3 -7
- package/dist/admin/components/AssetCard/DocAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs +1 -1
- package/dist/admin/components/AssetCard/ImageAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.js +5 -4
- package/dist/admin/components/AssetCard/UploadingAssetCard.js.map +1 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs +2 -1
- package/dist/admin/components/AssetCard/UploadingAssetCard.mjs.map +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.js +1 -1
- package/dist/admin/components/AssetCard/VideoAssetCard.mjs +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.js +1 -1
- package/dist/admin/components/AssetDialog/AssetDialog.mjs +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js +2 -0
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs +2 -0
- package/dist/admin/components/AssetDialog/BrowseStep/BrowseStep.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.js +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/Filters.mjs +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js +3 -3
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.js.map +1 -1
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs +2 -2
- package/dist/admin/components/AssetDialog/BrowseStep/SearchAsset/SearchAsset.mjs.map +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.js +1 -1
- package/dist/admin/components/AssetDialog/SelectedStep/SelectedStep.mjs +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 +1 -1
- package/dist/admin/components/Breadcrumbs/CrumbSimpleMenuAsync.mjs +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.js +1 -1
- package/dist/admin/components/BulkMoveDialog/BulkMoveDialog.mjs +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.js +1 -1
- package/dist/admin/components/CopyLinkButton/CopyLinkButton.mjs +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js +9 -6
- package/dist/admin/components/EditAssetDialog/EditAssetContent.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs +8 -5
- package/dist/admin/components/EditAssetDialog/EditAssetContent.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js +15 -34
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs +15 -34
- package/dist/admin/components/EditAssetDialog/PreviewBox/AssetPreview.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.js +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/CroppingActions.mjs +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js +5 -4
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs +3 -2
- package/dist/admin/components/EditAssetDialog/PreviewBox/PreviewBox.mjs.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js +3 -3
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.js.map +1 -1
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs +2 -2
- package/dist/admin/components/EditAssetDialog/ReplaceMediaButton.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.js +3 -2
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.js.map +1 -1
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs +3 -2
- package/dist/admin/components/EditFolderDialog/EditFolderDialog.mjs.map +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.js +1 -1
- package/dist/admin/components/EditFolderDialog/ModalHeader/ModalHeader.mjs +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/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/FolderCard/FolderCardBody/FolderCardBody.js.map +1 -1
- package/dist/admin/components/FolderCard/FolderCardBody/FolderCardBody.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/MediaLibraryInput/Carousel/CarouselAsset.js +8 -10
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs +5 -7
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.js +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/CarouselAssetActions.mjs +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs +1 -0
- package/dist/admin/components/MediaLibraryInput/Carousel/EmptyStateAsset.mjs.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.js.map +1 -1
- package/dist/admin/components/MediaLibraryInput/MediaLibraryInput.mjs +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.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/SortPicker/SortPicker.js +1 -0
- package/dist/admin/components/SortPicker/SortPicker.js.map +1 -1
- package/dist/admin/components/SortPicker/SortPicker.mjs +1 -0
- package/dist/admin/components/SortPicker/SortPicker.mjs.map +1 -1
- package/dist/admin/components/TableList/CellContent.js +1 -1
- package/dist/admin/components/TableList/CellContent.mjs +1 -1
- package/dist/admin/components/TableList/PreviewCell.js +5 -4
- package/dist/admin/components/TableList/PreviewCell.js.map +1 -1
- package/dist/admin/components/TableList/PreviewCell.mjs +2 -1
- package/dist/admin/components/TableList/PreviewCell.mjs.map +1 -1
- package/dist/admin/components/TableList/TableList.js +1 -0
- package/dist/admin/components/TableList/TableList.js.map +1 -1
- package/dist/admin/components/TableList/TableList.mjs +1 -0
- package/dist/admin/components/TableList/TableList.mjs.map +1 -1
- package/dist/admin/components/TableList/TableRows.js +1 -0
- package/dist/admin/components/TableList/TableRows.js.map +1 -1
- package/dist/admin/components/TableList/TableRows.mjs +1 -0
- package/dist/admin/components/TableList/TableRows.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.js +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/AddAssetStep.mjs +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js +3 -2
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs +2 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromComputerForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +3 -3
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +2 -2
- package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js +3 -3
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.js.map +1 -1
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.mjs +2 -2
- package/dist/admin/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.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 +5 -10
- package/dist/admin/constants.js.map +1 -1
- package/dist/admin/constants.mjs +5 -11
- package/dist/admin/constants.mjs.map +1 -1
- package/dist/admin/enums.js +20 -0
- package/dist/admin/enums.js.map +1 -0
- package/dist/admin/enums.mjs +17 -0
- package/dist/admin/enums.mjs.map +1 -0
- package/dist/admin/hooks/useBulkEdit.js +1 -1
- package/dist/admin/hooks/useBulkEdit.mjs +1 -1
- package/dist/admin/hooks/useBulkMove.js +1 -1
- package/dist/admin/hooks/useBulkMove.mjs +1 -1
- package/dist/admin/hooks/useBulkRemove.js +1 -1
- package/dist/admin/hooks/useBulkRemove.mjs +1 -1
- package/dist/admin/hooks/useConfig.js +2 -1
- package/dist/admin/hooks/useConfig.js.map +1 -1
- package/dist/admin/hooks/useConfig.mjs +2 -1
- package/dist/admin/hooks/useConfig.mjs.map +1 -1
- package/dist/admin/hooks/useEditAsset.js +1 -1
- package/dist/admin/hooks/useEditAsset.js.map +1 -1
- package/dist/admin/hooks/useEditAsset.mjs +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 +1 -1
- package/dist/admin/hooks/useFolder.js.map +1 -1
- package/dist/admin/hooks/useFolder.mjs +1 -1
- package/dist/admin/hooks/useFolder.mjs.map +1 -1
- package/dist/admin/hooks/useFolderStructure.js +1 -1
- package/dist/admin/hooks/useFolderStructure.mjs +1 -1
- package/dist/admin/hooks/useModalQueryParams.js +2 -2
- package/dist/admin/hooks/useModalQueryParams.js.map +1 -1
- package/dist/admin/hooks/useModalQueryParams.mjs +1 -1
- package/dist/admin/hooks/useModalQueryParams.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/useTracking.js +24 -0
- package/dist/admin/hooks/useTracking.js.map +1 -0
- package/dist/admin/hooks/useTracking.mjs +22 -0
- package/dist/admin/hooks/useTracking.mjs.map +1 -0
- package/dist/admin/hooks/useUpload.js.map +1 -1
- package/dist/admin/hooks/useUpload.mjs.map +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -0
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/package.json.js +5 -5
- package/dist/admin/package.json.mjs +5 -5
- package/dist/admin/pages/App/App.js +1 -1
- package/dist/admin/pages/App/App.mjs +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js +1 -0
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/components/Settings.mjs +1 -0
- 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/MediaLibrary/MediaLibrary.js +1 -0
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.mjs +1 -0
- package/dist/admin/pages/App/MediaLibrary/MediaLibrary.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/BulkActions.js +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/BulkActions.mjs +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/EmptyOrNoPermissions.js +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/EmptyOrNoPermissions.mjs +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Filters.js +3 -2
- package/dist/admin/pages/App/MediaLibrary/components/Filters.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Filters.mjs +3 -2
- package/dist/admin/pages/App/MediaLibrary/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Header.js +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Header.js.map +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Header.mjs +1 -1
- package/dist/admin/pages/App/MediaLibrary/components/Header.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +1 -0
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +1 -0
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/components/AssetCard/UploadingAssetCard.d.ts +1 -1
- package/dist/admin/src/components/UploadAssetDialog/PendingAssetStep/PendingAssetStep.d.ts +1 -1
- package/dist/admin/src/constants.d.ts +0 -6
- package/dist/admin/src/enums.d.ts +12 -0
- package/dist/admin/src/hooks/useTracking.d.ts +4 -0
- package/dist/admin/src/utils/icons.d.ts +14 -0
- package/dist/admin/src/utils/rawFileToAsset.d.ts +1 -1
- package/dist/admin/src/utils/typeFromMime.d.ts +2 -2
- package/dist/admin/src/utils/urlsToAssets.d.ts +1 -1
- package/dist/admin/translations/pt-BR.json.js +75 -7
- package/dist/admin/translations/pt-BR.json.js.map +1 -1
- package/dist/admin/translations/pt-BR.json.mjs +75 -7
- package/dist/admin/translations/pt-BR.json.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/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 +23 -0
- package/dist/admin/utils/icons.js.map +1 -0
- package/dist/admin/utils/icons.mjs +19 -0
- package/dist/admin/utils/icons.mjs.map +1 -0
- 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/typeFromMime.js +15 -11
- package/dist/admin/utils/typeFromMime.js.map +1 -1
- package/dist/admin/utils/typeFromMime.mjs +15 -11
- package/dist/admin/utils/typeFromMime.mjs.map +1 -1
- package/dist/server/controllers/admin-folder-file.js +2 -2
- 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-upload.js +1 -1
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +1 -1
- package/dist/server/controllers/admin-upload.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/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 +1 -1
- package/dist/server/controllers/validation/admin/folder.js.map +1 -1
- package/dist/server/controllers/validation/admin/folder.mjs +1 -1
- package/dist/server/controllers/validation/admin/folder.mjs.map +1 -1
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.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/folder.js.map +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.map +1 -1
- package/dist/server/services/metrics.js +14 -1
- package/dist/server/services/metrics.js.map +1 -1
- package/dist/server/services/metrics.mjs +14 -1
- package/dist/server/services/metrics.mjs.map +1 -1
- package/dist/server/services/upload.js +8 -8
- package/dist/server/services/upload.js.map +1 -1
- package/dist/server/services/upload.mjs +8 -8
- package/dist/server/services/upload.mjs.map +1 -1
- package/dist/server/services/weekly-metrics.js +3 -6
- package/dist/server/services/weekly-metrics.js.map +1 -1
- package/dist/server/services/weekly-metrics.mjs +3 -6
- package/dist/server/services/weekly-metrics.mjs.map +1 -1
- package/dist/server/src/index.d.ts +1 -1
- package/dist/server/src/services/index.d.ts +1 -1
- package/dist/server/src/services/metrics.d.ts +1 -0
- package/dist/server/src/services/metrics.d.ts.map +1 -1
- package/dist/server/src/services/upload.d.ts.map +1 -1
- package/dist/server/src/services/weekly-metrics.d.ts +0 -1
- package/dist/server/src/services/weekly-metrics.d.ts.map +1 -1
- package/dist/server/utils/cron.js.map +1 -1
- package/dist/server/utils/cron.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.mjs","sources":["../../../../../server/src/controllers/validation/admin/folder.ts"],"sourcesContent":["import { isUndefined, get, isNil } from 'lodash/fp';\nimport { yup, validateYupSchema } from '@strapi/utils';\nimport { getService } from '../../../utils';\nimport { FOLDER_MODEL_UID } from '../../../constants';\nimport { folderExists } from './utils';\nimport { isFolderOrChild } from '../../utils/folders';\n\nconst NO_SLASH_REGEX = /^[^/]+$/;\nconst NO_SPACES_AROUND = /^(?! ).+(?<! )$/;\n\nconst isNameUniqueInFolder = (id?: number): yup.TestFunction<string | undefined> => {\n return async function test(name?: string) {\n const { exists } = getService('folder');\n const filters: Record<string, unknown> = { name, parent: this.parent.parent || null };\n if (id) {\n filters.id = { $ne: id };\n\n if (isUndefined(name)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n filters.name = get('name', existingFolder);\n }\n }\n\n const doesExist = await exists(filters);\n return !doesExist;\n };\n};\n\nconst validateCreateFolderSchema = yup\n .object()\n .shape({\n name: yup\n .string()\n .min(1)\n .matches(NO_SLASH_REGEX, 'name cannot contain slashes')\n .matches(NO_SPACES_AROUND, 'name cannot start or end with a whitespace')\n .required()\n .test('is-folder-unique', 'A folder with this name already exists', isNameUniqueInFolder()),\n parent: yup\n .strapiID()\n .nullable()\n .test('folder-exists', 'parent folder does not exist', folderExists),\n })\n .noUnknown()\n .required();\n\nconst validateUpdateFolderSchema = (id: number) =>\n yup\n .object()\n .shape({\n name: yup\n .string()\n .min(1)\n .matches(NO_SLASH_REGEX, 'name cannot contain slashes')\n .matches(NO_SPACES_AROUND, 'name cannot start or end with a whitespace')\n .test(\n 'is-folder-unique',\n 'A folder with this name already exists',\n isNameUniqueInFolder(id)\n ),\n parent: yup\n .strapiID()\n .nullable()\n .test('folder-exists', 'parent folder does not exist', folderExists)\n .test(\n 'dont-move-inside-self',\n 'folder cannot be moved inside itself',\n async function test(parent) {\n if (isNil(parent)) return true;\n\n const destinationFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id: parent },\n });\n\n const currentFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id },\n });\n\n if (!destinationFolder || !currentFolder) return true;\n\n return !isFolderOrChild(destinationFolder, currentFolder);\n }\n ),\n })\n .noUnknown()\n .required();\n\nexport const validateCreateFolder = validateYupSchema(validateCreateFolderSchema);\nexport const validateUpdateFolder = (id: number) =>\n validateYupSchema(validateUpdateFolderSchema(id));\n"],"names":["NO_SLASH_REGEX","NO_SPACES_AROUND","isNameUniqueInFolder","id","test","name","exists","getService","filters","parent","$ne","isUndefined","existingFolder","strapi","db","query","FOLDER_MODEL_UID","findOne","where","get","doesExist","validateCreateFolderSchema","yup","object","shape","string","min","matches","required","strapiID","nullable","folderExists","noUnknown","validateUpdateFolderSchema","isNil","destinationFolder","select","currentFolder","isFolderOrChild","validateCreateFolder","validateYupSchema","validateUpdateFolder"],"mappings":";;;;;;;AAOA,MAAMA,cAAiB,GAAA,SAAA;AACvB,MAAMC,gBAAmB,GAAA,
|
|
1
|
+
{"version":3,"file":"folder.mjs","sources":["../../../../../server/src/controllers/validation/admin/folder.ts"],"sourcesContent":["import { isUndefined, get, isNil } from 'lodash/fp';\nimport { yup, validateYupSchema } from '@strapi/utils';\nimport { getService } from '../../../utils';\nimport { FOLDER_MODEL_UID } from '../../../constants';\nimport { folderExists } from './utils';\nimport { isFolderOrChild } from '../../utils/folders';\n\nconst NO_SLASH_REGEX = /^[^/]+$/;\nconst NO_SPACES_AROUND = /^(?! ).+(?<! )$/;\n\nconst isNameUniqueInFolder = (id?: number): yup.TestFunction<string | undefined> => {\n return async function test(name?: string) {\n const { exists } = getService('folder');\n const filters: Record<string, unknown> = { name, parent: this.parent.parent || null };\n if (id) {\n filters.id = { $ne: id };\n\n if (isUndefined(name)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n filters.name = get('name', existingFolder);\n }\n }\n\n const doesExist = await exists(filters);\n return !doesExist;\n };\n};\n\nconst validateCreateFolderSchema = yup\n .object()\n .shape({\n name: yup\n .string()\n .min(1)\n .matches(NO_SLASH_REGEX, 'name cannot contain slashes')\n .matches(NO_SPACES_AROUND, 'name cannot start or end with a whitespace')\n .required()\n .test('is-folder-unique', 'A folder with this name already exists', isNameUniqueInFolder()),\n parent: yup\n .strapiID()\n .nullable()\n .test('folder-exists', 'parent folder does not exist', folderExists),\n })\n .noUnknown()\n .required();\n\nconst validateUpdateFolderSchema = (id: number) =>\n yup\n .object()\n .shape({\n name: yup\n .string()\n .min(1)\n .matches(NO_SLASH_REGEX, 'name cannot contain slashes')\n .matches(NO_SPACES_AROUND, 'name cannot start or end with a whitespace')\n .test(\n 'is-folder-unique',\n 'A folder with this name already exists',\n isNameUniqueInFolder(id)\n ),\n parent: yup\n .strapiID()\n .nullable()\n .test('folder-exists', 'parent folder does not exist', folderExists)\n .test(\n 'dont-move-inside-self',\n 'folder cannot be moved inside itself',\n async function test(parent) {\n if (isNil(parent)) return true;\n\n const destinationFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id: parent },\n });\n\n const currentFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({\n select: ['path'],\n where: { id },\n });\n\n if (!destinationFolder || !currentFolder) return true;\n\n return !isFolderOrChild(destinationFolder, currentFolder);\n }\n ),\n })\n .noUnknown()\n .required();\n\nexport const validateCreateFolder = validateYupSchema(validateCreateFolderSchema);\nexport const validateUpdateFolder = (id: number) =>\n validateYupSchema(validateUpdateFolderSchema(id));\n"],"names":["NO_SLASH_REGEX","NO_SPACES_AROUND","isNameUniqueInFolder","id","test","name","exists","getService","filters","parent","$ne","isUndefined","existingFolder","strapi","db","query","FOLDER_MODEL_UID","findOne","where","get","doesExist","validateCreateFolderSchema","yup","object","shape","string","min","matches","required","strapiID","nullable","folderExists","noUnknown","validateUpdateFolderSchema","isNil","destinationFolder","select","currentFolder","isFolderOrChild","validateCreateFolder","validateYupSchema","validateUpdateFolder"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n strapi.plugin('upload').provider = createProvider(strapi.config.get<Config>('plugin::upload'));\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","plugin","provider","createProvider","config","get","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerOptions","actionOptions","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":";;;;;;;AASA,MAAM,EAAEA,oBAAoB,EAAE,GAAGC,YAAAA;AACjC,MAAM,EAAEC,oBAAoB,EAAEC,aAAa,EAAE,GAAGC,UAAAA;AAEhD;;AAEC,IACM,eAAeC,QAAS,CAAA,EAAEC,MAAM,EAA2B,EAAA;IAChEA,MAAOC,CAAAA,MAAM,CAAC,QAAA,CAAA,CAAUC,QAAQ,GAAGC,eAAeH,MAAOI,CAAAA,MAAM,CAACC,GAAG,CAAS,gBAAA,CAAA,CAAA;AAE5E,IAAA,MAAMC,MAAyB,CAAA;AAAEN,QAAAA;AAAO,KAAA,CAAA;IAExC,IAAIA,MAAAA,CAAOC,MAAM,CAAC,SAAY,CAAA,EAAA;AAC5B,QAAA,MAAM,EAAEM,uBAAuB,EAAE,GAAG,MAAM,oDAAO,cAAA,KAAA;QACjDA,uBAAwB,CAAA;AAAEP,YAAAA;AAAO,SAAA,CAAA;AACnC;IAEA,IAAIA,MAAAA,CAAOC,MAAM,CAAC,eAAkB,CAAA,EAAA;QAClCD,MACGC,CAAAA,MAAM,CAAC,eACPO,CAAAA,CAAAA,OAAO,CAAC,UACRC,CAAAA,CAAAA,gBAAgB,CAACC,kBAAM,EAAA;YACtBC,YAAc,EAAA,QAAA;YACdC,qBAAuB,EAAA;AAAC,gBAAA;AAAS;AACnC,SAAA,CAAA;AACJ;AACF;AAEA,MAAMT,iBAAiB,CAACC,MAAAA,GAAAA;AACtB,IAAA,MAAM,EAAES,eAAe,EAAEC,gBAAgB,EAAE,EAAE,GAAGV,MAAAA;AAEhD,IAAA,MAAMW,YAAeC,GAAAA,CAAAA,CAAEC,OAAO,CAACb,OAAOF,QAAQ,CAAA;IAC9C,IAAIA,QAAAA;IAEJ,IAAIgB,UAAAA;IACJ,IAAI;AACFA,QAAAA,UAAAA,GAAaC,QAAQC,OAAO,CAAC,CAAC,wBAAwB,EAAEL,
|
|
1
|
+
{"version":3,"file":"register.js","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n strapi.plugin('upload').provider = createProvider(strapi.config.get<Config>('plugin::upload'));\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","plugin","provider","createProvider","config","get","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerOptions","actionOptions","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.mjs","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n strapi.plugin('upload').provider = createProvider(strapi.config.get<Config>('plugin::upload'));\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","plugin","provider","createProvider","config","get","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerOptions","actionOptions","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":";;;;;AASA,MAAM,EAAEA,oBAAoB,EAAE,GAAGC,MAAAA;AACjC,MAAM,EAAEC,oBAAoB,EAAEC,aAAa,EAAE,GAAGC,IAAAA;AAEhD;;AAEC,IACM,eAAeC,QAAS,CAAA,EAAEC,MAAM,EAA2B,EAAA;IAChEA,MAAOC,CAAAA,MAAM,CAAC,QAAA,CAAA,CAAUC,QAAQ,GAAGC,eAAeH,MAAOI,CAAAA,MAAM,CAACC,GAAG,CAAS,gBAAA,CAAA,CAAA;AAE5E,IAAA,MAAMC,wBAAyB,CAAA;AAAEN,QAAAA;AAAO,KAAA,CAAA;IAExC,IAAIA,MAAAA,CAAOC,MAAM,CAAC,SAAY,CAAA,EAAA;AAC5B,QAAA,MAAM,EAAEM,uBAAuB,EAAE,GAAG,MAAM,OAAO,eAAA,CAAA;QACjDA,uBAAwB,CAAA;AAAEP,YAAAA;AAAO,SAAA,CAAA;AACnC;IAEA,IAAIA,MAAAA,CAAOC,MAAM,CAAC,eAAkB,CAAA,EAAA;QAClCD,MACGC,CAAAA,MAAM,CAAC,eACPO,CAAAA,CAAAA,OAAO,CAAC,UACRC,CAAAA,CAAAA,gBAAgB,CAACC,IAAM,EAAA;YACtBC,YAAc,EAAA,QAAA;YACdC,qBAAuB,EAAA;AAAC,gBAAA;AAAS;AACnC,SAAA,CAAA;AACJ;AACF;AAEA,MAAMT,iBAAiB,CAACC,MAAAA,GAAAA;AACtB,IAAA,MAAM,EAAES,eAAe,EAAEC,gBAAgB,EAAE,EAAE,GAAGV,MAAAA;AAEhD,IAAA,MAAMW,YAAeC,GAAAA,CAAAA,CAAEC,OAAO,CAACb,OAAOF,QAAQ,CAAA;IAC9C,IAAIA,QAAAA;IAEJ,IAAIgB,UAAAA;IACJ,IAAI;AACFA,QAAAA,UAAAA,GAAaC,QAAQC,OAAO,CAAC,CAAC,wBAAwB,EAAEL,
|
|
1
|
+
{"version":3,"file":"register.mjs","sources":["../../server/src/register.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { errors, file } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\n\nimport registerUploadMiddleware from './middlewares/upload';\nimport spec from '../../documentation/content-api.json';\nimport type { Config, File, InputFile } from './types';\n\nconst { PayloadTooLargeError } = errors;\nconst { bytesToHumanReadable, kbytesToBytes } = file;\n\n/**\n * Register upload plugin\n */\nexport async function register({ strapi }: { strapi: Core.Strapi }) {\n strapi.plugin('upload').provider = createProvider(strapi.config.get<Config>('plugin::upload'));\n\n await registerUploadMiddleware({ strapi });\n\n if (strapi.plugin('graphql')) {\n const { installGraphqlExtension } = await import('./graphql.js');\n installGraphqlExtension({ strapi });\n }\n\n if (strapi.plugin('documentation')) {\n strapi\n .plugin('documentation')\n .service('override')\n .registerOverride(spec, {\n pluginOrigin: 'upload',\n excludeFromGeneration: ['upload'],\n });\n }\n}\n\nconst createProvider = (config: Config) => {\n const { providerOptions, actionOptions = {} } = config;\n\n const providerName = _.toLower(config.provider);\n let provider;\n\n let modulePath;\n try {\n modulePath = require.resolve(`@strapi/provider-upload-${providerName}`);\n } catch (error) {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n ) {\n modulePath = providerName;\n } else {\n throw error;\n }\n }\n\n try {\n provider = require(modulePath);\n } catch (err) {\n const newError = new Error(`Could not load upload provider \"${providerName}\".`);\n\n if (err instanceof Error) {\n newError.stack = err.stack;\n }\n\n throw newError;\n }\n\n const providerInstance = provider.init(providerOptions);\n\n if (!providerInstance.delete) {\n throw new Error(`The upload provider \"${providerName}\" doesn't implement the delete method.`);\n }\n\n if (!providerInstance.upload && !providerInstance.uploadStream) {\n throw new Error(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream nor the upload method.`\n );\n }\n\n if (!providerInstance.uploadStream) {\n process.emitWarning(\n `The upload provider \"${providerName}\" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.`\n );\n }\n\n const wrappedProvider = _.mapValues(providerInstance, (method, methodName) => {\n return async (file: File, options = actionOptions[methodName]) =>\n providerInstance[methodName](file, options);\n });\n\n return Object.assign(Object.create(baseProvider), wrappedProvider);\n};\n\nconst baseProvider = {\n extend(obj: unknown) {\n Object.assign(this, obj);\n },\n checkFileSize(file: InputFile, { sizeLimit }: { sizeLimit: number }) {\n if (sizeLimit && kbytesToBytes(file.size) > sizeLimit) {\n throw new PayloadTooLargeError(\n `${file.originalFilename} exceeds size limit of ${bytesToHumanReadable(sizeLimit)}.`\n );\n }\n },\n getSignedUrl(file: File) {\n return file;\n },\n isPrivate() {\n return false;\n },\n};\n"],"names":["PayloadTooLargeError","errors","bytesToHumanReadable","kbytesToBytes","file","register","strapi","plugin","provider","createProvider","config","get","registerUploadMiddleware","installGraphqlExtension","service","registerOverride","spec","pluginOrigin","excludeFromGeneration","providerOptions","actionOptions","providerName","_","toLower","modulePath","require","resolve","error","code","err","newError","Error","stack","providerInstance","init","delete","upload","uploadStream","process","emitWarning","wrappedProvider","mapValues","method","methodName","options","Object","assign","create","baseProvider","extend","obj","checkFileSize","sizeLimit","size","originalFilename","getSignedUrl","isPrivate"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-metadata.js","sources":["../../../server/src/services/ai-metadata.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { z } from 'zod';\nimport { InputFile } from '../types';\nimport { Settings } from '../controllers/validation/admin/settings';\n\nconst createAIMetadataService = ({ strapi }: { strapi: Core.Strapi }) => {\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return {\n async isEnabled() {\n // Check if user disabled AI features globally\n const isAIEnabled = strapi.config.get('admin.ai.enabled', true);\n if (!isAIEnabled) {\n return false;\n }\n\n // Check if the user's license grants access to AI features\n const hasAccess = strapi.ee.features.isEnabled('cms-ai');\n if (!hasAccess) {\n return false;\n }\n\n // Check if feature is specifically enabled, defaulting to true\n const settings: Settings = await strapi.plugin('upload').service('upload').getSettings();\n const aiMetadata: boolean = settings.aiMetadata ?? true;\n\n return aiMetadata;\n },\n\n async processFiles(\n files: InputFile[]\n ): Promise<Array<{ altText: string; caption: string } | null>> {\n if (!(await this.isEnabled()) || !aiServerUrl) {\n throw new Error('AI Metadata service is not enabled');\n }\n\n // Filter for image files only and track their original positions\n // We need to maintain the original indices so we can map AI results back correctly\n const imageFiles = files\n .map((file, index) => ({ file, originalIndex: index }))\n .filter(({ file }) => file.mimetype?.startsWith('image/'));\n\n // If no image files, return sparse array with all nulls to avoid calling the AI server\n // This maintains the same array length as input files for proper index alignment\n if (imageFiles.length === 0) {\n return new Array(files.length).fill(null);\n }\n\n const formData = new FormData();\n\n for (const { file } of imageFiles) {\n const fullUrl =\n file.provider === 'local'\n ? strapi.config.get('server.absoluteUrl') + file.filepath\n : file.filepath;\n\n const resp = await fetch(fullUrl);\n if (!resp.ok) {\n throw new Error(`Failed to fetch image from URL: ${fullUrl} (${resp.status})`);\n }\n const ab = await resp.arrayBuffer();\n const blob: Blob = new Blob([ab], { type: file.mimetype || undefined });\n formData.append('files', blob);\n }\n\n let token: string;\n try {\n const tokenData = await strapi.service('admin::user').getAiToken();\n token = tokenData.token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n strapi.log.http('Contacting AI Server for media metadata generation');\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n throw Error(`AI metadata generation failed`, { cause: await res.text() });\n }\n\n const responseSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n });\n\n const { results } = responseSchema.parse(await res.json());\n strapi.log.http(`Media metadata generated successfully for ${results.length} files`);\n\n // Create sparse array with results at original indices\n // Example: files=[img1, pdf, img2] -> imageFiles=[{img1, index:0}, {img2, index:2}]\n // AI results=[meta1, meta2] -> sparse=[meta1, null, meta2]\n // This ensures metadata[i] corresponds to files[i], with null for non-images\n return imageFiles.reduce((sparseResults, { originalIndex }, resultIndex) => {\n sparseResults[originalIndex] = results[resultIndex];\n return sparseResults;\n }, new Array(files.length).fill(null));\n },\n };\n};\n\nexport { createAIMetadataService };\n"],"names":["createAIMetadataService","strapi","aiServerUrl","process","env","STRAPI_AI_URL","isEnabled","isAIEnabled","config","get","hasAccess","ee","features","settings","plugin","service","getSettings","aiMetadata","processFiles","files","Error","imageFiles","map","file","index","originalIndex","filter","mimetype","startsWith","length","Array","fill","formData","FormData","fullUrl","provider","filepath","resp","fetch","ok","status","ab","arrayBuffer","blob","Blob","type","undefined","append","token","tokenData","getAiToken","error","cause","log","http","res","method","body","headers","Authorization","text","responseSchema","z","object","results","array","altText","string","caption","parse","json","reduce","sparseResults","resultIndex"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ai-metadata.js","sources":["../../../server/src/services/ai-metadata.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { z } from 'zod';\nimport { InputFile } from '../types';\nimport { Settings } from '../controllers/validation/admin/settings';\n\nconst createAIMetadataService = ({ strapi }: { strapi: Core.Strapi }) => {\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return {\n async isEnabled() {\n // Check if user disabled AI features globally\n const isAIEnabled = strapi.config.get('admin.ai.enabled', true);\n if (!isAIEnabled) {\n return false;\n }\n\n // Check if the user's license grants access to AI features\n const hasAccess = strapi.ee.features.isEnabled('cms-ai');\n if (!hasAccess) {\n return false;\n }\n\n // Check if feature is specifically enabled, defaulting to true\n const settings: Settings = await strapi.plugin('upload').service('upload').getSettings();\n const aiMetadata: boolean = settings.aiMetadata ?? true;\n\n return aiMetadata;\n },\n\n async processFiles(\n files: InputFile[]\n ): Promise<Array<{ altText: string; caption: string } | null>> {\n if (!(await this.isEnabled()) || !aiServerUrl) {\n throw new Error('AI Metadata service is not enabled');\n }\n\n // Filter for image files only and track their original positions\n // We need to maintain the original indices so we can map AI results back correctly\n const imageFiles = files\n .map((file, index) => ({ file, originalIndex: index }))\n .filter(({ file }) => file.mimetype?.startsWith('image/'));\n\n // If no image files, return sparse array with all nulls to avoid calling the AI server\n // This maintains the same array length as input files for proper index alignment\n if (imageFiles.length === 0) {\n return new Array(files.length).fill(null);\n }\n\n const formData = new FormData();\n\n for (const { file } of imageFiles) {\n const fullUrl =\n file.provider === 'local'\n ? strapi.config.get('server.absoluteUrl') + file.filepath\n : file.filepath;\n\n const resp = await fetch(fullUrl);\n if (!resp.ok) {\n throw new Error(`Failed to fetch image from URL: ${fullUrl} (${resp.status})`);\n }\n const ab = await resp.arrayBuffer();\n const blob: Blob = new Blob([ab], { type: file.mimetype || undefined });\n formData.append('files', blob);\n }\n\n let token: string;\n try {\n const tokenData = await strapi.service('admin::user').getAiToken();\n token = tokenData.token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n strapi.log.http('Contacting AI Server for media metadata generation');\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n throw Error(`AI metadata generation failed`, { cause: await res.text() });\n }\n\n const responseSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n });\n\n const { results } = responseSchema.parse(await res.json());\n strapi.log.http(`Media metadata generated successfully for ${results.length} files`);\n\n // Create sparse array with results at original indices\n // Example: files=[img1, pdf, img2] -> imageFiles=[{img1, index:0}, {img2, index:2}]\n // AI results=[meta1, meta2] -> sparse=[meta1, null, meta2]\n // This ensures metadata[i] corresponds to files[i], with null for non-images\n return imageFiles.reduce((sparseResults, { originalIndex }, resultIndex) => {\n sparseResults[originalIndex] = results[resultIndex];\n return sparseResults;\n }, new Array(files.length).fill(null));\n },\n };\n};\n\nexport { createAIMetadataService };\n"],"names":["createAIMetadataService","strapi","aiServerUrl","process","env","STRAPI_AI_URL","isEnabled","isAIEnabled","config","get","hasAccess","ee","features","settings","plugin","service","getSettings","aiMetadata","processFiles","files","Error","imageFiles","map","file","index","originalIndex","filter","mimetype","startsWith","length","Array","fill","formData","FormData","fullUrl","provider","filepath","resp","fetch","ok","status","ab","arrayBuffer","blob","Blob","type","undefined","append","token","tokenData","getAiToken","error","cause","log","http","res","method","body","headers","Authorization","text","responseSchema","z","object","results","array","altText","string","caption","parse","json","reduce","sparseResults","resultIndex"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-metadata.mjs","sources":["../../../server/src/services/ai-metadata.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { z } from 'zod';\nimport { InputFile } from '../types';\nimport { Settings } from '../controllers/validation/admin/settings';\n\nconst createAIMetadataService = ({ strapi }: { strapi: Core.Strapi }) => {\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return {\n async isEnabled() {\n // Check if user disabled AI features globally\n const isAIEnabled = strapi.config.get('admin.ai.enabled', true);\n if (!isAIEnabled) {\n return false;\n }\n\n // Check if the user's license grants access to AI features\n const hasAccess = strapi.ee.features.isEnabled('cms-ai');\n if (!hasAccess) {\n return false;\n }\n\n // Check if feature is specifically enabled, defaulting to true\n const settings: Settings = await strapi.plugin('upload').service('upload').getSettings();\n const aiMetadata: boolean = settings.aiMetadata ?? true;\n\n return aiMetadata;\n },\n\n async processFiles(\n files: InputFile[]\n ): Promise<Array<{ altText: string; caption: string } | null>> {\n if (!(await this.isEnabled()) || !aiServerUrl) {\n throw new Error('AI Metadata service is not enabled');\n }\n\n // Filter for image files only and track their original positions\n // We need to maintain the original indices so we can map AI results back correctly\n const imageFiles = files\n .map((file, index) => ({ file, originalIndex: index }))\n .filter(({ file }) => file.mimetype?.startsWith('image/'));\n\n // If no image files, return sparse array with all nulls to avoid calling the AI server\n // This maintains the same array length as input files for proper index alignment\n if (imageFiles.length === 0) {\n return new Array(files.length).fill(null);\n }\n\n const formData = new FormData();\n\n for (const { file } of imageFiles) {\n const fullUrl =\n file.provider === 'local'\n ? strapi.config.get('server.absoluteUrl') + file.filepath\n : file.filepath;\n\n const resp = await fetch(fullUrl);\n if (!resp.ok) {\n throw new Error(`Failed to fetch image from URL: ${fullUrl} (${resp.status})`);\n }\n const ab = await resp.arrayBuffer();\n const blob: Blob = new Blob([ab], { type: file.mimetype || undefined });\n formData.append('files', blob);\n }\n\n let token: string;\n try {\n const tokenData = await strapi.service('admin::user').getAiToken();\n token = tokenData.token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n strapi.log.http('Contacting AI Server for media metadata generation');\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n throw Error(`AI metadata generation failed`, { cause: await res.text() });\n }\n\n const responseSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n });\n\n const { results } = responseSchema.parse(await res.json());\n strapi.log.http(`Media metadata generated successfully for ${results.length} files`);\n\n // Create sparse array with results at original indices\n // Example: files=[img1, pdf, img2] -> imageFiles=[{img1, index:0}, {img2, index:2}]\n // AI results=[meta1, meta2] -> sparse=[meta1, null, meta2]\n // This ensures metadata[i] corresponds to files[i], with null for non-images\n return imageFiles.reduce((sparseResults, { originalIndex }, resultIndex) => {\n sparseResults[originalIndex] = results[resultIndex];\n return sparseResults;\n }, new Array(files.length).fill(null));\n },\n };\n};\n\nexport { createAIMetadataService };\n"],"names":["createAIMetadataService","strapi","aiServerUrl","process","env","STRAPI_AI_URL","isEnabled","isAIEnabled","config","get","hasAccess","ee","features","settings","plugin","service","getSettings","aiMetadata","processFiles","files","Error","imageFiles","map","file","index","originalIndex","filter","mimetype","startsWith","length","Array","fill","formData","FormData","fullUrl","provider","filepath","resp","fetch","ok","status","ab","arrayBuffer","blob","Blob","type","undefined","append","token","tokenData","getAiToken","error","cause","log","http","res","method","body","headers","Authorization","text","responseSchema","z","object","results","array","altText","string","caption","parse","json","reduce","sparseResults","resultIndex"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ai-metadata.mjs","sources":["../../../server/src/services/ai-metadata.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport { z } from 'zod';\nimport { InputFile } from '../types';\nimport { Settings } from '../controllers/validation/admin/settings';\n\nconst createAIMetadataService = ({ strapi }: { strapi: Core.Strapi }) => {\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n return {\n async isEnabled() {\n // Check if user disabled AI features globally\n const isAIEnabled = strapi.config.get('admin.ai.enabled', true);\n if (!isAIEnabled) {\n return false;\n }\n\n // Check if the user's license grants access to AI features\n const hasAccess = strapi.ee.features.isEnabled('cms-ai');\n if (!hasAccess) {\n return false;\n }\n\n // Check if feature is specifically enabled, defaulting to true\n const settings: Settings = await strapi.plugin('upload').service('upload').getSettings();\n const aiMetadata: boolean = settings.aiMetadata ?? true;\n\n return aiMetadata;\n },\n\n async processFiles(\n files: InputFile[]\n ): Promise<Array<{ altText: string; caption: string } | null>> {\n if (!(await this.isEnabled()) || !aiServerUrl) {\n throw new Error('AI Metadata service is not enabled');\n }\n\n // Filter for image files only and track their original positions\n // We need to maintain the original indices so we can map AI results back correctly\n const imageFiles = files\n .map((file, index) => ({ file, originalIndex: index }))\n .filter(({ file }) => file.mimetype?.startsWith('image/'));\n\n // If no image files, return sparse array with all nulls to avoid calling the AI server\n // This maintains the same array length as input files for proper index alignment\n if (imageFiles.length === 0) {\n return new Array(files.length).fill(null);\n }\n\n const formData = new FormData();\n\n for (const { file } of imageFiles) {\n const fullUrl =\n file.provider === 'local'\n ? strapi.config.get('server.absoluteUrl') + file.filepath\n : file.filepath;\n\n const resp = await fetch(fullUrl);\n if (!resp.ok) {\n throw new Error(`Failed to fetch image from URL: ${fullUrl} (${resp.status})`);\n }\n const ab = await resp.arrayBuffer();\n const blob: Blob = new Blob([ab], { type: file.mimetype || undefined });\n formData.append('files', blob);\n }\n\n let token: string;\n try {\n const tokenData = await strapi.service('admin::user').getAiToken();\n token = tokenData.token;\n } catch (error) {\n throw new Error('Failed to retrieve AI token', {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n strapi.log.http('Contacting AI Server for media metadata generation');\n const res = await fetch(`${aiServerUrl}/media-library/generate-metadata`, {\n method: 'POST',\n body: formData,\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n throw Error(`AI metadata generation failed`, { cause: await res.text() });\n }\n\n const responseSchema = z.object({\n results: z.array(\n z.object({\n altText: z.string(),\n caption: z.string(),\n })\n ),\n });\n\n const { results } = responseSchema.parse(await res.json());\n strapi.log.http(`Media metadata generated successfully for ${results.length} files`);\n\n // Create sparse array with results at original indices\n // Example: files=[img1, pdf, img2] -> imageFiles=[{img1, index:0}, {img2, index:2}]\n // AI results=[meta1, meta2] -> sparse=[meta1, null, meta2]\n // This ensures metadata[i] corresponds to files[i], with null for non-images\n return imageFiles.reduce((sparseResults, { originalIndex }, resultIndex) => {\n sparseResults[originalIndex] = results[resultIndex];\n return sparseResults;\n }, new Array(files.length).fill(null));\n },\n };\n};\n\nexport { createAIMetadataService };\n"],"names":["createAIMetadataService","strapi","aiServerUrl","process","env","STRAPI_AI_URL","isEnabled","isAIEnabled","config","get","hasAccess","ee","features","settings","plugin","service","getSettings","aiMetadata","processFiles","files","Error","imageFiles","map","file","index","originalIndex","filter","mimetype","startsWith","length","Array","fill","formData","FormData","fullUrl","provider","filepath","resp","fetch","ok","status","ab","arrayBuffer","blob","Blob","type","undefined","append","token","tokenData","getAiToken","error","cause","log","http","res","method","body","headers","Authorization","text","responseSchema","z","object","results","array","altText","string","caption","parse","json","reduce","sparseResults","resultIndex"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-upload-folder.js","sources":["../../../server/src/services/api-upload-folder.ts"],"sourcesContent":["import { isNil, get } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID, API_UPLOAD_FOLDER_BASE_NAME } from '../constants';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'upload', key: 'api-folder' });\n\nconst createApiUploadFolder = async () => {\n let name = API_UPLOAD_FOLDER_BASE_NAME;\n const folderService = getService('folder');\n\n let exists = true;\n let index = 1;\n while (exists) {\n exists = await folderService.exists({ name, parent: null });\n if (exists) {\n name = `${API_UPLOAD_FOLDER_BASE_NAME} (${index})`;\n index += 1;\n }\n }\n\n const folder = await folderService.create({ name });\n\n await getStore().set({ value: { id: folder.id } });\n\n return folder;\n};\n\nconst getAPIUploadFolder = async () => {\n const storeValue = await getStore().get({});\n const folderId = get('id', storeValue);\n\n const folder = folderId\n ? await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id: folderId } })\n : null;\n\n return isNil(folder) ? createApiUploadFolder() : folder;\n};\n\nexport default {\n getAPIUploadFolder,\n};\n"],"names":["getStore","strapi","store","type","name","key","createApiUploadFolder","API_UPLOAD_FOLDER_BASE_NAME","folderService","getService","exists","index","parent","folder","create","set","value","id","getAPIUploadFolder","storeValue","get","folderId","db","query","FOLDER_MODEL_UID","findOne","where","isNil"],"mappings":";;;;;;AAIA,MAAMA,QAAW,GAAA,IAAMC,MAAOC,CAAAA,KAAK,CAAC;QAAEC,IAAM,EAAA,QAAA;QAAUC,IAAM,EAAA,QAAA;QAAUC,GAAK,EAAA;AAAa,KAAA,CAAA;AAExF,MAAMC,qBAAwB,GAAA,UAAA;AAC5B,IAAA,IAAIF,IAAOG,GAAAA,qCAAAA;AACX,IAAA,MAAMC,gBAAgBC,gBAAW,CAAA,QAAA,CAAA;AAEjC,IAAA,IAAIC,MAAS,GAAA,IAAA;AACb,IAAA,IAAIC,OAAQ,GAAA,CAAA;AACZ,IAAA,MAAOD,MAAQ,CAAA;QACbA,MAAS,GAAA,MAAMF,aAAcE,CAAAA,MAAM,CAAC;AAAEN,YAAAA,IAAAA;YAAMQ,MAAQ,EAAA;AAAK,SAAA,CAAA;AACzD,QAAA,IAAIF,MAAQ,EAAA;AACVN,YAAAA,IAAAA,GAAO,
|
|
1
|
+
{"version":3,"file":"api-upload-folder.js","sources":["../../../server/src/services/api-upload-folder.ts"],"sourcesContent":["import { isNil, get } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID, API_UPLOAD_FOLDER_BASE_NAME } from '../constants';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'upload', key: 'api-folder' });\n\nconst createApiUploadFolder = async () => {\n let name = API_UPLOAD_FOLDER_BASE_NAME;\n const folderService = getService('folder');\n\n let exists = true;\n let index = 1;\n while (exists) {\n exists = await folderService.exists({ name, parent: null });\n if (exists) {\n name = `${API_UPLOAD_FOLDER_BASE_NAME} (${index})`;\n index += 1;\n }\n }\n\n const folder = await folderService.create({ name });\n\n await getStore().set({ value: { id: folder.id } });\n\n return folder;\n};\n\nconst getAPIUploadFolder = async () => {\n const storeValue = await getStore().get({});\n const folderId = get('id', storeValue);\n\n const folder = folderId\n ? await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id: folderId } })\n : null;\n\n return isNil(folder) ? createApiUploadFolder() : folder;\n};\n\nexport default {\n getAPIUploadFolder,\n};\n"],"names":["getStore","strapi","store","type","name","key","createApiUploadFolder","API_UPLOAD_FOLDER_BASE_NAME","folderService","getService","exists","index","parent","folder","create","set","value","id","getAPIUploadFolder","storeValue","get","folderId","db","query","FOLDER_MODEL_UID","findOne","where","isNil"],"mappings":";;;;;;AAIA,MAAMA,QAAW,GAAA,IAAMC,MAAOC,CAAAA,KAAK,CAAC;QAAEC,IAAM,EAAA,QAAA;QAAUC,IAAM,EAAA,QAAA;QAAUC,GAAK,EAAA;AAAa,KAAA,CAAA;AAExF,MAAMC,qBAAwB,GAAA,UAAA;AAC5B,IAAA,IAAIF,IAAOG,GAAAA,qCAAAA;AACX,IAAA,MAAMC,gBAAgBC,gBAAW,CAAA,QAAA,CAAA;AAEjC,IAAA,IAAIC,MAAS,GAAA,IAAA;AACb,IAAA,IAAIC,OAAQ,GAAA,CAAA;AACZ,IAAA,MAAOD,MAAQ,CAAA;QACbA,MAAS,GAAA,MAAMF,aAAcE,CAAAA,MAAM,CAAC;AAAEN,YAAAA,IAAAA;YAAMQ,MAAQ,EAAA;AAAK,SAAA,CAAA;AACzD,QAAA,IAAIF,MAAQ,EAAA;AACVN,YAAAA,IAAAA,GAAO,GAAGG,qCAA4B,CAAA,EAAE,EAAEI,OAAAA,CAAM,CAAC,CAAC;YAClDA,OAAS,IAAA,CAAA;AACX;AACF;AAEA,IAAA,MAAME,MAAS,GAAA,MAAML,aAAcM,CAAAA,MAAM,CAAC;AAAEV,QAAAA;AAAK,KAAA,CAAA;IAEjD,MAAMJ,QAAAA,EAAAA,CAAWe,GAAG,CAAC;QAAEC,KAAO,EAAA;AAAEC,YAAAA,EAAAA,EAAIJ,OAAOI;AAAG;AAAE,KAAA,CAAA;IAEhD,OAAOJ,MAAAA;AACT,CAAA;AAEA,MAAMK,kBAAqB,GAAA,UAAA;AACzB,IAAA,MAAMC,UAAa,GAAA,MAAMnB,QAAWoB,EAAAA,CAAAA,GAAG,CAAC,EAAC,CAAA;IACzC,MAAMC,QAAAA,GAAWD,OAAI,IAAMD,EAAAA,UAAAA,CAAAA;IAE3B,MAAMN,MAAAA,GAASQ,QACX,GAAA,MAAMpB,MAAOqB,CAAAA,EAAE,CAACC,KAAK,CAACC,0BAAkBC,CAAAA,CAAAA,OAAO,CAAC;QAAEC,KAAO,EAAA;YAAET,EAAII,EAAAA;AAAS;KACxE,CAAA,GAAA,IAAA;IAEJ,OAAOM,QAAAA,CAAMd,UAAUP,qBAA0BO,EAAAA,GAAAA,MAAAA;AACnD,CAAA;AAEA,sBAAe;AACbK,IAAAA;AACF,CAAE;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-upload-folder.mjs","sources":["../../../server/src/services/api-upload-folder.ts"],"sourcesContent":["import { isNil, get } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID, API_UPLOAD_FOLDER_BASE_NAME } from '../constants';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'upload', key: 'api-folder' });\n\nconst createApiUploadFolder = async () => {\n let name = API_UPLOAD_FOLDER_BASE_NAME;\n const folderService = getService('folder');\n\n let exists = true;\n let index = 1;\n while (exists) {\n exists = await folderService.exists({ name, parent: null });\n if (exists) {\n name = `${API_UPLOAD_FOLDER_BASE_NAME} (${index})`;\n index += 1;\n }\n }\n\n const folder = await folderService.create({ name });\n\n await getStore().set({ value: { id: folder.id } });\n\n return folder;\n};\n\nconst getAPIUploadFolder = async () => {\n const storeValue = await getStore().get({});\n const folderId = get('id', storeValue);\n\n const folder = folderId\n ? await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id: folderId } })\n : null;\n\n return isNil(folder) ? createApiUploadFolder() : folder;\n};\n\nexport default {\n getAPIUploadFolder,\n};\n"],"names":["getStore","strapi","store","type","name","key","createApiUploadFolder","API_UPLOAD_FOLDER_BASE_NAME","folderService","getService","exists","index","parent","folder","create","set","value","id","getAPIUploadFolder","storeValue","get","folderId","db","query","FOLDER_MODEL_UID","findOne","where","isNil"],"mappings":";;;;AAIA,MAAMA,QAAW,GAAA,IAAMC,MAAOC,CAAAA,KAAK,CAAC;QAAEC,IAAM,EAAA,QAAA;QAAUC,IAAM,EAAA,QAAA;QAAUC,GAAK,EAAA;AAAa,KAAA,CAAA;AAExF,MAAMC,qBAAwB,GAAA,UAAA;AAC5B,IAAA,IAAIF,IAAOG,GAAAA,2BAAAA;AACX,IAAA,MAAMC,gBAAgBC,UAAW,CAAA,QAAA,CAAA;AAEjC,IAAA,IAAIC,MAAS,GAAA,IAAA;AACb,IAAA,IAAIC,KAAQ,GAAA,CAAA;AACZ,IAAA,MAAOD,MAAQ,CAAA;QACbA,MAAS,GAAA,MAAMF,aAAcE,CAAAA,MAAM,CAAC;AAAEN,YAAAA,IAAAA;YAAMQ,MAAQ,EAAA;AAAK,SAAA,CAAA;AACzD,QAAA,IAAIF,MAAQ,EAAA;AACVN,YAAAA,IAAAA,GAAO,
|
|
1
|
+
{"version":3,"file":"api-upload-folder.mjs","sources":["../../../server/src/services/api-upload-folder.ts"],"sourcesContent":["import { isNil, get } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { FOLDER_MODEL_UID, API_UPLOAD_FOLDER_BASE_NAME } from '../constants';\n\nconst getStore = () => strapi.store({ type: 'plugin', name: 'upload', key: 'api-folder' });\n\nconst createApiUploadFolder = async () => {\n let name = API_UPLOAD_FOLDER_BASE_NAME;\n const folderService = getService('folder');\n\n let exists = true;\n let index = 1;\n while (exists) {\n exists = await folderService.exists({ name, parent: null });\n if (exists) {\n name = `${API_UPLOAD_FOLDER_BASE_NAME} (${index})`;\n index += 1;\n }\n }\n\n const folder = await folderService.create({ name });\n\n await getStore().set({ value: { id: folder.id } });\n\n return folder;\n};\n\nconst getAPIUploadFolder = async () => {\n const storeValue = await getStore().get({});\n const folderId = get('id', storeValue);\n\n const folder = folderId\n ? await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id: folderId } })\n : null;\n\n return isNil(folder) ? createApiUploadFolder() : folder;\n};\n\nexport default {\n getAPIUploadFolder,\n};\n"],"names":["getStore","strapi","store","type","name","key","createApiUploadFolder","API_UPLOAD_FOLDER_BASE_NAME","folderService","getService","exists","index","parent","folder","create","set","value","id","getAPIUploadFolder","storeValue","get","folderId","db","query","FOLDER_MODEL_UID","findOne","where","isNil"],"mappings":";;;;AAIA,MAAMA,QAAW,GAAA,IAAMC,MAAOC,CAAAA,KAAK,CAAC;QAAEC,IAAM,EAAA,QAAA;QAAUC,IAAM,EAAA,QAAA;QAAUC,GAAK,EAAA;AAAa,KAAA,CAAA;AAExF,MAAMC,qBAAwB,GAAA,UAAA;AAC5B,IAAA,IAAIF,IAAOG,GAAAA,2BAAAA;AACX,IAAA,MAAMC,gBAAgBC,UAAW,CAAA,QAAA,CAAA;AAEjC,IAAA,IAAIC,MAAS,GAAA,IAAA;AACb,IAAA,IAAIC,KAAQ,GAAA,CAAA;AACZ,IAAA,MAAOD,MAAQ,CAAA;QACbA,MAAS,GAAA,MAAMF,aAAcE,CAAAA,MAAM,CAAC;AAAEN,YAAAA,IAAAA;YAAMQ,MAAQ,EAAA;AAAK,SAAA,CAAA;AACzD,QAAA,IAAIF,MAAQ,EAAA;AACVN,YAAAA,IAAAA,GAAO,GAAGG,2BAA4B,CAAA,EAAE,EAAEI,KAAAA,CAAM,CAAC,CAAC;YAClDA,KAAS,IAAA,CAAA;AACX;AACF;AAEA,IAAA,MAAME,MAAS,GAAA,MAAML,aAAcM,CAAAA,MAAM,CAAC;AAAEV,QAAAA;AAAK,KAAA,CAAA;IAEjD,MAAMJ,QAAAA,EAAAA,CAAWe,GAAG,CAAC;QAAEC,KAAO,EAAA;AAAEC,YAAAA,EAAAA,EAAIJ,OAAOI;AAAG;AAAE,KAAA,CAAA;IAEhD,OAAOJ,MAAAA;AACT,CAAA;AAEA,MAAMK,kBAAqB,GAAA,UAAA;AACzB,IAAA,MAAMC,UAAa,GAAA,MAAMnB,QAAWoB,EAAAA,CAAAA,GAAG,CAAC,EAAC,CAAA;IACzC,MAAMC,QAAAA,GAAWD,IAAI,IAAMD,EAAAA,UAAAA,CAAAA;IAE3B,MAAMN,MAAAA,GAASQ,QACX,GAAA,MAAMpB,MAAOqB,CAAAA,EAAE,CAACC,KAAK,CAACC,gBAAkBC,CAAAA,CAAAA,OAAO,CAAC;QAAEC,KAAO,EAAA;YAAET,EAAII,EAAAA;AAAS;KACxE,CAAA,GAAA,IAAA;IAEJ,OAAOM,KAAAA,CAAMd,UAAUP,qBAA0BO,EAAAA,GAAAA,MAAAA;AACnD,CAAA;AAEA,sBAAe;AACbK,IAAAA;AACF,CAAE;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\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]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"folder.js","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\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]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\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]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"folder.mjs","sources":["../../../server/src/services/folder.ts"],"sourcesContent":["import { sortBy, map, isUndefined } from 'lodash/fp';\nimport { strings, setCreatorFields } from '@strapi/utils';\nimport { FOLDER_MODEL_UID, FILE_MODEL_UID } from '../constants';\nimport { getService } from '../utils';\n\nimport type { File, Folder } from '../types';\n\ntype FolderMap = {\n [key: string]: Partial<Folder> & {\n children: FolderNode[];\n };\n};\n\ntype FolderNode = Partial<Folder> & {\n children: FolderNode[];\n};\n\nconst setPathIdAndPath = async (folder: Pick<Folder, 'parent'>) => {\n const { max } = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .max('pathId')\n .first()\n .execute<{ max: number }>();\n\n const pathId = max + 1;\n let parentPath = '/';\n if (folder.parent) {\n const parentFolder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .findOne({ where: { id: folder.parent } });\n\n parentPath = parentFolder.path;\n }\n\n return Object.assign(folder, {\n pathId,\n path: strings.joinBy('/', parentPath, `${pathId}`),\n });\n};\n\nconst create = async (\n folderData: Pick<Folder, 'name' | 'parent'>,\n opts?: { user: { id: string | number } }\n) => {\n const folderService = getService('folder');\n\n const { user } = opts || {};\n\n let enrichedFolder = await folderService.setPathIdAndPath(folderData);\n if (user) {\n enrichedFolder = await setCreatorFields({ user })(enrichedFolder);\n }\n\n const folder = await strapi.db.query(FOLDER_MODEL_UID).create({ data: enrichedFolder });\n\n strapi.eventHub.emit('media-folder.create', { folder });\n\n return folder;\n};\n\n/**\n * Recursively delete folders and included files\n * @param ids ids of the folders to delete\n * @returns {Promise<Object[]>}\n */\nconst deleteByIds = async (ids = []) => {\n const folders = await strapi.db.query(FOLDER_MODEL_UID).findMany({ where: { id: { $in: ids } } });\n if (folders.length === 0) {\n return {\n folders: [],\n totalFolderNumber: 0,\n totalFileNumber: 0,\n };\n }\n\n const pathsToDelete = map('path', folders);\n\n // delete files\n const filesToDelete = await strapi.db.query(FILE_MODEL_UID).findMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { folderPath: { $eq: path } },\n { folderPath: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n await Promise.all(filesToDelete.map((file: File) => getService('upload').remove(file)));\n\n // delete folders and subfolders\n const { count: totalFolderNumber } = await strapi.db.query(FOLDER_MODEL_UID).deleteMany({\n where: {\n $or: pathsToDelete.flatMap((path) => [\n { path: { $eq: path } },\n { path: { $startsWith: `${path}/` } },\n ]),\n },\n });\n\n strapi.eventHub.emit('media-folder.delete', { folders });\n\n return {\n folders,\n totalFolderNumber,\n totalFileNumber: filesToDelete.length,\n };\n};\n\n/**\n * Update name and location of a folder and its belonging folders and files\n */\nconst update = async (\n id: number,\n {\n name,\n parent,\n }: {\n name: string;\n parent: number | null;\n },\n { user }: { user: { id: string | number } }\n) => {\n // only name is updated\n if (isUndefined(parent)) {\n const existingFolder = await strapi.db.query(FOLDER_MODEL_UID).findOne({ where: { id } });\n\n if (!existingFolder) {\n return undefined;\n }\n\n const newFolder = setCreatorFields({ user, isEdition: true })({ name, parent });\n\n if (isUndefined(parent)) {\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n return folder;\n }\n // location is updated => using transaction\n } else {\n const trx = await strapi.db.transaction();\n try {\n // fetch existing folder\n const existingFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select(['pathId', 'path'])\n .where({ id })\n .transacting(trx.get())\n .forUpdate()\n .first()\n .execute<Folder>();\n\n // update parent folder (delete + insert; upsert not possible)\n // @ts-expect-error - no dynamic types\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]: id })\n .execute();\n\n if (parent !== null) {\n await strapi.db\n .queryBuilder(joinTable.name)\n .transacting(trx.get())\n .insert({ [joinTable.inverseJoinColumn.name]: parent, [joinTable.joinColumn.name]: id })\n .where({ [joinTable.joinColumn.name]: id })\n .execute();\n }\n\n // fetch destinationFolder path\n let destinationFolderPath = '/';\n if (parent !== null) {\n const destinationFolder = await strapi.db\n .queryBuilder(FOLDER_MODEL_UID)\n .select('path')\n .where({ id: parent })\n .transacting(trx.get())\n .first()\n .execute<Folder>();\n destinationFolderPath = destinationFolder.path;\n }\n\n const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName;\n const fileTable = strapi.getModel(FILE_MODEL_UID).collectionName;\n const folderPathColumnName =\n // @ts-expect-error - no dynamic types\n strapi.db.metadata.get(FILE_MODEL_UID).attributes.folderPath.columnName;\n // @ts-expect-error - no dynamic types\n const pathColumnName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName;\n\n // update folders below\n await strapi.db\n .getConnection(folderTable)\n .transacting(trx.get())\n .where(pathColumnName, existingFolder.path)\n .orWhere(pathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n pathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n pathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n // update files below\n await strapi.db\n .getConnection(fileTable)\n .transacting(trx.get())\n .where(folderPathColumnName, existingFolder.path)\n .orWhere(folderPathColumnName, 'like', `${existingFolder.path}/%`)\n .update(\n folderPathColumnName,\n strapi.db.connection.raw('REPLACE(??, ?, ?)', [\n folderPathColumnName,\n existingFolder.path,\n strings.joinBy('/', destinationFolderPath, `${existingFolder.pathId}`),\n ])\n );\n\n await trx.commit();\n } catch (e) {\n await trx.rollback();\n throw e;\n }\n\n // update less critical information (name + updatedBy)\n const newFolder = setCreatorFields({ user, isEdition: true })({ name });\n\n const folder = await strapi.db\n .query(FOLDER_MODEL_UID)\n .update({ where: { id }, data: newFolder });\n\n strapi.eventHub.emit('media-folder.update', { folder });\n return folder;\n }\n};\n\n/**\n * Check if a folder exists in database\n * @param params query params to find the folder\n * @returns {Promise<boolean>}\n */\nconst exists = async (params = {}) => {\n const count = await strapi.db.query(FOLDER_MODEL_UID).count({ where: params });\n return count > 0;\n};\n\n/**\n * Returns the nested structure of folders\n * @returns {Promise<array>}\n */\nconst getStructure = async () => {\n // @ts-expect-error - no dynamic types\n const { joinTable } = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.parent;\n const qb = strapi.db.queryBuilder(FOLDER_MODEL_UID);\n const alias = qb.getAlias();\n const folders = (await qb\n .select(['id', 'name', `${alias}.${joinTable.inverseJoinColumn.name} as parent`])\n .join({\n alias,\n referencedTable: joinTable.name,\n referencedColumn: joinTable.joinColumn.name,\n rootColumn: joinTable.joinColumn.referencedColumn,\n rootTable: qb.alias,\n })\n .execute({ mapResults: false })) as Folder[];\n\n const folderMap: FolderMap = {\n null: { children: [] },\n };\n\n folders.forEach((f) => {\n folderMap[f.id] = { ...f, children: [] };\n });\n\n folders.forEach((f) => {\n const parentId = f.parent || 'null';\n\n if (!folderMap[parentId]) {\n folderMap[parentId] = { children: [] };\n }\n\n folderMap[parentId].children.push(folderMap[f.id]);\n folderMap[parentId].children = sortBy('name', folderMap[parentId].children);\n delete folderMap[f.id].parent;\n });\n\n return folderMap.null.children;\n};\n\nexport default {\n create,\n exists,\n deleteByIds,\n update,\n setPathIdAndPath,\n getStructure,\n};\n"],"names":["setPathIdAndPath","folder","max","strapi","db","queryBuilder","FOLDER_MODEL_UID","first","execute","pathId","parentPath","parent","parentFolder","query","findOne","where","id","path","Object","assign","strings","joinBy","create","folderData","opts","folderService","getService","user","enrichedFolder","setCreatorFields","data","eventHub","emit","deleteByIds","ids","folders","findMany","$in","length","totalFolderNumber","totalFileNumber","pathsToDelete","map","filesToDelete","FILE_MODEL_UID","$or","flatMap","folderPath","$eq","$startsWith","Promise","all","file","remove","count","deleteMany","update","name","isUndefined","existingFolder","undefined","newFolder","isEdition","trx","transaction","select","transacting","get","forUpdate","joinTable","metadata","attributes","delete","joinColumn","insert","inverseJoinColumn","destinationFolderPath","destinationFolder","folderTable","getModel","collectionName","fileTable","folderPathColumnName","columnName","pathColumnName","getConnection","orWhere","connection","raw","commit","e","rollback","exists","params","getStructure","qb","alias","getAlias","join","referencedTable","referencedColumn","rootColumn","rootTable","mapResults","folderMap","null","children","forEach","f","parentId","push","sortBy"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-manipulation.js","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport crypto from 'crypto';\nimport { strings, file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nconst generateFileName = (name: string) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n generateFileName,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage","generateFileName","randomSuffix","crypto","randomBytes","toString","baseName","strings","nameToSlug","separator","lowercase"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-manipulation.js","sources":["../../../server/src/services/image-manipulation.ts"],"sourcesContent":["import fs from 'fs';\nimport { join } from 'path';\nimport sharp from 'sharp';\nimport crypto from 'crypto';\nimport { strings, file as fileUtils } from '@strapi/utils';\n\nimport { getService } from '../utils';\n\nimport type { UploadableFile } from '../types';\n\ntype Dimensions = {\n width: number | null;\n height: number | null;\n};\n\nconst { bytesToKbytes } = fileUtils;\n\nconst FORMATS_TO_RESIZE = ['jpeg', 'png', 'webp', 'tiff', 'gif'];\nconst FORMATS_TO_PROCESS = ['jpeg', 'png', 'webp', 'tiff', 'svg', 'gif', 'avif'];\nconst FORMATS_TO_OPTIMIZE = ['jpeg', 'png', 'webp', 'tiff', 'avif'];\n\nconst isOptimizableFormat = (\n format: string | undefined\n): format is 'jpeg' | 'png' | 'webp' | 'tiff' | 'avif' =>\n format !== undefined && FORMATS_TO_OPTIMIZE.includes(format);\n\nconst writeStreamToFile = (stream: NodeJS.ReadWriteStream, path: string) =>\n new Promise((resolve, reject) => {\n const writeStream = fs.createWriteStream(path);\n // Reject promise if there is an error with the provided stream\n stream.on('error', reject);\n stream.pipe(writeStream);\n writeStream.on('close', resolve);\n writeStream.on('error', reject);\n });\n\nconst getMetadata = (file: UploadableFile): Promise<sharp.Metadata> => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.metadata().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n return sharp(file.filepath).metadata();\n};\n\nconst getDimensions = async (file: UploadableFile): Promise<Dimensions> => {\n const { width = null, height = null } = await getMetadata(file);\n\n return { width, height };\n};\n\nconst THUMBNAIL_RESIZE_OPTIONS = {\n width: 245,\n height: 156,\n fit: 'inside',\n} satisfies sharp.ResizeOptions;\n\nconst resizeFileTo = async (\n file: UploadableFile,\n options: sharp.ResizeOptions,\n {\n name,\n hash,\n }: {\n name: string;\n hash: string;\n }\n) => {\n const filePath = file.tmpWorkingDirectory ? join(file.tmpWorkingDirectory, hash) : hash;\n\n let newInfo;\n if (!file.filepath) {\n const transform = sharp()\n .resize(options)\n .on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transform), filePath);\n } else {\n newInfo = await sharp(file.filepath).resize(options).toFile(filePath);\n }\n\n const { width, height, size } = newInfo ?? {};\n\n const newFile: UploadableFile = {\n name,\n hash,\n ext: file.ext,\n mime: file.mime,\n filepath: filePath,\n path: file.path || null,\n getStream: () => fs.createReadStream(filePath),\n };\n\n Object.assign(newFile, {\n width,\n height,\n size: size ? bytesToKbytes(size) : 0,\n sizeInBytes: size,\n });\n return newFile;\n};\n\nconst generateThumbnail = async (file: UploadableFile) => {\n if (\n file.width &&\n file.height &&\n (file.width > THUMBNAIL_RESIZE_OPTIONS.width || file.height > THUMBNAIL_RESIZE_OPTIONS.height)\n ) {\n return resizeFileTo(file, THUMBNAIL_RESIZE_OPTIONS, {\n name: `thumbnail_${file.name}`,\n hash: `thumbnail_${file.hash}`,\n });\n }\n\n return null;\n};\n\n/**\n * Optimize image by:\n * - auto orienting image based on EXIF data\n * - reduce image quality\n *\n */\nconst optimize = async (file: UploadableFile) => {\n const { sizeOptimization = false, autoOrientation = false } =\n (await getService('upload').getSettings()) ?? {};\n\n const { format, size } = await getMetadata(file);\n\n if ((sizeOptimization || autoOrientation) && isOptimizableFormat(format)) {\n let transformer;\n if (!file.filepath) {\n transformer = sharp();\n } else {\n transformer = sharp(file.filepath);\n }\n // reduce image quality\n transformer[format]({ quality: sizeOptimization ? 80 : 100 });\n // rotate image based on EXIF data\n if (autoOrientation) {\n transformer.rotate();\n }\n const filePath = file.tmpWorkingDirectory\n ? join(file.tmpWorkingDirectory, `optimized-${file.hash}`)\n : `optimized-${file.hash}`;\n\n let newInfo;\n if (!file.filepath) {\n transformer.on('info', (info) => {\n newInfo = info;\n });\n\n await writeStreamToFile(file.getStream().pipe(transformer), filePath);\n } else {\n newInfo = await transformer.toFile(filePath);\n }\n\n const { width: newWidth, height: newHeight, size: newSize } = newInfo ?? {};\n\n const newFile = { ...file };\n\n newFile.getStream = () => fs.createReadStream(filePath);\n newFile.filepath = filePath;\n\n if (newSize && size && newSize > size) {\n // Ignore optimization if output is bigger than original\n return file;\n }\n\n return Object.assign(newFile, {\n width: newWidth,\n height: newHeight,\n size: newSize ? bytesToKbytes(newSize) : 0,\n sizeInBytes: newSize,\n });\n }\n\n return file;\n};\n\nconst DEFAULT_BREAKPOINTS = {\n large: 1000,\n medium: 750,\n small: 500,\n};\n\nconst getBreakpoints = () =>\n strapi.config.get<Record<string, number>>('plugin::upload.breakpoints', DEFAULT_BREAKPOINTS);\n\nconst generateResponsiveFormats = async (file: UploadableFile) => {\n const { responsiveDimensions = false } = (await getService('upload').getSettings()) ?? {};\n\n if (!responsiveDimensions) return [];\n\n const originalDimensions = await getDimensions(file);\n\n const breakpoints = getBreakpoints();\n return Promise.all(\n Object.keys(breakpoints).map((key) => {\n const breakpoint = breakpoints[key];\n\n if (breakpointSmallerThan(breakpoint, originalDimensions)) {\n return generateBreakpoint(key, { file, breakpoint });\n }\n\n return undefined;\n })\n );\n};\n\nconst generateBreakpoint = async (\n key: string,\n { file, breakpoint }: { file: UploadableFile; breakpoint: number }\n) => {\n const newFile = await resizeFileTo(\n file,\n {\n width: breakpoint,\n height: breakpoint,\n fit: 'inside',\n },\n {\n name: `${key}_${file.name}`,\n hash: `${key}_${file.hash}`,\n }\n );\n return {\n key,\n file: newFile,\n };\n};\n\nconst breakpointSmallerThan = (breakpoint: number, { width, height }: Dimensions) => {\n return breakpoint < (width ?? 0) || breakpoint < (height ?? 0);\n};\n\n/**\n * Applies a simple image transformation to see if the image is faulty/corrupted.\n */\nconst isFaultyImage = async (file: UploadableFile) => {\n if (!file.filepath) {\n return new Promise((resolve, reject) => {\n const pipeline = sharp();\n pipeline.stats().then(resolve).catch(reject);\n file.getStream().pipe(pipeline);\n });\n }\n\n try {\n await sharp(file.filepath).stats();\n return false;\n } catch (e) {\n return true;\n }\n};\n\nconst isOptimizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_OPTIMIZE.includes(format);\n};\n\nconst isResizableImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_RESIZE.includes(format);\n};\n\nconst isImage = async (file: UploadableFile) => {\n let format;\n try {\n const metadata = await getMetadata(file);\n format = metadata.format;\n } catch (e) {\n // throw when the file is not a supported image\n return false;\n }\n return format && FORMATS_TO_PROCESS.includes(format);\n};\n\nconst generateFileName = (name: string) => {\n const randomSuffix = () => crypto.randomBytes(5).toString('hex');\n const baseName = strings.nameToSlug(name, { separator: '_', lowercase: false });\n\n return `${baseName}_${randomSuffix()}`;\n};\n\nexport default {\n isFaultyImage,\n isOptimizableImage,\n isResizableImage,\n isImage,\n getDimensions,\n generateResponsiveFormats,\n generateThumbnail,\n optimize,\n generateFileName,\n};\n"],"names":["bytesToKbytes","fileUtils","FORMATS_TO_RESIZE","FORMATS_TO_PROCESS","FORMATS_TO_OPTIMIZE","isOptimizableFormat","format","undefined","includes","writeStreamToFile","stream","path","Promise","resolve","reject","writeStream","fs","createWriteStream","on","pipe","getMetadata","file","filepath","pipeline","sharp","metadata","then","catch","getStream","getDimensions","width","height","THUMBNAIL_RESIZE_OPTIONS","fit","resizeFileTo","options","name","hash","filePath","tmpWorkingDirectory","join","newInfo","transform","resize","info","toFile","size","newFile","ext","mime","createReadStream","Object","assign","sizeInBytes","generateThumbnail","optimize","sizeOptimization","autoOrientation","getService","getSettings","transformer","quality","rotate","newWidth","newHeight","newSize","DEFAULT_BREAKPOINTS","large","medium","small","getBreakpoints","strapi","config","get","generateResponsiveFormats","responsiveDimensions","originalDimensions","breakpoints","all","keys","map","key","breakpoint","breakpointSmallerThan","generateBreakpoint","isFaultyImage","stats","e","isOptimizableImage","isResizableImage","isImage","generateFileName","randomSuffix","crypto","randomBytes","toString","baseName","strings","nameToSlug","separator","lowercase"],"mappings":"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"}
|