@webiny/api-file-manager 0.0.0-unstable.e6f0dc8ca7 → 0.0.0-unstable.eb81deee7e
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/FileManagerAppFeature.d.ts +5 -0
- package/FileManagerAppFeature.js +21 -0
- package/FileManagerAppFeature.js.map +1 -0
- package/contants.js +2 -1
- package/contants.js.map +1 -1
- package/delivery/AssetDelivery/Asset.js +50 -56
- package/delivery/AssetDelivery/Asset.js.map +1 -1
- package/delivery/AssetDelivery/AssetRequest.d.ts +1 -1
- package/delivery/AssetDelivery/AssetRequest.js +20 -19
- package/delivery/AssetDelivery/AssetRequest.js.map +1 -1
- package/delivery/AssetDelivery/abstractions/AssetReply.js +28 -27
- package/delivery/AssetDelivery/abstractions/AssetReply.js.map +1 -1
- package/delivery/AssetDelivery/createAssetDeliveryPluginLoader.js +4 -5
- package/delivery/AssetDelivery/createAssetDeliveryPluginLoader.js.map +1 -1
- package/delivery/AssetDeliveryRoute.d.ts +24 -0
- package/delivery/AssetDeliveryRoute.js +69 -0
- package/delivery/AssetDeliveryRoute.js.map +1 -0
- package/delivery/index.d.ts +3 -12
- package/delivery/index.js +2 -8
- package/delivery/setupAssetDelivery.d.ts +1 -2
- package/delivery/setupAssetDelivery.js +2 -112
- package/delivery/setupAssetDelivery.js.map +1 -1
- package/domain/file/abstractions.d.ts +13 -5
- package/domain/file/abstractions.js +2 -5
- package/domain/file/abstractions.js.map +1 -1
- package/domain/file/errors.js +67 -76
- package/domain/file/errors.js.map +1 -1
- package/domain/file/file.model.d.ts +3 -3
- package/domain/file/file.model.js +63 -50
- package/domain/file/file.model.js.map +1 -1
- package/domain/file/types.js +0 -3
- package/domain/identity/Identity.js +9 -8
- package/domain/identity/Identity.js.map +1 -1
- package/domain/permissionsSchema.js +26 -15
- package/domain/permissionsSchema.js.map +1 -1
- package/domain/settings/constants.js +2 -1
- package/domain/settings/constants.js.map +1 -1
- package/domain/settings/errors.js +22 -24
- package/domain/settings/errors.js.map +1 -1
- package/domain/settings/types.js +0 -3
- package/domain/settings/validation.js +19 -28
- package/domain/settings/validation.js.map +1 -1
- package/exports/api/file-manager/assetDelivery.d.ts +10 -0
- package/exports/api/file-manager/assetDelivery.js +8 -0
- package/exports/api/file-manager/file.d.ts +2 -1
- package/exports/api/file-manager/file.js +2 -3
- package/exports/api/file-manager/permissions.js +0 -2
- package/exports/api/file-manager/settings.js +0 -2
- package/features/FileManagerFeature.js +22 -15
- package/features/FileManagerFeature.js.map +1 -1
- package/features/assetDelivery/Asset/Asset.d.ts +8 -0
- package/features/assetDelivery/Asset/Asset.js +14 -0
- package/features/assetDelivery/Asset/Asset.js.map +1 -0
- package/features/assetDelivery/Asset/abstractions.d.ts +10 -0
- package/features/assetDelivery/Asset/abstractions.js +5 -0
- package/features/assetDelivery/Asset/abstractions.js.map +1 -0
- package/features/assetDelivery/Asset/index.d.ts +1 -0
- package/features/assetDelivery/Asset/index.js +1 -0
- package/features/assetDelivery/FilesAssetRequestResolver.d.ts +9 -0
- package/features/assetDelivery/FilesAssetRequestResolver.js +29 -0
- package/features/assetDelivery/FilesAssetRequestResolver.js.map +1 -0
- package/features/assetDelivery/NullAssetOutputStrategy.d.ts +8 -0
- package/features/assetDelivery/NullAssetOutputStrategy.js +14 -0
- package/features/assetDelivery/NullAssetOutputStrategy.js.map +1 -0
- package/features/assetDelivery/NullAssetReply.js +14 -0
- package/features/assetDelivery/NullAssetReply.js.map +1 -0
- package/features/assetDelivery/NullAssetResolver.d.ts +8 -0
- package/features/assetDelivery/NullAssetResolver.js +13 -0
- package/features/assetDelivery/NullAssetResolver.js.map +1 -0
- package/features/assetDelivery/ObjectKey/ObjectKey.d.ts +8 -0
- package/features/assetDelivery/ObjectKey/ObjectKey.js +28 -0
- package/features/assetDelivery/ObjectKey/ObjectKey.js.map +1 -0
- package/features/assetDelivery/ObjectKey/abstractions.d.ts +12 -0
- package/features/assetDelivery/ObjectKey/abstractions.js +5 -0
- package/features/assetDelivery/ObjectKey/abstractions.js.map +1 -0
- package/features/assetDelivery/ObjectKey/index.d.ts +1 -0
- package/features/assetDelivery/ObjectKey/index.js +1 -0
- package/features/assetDelivery/StreamAssetReply/StreamAssetReply.d.ts +8 -0
- package/features/assetDelivery/StreamAssetReply/StreamAssetReply.js +22 -0
- package/features/assetDelivery/StreamAssetReply/StreamAssetReply.js.map +1 -0
- package/features/assetDelivery/StreamAssetReply/abstractions.d.ts +11 -0
- package/features/assetDelivery/StreamAssetReply/abstractions.js +5 -0
- package/features/assetDelivery/StreamAssetReply/abstractions.js.map +1 -0
- package/features/assetDelivery/StreamAssetReply/index.d.ts +1 -0
- package/features/assetDelivery/StreamAssetReply/index.js +1 -0
- package/features/assetDelivery/abstractions/AssetType.d.ts +17 -0
- package/features/assetDelivery/abstractions/AssetType.js +5 -0
- package/features/assetDelivery/abstractions/AssetType.js.map +1 -0
- package/features/assetDelivery/abstractions.d.ts +65 -0
- package/features/assetDelivery/abstractions.js +11 -0
- package/features/assetDelivery/abstractions.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/AssetKeyGenerator.d.ts +12 -0
- package/features/assetDelivery/assetTypes/image/AssetKeyGenerator.js +30 -0
- package/features/assetDelivery/assetTypes/image/AssetKeyGenerator.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.d.ts +9 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.js +18 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.d.ts +5 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.js +5 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.d.ts +18 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.js +47 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/WidthCollection.d.ts +8 -0
- package/features/assetDelivery/assetTypes/image/WidthCollection.js +22 -0
- package/features/assetDelivery/assetTypes/image/WidthCollection.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.d.ts +26 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.js +51 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/imageTypes.d.ts +39 -0
- package/features/assetDelivery/assetTypes/image/imageTypes.js +0 -0
- package/features/assetDelivery/assetTypes/image/index.d.ts +5 -0
- package/features/assetDelivery/assetTypes/image/index.js +4 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.d.ts +6 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.js +56 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/transformImage.d.ts +59 -0
- package/features/assetDelivery/assetTypes/image/transformImage.js +146 -0
- package/features/assetDelivery/assetTypes/image/transformImage.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/utils.d.ts +26 -0
- package/features/assetDelivery/assetTypes/image/utils.js +47 -0
- package/features/assetDelivery/assetTypes/image/utils.js.map +1 -0
- package/features/assetDelivery/feature.d.ts +4 -0
- package/features/assetDelivery/feature.js +35 -0
- package/features/assetDelivery/feature.js.map +1 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedAssetReply.d.ts +4 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedAssetReply.js +20 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedAssetReply.js.map +1 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedOutputStrategy.d.ts +5 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedOutputStrategy.js +9 -0
- package/features/assetDelivery/privateFiles/NotAuthorizedOutputStrategy.js.map +1 -0
- package/features/assetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.d.ts +11 -0
- package/features/assetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.js +26 -0
- package/features/assetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.js.map +1 -0
- package/features/assetDelivery/privateFiles/PrivateCache.d.ts +8 -0
- package/features/assetDelivery/privateFiles/PrivateCache.js +22 -0
- package/features/assetDelivery/privateFiles/PrivateCache.js.map +1 -0
- package/features/assetDelivery/privateFiles/PrivateFileAssetRequestResolver.d.ts +11 -0
- package/features/assetDelivery/privateFiles/PrivateFileAssetRequestResolver.js +31 -0
- package/features/assetDelivery/privateFiles/PrivateFileAssetRequestResolver.js.map +1 -0
- package/features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.d.ts +19 -0
- package/features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.js +65 -0
- package/features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.js.map +1 -0
- package/features/assetDelivery/privateFiles/PublicCache.d.ts +8 -0
- package/features/assetDelivery/privateFiles/PublicCache.js +22 -0
- package/features/assetDelivery/privateFiles/PublicCache.js.map +1 -0
- package/features/assetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.d.ts +9 -0
- package/features/assetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.js +21 -0
- package/features/assetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.js.map +1 -0
- package/features/assetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.d.ts +9 -0
- package/features/assetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.js +21 -0
- package/features/assetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.js.map +1 -0
- package/features/assetDelivery/transformation/CallableContentsReader.d.ts +11 -0
- package/features/assetDelivery/transformation/CallableContentsReader.js +14 -0
- package/features/assetDelivery/transformation/CallableContentsReader.js.map +1 -0
- package/features/assetDelivery/transformation/TransformationAssetProcessor.d.ts +9 -0
- package/features/assetDelivery/transformation/TransformationAssetProcessor.js +25 -0
- package/features/assetDelivery/transformation/TransformationAssetProcessor.js.map +1 -0
- package/features/assetDelivery/transformation/index.d.ts +5 -0
- package/features/assetDelivery/transformation/index.js +4 -0
- package/features/extractMetadata/ExtractMetadataHandler.d.ts +11 -0
- package/features/extractMetadata/ExtractMetadataHandler.js +25 -0
- package/features/extractMetadata/ExtractMetadataHandler.js.map +1 -0
- package/features/extractMetadata/ExtractMetadataInput.d.ts +3 -0
- package/features/extractMetadata/ExtractMetadataInput.js +0 -0
- package/features/file/CreateFile/CreateFileRepository.d.ts +3 -3
- package/features/file/CreateFile/CreateFileRepository.js +22 -19
- package/features/file/CreateFile/CreateFileRepository.js.map +1 -1
- package/features/file/CreateFile/CreateFileUseCase.js +68 -75
- package/features/file/CreateFile/CreateFileUseCase.js.map +1 -1
- package/features/file/CreateFile/abstractions.js +3 -14
- package/features/file/CreateFile/abstractions.js.map +1 -1
- package/features/file/CreateFile/events.js +17 -26
- package/features/file/CreateFile/events.js.map +1 -1
- package/features/file/CreateFile/feature.js +7 -6
- package/features/file/CreateFile/feature.js.map +1 -1
- package/features/file/CreateFile/index.js +0 -2
- package/features/file/CreateFilesInBatch/CreateFilesInBatchRepository.js +15 -17
- package/features/file/CreateFilesInBatch/CreateFilesInBatchRepository.js.map +1 -1
- package/features/file/CreateFilesInBatch/CreateFilesInBatchUseCase.js +59 -70
- package/features/file/CreateFilesInBatch/CreateFilesInBatchUseCase.js.map +1 -1
- package/features/file/CreateFilesInBatch/abstractions.js +3 -14
- package/features/file/CreateFilesInBatch/abstractions.js.map +1 -1
- package/features/file/CreateFilesInBatch/events.js +17 -26
- package/features/file/CreateFilesInBatch/events.js.map +1 -1
- package/features/file/CreateFilesInBatch/feature.js +7 -6
- package/features/file/CreateFilesInBatch/feature.js.map +1 -1
- package/features/file/CreateFilesInBatch/index.js +0 -2
- package/features/file/DeleteFile/DeleteFileRepository.d.ts +3 -3
- package/features/file/DeleteFile/DeleteFileRepository.js +23 -21
- package/features/file/DeleteFile/DeleteFileRepository.js.map +1 -1
- package/features/file/DeleteFile/DeleteFileUseCase.js +31 -33
- package/features/file/DeleteFile/DeleteFileUseCase.js.map +1 -1
- package/features/file/DeleteFile/abstractions.js +3 -14
- package/features/file/DeleteFile/abstractions.js.map +1 -1
- package/features/file/DeleteFile/events.js +17 -26
- package/features/file/DeleteFile/events.js.map +1 -1
- package/features/file/DeleteFile/feature.js +7 -6
- package/features/file/DeleteFile/feature.js.map +1 -1
- package/features/file/DeleteFile/index.js +1 -3
- package/features/file/FileModelProvider.d.ts +31 -0
- package/features/file/FileModelProvider.js +22 -0
- package/features/file/FileModelProvider.js.map +1 -0
- package/features/file/FileUrlGenerator/FileUrlGenerator.d.ts +12 -0
- package/features/file/FileUrlGenerator/FileUrlGenerator.js +19 -0
- package/features/file/FileUrlGenerator/FileUrlGenerator.js.map +1 -0
- package/features/file/FileUrlGenerator/SettingsFileUrlPrefixProvider.d.ts +13 -0
- package/features/file/FileUrlGenerator/SettingsFileUrlPrefixProvider.js +28 -0
- package/features/file/FileUrlGenerator/SettingsFileUrlPrefixProvider.js.map +1 -0
- package/features/file/FileUrlGenerator/abstractions.d.ts +15 -4
- package/features/file/FileUrlGenerator/abstractions.js +3 -2
- package/features/file/FileUrlGenerator/abstractions.js.map +1 -1
- package/features/file/FileUrlGenerator/feature.d.ts +4 -0
- package/features/file/FileUrlGenerator/feature.js +13 -0
- package/features/file/FileUrlGenerator/feature.js.map +1 -0
- package/features/file/FileUrlGenerator/index.d.ts +2 -0
- package/features/file/FileUrlGenerator/index.js +1 -0
- package/features/file/GetFile/GetFileRepository.d.ts +3 -3
- package/features/file/GetFile/GetFileRepository.js +24 -23
- package/features/file/GetFile/GetFileRepository.js.map +1 -1
- package/features/file/GetFile/GetFileUseCase.js +19 -21
- package/features/file/GetFile/GetFileUseCase.js.map +1 -1
- package/features/file/GetFile/abstractions.js +3 -14
- package/features/file/GetFile/abstractions.js.map +1 -1
- package/features/file/GetFile/feature.js +7 -6
- package/features/file/GetFile/feature.js.map +1 -1
- package/features/file/GetFile/index.js +0 -2
- package/features/file/GetFileByUrl/GetFileByUrlUseCase.d.ts +15 -0
- package/features/file/GetFileByUrl/GetFileByUrlUseCase.js +37 -0
- package/features/file/GetFileByUrl/GetFileByUrlUseCase.js.map +1 -0
- package/features/file/GetFileByUrl/abstractions.d.ts +18 -0
- package/features/file/GetFileByUrl/abstractions.js +5 -0
- package/features/file/GetFileByUrl/abstractions.js.map +1 -0
- package/features/file/GetFileByUrl/feature.d.ts +4 -0
- package/features/file/GetFileByUrl/feature.js +11 -0
- package/features/file/GetFileByUrl/feature.js.map +1 -0
- package/features/file/GetFileByUrl/index.d.ts +1 -0
- package/features/file/GetFileByUrl/index.js +1 -0
- package/features/file/GetFileContentsById/abstractions.d.ts +20 -0
- package/features/file/GetFileContentsById/abstractions.js +5 -0
- package/features/file/GetFileContentsById/abstractions.js.map +1 -0
- package/features/file/GetFileContentsById/index.d.ts +1 -0
- package/features/file/GetFileContentsById/index.js +1 -0
- package/features/file/GetFileContentsByKey/abstractions.d.ts +17 -0
- package/features/file/GetFileContentsByKey/abstractions.js +5 -0
- package/features/file/GetFileContentsByKey/abstractions.js.map +1 -0
- package/features/file/GetFileContentsByKey/index.d.ts +1 -0
- package/features/file/GetFileContentsByKey/index.js +1 -0
- package/features/file/ListFiles/ListFilesRepository.d.ts +3 -3
- package/features/file/ListFiles/ListFilesRepository.js +44 -41
- package/features/file/ListFiles/ListFilesRepository.js.map +1 -1
- package/features/file/ListFiles/ListFilesUseCase.js +33 -34
- package/features/file/ListFiles/ListFilesUseCase.js.map +1 -1
- package/features/file/ListFiles/abstractions.js +3 -14
- package/features/file/ListFiles/abstractions.js.map +1 -1
- package/features/file/ListFiles/feature.js +7 -6
- package/features/file/ListFiles/feature.js.map +1 -1
- package/features/file/ListFiles/index.js +0 -2
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.d.ts +15 -5
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.js +46 -29
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.js.map +1 -1
- package/features/file/ListImagesByTagTool/feature.js +6 -5
- package/features/file/ListImagesByTagTool/feature.js.map +1 -1
- package/features/file/ListTags/ListTagsRepository.d.ts +3 -3
- package/features/file/ListTags/ListTagsRepository.js +33 -37
- package/features/file/ListTags/ListTagsRepository.js.map +1 -1
- package/features/file/ListTags/ListTagsUseCase.js +21 -21
- package/features/file/ListTags/ListTagsUseCase.js.map +1 -1
- package/features/file/ListTags/abstractions.js +3 -14
- package/features/file/ListTags/abstractions.js.map +1 -1
- package/features/file/ListTags/feature.js +7 -6
- package/features/file/ListTags/feature.js.map +1 -1
- package/features/file/ListTags/index.js +0 -2
- package/features/file/UpdateFile/UpdateFileRepository.d.ts +3 -3
- package/features/file/UpdateFile/UpdateFileRepository.js +28 -29
- package/features/file/UpdateFile/UpdateFileRepository.js.map +1 -1
- package/features/file/UpdateFile/UpdateFileUseCase.js +57 -65
- package/features/file/UpdateFile/UpdateFileUseCase.js.map +1 -1
- package/features/file/UpdateFile/abstractions.js +3 -14
- package/features/file/UpdateFile/abstractions.js.map +1 -1
- package/features/file/UpdateFile/events.js +17 -26
- package/features/file/UpdateFile/events.js.map +1 -1
- package/features/file/UpdateFile/feature.js +7 -6
- package/features/file/UpdateFile/feature.js.map +1 -1
- package/features/file/UpdateFile/index.js +1 -3
- package/features/file/shared/EntryToFileMapper.js +25 -24
- package/features/file/shared/EntryToFileMapper.js.map +1 -1
- package/features/file/shared/FileInputToEntryInputMapper.js +29 -28
- package/features/file/shared/FileInputToEntryInputMapper.js.map +1 -1
- package/features/file/shared/FileToEntryMapper.js +28 -27
- package/features/file/shared/FileToEntryMapper.js.map +1 -1
- package/features/permissions/abstractions.js +2 -1
- package/features/permissions/abstractions.js.map +1 -1
- package/features/permissions/feature.js +2 -1
- package/features/permissions/feature.js.map +1 -1
- package/features/settings/GetSettings/GetSettingsUseCase.js +19 -19
- package/features/settings/GetSettings/GetSettingsUseCase.js.map +1 -1
- package/features/settings/GetSettings/abstractions.js +2 -7
- package/features/settings/GetSettings/abstractions.js.map +1 -1
- package/features/settings/GetSettings/feature.js +6 -5
- package/features/settings/GetSettings/feature.js.map +1 -1
- package/features/settings/SettingsInstaller/SettingsInstaller.d.ts +3 -1
- package/features/settings/SettingsInstaller/SettingsInstaller.js +29 -25
- package/features/settings/SettingsInstaller/SettingsInstaller.js.map +1 -1
- package/features/settings/SettingsInstaller/feature.js +6 -5
- package/features/settings/SettingsInstaller/feature.js.map +1 -1
- package/features/settings/UpdateSettings/UpdateSettingsUseCase.js +41 -48
- package/features/settings/UpdateSettings/UpdateSettingsUseCase.js.map +1 -1
- package/features/settings/UpdateSettings/abstractions.js +2 -7
- package/features/settings/UpdateSettings/abstractions.js.map +1 -1
- package/features/settings/UpdateSettings/events.js +17 -26
- package/features/settings/UpdateSettings/events.js.map +1 -1
- package/features/settings/UpdateSettings/feature.js +6 -5
- package/features/settings/UpdateSettings/feature.js.map +1 -1
- package/features/settings/UpdateSettings/index.js +0 -2
- package/features/shared/abstractions.js +0 -2
- package/features/upload/CompleteMultiPartUpload/abstractions.d.ts +12 -0
- package/features/upload/CompleteMultiPartUpload/abstractions.js +5 -0
- package/features/upload/CompleteMultiPartUpload/abstractions.js.map +1 -0
- package/features/upload/CompleteMultiPartUpload/index.d.ts +1 -0
- package/features/upload/CompleteMultiPartUpload/index.js +1 -0
- package/features/upload/CreateMultiPartUpload/abstractions.d.ts +14 -0
- package/features/upload/CreateMultiPartUpload/abstractions.js +5 -0
- package/features/upload/CreateMultiPartUpload/abstractions.js.map +1 -0
- package/features/upload/CreateMultiPartUpload/index.d.ts +1 -0
- package/features/upload/CreateMultiPartUpload/index.js +1 -0
- package/features/upload/GetUploadPayload/abstractions.d.ts +10 -0
- package/features/upload/GetUploadPayload/abstractions.js +5 -0
- package/features/upload/GetUploadPayload/abstractions.js.map +1 -0
- package/features/upload/GetUploadPayload/index.d.ts +1 -0
- package/features/upload/GetUploadPayload/index.js +1 -0
- package/features/upload/ReadFileMetadata/MetadataReader.d.ts +11 -0
- package/features/upload/ReadFileMetadata/MetadataReader.js +21 -0
- package/features/upload/ReadFileMetadata/MetadataReader.js.map +1 -0
- package/features/upload/ReadFileMetadata/abstractions.d.ts +15 -0
- package/features/upload/ReadFileMetadata/abstractions.js +5 -0
- package/features/upload/ReadFileMetadata/abstractions.js.map +1 -0
- package/features/upload/ReadFileMetadata/feature.d.ts +4 -0
- package/features/upload/ReadFileMetadata/feature.js +11 -0
- package/features/upload/ReadFileMetadata/feature.js.map +1 -0
- package/features/upload/ReadFileMetadata/index.d.ts +1 -0
- package/features/upload/ReadFileMetadata/index.js +1 -0
- package/features/upload/WriteFileMetadata/MetadataWriter.d.ts +14 -0
- package/features/upload/WriteFileMetadata/MetadataWriter.js +36 -0
- package/features/upload/WriteFileMetadata/MetadataWriter.js.map +1 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.d.ts +11 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +20 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterCreateHandler.d.ts +11 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +22 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.d.ts +11 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.js +22 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.js.map +1 -0
- package/features/upload/WriteFileMetadata/abstractions.d.ts +9 -0
- package/features/upload/WriteFileMetadata/abstractions.js +5 -0
- package/features/upload/WriteFileMetadata/abstractions.js.map +1 -0
- package/features/upload/WriteFileMetadata/feature.d.ts +4 -0
- package/features/upload/WriteFileMetadata/feature.js +17 -0
- package/features/upload/WriteFileMetadata/feature.js.map +1 -0
- package/features/upload/index.d.ts +17 -0
- package/features/upload/index.js +10 -0
- package/features/upload/types.d.ts +28 -0
- package/features/upload/types.js +0 -0
- package/features/upload/utils/FileExtension.d.ts +6 -0
- package/features/upload/utils/FileExtension.js +16 -0
- package/features/upload/utils/FileExtension.js.map +1 -0
- package/features/upload/utils/FileKey.d.ts +11 -0
- package/features/upload/utils/FileKey.js +33 -0
- package/features/upload/utils/FileKey.js.map +1 -0
- package/features/upload/utils/FileNormalizer.d.ts +13 -0
- package/features/upload/utils/FileNormalizer.js +41 -0
- package/features/upload/utils/FileNormalizer.js.map +1 -0
- package/features/upload/utils/FileUploadModifier.d.ts +30 -0
- package/features/upload/utils/FileUploadModifier.js +39 -0
- package/features/upload/utils/FileUploadModifier.js.map +1 -0
- package/features/upload/utils/checkPermissions.d.ts +5 -0
- package/features/upload/utils/checkPermissions.js +22 -0
- package/features/upload/utils/checkPermissions.js.map +1 -0
- package/features/upload/utils/createFileNormalizerFromContext.d.ts +3 -0
- package/features/upload/utils/createFileNormalizerFromContext.js +9 -0
- package/features/upload/utils/createFileNormalizerFromContext.js.map +1 -0
- package/features/upload/utils/mimeTypes.d.ts +1 -0
- package/features/upload/utils/mimeTypes.js +9 -0
- package/features/upload/utils/mimeTypes.js.map +1 -0
- package/graphql/FmGraphQLSchema.d.ts +24 -0
- package/graphql/FmGraphQLSchema.js +458 -0
- package/graphql/FmGraphQLSchema.js.map +1 -0
- package/index.d.ts +3 -6
- package/index.js +11 -33
- package/index.js.map +1 -1
- package/package.json +28 -21
- package/types.d.ts +1 -1
- package/types.js +1 -3
- package/delivery/AssetDelivery/AssetDeliveryConfig.d.ts +0 -65
- package/delivery/AssetDelivery/AssetDeliveryConfig.js +0 -94
- package/delivery/AssetDelivery/AssetDeliveryConfig.js.map +0 -1
- package/delivery/AssetDelivery/FilesAssetRequestResolver.d.ts +0 -6
- package/delivery/AssetDelivery/FilesAssetRequestResolver.js +0 -30
- package/delivery/AssetDelivery/FilesAssetRequestResolver.js.map +0 -1
- package/delivery/AssetDelivery/NullAssetOutputStrategy.d.ts +0 -4
- package/delivery/AssetDelivery/NullAssetOutputStrategy.js +0 -8
- package/delivery/AssetDelivery/NullAssetOutputStrategy.js.map +0 -1
- package/delivery/AssetDelivery/NullAssetReply.js +0 -13
- package/delivery/AssetDelivery/NullAssetReply.js.map +0 -1
- package/delivery/AssetDelivery/NullAssetResolver.d.ts +0 -5
- package/delivery/AssetDelivery/NullAssetResolver.js +0 -7
- package/delivery/AssetDelivery/NullAssetResolver.js.map +0 -1
- package/delivery/AssetDelivery/NullRequestResolver.d.ts +0 -4
- package/delivery/AssetDelivery/NullRequestResolver.js +0 -7
- package/delivery/AssetDelivery/NullRequestResolver.js.map +0 -1
- package/delivery/AssetDelivery/SetCacheControlHeaders.d.ts +0 -8
- package/delivery/AssetDelivery/SetCacheControlHeaders.js +0 -18
- package/delivery/AssetDelivery/SetCacheControlHeaders.js.map +0 -1
- package/delivery/AssetDelivery/SetResponseHeaders.d.ts +0 -18
- package/delivery/AssetDelivery/SetResponseHeaders.js +0 -18
- package/delivery/AssetDelivery/SetResponseHeaders.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetContentsReader.d.ts +0 -4
- package/delivery/AssetDelivery/abstractions/AssetContentsReader.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetContentsReader.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetOutputStrategy.d.ts +0 -4
- package/delivery/AssetDelivery/abstractions/AssetOutputStrategy.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetOutputStrategy.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetProcessor.d.ts +0 -4
- package/delivery/AssetDelivery/abstractions/AssetProcessor.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetProcessor.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetRequestResolver.d.ts +0 -5
- package/delivery/AssetDelivery/abstractions/AssetRequestResolver.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetRequestResolver.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetResolver.d.ts +0 -4
- package/delivery/AssetDelivery/abstractions/AssetResolver.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetResolver.js.map +0 -1
- package/delivery/AssetDelivery/abstractions/AssetTransformationStrategy.d.ts +0 -4
- package/delivery/AssetDelivery/abstractions/AssetTransformationStrategy.js +0 -3
- package/delivery/AssetDelivery/abstractions/AssetTransformationStrategy.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/AssetAuthorizer.d.ts +0 -4
- package/delivery/AssetDelivery/privateFiles/AssetAuthorizer.js +0 -3
- package/delivery/AssetDelivery/privateFiles/AssetAuthorizer.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedAssetReply.d.ts +0 -4
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedAssetReply.js +0 -19
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedAssetReply.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedOutputStrategy.d.ts +0 -4
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedOutputStrategy.js +0 -8
- package/delivery/AssetDelivery/privateFiles/NotAuthorizedOutputStrategy.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.d.ts +0 -8
- package/delivery/AssetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.js +0 -20
- package/delivery/AssetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/PrivateCache.d.ts +0 -6
- package/delivery/AssetDelivery/privateFiles/PrivateCache.js +0 -21
- package/delivery/AssetDelivery/privateFiles/PrivateCache.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/PrivateFileAssetRequestResolver.d.ts +0 -8
- package/delivery/AssetDelivery/privateFiles/PrivateFileAssetRequestResolver.js +0 -30
- package/delivery/AssetDelivery/privateFiles/PrivateFileAssetRequestResolver.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/PrivateFilesAssetProcessor.d.ts +0 -13
- package/delivery/AssetDelivery/privateFiles/PrivateFilesAssetProcessor.js +0 -63
- package/delivery/AssetDelivery/privateFiles/PrivateFilesAssetProcessor.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/PublicCache.d.ts +0 -6
- package/delivery/AssetDelivery/privateFiles/PublicCache.js +0 -21
- package/delivery/AssetDelivery/privateFiles/PublicCache.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.d.ts +0 -7
- package/delivery/AssetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.js +0 -20
- package/delivery/AssetDelivery/privateFiles/RedirectToPrivateUrlOutputStrategy.js.map +0 -1
- package/delivery/AssetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.d.ts +0 -7
- package/delivery/AssetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.js +0 -20
- package/delivery/AssetDelivery/privateFiles/RedirectToPublicUrlOutputStrategy.js.map +0 -1
- package/delivery/AssetDelivery/transformation/PassthroughAssetProcessor.d.ts +0 -4
- package/delivery/AssetDelivery/transformation/PassthroughAssetProcessor.js +0 -7
- package/delivery/AssetDelivery/transformation/PassthroughAssetProcessor.js.map +0 -1
- package/delivery/AssetDelivery/transformation/PassthroughAssetTransformationStrategy.d.ts +0 -4
- package/delivery/AssetDelivery/transformation/PassthroughAssetTransformationStrategy.js +0 -7
- package/delivery/AssetDelivery/transformation/PassthroughAssetTransformationStrategy.js.map +0 -1
- package/delivery/AssetDelivery/transformation/TransformationAssetProcessor.d.ts +0 -6
- package/delivery/AssetDelivery/transformation/TransformationAssetProcessor.js +0 -19
- package/delivery/AssetDelivery/transformation/TransformationAssetProcessor.js.map +0 -1
- package/delivery/index.js.map +0 -1
- package/domain/file/types.js.map +0 -1
- package/domain/settings/types.js.map +0 -1
- package/exports/api/file-manager/file.js.map +0 -1
- package/exports/api/file-manager/permissions.js.map +0 -1
- package/exports/api/file-manager/settings.js.map +0 -1
- package/features/file/CreateFile/index.js.map +0 -1
- package/features/file/CreateFilesInBatch/index.js.map +0 -1
- package/features/file/DeleteFile/index.js.map +0 -1
- package/features/file/GetFile/index.js.map +0 -1
- package/features/file/GetFileContents/abstractions.d.ts +0 -20
- package/features/file/GetFileContents/abstractions.js +0 -4
- package/features/file/GetFileContents/abstractions.js.map +0 -1
- package/features/file/GetFileContents/index.d.ts +0 -1
- package/features/file/GetFileContents/index.js +0 -3
- package/features/file/GetFileContents/index.js.map +0 -1
- package/features/file/ListFiles/index.js.map +0 -1
- package/features/file/ListTags/index.js.map +0 -1
- package/features/file/UpdateFile/index.js.map +0 -1
- package/features/settings/UpdateSettings/index.js.map +0 -1
- package/features/shared/abstractions.js.map +0 -1
- package/graphql/baseSchema.d.ts +0 -3
- package/graphql/baseSchema.js +0 -103
- package/graphql/baseSchema.js.map +0 -1
- package/graphql/createFilesTypeDefs.d.ts +0 -8
- package/graphql/createFilesTypeDefs.js +0 -199
- package/graphql/createFilesTypeDefs.js.map +0 -1
- package/graphql/filesSchema.d.ts +0 -4
- package/graphql/filesSchema.js +0 -116
- package/graphql/filesSchema.js.map +0 -1
- package/graphql/getFileByUrl.d.ts +0 -3
- package/graphql/getFileByUrl.js +0 -69
- package/graphql/getFileByUrl.js.map +0 -1
- package/graphql/index.d.ts +0 -4
- package/graphql/index.js +0 -54
- package/graphql/index.js.map +0 -1
- package/graphql/utils.d.ts +0 -11
- package/graphql/utils.js +0 -17
- package/graphql/utils.js.map +0 -1
- package/modelModifier/CmsModelModifier.d.ts +0 -26
- package/modelModifier/CmsModelModifier.js +0 -54
- package/modelModifier/CmsModelModifier.js.map +0 -1
- package/types.js.map +0 -1
- /package/{delivery/AssetDelivery → features/assetDelivery}/NullAssetReply.d.ts +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import sharp from "sharp";
|
|
2
|
+
import { WidthCollection } from "./WidthCollection.js";
|
|
3
|
+
import { DEFAULT_IMAGE_QUALITY, contentTypeForFormat, formatFromContentType } from "./imageFormat.js";
|
|
4
|
+
const applyOutputFormat = (pipeline, sourceContentType, options, qualityDefaults)=>{
|
|
5
|
+
const targetFormat = options.format ?? formatFromContentType(sourceContentType);
|
|
6
|
+
if (!targetFormat || !options.format && void 0 === options.quality) return {
|
|
7
|
+
pipeline,
|
|
8
|
+
contentType: sourceContentType
|
|
9
|
+
};
|
|
10
|
+
const quality = options.quality ?? qualityDefaults[targetFormat];
|
|
11
|
+
switch(targetFormat){
|
|
12
|
+
case "jpeg":
|
|
13
|
+
return {
|
|
14
|
+
pipeline: pipeline.jpeg({
|
|
15
|
+
quality
|
|
16
|
+
}),
|
|
17
|
+
contentType: contentTypeForFormat("jpeg")
|
|
18
|
+
};
|
|
19
|
+
case "webp":
|
|
20
|
+
return {
|
|
21
|
+
pipeline: pipeline.webp({
|
|
22
|
+
quality
|
|
23
|
+
}),
|
|
24
|
+
contentType: contentTypeForFormat("webp")
|
|
25
|
+
};
|
|
26
|
+
case "avif":
|
|
27
|
+
return {
|
|
28
|
+
pipeline: pipeline.avif({
|
|
29
|
+
quality
|
|
30
|
+
}),
|
|
31
|
+
contentType: contentTypeForFormat("avif")
|
|
32
|
+
};
|
|
33
|
+
case "png":
|
|
34
|
+
return {
|
|
35
|
+
pipeline: pipeline.png({
|
|
36
|
+
quality,
|
|
37
|
+
compressionLevel: 9,
|
|
38
|
+
adaptiveFiltering: true
|
|
39
|
+
}),
|
|
40
|
+
contentType: contentTypeForFormat("png")
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const clamp01 = (n)=>Math.min(1, Math.max(0, n));
|
|
45
|
+
const cropImageBuffer = async (buffer, crop)=>{
|
|
46
|
+
const image = sharp(buffer);
|
|
47
|
+
const meta = await image.metadata();
|
|
48
|
+
const w = meta.width ?? 0;
|
|
49
|
+
const h = meta.height ?? 0;
|
|
50
|
+
if (!w || !h) return buffer;
|
|
51
|
+
const left = Math.max(0, Math.min(w - 1, Math.round(clamp01(crop.left) * w)));
|
|
52
|
+
const top = Math.max(0, Math.min(h - 1, Math.round(clamp01(crop.top) * h)));
|
|
53
|
+
const width = Math.max(1, Math.min(w - left, Math.round((1 - clamp01(crop.left) - clamp01(crop.right)) * w)));
|
|
54
|
+
const height = Math.max(1, Math.min(h - top, Math.round((1 - clamp01(crop.top) - clamp01(crop.bottom)) * h)));
|
|
55
|
+
if (0 === left && 0 === top && width === w && height === h) return buffer;
|
|
56
|
+
return image.extract({
|
|
57
|
+
left,
|
|
58
|
+
top,
|
|
59
|
+
width,
|
|
60
|
+
height
|
|
61
|
+
}).toBuffer();
|
|
62
|
+
};
|
|
63
|
+
const cropToRect = (crop)=>{
|
|
64
|
+
const left = clamp01(crop?.left ?? 0);
|
|
65
|
+
const top = clamp01(crop?.top ?? 0);
|
|
66
|
+
return {
|
|
67
|
+
x: left,
|
|
68
|
+
y: top,
|
|
69
|
+
width: Math.max(0, 1 - left - clamp01(crop?.right ?? 0)),
|
|
70
|
+
height: Math.max(0, 1 - top - clamp01(crop?.bottom ?? 0))
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
const getVisibleRect = (imageWidth, imageHeight, crop, focal, aspectRatio)=>{
|
|
74
|
+
const cr = cropToRect(crop);
|
|
75
|
+
if (void 0 === aspectRatio || aspectRatio <= 0 || cr.width <= 0 || cr.height <= 0) return cr;
|
|
76
|
+
const iw = imageWidth > 0 ? imageWidth : 1;
|
|
77
|
+
const ih = imageHeight > 0 ? imageHeight : 1;
|
|
78
|
+
const cropAR = cr.width * iw / (cr.height * ih);
|
|
79
|
+
let w;
|
|
80
|
+
let h;
|
|
81
|
+
if (aspectRatio > cropAR) {
|
|
82
|
+
w = cr.width;
|
|
83
|
+
h = cr.width * iw / aspectRatio / ih;
|
|
84
|
+
} else {
|
|
85
|
+
h = cr.height;
|
|
86
|
+
w = cr.height * ih * aspectRatio / iw;
|
|
87
|
+
}
|
|
88
|
+
const fx = clamp01(focal?.x ?? 0.5);
|
|
89
|
+
const fy = clamp01(focal?.y ?? 0.5);
|
|
90
|
+
const maxX = cr.x + cr.width - w;
|
|
91
|
+
const maxY = cr.y + cr.height - h;
|
|
92
|
+
const x = Math.min(Math.max(fx - w / 2, cr.x), Math.max(cr.x, maxX));
|
|
93
|
+
const y = Math.min(Math.max(fy - h / 2, cr.y), Math.max(cr.y, maxY));
|
|
94
|
+
return {
|
|
95
|
+
x,
|
|
96
|
+
y,
|
|
97
|
+
width: w,
|
|
98
|
+
height: h
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
const hasFraming = (framing)=>{
|
|
102
|
+
const c = framing.crop;
|
|
103
|
+
const cropped = !!c && !(0 === c.top && 0 === c.left && 0 === c.bottom && 0 === c.right);
|
|
104
|
+
return cropped || void 0 !== framing.aspectRatio;
|
|
105
|
+
};
|
|
106
|
+
const extractFramedRegion = async (buffer, framing)=>{
|
|
107
|
+
if (!hasFraming(framing)) return buffer;
|
|
108
|
+
const image = sharp(buffer);
|
|
109
|
+
const meta = await image.metadata();
|
|
110
|
+
const w = meta.width ?? 0;
|
|
111
|
+
const h = meta.height ?? 0;
|
|
112
|
+
if (!w || !h) return buffer;
|
|
113
|
+
const rect = getVisibleRect(w, h, framing.crop, framing.focal, framing.aspectRatio);
|
|
114
|
+
const left = Math.max(0, Math.min(w - 1, Math.round(rect.x * w)));
|
|
115
|
+
const top = Math.max(0, Math.min(h - 1, Math.round(rect.y * h)));
|
|
116
|
+
const width = Math.max(1, Math.min(w - left, Math.round(rect.width * w)));
|
|
117
|
+
const height = Math.max(1, Math.min(h - top, Math.round(rect.height * h)));
|
|
118
|
+
if (0 === left && 0 === top && width === w && height === h) return buffer;
|
|
119
|
+
return image.extract({
|
|
120
|
+
left,
|
|
121
|
+
top,
|
|
122
|
+
width,
|
|
123
|
+
height
|
|
124
|
+
}).toBuffer();
|
|
125
|
+
};
|
|
126
|
+
const transformImageBuffer = async (params)=>{
|
|
127
|
+
let pipeline = sharp(params.buffer, {
|
|
128
|
+
animated: params.animated
|
|
129
|
+
}).withMetadata();
|
|
130
|
+
if (params.options.width) {
|
|
131
|
+
const width = WidthCollection.create(params.widths).getClosestOrMax(params.options.width);
|
|
132
|
+
pipeline = pipeline.resize({
|
|
133
|
+
width,
|
|
134
|
+
withoutEnlargement: true
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const { pipeline: encoded, contentType } = applyOutputFormat(pipeline, params.sourceContentType, params.options, params.qualityDefaults ?? DEFAULT_IMAGE_QUALITY);
|
|
138
|
+
const buffer = await encoded.toBuffer();
|
|
139
|
+
return {
|
|
140
|
+
buffer,
|
|
141
|
+
contentType
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
export { cropImageBuffer, extractFramedRegion, getVisibleRect, hasFraming, transformImageBuffer };
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=transformImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/transformImage.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/transformImage.ts"],"sourcesContent":["/**\n * The sharp-backed image pipeline. This module imports `sharp` (a native module),\n * so it must ONLY be imported by the transform strategies (the image Lambda) —\n * never from the barrel (`index.ts`) or from anything the GraphQL API handler\n * loads. See `imageFormat.ts` for the reasoning.\n */\nimport sharp from \"sharp\";\nimport type { Sharp } from \"sharp\";\nimport { WidthCollection } from \"./WidthCollection.js\";\nimport {\n contentTypeForFormat,\n DEFAULT_IMAGE_QUALITY,\n formatFromContentType,\n type ImageFormat\n} from \"./imageFormat.js\";\n\ninterface ApplyOutputFormatResult {\n pipeline: Sharp;\n contentType: string;\n}\n\n/**\n * Apply the target format + quality to a sharp pipeline. When no `format` is given,\n * re-encodes in the source format only if a `quality` was requested; otherwise the\n * pipeline is left untouched.\n */\nconst applyOutputFormat = (\n pipeline: Sharp,\n sourceContentType: string,\n options: { format?: ImageFormat; quality?: number },\n qualityDefaults: Record<ImageFormat, number>\n): ApplyOutputFormatResult => {\n const targetFormat = options.format ?? formatFromContentType(sourceContentType);\n\n // Nothing to change: unknown source format, or neither a conversion nor a quality.\n if (!targetFormat || (!options.format && options.quality === undefined)) {\n return { pipeline, contentType: sourceContentType };\n }\n\n const quality = options.quality ?? qualityDefaults[targetFormat];\n\n switch (targetFormat) {\n case \"jpeg\":\n return {\n pipeline: pipeline.jpeg({ quality }),\n contentType: contentTypeForFormat(\"jpeg\")\n };\n case \"webp\":\n return {\n pipeline: pipeline.webp({ quality }),\n contentType: contentTypeForFormat(\"webp\")\n };\n case \"avif\":\n return {\n pipeline: pipeline.avif({ quality }),\n contentType: contentTypeForFormat(\"avif\")\n };\n case \"png\":\n return {\n pipeline: pipeline.png({ quality, compressionLevel: 9, adaptiveFiltering: true }),\n contentType: contentTypeForFormat(\"png\")\n };\n }\n};\n\nexport interface TransformImageParams {\n buffer: Buffer;\n animated: boolean;\n sourceContentType: string;\n widths: number[];\n options: { width?: number; format?: ImageFormat; quality?: number };\n qualityDefaults?: Record<ImageFormat, number>;\n}\n\nexport interface TransformImageResult {\n buffer: Buffer;\n contentType: string;\n}\n\n/**\n * Single sharp pipeline shared by the S3 and local transform strategies: optional\n * resize (snapped to the configured width ladder) → optional format conversion +\n * quality. Returns the resulting buffer and its content type.\n */\ninterface CropInsets {\n top: number;\n left: number;\n bottom: number;\n right: number;\n}\n\nconst clamp01 = (n: number) => Math.min(1, Math.max(0, n));\n\n/**\n * Extract the crop region (edge insets, 0..1) from an image buffer. Returns the\n * original buffer unchanged if the crop is empty/full or the dimensions are unknown.\n */\nexport const cropImageBuffer = async (buffer: Buffer, crop: CropInsets): Promise<Buffer> => {\n const image = sharp(buffer);\n const meta = await image.metadata();\n const w = meta.width ?? 0;\n const h = meta.height ?? 0;\n if (!w || !h) {\n return buffer;\n }\n\n const left = Math.max(0, Math.min(w - 1, Math.round(clamp01(crop.left) * w)));\n const top = Math.max(0, Math.min(h - 1, Math.round(clamp01(crop.top) * h)));\n const width = Math.max(\n 1,\n Math.min(w - left, Math.round((1 - clamp01(crop.left) - clamp01(crop.right)) * w))\n );\n const height = Math.max(\n 1,\n Math.min(h - top, Math.round((1 - clamp01(crop.top) - clamp01(crop.bottom)) * h))\n );\n\n if (left === 0 && top === 0 && width === w && height === h) {\n return buffer;\n }\n\n return image.extract({ left, top, width, height }).toBuffer();\n};\n\ninterface NormalizedRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst cropToRect = (crop?: CropInsets): NormalizedRect => {\n const left = clamp01(crop?.left ?? 0);\n const top = clamp01(crop?.top ?? 0);\n return {\n x: left,\n y: top,\n width: Math.max(0, 1 - left - clamp01(crop?.right ?? 0)),\n height: Math.max(0, 1 - top - clamp01(crop?.bottom ?? 0))\n };\n};\n\n/**\n * The visible region (normalized 0–1) for the given framing. The largest rectangle\n * of `aspectRatio` that fits inside the crop, centered on the focal point.\n */\nexport const getVisibleRect = (\n imageWidth: number,\n imageHeight: number,\n crop?: CropInsets,\n focal?: { x: number; y: number },\n aspectRatio?: number\n): NormalizedRect => {\n const cr = cropToRect(crop);\n if (aspectRatio === undefined || aspectRatio <= 0 || cr.width <= 0 || cr.height <= 0) {\n return cr;\n }\n const iw = imageWidth > 0 ? imageWidth : 1;\n const ih = imageHeight > 0 ? imageHeight : 1;\n const cropAR = (cr.width * iw) / (cr.height * ih);\n\n let w: number;\n let h: number;\n if (aspectRatio > cropAR) {\n w = cr.width;\n h = (cr.width * iw) / aspectRatio / ih;\n } else {\n h = cr.height;\n w = (cr.height * ih * aspectRatio) / iw;\n }\n\n const fx = clamp01(focal?.x ?? 0.5);\n const fy = clamp01(focal?.y ?? 0.5);\n const maxX = cr.x + cr.width - w;\n const maxY = cr.y + cr.height - h;\n const x = Math.min(Math.max(fx - w / 2, cr.x), Math.max(cr.x, maxX));\n const y = Math.min(Math.max(fy - h / 2, cr.y), Math.max(cr.y, maxY));\n return { x, y, width: w, height: h };\n};\n\nexport interface Framing {\n crop?: CropInsets;\n focal?: { x: number; y: number };\n aspectRatio?: number;\n}\n\nexport const hasFraming = (framing: Framing): boolean => {\n const c = framing.crop;\n const cropped = !!c && !(c.top === 0 && c.left === 0 && c.bottom === 0 && c.right === 0);\n return cropped || framing.aspectRatio !== undefined;\n};\n\nexport const extractFramedRegion = async (buffer: Buffer, framing: Framing): Promise<Buffer> => {\n if (!hasFraming(framing)) {\n return buffer;\n }\n const image = sharp(buffer);\n const meta = await image.metadata();\n const w = meta.width ?? 0;\n const h = meta.height ?? 0;\n if (!w || !h) {\n return buffer;\n }\n\n const rect = getVisibleRect(w, h, framing.crop, framing.focal, framing.aspectRatio);\n const left = Math.max(0, Math.min(w - 1, Math.round(rect.x * w)));\n const top = Math.max(0, Math.min(h - 1, Math.round(rect.y * h)));\n const width = Math.max(1, Math.min(w - left, Math.round(rect.width * w)));\n const height = Math.max(1, Math.min(h - top, Math.round(rect.height * h)));\n\n if (left === 0 && top === 0 && width === w && height === h) {\n return buffer;\n }\n return image.extract({ left, top, width, height }).toBuffer();\n};\n\nexport const transformImageBuffer = async (\n params: TransformImageParams\n): Promise<TransformImageResult> => {\n let pipeline = sharp(params.buffer, { animated: params.animated }).withMetadata();\n\n if (params.options.width) {\n const width = WidthCollection.create(params.widths).getClosestOrMax(params.options.width);\n pipeline = pipeline.resize({ width, withoutEnlargement: true });\n }\n\n const { pipeline: encoded, contentType } = applyOutputFormat(\n pipeline,\n params.sourceContentType,\n params.options,\n params.qualityDefaults ?? DEFAULT_IMAGE_QUALITY\n );\n\n const buffer = await encoded.toBuffer();\n\n return { buffer, contentType };\n};\n"],"names":["applyOutputFormat","pipeline","sourceContentType","options","qualityDefaults","targetFormat","formatFromContentType","undefined","quality","contentTypeForFormat","clamp01","n","Math","cropImageBuffer","buffer","crop","image","sharp","meta","w","h","left","top","width","height","cropToRect","getVisibleRect","imageWidth","imageHeight","focal","aspectRatio","cr","iw","ih","cropAR","fx","fy","maxX","maxY","x","y","hasFraming","framing","c","cropped","extractFramedRegion","rect","transformImageBuffer","params","WidthCollection","encoded","contentType","DEFAULT_IMAGE_QUALITY"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Framing } from "./imageTypes.js";
|
|
2
|
+
declare const SUPPORTED_TRANSFORMABLE_IMAGES: string[];
|
|
3
|
+
declare const getOptimizedImageKeyPrefix: (key: string, cropSignature?: string) => string;
|
|
4
|
+
declare const getOptimizedTransformedImageKeyPrefix: (key: string, transformationsHash: string, cropSignature?: string) => string;
|
|
5
|
+
interface Crop {
|
|
6
|
+
top: number;
|
|
7
|
+
left: number;
|
|
8
|
+
bottom: number;
|
|
9
|
+
right: number;
|
|
10
|
+
}
|
|
11
|
+
/** Short, stable signature of a crop; `undefined` for no/empty crop (so keys are unchanged). */
|
|
12
|
+
declare const getCropSignature: (crop?: Crop) => string | undefined;
|
|
13
|
+
interface GetImageKeyParams {
|
|
14
|
+
key: string;
|
|
15
|
+
transformations?: any;
|
|
16
|
+
cropSignature?: string;
|
|
17
|
+
}
|
|
18
|
+
declare const getImageKey: ({ key, transformations, cropSignature }: GetImageKeyParams) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Signature for a full framing (crop + focal + aspect ratio) used to namespace
|
|
21
|
+
* cached derivatives. `undefined` when the framing is a no-op. A crop-only framing
|
|
22
|
+
* intentionally hashes to the same value as `getCropSignature`, so existing
|
|
23
|
+
* asset-level-crop derivatives keep their cache keys (backward compatible).
|
|
24
|
+
*/
|
|
25
|
+
declare const getFramingSignature: (framing: Framing) => string | undefined;
|
|
26
|
+
export { SUPPORTED_TRANSFORMABLE_IMAGES, getImageKey, getCropSignature, getFramingSignature, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import object_hash from "object-hash";
|
|
2
|
+
import node_path from "node:path";
|
|
3
|
+
const SUPPORTED_TRANSFORMABLE_IMAGES = [
|
|
4
|
+
"jpg",
|
|
5
|
+
"jpeg",
|
|
6
|
+
"png",
|
|
7
|
+
"webp"
|
|
8
|
+
];
|
|
9
|
+
const parseKey = (key)=>{
|
|
10
|
+
const filename = node_path.basename(key);
|
|
11
|
+
const dirname = node_path.dirname(key);
|
|
12
|
+
return {
|
|
13
|
+
filename,
|
|
14
|
+
dirname
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const cropSegment = (cropSignature)=>cropSignature ? `${cropSignature}/` : "";
|
|
18
|
+
const getOptimizedImageKeyPrefix = (key, cropSignature)=>{
|
|
19
|
+
const { filename, dirname } = parseKey(key);
|
|
20
|
+
return `${dirname}/optimized/${cropSegment(cropSignature)}${filename}`;
|
|
21
|
+
};
|
|
22
|
+
const getOptimizedTransformedImageKeyPrefix = (key, transformationsHash, cropSignature)=>{
|
|
23
|
+
const { filename, dirname } = parseKey(key);
|
|
24
|
+
return `${dirname}/optimized/${cropSegment(cropSignature)}${transformationsHash}-${filename}`;
|
|
25
|
+
};
|
|
26
|
+
const getCropSignature = (crop)=>{
|
|
27
|
+
if (!crop || 0 === crop.top && 0 === crop.left && 0 === crop.bottom && 0 === crop.right) return;
|
|
28
|
+
return object_hash(crop).slice(0, 16);
|
|
29
|
+
};
|
|
30
|
+
const getImageKey = ({ key, transformations, cropSignature })=>{
|
|
31
|
+
if (!transformations) return getOptimizedImageKeyPrefix(key, cropSignature);
|
|
32
|
+
return getOptimizedTransformedImageKeyPrefix(key, object_hash(transformations), cropSignature);
|
|
33
|
+
};
|
|
34
|
+
const getFramingSignature = (framing)=>{
|
|
35
|
+
const { crop, focal, aspectRatio } = framing;
|
|
36
|
+
const cropped = !!crop && !(0 === crop.top && 0 === crop.left && 0 === crop.bottom && 0 === crop.right);
|
|
37
|
+
if (!cropped && void 0 === aspectRatio) return;
|
|
38
|
+
if (cropped && void 0 === focal && void 0 === aspectRatio) return object_hash(crop).slice(0, 16);
|
|
39
|
+
return object_hash({
|
|
40
|
+
crop: cropped ? crop : void 0,
|
|
41
|
+
focal,
|
|
42
|
+
aspectRatio
|
|
43
|
+
}).slice(0, 16);
|
|
44
|
+
};
|
|
45
|
+
export { SUPPORTED_TRANSFORMABLE_IMAGES, getCropSignature, getFramingSignature, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/utils.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/utils.ts"],"sourcesContent":["import objectHash from \"object-hash\";\nimport path from \"node:path\";\nimport type { Framing } from \"./imageTypes.js\";\n\nconst SUPPORTED_TRANSFORMABLE_IMAGES = [\"jpg\", \"jpeg\", \"png\", \"webp\"];\n\nconst parseKey = (key: string) => {\n const filename = path.basename(key);\n const dirname = path.dirname(key);\n\n return { filename, dirname };\n};\n\n// An optional per-file crop signature segment. Keeps un-cropped keys unchanged\n// (backward compatible) while giving cropped files their own cache namespace, so\n// changing a file's crop invalidates its derivatives.\nconst cropSegment = (cropSignature?: string): string => {\n return cropSignature ? `${cropSignature}/` : \"\";\n};\n\nconst getOptimizedImageKeyPrefix = (key: string, cropSignature?: string): string => {\n const { filename, dirname } = parseKey(key);\n\n return `${dirname}/optimized/${cropSegment(cropSignature)}${filename}`;\n};\n\nconst getOptimizedTransformedImageKeyPrefix = (\n key: string,\n transformationsHash: string,\n cropSignature?: string\n): string => {\n const { filename, dirname } = parseKey(key);\n\n return `${dirname}/optimized/${cropSegment(cropSignature)}${transformationsHash}-${filename}`;\n};\n\ninterface Crop {\n top: number;\n left: number;\n bottom: number;\n right: number;\n}\n\n/** Short, stable signature of a crop; `undefined` for no/empty crop (so keys are unchanged). */\nconst getCropSignature = (crop?: Crop): string | undefined => {\n if (!crop || (crop.top === 0 && crop.left === 0 && crop.bottom === 0 && crop.right === 0)) {\n return undefined;\n }\n return objectHash(crop).slice(0, 16);\n};\n\ninterface GetImageKeyParams {\n key: string;\n transformations?: any;\n cropSignature?: string;\n}\n\nconst getImageKey = ({ key, transformations, cropSignature }: GetImageKeyParams): string => {\n if (!transformations) {\n return getOptimizedImageKeyPrefix(key, cropSignature);\n }\n\n return getOptimizedTransformedImageKeyPrefix(key, objectHash(transformations), cropSignature);\n};\n\n/**\n * Signature for a full framing (crop + focal + aspect ratio) used to namespace\n * cached derivatives. `undefined` when the framing is a no-op. A crop-only framing\n * intentionally hashes to the same value as `getCropSignature`, so existing\n * asset-level-crop derivatives keep their cache keys (backward compatible).\n */\nconst getFramingSignature = (framing: Framing): string | undefined => {\n const { crop, focal, aspectRatio } = framing;\n const cropped =\n !!crop && !(crop.top === 0 && crop.left === 0 && crop.bottom === 0 && crop.right === 0);\n\n if (!cropped && aspectRatio === undefined) {\n return undefined;\n }\n if (cropped && focal === undefined && aspectRatio === undefined) {\n return objectHash(crop).slice(0, 16);\n }\n return objectHash({ crop: cropped ? crop : undefined, focal, aspectRatio }).slice(0, 16);\n};\n\nexport {\n SUPPORTED_TRANSFORMABLE_IMAGES,\n getImageKey,\n getCropSignature,\n getFramingSignature,\n getOptimizedImageKeyPrefix,\n getOptimizedTransformedImageKeyPrefix\n};\n"],"names":["SUPPORTED_TRANSFORMABLE_IMAGES","parseKey","key","filename","path","dirname","cropSegment","cropSignature","getOptimizedImageKeyPrefix","getOptimizedTransformedImageKeyPrefix","transformationsHash","getCropSignature","crop","objectHash","getImageKey","transformations","getFramingSignature","framing","focal","aspectRatio","cropped","undefined"],"mappings":";;AAIA,MAAMA,iCAAiC;IAAC;IAAO;IAAQ;IAAO;CAAO;AAErE,MAAMC,WAAW,CAACC;IACd,MAAMC,WAAWC,UAAAA,QAAa,CAACF;IAC/B,MAAMG,UAAUD,UAAAA,OAAY,CAACF;IAE7B,OAAO;QAAEC;QAAUE;IAAQ;AAC/B;AAKA,MAAMC,cAAc,CAACC,gBACVA,gBAAgB,GAAGA,cAAc,CAAC,CAAC,GAAG;AAGjD,MAAMC,6BAA6B,CAACN,KAAaK;IAC7C,MAAM,EAAEJ,QAAQ,EAAEE,OAAO,EAAE,GAAGJ,SAASC;IAEvC,OAAO,GAAGG,QAAQ,WAAW,EAAEC,YAAYC,iBAAiBJ,UAAU;AAC1E;AAEA,MAAMM,wCAAwC,CAC1CP,KACAQ,qBACAH;IAEA,MAAM,EAAEJ,QAAQ,EAAEE,OAAO,EAAE,GAAGJ,SAASC;IAEvC,OAAO,GAAGG,QAAQ,WAAW,EAAEC,YAAYC,iBAAiBG,oBAAoB,CAAC,EAAEP,UAAU;AACjG;AAUA,MAAMQ,mBAAmB,CAACC;IACtB,IAAI,CAACA,QAASA,AAAa,MAAbA,KAAK,GAAG,IAAUA,AAAc,MAAdA,KAAK,IAAI,IAAUA,AAAgB,MAAhBA,KAAK,MAAM,IAAUA,AAAe,MAAfA,KAAK,KAAK,EAC9E;IAEJ,OAAOC,YAAWD,MAAM,KAAK,CAAC,GAAG;AACrC;AAQA,MAAME,cAAc,CAAC,EAAEZ,GAAG,EAAEa,eAAe,EAAER,aAAa,EAAqB;IAC3E,IAAI,CAACQ,iBACD,OAAOP,2BAA2BN,KAAKK;IAG3C,OAAOE,sCAAsCP,KAAKW,YAAWE,kBAAkBR;AACnF;AAQA,MAAMS,sBAAsB,CAACC;IACzB,MAAM,EAAEL,IAAI,EAAEM,KAAK,EAAEC,WAAW,EAAE,GAAGF;IACrC,MAAMG,UACF,CAAC,CAACR,QAAQ,CAAEA,CAAAA,AAAa,MAAbA,KAAK,GAAG,IAAUA,AAAc,MAAdA,KAAK,IAAI,IAAUA,AAAgB,MAAhBA,KAAK,MAAM,IAAUA,AAAe,MAAfA,KAAK,KAAK,AAAK;IAEzF,IAAI,CAACQ,WAAWD,AAAgBE,WAAhBF,aACZ;IAEJ,IAAIC,WAAWF,AAAUG,WAAVH,SAAuBC,AAAgBE,WAAhBF,aAClC,OAAON,YAAWD,MAAM,KAAK,CAAC,GAAG;IAErC,OAAOC,YAAW;QAAE,MAAMO,UAAUR,OAAOS;QAAWH;QAAOC;IAAY,GAAG,KAAK,CAAC,GAAG;AACzF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/api";
|
|
2
|
+
import { FeatureFlags } from "@webiny/api-core/features/featureFlags/abstractions.js";
|
|
3
|
+
import { AssetProcessor } from "./abstractions.js";
|
|
4
|
+
import { FilesAssetRequestResolverImpl } from "./FilesAssetRequestResolver.js";
|
|
5
|
+
import { NullAssetResolverImpl } from "./NullAssetResolver.js";
|
|
6
|
+
import { NullAssetOutputStrategyImpl } from "./NullAssetOutputStrategy.js";
|
|
7
|
+
import { AssetFactory } from "./Asset/Asset.js";
|
|
8
|
+
import { ObjectKey } from "./ObjectKey/ObjectKey.js";
|
|
9
|
+
import { StreamAssetReply } from "./StreamAssetReply/StreamAssetReply.js";
|
|
10
|
+
import { TransformationAssetProcessor } from "./transformation/TransformationAssetProcessor.js";
|
|
11
|
+
import { ImageAssetType } from "./assetTypes/image/ImageAssetType.js";
|
|
12
|
+
import { PrivateFileAssetRequestResolverDecorator } from "./privateFiles/PrivateFileAssetRequestResolver.js";
|
|
13
|
+
import { PrivateAuthenticatedAuthorizerImpl } from "./privateFiles/PrivateAuthenticatedAuthorizer.js";
|
|
14
|
+
import { PrivateFilesAssetProcessorDecorator } from "./privateFiles/PrivateFilesAssetProcessor.js";
|
|
15
|
+
const AssetDeliveryFeature = createFeature({
|
|
16
|
+
name: "AssetDelivery",
|
|
17
|
+
register (container) {
|
|
18
|
+
container.register(FilesAssetRequestResolverImpl);
|
|
19
|
+
container.register(NullAssetResolverImpl);
|
|
20
|
+
container.register(NullAssetOutputStrategyImpl);
|
|
21
|
+
container.register(AssetFactory).inSingletonScope();
|
|
22
|
+
container.register(ObjectKey).inSingletonScope();
|
|
23
|
+
container.register(StreamAssetReply).inSingletonScope();
|
|
24
|
+
container.register(ImageAssetType);
|
|
25
|
+
container.registerInstance(AssetProcessor, new TransformationAssetProcessor(container));
|
|
26
|
+
container.registerDecorator(PrivateFileAssetRequestResolverDecorator);
|
|
27
|
+
if (container.resolve(FeatureFlags).get().isEnabled("advancedAccessControlLayer.privateFiles")) {
|
|
28
|
+
container.register(PrivateAuthenticatedAuthorizerImpl);
|
|
29
|
+
container.registerDecorator(PrivateFilesAssetProcessorDecorator);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
export { AssetDeliveryFeature };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/feature.js","sources":["../../../src/features/assetDelivery/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { FeatureFlags } from \"@webiny/api-core/features/featureFlags/abstractions.js\";\nimport { AssetProcessor } from \"./abstractions.js\";\nimport { FilesAssetRequestResolverImpl } from \"./FilesAssetRequestResolver.js\";\nimport { NullAssetResolverImpl } from \"./NullAssetResolver.js\";\nimport { NullAssetOutputStrategyImpl } from \"./NullAssetOutputStrategy.js\";\nimport { AssetFactory } from \"./Asset/Asset.js\";\nimport { ObjectKey } from \"./ObjectKey/ObjectKey.js\";\nimport { StreamAssetReply } from \"./StreamAssetReply/StreamAssetReply.js\";\nimport { TransformationAssetProcessor } from \"./transformation/TransformationAssetProcessor.js\";\nimport { ImageAssetType } from \"./assetTypes/image/ImageAssetType.js\";\nimport { PrivateFileAssetRequestResolverDecorator } from \"./privateFiles/PrivateFileAssetRequestResolver.js\";\nimport { PrivateAuthenticatedAuthorizerImpl } from \"./privateFiles/PrivateAuthenticatedAuthorizer.js\";\nimport { PrivateFilesAssetProcessorDecorator } from \"./privateFiles/PrivateFilesAssetProcessor.js\";\n\nexport const AssetDeliveryFeature = createFeature({\n name: \"AssetDelivery\",\n register(container) {\n container.register(FilesAssetRequestResolverImpl);\n container.register(NullAssetResolverImpl);\n container.register(NullAssetOutputStrategyImpl);\n container.register(AssetFactory).inSingletonScope();\n container.register(ObjectKey).inSingletonScope();\n container.register(StreamAssetReply).inSingletonScope();\n container.register(ImageAssetType);\n container.registerInstance(AssetProcessor, new TransformationAssetProcessor(container));\n\n container.registerDecorator(PrivateFileAssetRequestResolverDecorator);\n\n // Register-time gate on the effective feature flags (userFlag && live WCP license). Valid at\n // register() time because the license is refreshed PRE-register (WcpLicenseLoader.load in\n // registerApiRequestStack) and FeatureFlags reads that process cache — and it re-evaluates per\n // request since the child re-registers, so a license change takes effect on the next request.\n if (\n container\n .resolve(FeatureFlags)\n .get()\n .isEnabled(\"advancedAccessControlLayer.privateFiles\")\n ) {\n container.register(PrivateAuthenticatedAuthorizerImpl);\n container.registerDecorator(PrivateFilesAssetProcessorDecorator);\n }\n }\n});\n"],"names":["AssetDeliveryFeature","createFeature","container","FilesAssetRequestResolverImpl","NullAssetResolverImpl","NullAssetOutputStrategyImpl","AssetFactory","ObjectKey","StreamAssetReply","ImageAssetType","AssetProcessor","TransformationAssetProcessor","PrivateFileAssetRequestResolverDecorator","FeatureFlags","PrivateAuthenticatedAuthorizerImpl","PrivateFilesAssetProcessorDecorator"],"mappings":";;;;;;;;;;;;;;AAeO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;QACnBH,UAAU,QAAQ,CAACI,cAAc,gBAAgB;QACjDJ,UAAU,QAAQ,CAACK,WAAW,gBAAgB;QAC9CL,UAAU,QAAQ,CAACM,kBAAkB,gBAAgB;QACrDN,UAAU,QAAQ,CAACO;QACnBP,UAAU,gBAAgB,CAACQ,gBAAgB,IAAIC,6BAA6BT;QAE5EA,UAAU,iBAAiB,CAACU;QAM5B,IACIV,UACK,OAAO,CAACW,cACR,GAAG,GACH,SAAS,CAAC,4CACjB;YACEX,UAAU,QAAQ,CAACY;YACnBZ,UAAU,iBAAiB,CAACa;QAChC;IACJ;AACJ"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ResponseHeaders } from "@webiny/handler";
|
|
2
|
+
import { AssetReply } from "../../../delivery/AssetDelivery/abstractions/AssetReply.js";
|
|
3
|
+
class NotAuthorizedAssetReply extends AssetReply {
|
|
4
|
+
constructor(){
|
|
5
|
+
super({
|
|
6
|
+
code: 403,
|
|
7
|
+
headers: ResponseHeaders.create({
|
|
8
|
+
"cache-control": "no-store",
|
|
9
|
+
"content-type": "application/json; charset=utf-8"
|
|
10
|
+
}),
|
|
11
|
+
body: ()=>({
|
|
12
|
+
error: "Not authorized!",
|
|
13
|
+
code: "NOT_AUTHORIZED"
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export { NotAuthorizedAssetReply };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=NotAuthorizedAssetReply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/NotAuthorizedAssetReply.js","sources":["../../../../src/features/assetDelivery/privateFiles/NotAuthorizedAssetReply.ts"],"sourcesContent":["import { ResponseHeaders } from \"@webiny/handler\";\nimport { AssetReply } from \"~/delivery/AssetDelivery/abstractions/AssetReply.js\";\n\nexport class NotAuthorizedAssetReply extends AssetReply {\n constructor() {\n super({\n code: 403,\n headers: ResponseHeaders.create({\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json; charset=utf-8\"\n }),\n body: () => ({ error: \"Not authorized!\", code: \"NOT_AUTHORIZED\" })\n });\n }\n}\n"],"names":["NotAuthorizedAssetReply","AssetReply","ResponseHeaders"],"mappings":";;AAGO,MAAMA,gCAAgCC;IACzC,aAAc;QACV,KAAK,CAAC;YACF,MAAM;YACN,SAASC,gBAAgB,MAAM,CAAC;gBAC5B,iBAAiB;gBACjB,gBAAgB;YACpB;YACA,MAAM,IAAO;oBAAE,OAAO;oBAAmB,MAAM;gBAAiB;QACpE;IACJ;AACJ"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AssetReply } from "../../../delivery/AssetDelivery/abstractions/AssetReply.js";
|
|
2
|
+
import type { IAssetOutputStrategy } from "../abstractions.js";
|
|
3
|
+
export declare class NotAuthorizedOutputStrategy implements IAssetOutputStrategy {
|
|
4
|
+
output(): Promise<AssetReply>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NotAuthorizedAssetReply } from "./NotAuthorizedAssetReply.js";
|
|
2
|
+
class NotAuthorizedOutputStrategy {
|
|
3
|
+
async output() {
|
|
4
|
+
return new NotAuthorizedAssetReply();
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export { NotAuthorizedOutputStrategy };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=NotAuthorizedOutputStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/NotAuthorizedOutputStrategy.js","sources":["../../../../src/features/assetDelivery/privateFiles/NotAuthorizedOutputStrategy.ts"],"sourcesContent":["import type { AssetReply } from \"~/delivery/AssetDelivery/abstractions/AssetReply.js\";\nimport { NotAuthorizedAssetReply } from \"./NotAuthorizedAssetReply.js\";\nimport type { IAssetOutputStrategy } from \"../abstractions.js\";\n\nexport class NotAuthorizedOutputStrategy implements IAssetOutputStrategy {\n async output(): Promise<AssetReply> {\n return new NotAuthorizedAssetReply();\n }\n}\n"],"names":["NotAuthorizedOutputStrategy","NotAuthorizedAssetReply"],"mappings":";AAIO,MAAMA;IACT,MAAM,SAA8B;QAChC,OAAO,IAAIC;IACf;AACJ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { File } from "../../../domain/file/types.js";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
3
|
+
import { type IAssetAuthorizer } from "../abstractions.js";
|
|
4
|
+
export declare class PrivateAuthenticatedAuthorizer implements IAssetAuthorizer {
|
|
5
|
+
private identityContext;
|
|
6
|
+
constructor(identityContext: IdentityContext.Interface);
|
|
7
|
+
authorize(file: File): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare const PrivateAuthenticatedAuthorizerImpl: typeof PrivateAuthenticatedAuthorizer & {
|
|
10
|
+
__abstraction: import("@webiny/di").Abstraction<IAssetAuthorizer>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import error from "@webiny/error";
|
|
2
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
3
|
+
import { AssetAuthorizer } from "../abstractions.js";
|
|
4
|
+
class PrivateAuthenticatedAuthorizer {
|
|
5
|
+
constructor(identityContext){
|
|
6
|
+
this.identityContext = identityContext;
|
|
7
|
+
}
|
|
8
|
+
async authorize(file) {
|
|
9
|
+
if (file.accessControl && "private-authenticated" === file.accessControl.type) {
|
|
10
|
+
const identity = this.identityContext.getIdentity();
|
|
11
|
+
if (!identity) throw new error({
|
|
12
|
+
code: "NOT_AUTHORIZED",
|
|
13
|
+
message: "You're not authorized to access this asset!"
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const PrivateAuthenticatedAuthorizerImpl = AssetAuthorizer.createImplementation({
|
|
19
|
+
implementation: PrivateAuthenticatedAuthorizer,
|
|
20
|
+
dependencies: [
|
|
21
|
+
IdentityContext
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
export { PrivateAuthenticatedAuthorizer, PrivateAuthenticatedAuthorizerImpl };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=PrivateAuthenticatedAuthorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.js","sources":["../../../../src/features/assetDelivery/privateFiles/PrivateAuthenticatedAuthorizer.ts"],"sourcesContent":["import Error from \"@webiny/error\";\nimport type { File } from \"~/domain/file/types.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { AssetAuthorizer, type IAssetAuthorizer } from \"../abstractions.js\";\n\nexport class PrivateAuthenticatedAuthorizer implements IAssetAuthorizer {\n private identityContext: IdentityContext.Interface;\n\n constructor(identityContext: IdentityContext.Interface) {\n this.identityContext = identityContext;\n }\n\n async authorize(file: File) {\n if (file.accessControl && file.accessControl.type === \"private-authenticated\") {\n const identity = this.identityContext.getIdentity();\n\n if (!identity) {\n throw new Error({\n code: \"NOT_AUTHORIZED\",\n message: \"You're not authorized to access this asset!\"\n });\n }\n }\n }\n}\n\nexport const PrivateAuthenticatedAuthorizerImpl = AssetAuthorizer.createImplementation({\n implementation: PrivateAuthenticatedAuthorizer,\n dependencies: [IdentityContext]\n});\n"],"names":["PrivateAuthenticatedAuthorizer","identityContext","file","identity","Error","PrivateAuthenticatedAuthorizerImpl","AssetAuthorizer","IdentityContext"],"mappings":";;;AAKO,MAAMA;IAGT,YAAYC,eAA0C,CAAE;QACpD,IAAI,CAAC,eAAe,GAAGA;IAC3B;IAEA,MAAM,UAAUC,IAAU,EAAE;QACxB,IAAIA,KAAK,aAAa,IAAIA,AAA4B,4BAA5BA,KAAK,aAAa,CAAC,IAAI,EAA8B;YAC3E,MAAMC,WAAW,IAAI,CAAC,eAAe,CAAC,WAAW;YAEjD,IAAI,CAACA,UACD,MAAM,IAAIC,MAAM;gBACZ,MAAM;gBACN,SAAS;YACb;QAER;IACJ;AACJ;AAEO,MAAMC,qCAAqCC,gBAAgB,oBAAoB,CAAC;IACnF,gBAAgBN;IAChB,cAAc;QAACO;KAAgB;AACnC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Asset } from "../../../delivery/AssetDelivery/Asset.js";
|
|
2
|
+
import type { AssetReply } from "../../../delivery/AssetDelivery/abstractions/AssetReply.js";
|
|
3
|
+
import type { IAssetOutputStrategy } from "../abstractions.js";
|
|
4
|
+
export declare class PrivateCache implements IAssetOutputStrategy {
|
|
5
|
+
private strategy;
|
|
6
|
+
constructor(strategy: IAssetOutputStrategy);
|
|
7
|
+
output(asset: Asset): Promise<AssetReply>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parse, stringify } from "cache-control-parser";
|
|
2
|
+
class PrivateCache {
|
|
3
|
+
constructor(strategy){
|
|
4
|
+
this.strategy = strategy;
|
|
5
|
+
}
|
|
6
|
+
async output(asset) {
|
|
7
|
+
const reply = await this.strategy.output(asset);
|
|
8
|
+
reply.setHeaders((headers)=>{
|
|
9
|
+
headers.set("cache-control", (value = "")=>{
|
|
10
|
+
const cacheControl = parse(value);
|
|
11
|
+
cacheControl["private"] = true;
|
|
12
|
+
cacheControl["public"] = false;
|
|
13
|
+
return stringify(cacheControl);
|
|
14
|
+
});
|
|
15
|
+
return headers;
|
|
16
|
+
});
|
|
17
|
+
return reply;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export { PrivateCache };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=PrivateCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/PrivateCache.js","sources":["../../../../src/features/assetDelivery/privateFiles/PrivateCache.ts"],"sourcesContent":["import { parse, stringify } from \"cache-control-parser\";\nimport type { Asset } from \"~/delivery/AssetDelivery/Asset.js\";\nimport type { AssetReply } from \"~/delivery/AssetDelivery/abstractions/AssetReply.js\";\nimport type { IAssetOutputStrategy } from \"../abstractions.js\";\n\nexport class PrivateCache implements IAssetOutputStrategy {\n private strategy: IAssetOutputStrategy;\n\n constructor(strategy: IAssetOutputStrategy) {\n this.strategy = strategy;\n }\n\n async output(asset: Asset): Promise<AssetReply> {\n const reply = await this.strategy.output(asset);\n\n reply.setHeaders(headers => {\n headers.set(\"cache-control\", (value = \"\") => {\n const cacheControl = parse(value);\n cacheControl[\"private\"] = true;\n cacheControl[\"public\"] = false;\n return stringify(cacheControl);\n });\n return headers;\n });\n\n return reply;\n }\n}\n"],"names":["PrivateCache","strategy","asset","reply","headers","value","cacheControl","parse","stringify"],"mappings":";AAKO,MAAMA;IAGT,YAAYC,QAA8B,CAAE;QACxC,IAAI,CAAC,QAAQ,GAAGA;IACpB;IAEA,MAAM,OAAOC,KAAY,EAAuB;QAC5C,MAAMC,QAAQ,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAACD;QAEzCC,MAAM,UAAU,CAACC,CAAAA;YACbA,QAAQ,GAAG,CAAC,iBAAiB,CAACC,QAAQ,EAAE;gBACpC,MAAMC,eAAeC,MAAMF;gBAC3BC,YAAY,CAAC,UAAU,GAAG;gBAC1BA,YAAY,CAAC,SAAS,GAAG;gBACzB,OAAOE,UAAUF;YACrB;YACA,OAAOF;QACX;QAEA,OAAOD;IACX;AACJ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Request } from "@webiny/handler/types.js";
|
|
2
|
+
import { AssetRequest } from "../../../delivery/AssetDelivery/AssetRequest.js";
|
|
3
|
+
import { type IAssetRequestResolver } from "../abstractions.js";
|
|
4
|
+
export declare class PrivateFileAssetRequestResolver implements IAssetRequestResolver {
|
|
5
|
+
private readonly resolver;
|
|
6
|
+
constructor(resolver: IAssetRequestResolver);
|
|
7
|
+
resolve(request: Request): Promise<AssetRequest | undefined>;
|
|
8
|
+
}
|
|
9
|
+
export declare const PrivateFileAssetRequestResolverDecorator: typeof PrivateFileAssetRequestResolver & {
|
|
10
|
+
__abstraction: import("@webiny/di").Abstraction<IAssetRequestResolver>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AssetRequest } from "../../../delivery/AssetDelivery/AssetRequest.js";
|
|
2
|
+
import { AssetRequestResolver } from "../abstractions.js";
|
|
3
|
+
class PrivateFileAssetRequestResolver {
|
|
4
|
+
constructor(resolver){
|
|
5
|
+
this.resolver = resolver;
|
|
6
|
+
}
|
|
7
|
+
async resolve(request) {
|
|
8
|
+
if (!request.url?.startsWith("/private/")) return this.resolver.resolve(request);
|
|
9
|
+
const params = request.params ?? {};
|
|
10
|
+
const query = request.query ?? {};
|
|
11
|
+
const path = params["*"];
|
|
12
|
+
return new AssetRequest({
|
|
13
|
+
key: decodeURI(path).replace("/private/", ""),
|
|
14
|
+
context: {
|
|
15
|
+
url: request.url ?? "",
|
|
16
|
+
private: true
|
|
17
|
+
},
|
|
18
|
+
options: {
|
|
19
|
+
...query,
|
|
20
|
+
width: query.width ? parseInt(query.width) : void 0
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const PrivateFileAssetRequestResolverDecorator = AssetRequestResolver.createDecorator({
|
|
26
|
+
decorator: PrivateFileAssetRequestResolver,
|
|
27
|
+
dependencies: []
|
|
28
|
+
});
|
|
29
|
+
export { PrivateFileAssetRequestResolver, PrivateFileAssetRequestResolverDecorator };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=PrivateFileAssetRequestResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/PrivateFileAssetRequestResolver.js","sources":["../../../../src/features/assetDelivery/privateFiles/PrivateFileAssetRequestResolver.ts"],"sourcesContent":["import type { Request } from \"@webiny/handler/types.js\";\nimport { AssetRequest } from \"~/delivery/AssetDelivery/AssetRequest.js\";\nimport { AssetRequestResolver, type IAssetRequestResolver } from \"../abstractions.js\";\n\nexport class PrivateFileAssetRequestResolver implements IAssetRequestResolver {\n private readonly resolver: IAssetRequestResolver;\n\n constructor(resolver: IAssetRequestResolver) {\n this.resolver = resolver;\n }\n\n async resolve(request: Request): Promise<AssetRequest | undefined> {\n if (!request.url?.startsWith(\"/private/\")) {\n return this.resolver.resolve(request);\n }\n\n const params = (request.params ?? {}) as Record<string, any>;\n const query = (request.query ?? {}) as Record<string, any>;\n\n const path = params[\"*\"];\n\n return new AssetRequest({\n key: decodeURI(path).replace(\"/private/\", \"\"),\n context: {\n url: request.url ?? \"\",\n private: true\n },\n options: {\n ...query,\n width: query.width ? parseInt(query.width) : undefined\n }\n });\n }\n}\n\nexport const PrivateFileAssetRequestResolverDecorator = AssetRequestResolver.createDecorator({\n decorator: PrivateFileAssetRequestResolver,\n dependencies: []\n});\n"],"names":["PrivateFileAssetRequestResolver","resolver","request","params","query","path","AssetRequest","decodeURI","parseInt","undefined","PrivateFileAssetRequestResolverDecorator","AssetRequestResolver"],"mappings":";;AAIO,MAAMA;IAGT,YAAYC,QAA+B,CAAE;QACzC,IAAI,CAAC,QAAQ,GAAGA;IACpB;IAEA,MAAM,QAAQC,OAAgB,EAAqC;QAC/D,IAAI,CAACA,QAAQ,GAAG,EAAE,WAAW,cACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAACA;QAGjC,MAAMC,SAAUD,QAAQ,MAAM,IAAI,CAAC;QACnC,MAAME,QAASF,QAAQ,KAAK,IAAI,CAAC;QAEjC,MAAMG,OAAOF,MAAM,CAAC,IAAI;QAExB,OAAO,IAAIG,aAAa;YACpB,KAAKC,UAAUF,MAAM,OAAO,CAAC,aAAa;YAC1C,SAAS;gBACL,KAAKH,QAAQ,GAAG,IAAI;gBACpB,SAAS;YACb;YACA,SAAS;gBACL,GAAGE,KAAK;gBACR,OAAOA,MAAM,KAAK,GAAGI,SAASJ,MAAM,KAAK,IAAIK;YACjD;QACJ;IACJ;AACJ;AAEO,MAAMC,2CAA2CC,qBAAqB,eAAe,CAAC;IACzF,WAAWX;IACX,cAAc,EAAE;AACpB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Asset } from "../../../delivery/AssetDelivery/Asset.js";
|
|
2
|
+
import type { AssetRequest } from "../../../delivery/AssetDelivery/AssetRequest.js";
|
|
3
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
4
|
+
import { GetFileUseCase } from "../../../features/file/GetFile/index.js";
|
|
5
|
+
import { type IAssetProcessor, type IAssetAuthorizer } from "../abstractions.js";
|
|
6
|
+
export declare class PrivateFilesAssetProcessor implements IAssetProcessor {
|
|
7
|
+
private readonly identityContext;
|
|
8
|
+
private readonly getFile;
|
|
9
|
+
private readonly assetAuthorizer;
|
|
10
|
+
private readonly assetProcessor;
|
|
11
|
+
constructor(identityContext: IdentityContext.Interface, getFile: GetFileUseCase.Interface, assetAuthorizer: IAssetAuthorizer, assetProcessor: IAssetProcessor);
|
|
12
|
+
process(assetRequest: AssetRequest, asset: Asset): Promise<Asset>;
|
|
13
|
+
private isPrivate;
|
|
14
|
+
private requestedViaPrivateEndpoint;
|
|
15
|
+
private requestedViaPublicEndpoint;
|
|
16
|
+
}
|
|
17
|
+
export declare const PrivateFilesAssetProcessorDecorator: typeof PrivateFilesAssetProcessor & {
|
|
18
|
+
__abstraction: import("@webiny/di").Abstraction<IAssetProcessor>;
|
|
19
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
2
|
+
import { GetFileUseCase } from "../../file/GetFile/index.js";
|
|
3
|
+
import { NotAuthorizedOutputStrategy } from "./NotAuthorizedOutputStrategy.js";
|
|
4
|
+
import { RedirectToPublicUrlOutputStrategy } from "./RedirectToPublicUrlOutputStrategy.js";
|
|
5
|
+
import { RedirectToPrivateUrlOutputStrategy } from "./RedirectToPrivateUrlOutputStrategy.js";
|
|
6
|
+
import { PrivateCache } from "./PrivateCache.js";
|
|
7
|
+
import { PublicCache } from "./PublicCache.js";
|
|
8
|
+
import { AssetAuthorizer, AssetProcessor } from "../abstractions.js";
|
|
9
|
+
class PrivateFilesAssetProcessor {
|
|
10
|
+
constructor(identityContext, getFile, assetAuthorizer, assetProcessor){
|
|
11
|
+
this.identityContext = identityContext;
|
|
12
|
+
this.getFile = getFile;
|
|
13
|
+
this.assetAuthorizer = assetAuthorizer;
|
|
14
|
+
this.assetProcessor = assetProcessor;
|
|
15
|
+
}
|
|
16
|
+
async process(assetRequest, asset) {
|
|
17
|
+
const id = asset.getId();
|
|
18
|
+
const file = await this.identityContext.withoutAuthorization(async ()=>{
|
|
19
|
+
const fileResult = await this.getFile.execute(id);
|
|
20
|
+
if (fileResult.isFail()) throw fileResult.error;
|
|
21
|
+
return fileResult.value;
|
|
22
|
+
});
|
|
23
|
+
const isPrivateFile = this.isPrivate(file);
|
|
24
|
+
if (!isPrivateFile && this.requestedViaPrivateEndpoint(assetRequest)) {
|
|
25
|
+
asset.setOutputStrategy(new RedirectToPublicUrlOutputStrategy(assetRequest));
|
|
26
|
+
return asset;
|
|
27
|
+
}
|
|
28
|
+
if (isPrivateFile && this.requestedViaPublicEndpoint(assetRequest)) {
|
|
29
|
+
asset.setOutputStrategy(new RedirectToPrivateUrlOutputStrategy(assetRequest));
|
|
30
|
+
return asset;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
await this.assetAuthorizer.authorize(file);
|
|
34
|
+
} catch {
|
|
35
|
+
asset.setOutputStrategy(new NotAuthorizedOutputStrategy());
|
|
36
|
+
return asset;
|
|
37
|
+
}
|
|
38
|
+
const processedAsset = await this.assetProcessor.process(assetRequest, asset);
|
|
39
|
+
processedAsset.setOutputStrategy((strategy)=>{
|
|
40
|
+
if (!strategy) throw Error("No asset output strategy is configured!");
|
|
41
|
+
return isPrivateFile ? new PrivateCache(strategy) : new PublicCache(strategy);
|
|
42
|
+
});
|
|
43
|
+
return processedAsset;
|
|
44
|
+
}
|
|
45
|
+
isPrivate(file) {
|
|
46
|
+
return file.accessControl && file.accessControl.type.startsWith("private-");
|
|
47
|
+
}
|
|
48
|
+
requestedViaPrivateEndpoint(assetRequest) {
|
|
49
|
+
return assetRequest.getContext().private;
|
|
50
|
+
}
|
|
51
|
+
requestedViaPublicEndpoint(assetRequest) {
|
|
52
|
+
return !this.requestedViaPrivateEndpoint(assetRequest);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const PrivateFilesAssetProcessorDecorator = AssetProcessor.createDecorator({
|
|
56
|
+
decorator: PrivateFilesAssetProcessor,
|
|
57
|
+
dependencies: [
|
|
58
|
+
IdentityContext,
|
|
59
|
+
GetFileUseCase,
|
|
60
|
+
AssetAuthorizer
|
|
61
|
+
]
|
|
62
|
+
});
|
|
63
|
+
export { PrivateFilesAssetProcessor, PrivateFilesAssetProcessorDecorator };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=PrivateFilesAssetProcessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.js","sources":["../../../../src/features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.ts"],"sourcesContent":["import type { File } from \"~/domain/file/types.js\";\nimport type { Asset } from \"~/delivery/AssetDelivery/Asset.js\";\nimport type { AssetRequest } from \"~/delivery/AssetDelivery/AssetRequest.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { GetFileUseCase } from \"~/features/file/GetFile/index.js\";\nimport { NotAuthorizedOutputStrategy } from \"./NotAuthorizedOutputStrategy.js\";\nimport { RedirectToPublicUrlOutputStrategy } from \"./RedirectToPublicUrlOutputStrategy.js\";\nimport { RedirectToPrivateUrlOutputStrategy } from \"./RedirectToPrivateUrlOutputStrategy.js\";\nimport { PrivateCache } from \"./PrivateCache.js\";\nimport { PublicCache } from \"./PublicCache.js\";\nimport {\n AssetProcessor,\n AssetAuthorizer,\n type IAssetProcessor,\n type IAssetAuthorizer\n} from \"../abstractions.js\";\n\ninterface MaybePrivate {\n private?: boolean;\n}\n\nexport class PrivateFilesAssetProcessor implements IAssetProcessor {\n private readonly identityContext: IdentityContext.Interface;\n private readonly getFile: GetFileUseCase.Interface;\n private readonly assetAuthorizer: IAssetAuthorizer;\n private readonly assetProcessor: IAssetProcessor;\n\n constructor(\n identityContext: IdentityContext.Interface,\n getFile: GetFileUseCase.Interface,\n assetAuthorizer: IAssetAuthorizer,\n assetProcessor: IAssetProcessor\n ) {\n this.identityContext = identityContext;\n this.getFile = getFile;\n this.assetAuthorizer = assetAuthorizer;\n this.assetProcessor = assetProcessor;\n }\n\n async process(assetRequest: AssetRequest, asset: Asset): Promise<Asset> {\n // Only registered when private files are licensed (register-time gate in AssetDeliveryFeature),\n // so no per-request license guard is needed here.\n const id = asset.getId();\n\n const file = await this.identityContext.withoutAuthorization(async () => {\n const fileResult = await this.getFile.execute(id);\n if (fileResult.isFail()) {\n throw fileResult.error;\n }\n return fileResult.value;\n });\n\n const isPrivateFile = this.isPrivate(file);\n\n if (!isPrivateFile && this.requestedViaPrivateEndpoint(assetRequest)) {\n asset.setOutputStrategy(new RedirectToPublicUrlOutputStrategy(assetRequest));\n return asset;\n }\n\n if (isPrivateFile && this.requestedViaPublicEndpoint(assetRequest)) {\n asset.setOutputStrategy(new RedirectToPrivateUrlOutputStrategy(assetRequest));\n return asset;\n }\n\n try {\n await this.assetAuthorizer.authorize(file);\n } catch {\n asset.setOutputStrategy(new NotAuthorizedOutputStrategy());\n return asset;\n }\n\n const processedAsset = await this.assetProcessor.process(assetRequest, asset);\n\n processedAsset.setOutputStrategy(strategy => {\n if (!strategy) {\n throw Error(`No asset output strategy is configured!`);\n }\n return isPrivateFile ? new PrivateCache(strategy) : new PublicCache(strategy);\n });\n\n return processedAsset;\n }\n\n private isPrivate(file: File) {\n return file.accessControl && file.accessControl.type.startsWith(\"private-\");\n }\n\n private requestedViaPrivateEndpoint(assetRequest: AssetRequest) {\n return assetRequest.getContext<MaybePrivate>().private;\n }\n\n private requestedViaPublicEndpoint(assetRequest: AssetRequest) {\n return !this.requestedViaPrivateEndpoint(assetRequest);\n }\n}\n\nexport const PrivateFilesAssetProcessorDecorator = AssetProcessor.createDecorator({\n decorator: PrivateFilesAssetProcessor,\n dependencies: [IdentityContext, GetFileUseCase, AssetAuthorizer]\n});\n"],"names":["PrivateFilesAssetProcessor","identityContext","getFile","assetAuthorizer","assetProcessor","assetRequest","asset","id","file","fileResult","isPrivateFile","RedirectToPublicUrlOutputStrategy","RedirectToPrivateUrlOutputStrategy","NotAuthorizedOutputStrategy","processedAsset","strategy","Error","PrivateCache","PublicCache","PrivateFilesAssetProcessorDecorator","AssetProcessor","IdentityContext","GetFileUseCase","AssetAuthorizer"],"mappings":";;;;;;;;AAqBO,MAAMA;IAMT,YACIC,eAA0C,EAC1CC,OAAiC,EACjCC,eAAiC,EACjCC,cAA+B,CACjC;QACE,IAAI,CAAC,eAAe,GAAGH;QACvB,IAAI,CAAC,OAAO,GAAGC;QACf,IAAI,CAAC,eAAe,GAAGC;QACvB,IAAI,CAAC,cAAc,GAAGC;IAC1B;IAEA,MAAM,QAAQC,YAA0B,EAAEC,KAAY,EAAkB;QAGpE,MAAMC,KAAKD,MAAM,KAAK;QAEtB,MAAME,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC;YACzD,MAAMC,aAAa,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAACF;YAC9C,IAAIE,WAAW,MAAM,IACjB,MAAMA,WAAW,KAAK;YAE1B,OAAOA,WAAW,KAAK;QAC3B;QAEA,MAAMC,gBAAgB,IAAI,CAAC,SAAS,CAACF;QAErC,IAAI,CAACE,iBAAiB,IAAI,CAAC,2BAA2B,CAACL,eAAe;YAClEC,MAAM,iBAAiB,CAAC,IAAIK,kCAAkCN;YAC9D,OAAOC;QACX;QAEA,IAAII,iBAAiB,IAAI,CAAC,0BAA0B,CAACL,eAAe;YAChEC,MAAM,iBAAiB,CAAC,IAAIM,mCAAmCP;YAC/D,OAAOC;QACX;QAEA,IAAI;YACA,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAACE;QACzC,EAAE,OAAM;YACJF,MAAM,iBAAiB,CAAC,IAAIO;YAC5B,OAAOP;QACX;QAEA,MAAMQ,iBAAiB,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACT,cAAcC;QAEvEQ,eAAe,iBAAiB,CAACC,CAAAA;YAC7B,IAAI,CAACA,UACD,MAAMC,MAAM;YAEhB,OAAON,gBAAgB,IAAIO,aAAaF,YAAY,IAAIG,YAAYH;QACxE;QAEA,OAAOD;IACX;IAEQ,UAAUN,IAAU,EAAE;QAC1B,OAAOA,KAAK,aAAa,IAAIA,KAAK,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC;IACpE;IAEQ,4BAA4BH,YAA0B,EAAE;QAC5D,OAAOA,aAAa,UAAU,GAAiB,OAAO;IAC1D;IAEQ,2BAA2BA,YAA0B,EAAE;QAC3D,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAACA;IAC7C;AACJ;AAEO,MAAMc,sCAAsCC,eAAe,eAAe,CAAC;IAC9E,WAAWpB;IACX,cAAc;QAACqB;QAAiBC;QAAgBC;KAAgB;AACpE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Asset } from "../../../delivery/AssetDelivery/Asset.js";
|
|
2
|
+
import type { AssetReply } from "../../../delivery/AssetDelivery/abstractions/AssetReply.js";
|
|
3
|
+
import type { IAssetOutputStrategy } from "../abstractions.js";
|
|
4
|
+
export declare class PublicCache implements IAssetOutputStrategy {
|
|
5
|
+
private strategy;
|
|
6
|
+
constructor(strategy: IAssetOutputStrategy);
|
|
7
|
+
output(asset: Asset): Promise<AssetReply>;
|
|
8
|
+
}
|