@webiny/api-file-manager-s3 6.0.0-beta.0 → 6.0.0-rc.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.
Files changed (208) hide show
  1. package/README.md +11 -1
  2. package/assetDelivery/assetDeliveryConfig.d.ts +2 -6
  3. package/assetDelivery/assetDeliveryConfig.js +24 -23
  4. package/assetDelivery/assetDeliveryConfig.js.map +1 -1
  5. package/assetDelivery/createAssetDelivery.d.ts +3 -3
  6. package/assetDelivery/createAssetDelivery.js +15 -12
  7. package/assetDelivery/createAssetDelivery.js.map +1 -1
  8. package/assetDelivery/index.d.ts +8 -9
  9. package/assetDelivery/index.js +8 -68
  10. package/assetDelivery/index.js.map +1 -1
  11. package/assetDelivery/s3/S3AssetResolver.d.ts +8 -5
  12. package/assetDelivery/s3/S3AssetResolver.js +19 -27
  13. package/assetDelivery/s3/S3AssetResolver.js.map +1 -1
  14. package/assetDelivery/s3/S3ContentsReader.d.ts +2 -3
  15. package/assetDelivery/s3/S3ContentsReader.js +1 -8
  16. package/assetDelivery/s3/S3ContentsReader.js.map +1 -1
  17. package/assetDelivery/s3/S3ErrorAssetReply.js +2 -9
  18. package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -1
  19. package/assetDelivery/s3/S3OutputStrategy.d.ts +4 -3
  20. package/assetDelivery/s3/S3OutputStrategy.js +12 -17
  21. package/assetDelivery/s3/S3OutputStrategy.js.map +1 -1
  22. package/assetDelivery/s3/S3RedirectAssetReply.js +4 -11
  23. package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -1
  24. package/assetDelivery/s3/S3StreamAssetReply.d.ts +2 -1
  25. package/assetDelivery/s3/S3StreamAssetReply.js +4 -11
  26. package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -1
  27. package/assetDelivery/s3/SharpTransform.d.ts +2 -2
  28. package/assetDelivery/s3/SharpTransform.js +63 -37
  29. package/assetDelivery/s3/SharpTransform.js.map +1 -1
  30. package/assetDelivery/s3/transformation/AssetKeyGenerator.d.ts +1 -1
  31. package/assetDelivery/s3/transformation/AssetKeyGenerator.js +3 -12
  32. package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -1
  33. package/assetDelivery/s3/transformation/CallableContentsReader.d.ts +1 -2
  34. package/assetDelivery/s3/transformation/CallableContentsReader.js +1 -8
  35. package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -1
  36. package/assetDelivery/s3/transformation/WidthCollection.js +1 -8
  37. package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -1
  38. package/assetDelivery/s3/transformation/utils.d.ts +1 -3
  39. package/assetDelivery/s3/transformation/utils.js +23 -19
  40. package/assetDelivery/s3/transformation/utils.js.map +1 -1
  41. package/assetDelivery/threatDetection/ObjectKey.d.ts +7 -0
  42. package/assetDelivery/threatDetection/ObjectKey.js +17 -0
  43. package/assetDelivery/threatDetection/ObjectKey.js.map +1 -0
  44. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.d.ts +2 -0
  45. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js +51 -0
  46. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js.map +1 -0
  47. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.d.ts +2 -0
  48. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js +6 -0
  49. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js.map +1 -0
  50. package/assetDelivery/threatDetection/index.d.ts +2 -0
  51. package/assetDelivery/threatDetection/index.js +4 -0
  52. package/assetDelivery/threatDetection/index.js.map +1 -0
  53. package/assetDelivery/threatDetection/processThreatScanResult.d.ts +3 -0
  54. package/assetDelivery/threatDetection/processThreatScanResult.js +65 -0
  55. package/assetDelivery/threatDetection/processThreatScanResult.js.map +1 -0
  56. package/assetDelivery/threatDetection/types.d.ts +9 -0
  57. package/assetDelivery/threatDetection/types.js +3 -0
  58. package/assetDelivery/threatDetection/types.js.map +1 -0
  59. package/assetDelivery/types.d.ts +10 -0
  60. package/assetDelivery/types.js +3 -0
  61. package/assetDelivery/types.js.map +1 -0
  62. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.d.ts +11 -0
  63. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js +19 -0
  64. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js.map +1 -0
  65. package/enterprise/ApplyThreatScanning/feature.d.ts +1 -0
  66. package/enterprise/ApplyThreatScanning/feature.js +10 -0
  67. package/enterprise/ApplyThreatScanning/feature.js.map +1 -0
  68. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.d.ts +15 -0
  69. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js +36 -0
  70. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js.map +1 -0
  71. package/features/DeleteFileFromBucket/DeleteS3FolderTask.d.ts +31 -0
  72. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js +60 -0
  73. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js.map +1 -0
  74. package/features/DeleteFileFromBucket/feature.d.ts +1 -0
  75. package/features/DeleteFileFromBucket/feature.js +12 -0
  76. package/features/DeleteFileFromBucket/feature.js.map +1 -0
  77. package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +11 -0
  78. package/features/ExtractMetadata/ExtractMetadataHandler.js +26 -0
  79. package/features/ExtractMetadata/ExtractMetadataHandler.js.map +1 -0
  80. package/features/ExtractMetadata/ExtractMetadataTask.d.ts +23 -0
  81. package/features/ExtractMetadata/ExtractMetadataTask.js +128 -0
  82. package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
  83. package/features/ExtractMetadata/feature.d.ts +1 -0
  84. package/features/ExtractMetadata/feature.js +12 -0
  85. package/features/ExtractMetadata/feature.js.map +1 -0
  86. package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +12 -0
  87. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +27 -0
  88. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
  89. package/features/FlushCache/FlushCacheOnFileUpdateHandler.d.ts +12 -0
  90. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js +35 -0
  91. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js.map +1 -0
  92. package/features/FlushCache/InvalidateCacheTask.d.ts +25 -0
  93. package/features/FlushCache/InvalidateCacheTask.js +86 -0
  94. package/features/FlushCache/InvalidateCacheTask.js.map +1 -0
  95. package/features/FlushCache/feature.d.ts +1 -0
  96. package/features/FlushCache/feature.js +14 -0
  97. package/features/FlushCache/feature.js.map +1 -0
  98. package/features/WriteFileMetadata/MetadataReader.d.ts +14 -0
  99. package/features/WriteFileMetadata/MetadataReader.js +14 -0
  100. package/features/WriteFileMetadata/MetadataReader.js.map +1 -0
  101. package/features/WriteFileMetadata/MetadataWriter.d.ts +10 -0
  102. package/features/WriteFileMetadata/MetadataWriter.js +28 -0
  103. package/features/WriteFileMetadata/MetadataWriter.js.map +1 -0
  104. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.d.ts +12 -0
  105. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +21 -0
  106. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -0
  107. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.d.ts +12 -0
  108. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +21 -0
  109. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -0
  110. package/features/WriteFileMetadata/feature.d.ts +1 -0
  111. package/features/WriteFileMetadata/feature.js +12 -0
  112. package/features/WriteFileMetadata/feature.js.map +1 -0
  113. package/graphql/checkPermissions.d.ts +5 -0
  114. package/{plugins → graphql}/checkPermissions.js +4 -11
  115. package/graphql/checkPermissions.js.map +1 -0
  116. package/graphql/schema.d.ts +1 -0
  117. package/{plugins/graphqlFileStorageS3.js → graphql/schema.js} +49 -57
  118. package/graphql/schema.js.map +1 -0
  119. package/index.d.ts +4 -5
  120. package/index.js +21 -32
  121. package/index.js.map +1 -1
  122. package/multiPartUpload/CompleteMultiPartUploadUseCase.d.ts +1 -1
  123. package/multiPartUpload/CompleteMultiPartUploadUseCase.js +4 -11
  124. package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -1
  125. package/multiPartUpload/CreateMultiPartUploadUseCase.d.ts +2 -2
  126. package/multiPartUpload/CreateMultiPartUploadUseCase.js +3 -10
  127. package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -1
  128. package/package.json +23 -29
  129. package/types.d.ts +1 -1
  130. package/types.js +1 -5
  131. package/types.js.map +1 -1
  132. package/utils/CdnPathsGenerator.d.ts +3 -0
  133. package/utils/CdnPathsGenerator.js +7 -0
  134. package/utils/CdnPathsGenerator.js.map +1 -0
  135. package/utils/FileExtension.d.ts +1 -1
  136. package/utils/FileExtension.js +3 -10
  137. package/utils/FileExtension.js.map +1 -1
  138. package/utils/FileKey.d.ts +1 -1
  139. package/utils/FileKey.js +5 -13
  140. package/utils/FileKey.js.map +1 -1
  141. package/utils/FileKey.test.js +8 -9
  142. package/utils/FileKey.test.js.map +1 -1
  143. package/utils/FileNormalizer.d.ts +2 -2
  144. package/utils/FileNormalizer.js +5 -12
  145. package/utils/FileNormalizer.js.map +1 -1
  146. package/utils/FileUploadModifier.d.ts +1 -1
  147. package/utils/FileUploadModifier.js +6 -16
  148. package/utils/FileUploadModifier.js.map +1 -1
  149. package/utils/createFileNormalizerFromContext.d.ts +2 -2
  150. package/utils/createFileNormalizerFromContext.js +5 -12
  151. package/utils/createFileNormalizerFromContext.js.map +1 -1
  152. package/utils/getPresignedPostPayload.d.ts +4 -3
  153. package/utils/getPresignedPostPayload.js +10 -15
  154. package/utils/getPresignedPostPayload.js.map +1 -1
  155. package/utils/mimeTypes.js +5 -13
  156. package/utils/mimeTypes.js.map +1 -1
  157. package/utils/uploadFileToS3.d.ts +1 -3
  158. package/utils/uploadFileToS3.js +7 -20
  159. package/utils/uploadFileToS3.js.map +1 -1
  160. package/assetDelivery/createCustomAssetDelivery.d.ts +0 -12
  161. package/assetDelivery/createCustomAssetDelivery.js +0 -28
  162. package/assetDelivery/createCustomAssetDelivery.js.map +0 -1
  163. package/assetDelivery/customAssets/CustomAsset.d.ts +0 -6
  164. package/assetDelivery/customAssets/CustomAsset.js +0 -14
  165. package/assetDelivery/customAssets/CustomAsset.js.map +0 -1
  166. package/assetDelivery/customAssets/CustomAssetProcessor.d.ts +0 -10
  167. package/assetDelivery/customAssets/CustomAssetProcessor.js +0 -25
  168. package/assetDelivery/customAssets/CustomAssetProcessor.js.map +0 -1
  169. package/assetDelivery/customAssets/S3CustomAssetResolver.d.ts +0 -15
  170. package/assetDelivery/customAssets/S3CustomAssetResolver.js +0 -90
  171. package/assetDelivery/customAssets/S3CustomAssetResolver.js.map +0 -1
  172. package/assetDelivery/customAssets/customAssetDeliveryConfig.d.ts +0 -1
  173. package/assetDelivery/customAssets/customAssetDeliveryConfig.js +0 -30
  174. package/assetDelivery/customAssets/customAssetDeliveryConfig.js.map +0 -1
  175. package/assetDelivery/s3/S3AssetMetadataReader.d.ts +0 -15
  176. package/assetDelivery/s3/S3AssetMetadataReader.js +0 -36
  177. package/assetDelivery/s3/S3AssetMetadataReader.js.map +0 -1
  178. package/assetDelivery/s3/transformation/legacyUtils.d.ts +0 -12
  179. package/assetDelivery/s3/transformation/legacyUtils.js +0 -34
  180. package/assetDelivery/s3/transformation/legacyUtils.js.map +0 -1
  181. package/flushCdnCache/CdnPathsGenerator.d.ts +0 -4
  182. package/flushCdnCache/CdnPathsGenerator.js +0 -14
  183. package/flushCdnCache/CdnPathsGenerator.js.map +0 -1
  184. package/flushCdnCache/InvalidateCacheTask.d.ts +0 -18
  185. package/flushCdnCache/InvalidateCacheTask.js +0 -78
  186. package/flushCdnCache/InvalidateCacheTask.js.map +0 -1
  187. package/flushCdnCache/flushCacheOnFileDelete.d.ts +0 -3
  188. package/flushCdnCache/flushCacheOnFileDelete.js +0 -34
  189. package/flushCdnCache/flushCacheOnFileDelete.js.map +0 -1
  190. package/flushCdnCache/flushCacheOnFileUpdate.d.ts +0 -3
  191. package/flushCdnCache/flushCacheOnFileUpdate.js +0 -40
  192. package/flushCdnCache/flushCacheOnFileUpdate.js.map +0 -1
  193. package/flushCdnCache/index.d.ts +0 -1
  194. package/flushCdnCache/index.js +0 -15
  195. package/flushCdnCache/index.js.map +0 -1
  196. package/flushCdnCache/invalidateCacheTaskDefinition.d.ts +0 -2
  197. package/flushCdnCache/invalidateCacheTaskDefinition.js +0 -22
  198. package/flushCdnCache/invalidateCacheTaskDefinition.js.map +0 -1
  199. package/plugins/addFileMetadata.d.ts +0 -10
  200. package/plugins/addFileMetadata.js +0 -67
  201. package/plugins/addFileMetadata.js.map +0 -1
  202. package/plugins/checkPermissions.d.ts +0 -4
  203. package/plugins/checkPermissions.js.map +0 -1
  204. package/plugins/fileStorageS3.d.ts +0 -3
  205. package/plugins/fileStorageS3.js +0 -60
  206. package/plugins/fileStorageS3.js.map +0 -1
  207. package/plugins/graphqlFileStorageS3.d.ts +0 -4
  208. package/plugins/graphqlFileStorageS3.js.map +0 -1
@@ -0,0 +1,4 @@
1
+ export * from "./createThreatDetectionEventHandler.js";
2
+ export * from "./createThreatDetectionPluginLoader.js";
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./createThreatDetectionEventHandler.js\";\nexport * from \"./createThreatDetectionPluginLoader.js\";\n"],"mappings":"AAAA;AACA","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ import type { ApiCoreContext } from "@webiny/api-core/types/core.js";
2
+ import type { GuardDutyEvent } from "./types.js";
3
+ export declare const processThreatScanResult: (context: ApiCoreContext, eventDetail: GuardDutyEvent) => Promise<void>;
@@ -0,0 +1,65 @@
1
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
2
+ import { DeleteFileUseCase } from "@webiny/api-file-manager/features/file/DeleteFile/index.js";
3
+ import { WebsocketService } from "@webiny/api-websockets/features/WebsocketService/index.js";
4
+ import { ObjectKey } from "./ObjectKey.js";
5
+ import { GetFileUseCase } from "@webiny/api-file-manager/features/file/GetFile/index.js";
6
+ export const processThreatScanResult = async (context, eventDetail) => {
7
+ const websocketService = context.container.resolve(WebsocketService);
8
+ const getFile = context.container.resolve(GetFileUseCase);
9
+ const updateFile = context.container.resolve(UpdateFileUseCase);
10
+ const deleteFile = context.container.resolve(DeleteFileUseCase);
11
+ await context.security.withoutAuthorization(async () => {
12
+ const scanStatus = eventDetail.scanResultDetails.scanResultStatus;
13
+ const s3Object = eventDetail.s3ObjectDetails;
14
+ const fileId = ObjectKey.from(s3Object.objectKey).id();
15
+ const fileResult = await getFile.execute(fileId);
16
+ if (fileResult.isFail()) {
17
+ return;
18
+ }
19
+ const file = fileResult.value;
20
+ let allConnections = [];
21
+ const connectionsResult = await websocketService.listConnections();
22
+ if (connectionsResult.isOk()) {
23
+ allConnections = connectionsResult.value;
24
+ }
25
+ if (scanStatus === "NO_THREATS_FOUND") {
26
+ const newTags = file.tags.filter(tag => tag !== "threatScanInProgress");
27
+ await updateFile.execute({
28
+ id: file.id,
29
+ tags: newTags
30
+ });
31
+ await websocketService.sendToConnections(allConnections, {
32
+ action: "fm.threatScan.noThreatFound",
33
+ data: {
34
+ id: file.id,
35
+ tags: newTags
36
+ }
37
+ });
38
+ return;
39
+ }
40
+ if (scanStatus === "THREATS_FOUND") {
41
+ // Delete the infected file.
42
+ await deleteFile.execute(file.id);
43
+ await websocketService.sendToConnections(allConnections, {
44
+ action: "fm.threatScan.threatDetected",
45
+ data: {
46
+ id: file.id,
47
+ name: file.name
48
+ }
49
+ });
50
+ return;
51
+ }
52
+
53
+ // For all other outcomes, we delete the file, until better logic is implemented.
54
+ await deleteFile.execute(file.id);
55
+ await websocketService.sendToConnections(allConnections, {
56
+ action: "fm.threatScan.unsupported",
57
+ data: {
58
+ id: file.id,
59
+ name: file.name
60
+ }
61
+ });
62
+ });
63
+ };
64
+
65
+ //# sourceMappingURL=processThreatScanResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UpdateFileUseCase","DeleteFileUseCase","WebsocketService","ObjectKey","GetFileUseCase","processThreatScanResult","context","eventDetail","websocketService","container","resolve","getFile","updateFile","deleteFile","security","withoutAuthorization","scanStatus","scanResultDetails","scanResultStatus","s3Object","s3ObjectDetails","fileId","from","objectKey","id","fileResult","execute","isFail","file","value","allConnections","connectionsResult","listConnections","isOk","newTags","tags","filter","tag","sendToConnections","action","data","name"],"sources":["processThreatScanResult.ts"],"sourcesContent":["import type { ApiCoreContext } from \"@webiny/api-core/types/core.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { DeleteFileUseCase } from \"@webiny/api-file-manager/features/file/DeleteFile/index.js\";\nimport { WebsocketService } from \"@webiny/api-websockets/features/WebsocketService/index.js\";\nimport type { GuardDutyEvent } from \"./types.js\";\nimport { ObjectKey } from \"./ObjectKey.js\";\nimport { GetFileUseCase } from \"@webiny/api-file-manager/features/file/GetFile/index.js\";\n\nexport const processThreatScanResult = async (\n context: ApiCoreContext,\n eventDetail: GuardDutyEvent\n) => {\n const websocketService = context.container.resolve(WebsocketService);\n const getFile = context.container.resolve(GetFileUseCase);\n const updateFile = context.container.resolve(UpdateFileUseCase);\n const deleteFile = context.container.resolve(DeleteFileUseCase);\n\n await context.security.withoutAuthorization(async () => {\n const scanStatus = eventDetail.scanResultDetails.scanResultStatus;\n const s3Object = eventDetail.s3ObjectDetails;\n\n const fileId = ObjectKey.from(s3Object.objectKey).id();\n const fileResult = await getFile.execute(fileId);\n\n if (fileResult.isFail()) {\n return;\n }\n\n const file = fileResult.value;\n\n let allConnections: WebsocketService.Connection[] = [];\n const connectionsResult = await websocketService.listConnections();\n if (connectionsResult.isOk()) {\n allConnections = connectionsResult.value;\n }\n\n if (scanStatus === \"NO_THREATS_FOUND\") {\n const newTags = file.tags.filter(tag => tag !== \"threatScanInProgress\");\n await updateFile.execute({\n id: file.id,\n tags: newTags\n });\n\n await websocketService.sendToConnections(allConnections, {\n action: \"fm.threatScan.noThreatFound\",\n data: {\n id: file.id,\n tags: newTags\n }\n });\n\n return;\n }\n\n if (scanStatus === \"THREATS_FOUND\") {\n // Delete the infected file.\n await deleteFile.execute(file.id);\n\n await websocketService.sendToConnections(allConnections, {\n action: \"fm.threatScan.threatDetected\",\n data: {\n id: file.id,\n name: file.name\n }\n });\n\n return;\n }\n\n // For all other outcomes, we delete the file, until better logic is implemented.\n await deleteFile.execute(file.id);\n\n await websocketService.sendToConnections(allConnections, {\n action: \"fm.threatScan.unsupported\",\n data: {\n id: file.id,\n name: file.name\n }\n });\n });\n};\n"],"mappings":"AACA,SAASA,iBAAiB,QAAQ,4DAA4D;AAC9F,SAASC,iBAAiB,QAAQ,4DAA4D;AAC9F,SAASC,gBAAgB,QAAQ,2DAA2D;AAE5F,SAASC,SAAS;AAClB,SAASC,cAAc,QAAQ,yDAAyD;AAExF,OAAO,MAAMC,uBAAuB,GAAG,MAAAA,CACnCC,OAAuB,EACvBC,WAA2B,KAC1B;EACD,MAAMC,gBAAgB,GAAGF,OAAO,CAACG,SAAS,CAACC,OAAO,CAACR,gBAAgB,CAAC;EACpE,MAAMS,OAAO,GAAGL,OAAO,CAACG,SAAS,CAACC,OAAO,CAACN,cAAc,CAAC;EACzD,MAAMQ,UAAU,GAAGN,OAAO,CAACG,SAAS,CAACC,OAAO,CAACV,iBAAiB,CAAC;EAC/D,MAAMa,UAAU,GAAGP,OAAO,CAACG,SAAS,CAACC,OAAO,CAACT,iBAAiB,CAAC;EAE/D,MAAMK,OAAO,CAACQ,QAAQ,CAACC,oBAAoB,CAAC,YAAY;IACpD,MAAMC,UAAU,GAAGT,WAAW,CAACU,iBAAiB,CAACC,gBAAgB;IACjE,MAAMC,QAAQ,GAAGZ,WAAW,CAACa,eAAe;IAE5C,MAAMC,MAAM,GAAGlB,SAAS,CAACmB,IAAI,CAACH,QAAQ,CAACI,SAAS,CAAC,CAACC,EAAE,CAAC,CAAC;IACtD,MAAMC,UAAU,GAAG,MAAMd,OAAO,CAACe,OAAO,CAACL,MAAM,CAAC;IAEhD,IAAII,UAAU,CAACE,MAAM,CAAC,CAAC,EAAE;MACrB;IACJ;IAEA,MAAMC,IAAI,GAAGH,UAAU,CAACI,KAAK;IAE7B,IAAIC,cAA6C,GAAG,EAAE;IACtD,MAAMC,iBAAiB,GAAG,MAAMvB,gBAAgB,CAACwB,eAAe,CAAC,CAAC;IAClE,IAAID,iBAAiB,CAACE,IAAI,CAAC,CAAC,EAAE;MAC1BH,cAAc,GAAGC,iBAAiB,CAACF,KAAK;IAC5C;IAEA,IAAIb,UAAU,KAAK,kBAAkB,EAAE;MACnC,MAAMkB,OAAO,GAAGN,IAAI,CAACO,IAAI,CAACC,MAAM,CAACC,GAAG,IAAIA,GAAG,KAAK,sBAAsB,CAAC;MACvE,MAAMzB,UAAU,CAACc,OAAO,CAAC;QACrBF,EAAE,EAAEI,IAAI,CAACJ,EAAE;QACXW,IAAI,EAAED;MACV,CAAC,CAAC;MAEF,MAAM1B,gBAAgB,CAAC8B,iBAAiB,CAACR,cAAc,EAAE;QACrDS,MAAM,EAAE,6BAA6B;QACrCC,IAAI,EAAE;UACFhB,EAAE,EAAEI,IAAI,CAACJ,EAAE;UACXW,IAAI,EAAED;QACV;MACJ,CAAC,CAAC;MAEF;IACJ;IAEA,IAAIlB,UAAU,KAAK,eAAe,EAAE;MAChC;MACA,MAAMH,UAAU,CAACa,OAAO,CAACE,IAAI,CAACJ,EAAE,CAAC;MAEjC,MAAMhB,gBAAgB,CAAC8B,iBAAiB,CAACR,cAAc,EAAE;QACrDS,MAAM,EAAE,8BAA8B;QACtCC,IAAI,EAAE;UACFhB,EAAE,EAAEI,IAAI,CAACJ,EAAE;UACXiB,IAAI,EAAEb,IAAI,CAACa;QACf;MACJ,CAAC,CAAC;MAEF;IACJ;;IAEA;IACA,MAAM5B,UAAU,CAACa,OAAO,CAACE,IAAI,CAACJ,EAAE,CAAC;IAEjC,MAAMhB,gBAAgB,CAAC8B,iBAAiB,CAACR,cAAc,EAAE;MACrDS,MAAM,EAAE,2BAA2B;MACnCC,IAAI,EAAE;QACFhB,EAAE,EAAEI,IAAI,CAACJ,EAAE;QACXiB,IAAI,EAAEb,IAAI,CAACa;MACf;IACJ,CAAC,CAAC;EACN,CAAC,CAAC;AACN,CAAC","ignoreList":[]}
@@ -0,0 +1,9 @@
1
+ export type GuardDutyEvent = {
2
+ scanResultDetails: {
3
+ scanResultStatus: "UNSUPPORTED" | "FAILED" | "ACCESS_DENIED" | "THREATS_FOUND" | "NO_THREATS_FOUND";
4
+ };
5
+ s3ObjectDetails: {
6
+ bucketName: string;
7
+ objectKey: string;
8
+ };
9
+ };
@@ -0,0 +1,3 @@
1
+ export {};
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export type GuardDutyEvent = {\n scanResultDetails: {\n scanResultStatus:\n | \"UNSUPPORTED\"\n | \"FAILED\"\n | \"ACCESS_DENIED\"\n | \"THREATS_FOUND\"\n | \"NO_THREATS_FOUND\";\n };\n s3ObjectDetails: {\n bucketName: string;\n objectKey: string;\n };\n};\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ export type AssetDeliveryParams = {
2
+ imageResizeWidths?: number[];
3
+ /**
4
+ * BE CAREFUL!
5
+ * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.
6
+ * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration
7
+ */
8
+ presignedUrlTtl?: number;
9
+ assetStreamingMaxSize?: number;
10
+ };
@@ -0,0 +1,3 @@
1
+ export {};
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["export type AssetDeliveryParams = {\n imageResizeWidths?: number[];\n /**\n * BE CAREFUL!\n * Setting this to more than 1 hour may cause your URLs to still expire before the desired expiration time.\n * @see https://repost.aws/knowledge-center/presigned-url-s3-bucket-expiration\n */\n presignedUrlTtl?: number;\n assetStreamingMaxSize?: number;\n};\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { CreateFileUseCase } from "@webiny/api-file-manager/features/file/CreateFile/abstractions.js";
2
+ import type { CreateFileInput } from "@webiny/api-file-manager/features/file/CreateFile/abstractions.js";
3
+ declare class CreateFileWithThreatScanDecoratorImpl implements CreateFileUseCase.Interface {
4
+ private decoratee;
5
+ constructor(decoratee: CreateFileUseCase.Interface);
6
+ execute(input: CreateFileInput, meta?: Record<string, any>): ReturnType<CreateFileUseCase.Interface["execute"]>;
7
+ }
8
+ export declare const CreateFileWithThreatScanDecorator: typeof CreateFileWithThreatScanDecoratorImpl & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/file/CreateFile/abstractions.js").ICreateFileUseCase>;
10
+ };
11
+ export {};
@@ -0,0 +1,19 @@
1
+ import { CreateFileUseCase } from "@webiny/api-file-manager/features/file/CreateFile/abstractions.js";
2
+ class CreateFileWithThreatScanDecoratorImpl {
3
+ constructor(decoratee) {
4
+ this.decoratee = decoratee;
5
+ }
6
+ async execute(input, meta) {
7
+ const modifiedInput = {
8
+ ...input,
9
+ tags: [...(input.tags || []), "threatScanInProgress"]
10
+ };
11
+ return this.decoratee.execute(modifiedInput, meta);
12
+ }
13
+ }
14
+ export const CreateFileWithThreatScanDecorator = CreateFileUseCase.createDecorator({
15
+ decorator: CreateFileWithThreatScanDecoratorImpl,
16
+ dependencies: []
17
+ });
18
+
19
+ //# sourceMappingURL=CreateFileWithThreatScanDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["CreateFileUseCase","CreateFileWithThreatScanDecoratorImpl","constructor","decoratee","execute","input","meta","modifiedInput","tags","CreateFileWithThreatScanDecorator","createDecorator","decorator","dependencies"],"sources":["CreateFileWithThreatScanDecorator.ts"],"sourcesContent":["import { CreateFileUseCase } from \"@webiny/api-file-manager/features/file/CreateFile/abstractions.js\";\nimport type { CreateFileInput } from \"@webiny/api-file-manager/features/file/CreateFile/abstractions.js\";\n\nclass CreateFileWithThreatScanDecoratorImpl implements CreateFileUseCase.Interface {\n constructor(private decoratee: CreateFileUseCase.Interface) {}\n\n async execute(\n input: CreateFileInput,\n meta?: Record<string, any>\n ): ReturnType<CreateFileUseCase.Interface[\"execute\"]> {\n const modifiedInput: CreateFileInput = {\n ...input,\n tags: [...(input.tags || []), \"threatScanInProgress\"]\n };\n\n return this.decoratee.execute(modifiedInput, meta);\n }\n}\n\nexport const CreateFileWithThreatScanDecorator = CreateFileUseCase.createDecorator({\n decorator: CreateFileWithThreatScanDecoratorImpl,\n dependencies: []\n});\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,mEAAmE;AAGrG,MAAMC,qCAAqC,CAAwC;EAC/EC,WAAWA,CAASC,SAAsC,EAAE;IAAA,KAAxCA,SAAsC,GAAtCA,SAAsC;EAAG;EAE7D,MAAMC,OAAOA,CACTC,KAAsB,EACtBC,IAA0B,EACwB;IAClD,MAAMC,aAA8B,GAAG;MACnC,GAAGF,KAAK;MACRG,IAAI,EAAE,CAAC,IAAIH,KAAK,CAACG,IAAI,IAAI,EAAE,CAAC,EAAE,sBAAsB;IACxD,CAAC;IAED,OAAO,IAAI,CAACL,SAAS,CAACC,OAAO,CAACG,aAAa,EAAED,IAAI,CAAC;EACtD;AACJ;AAEA,OAAO,MAAMG,iCAAiC,GAAGT,iBAAiB,CAACU,eAAe,CAAC;EAC/EC,SAAS,EAAEV,qCAAqC;EAChDW,YAAY,EAAE;AAClB,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export declare const ApplyThreatScanningFeature: import("@webiny/feature/api/createFeature.js").FeatureDefinition<unknown>;
@@ -0,0 +1,10 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { CreateFileWithThreatScanDecorator } from "./CreateFileWithThreatScanDecorator.js";
3
+ export const ApplyThreatScanningFeature = createFeature({
4
+ name: "FileManagerS3/ApplyThreatScanning",
5
+ register(container) {
6
+ container.registerDecorator(CreateFileWithThreatScanDecorator);
7
+ }
8
+ });
9
+
10
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createFeature","CreateFileWithThreatScanDecorator","ApplyThreatScanningFeature","name","register","container","registerDecorator"],"sources":["feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CreateFileWithThreatScanDecorator } from \"./CreateFileWithThreatScanDecorator.js\";\n\nexport const ApplyThreatScanningFeature = createFeature({\n name: \"FileManagerS3/ApplyThreatScanning\",\n register(container) {\n container.registerDecorator(CreateFileWithThreatScanDecorator);\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,iCAAiC;AAE1C,OAAO,MAAMC,0BAA0B,GAAGF,aAAa,CAAC;EACpDG,IAAI,EAAE,mCAAmC;EACzCC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACC,iBAAiB,CAACL,iCAAiC,CAAC;EAClE;AACJ,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ import { FileAfterDeleteHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ declare class DeleteFileFromBucketHandlerImpl implements FileAfterDeleteHandler.Interface {
6
+ private tenantContext;
7
+ private taskService;
8
+ private keyValueStore;
9
+ constructor(tenantContext: TenantContext.Interface, taskService: TaskService.Interface, keyValueStore: GlobalKeyValueStore.Interface);
10
+ handle(event: FileAfterDeleteHandler.Event): Promise<void>;
11
+ }
12
+ export declare const DeleteFileFromBucketHandler: typeof DeleteFileFromBucketHandlerImpl & {
13
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/EventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/DeleteFile/events.js").FileAfterDeleteEvent>>;
14
+ };
15
+ export {};
@@ -0,0 +1,36 @@
1
+ import { FileAfterDeleteHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ class DeleteFileFromBucketHandlerImpl {
6
+ constructor(tenantContext, taskService, keyValueStore) {
7
+ this.tenantContext = tenantContext;
8
+ this.taskService = taskService;
9
+ this.keyValueStore = keyValueStore;
10
+ }
11
+ async handle(event) {
12
+ const {
13
+ file
14
+ } = event.payload;
15
+ const tenant = this.tenantContext.getTenant();
16
+
17
+ // Delete S3 folder recursively
18
+ await this.taskService.trigger({
19
+ definition: "fileManagerFolderDelete",
20
+ input: {
21
+ caller: "fm-after-delete",
22
+ bucket: String(process.env.S3_BUCKET),
23
+ folderKey: `tenants/${tenant.id}/files/${file.id}`
24
+ }
25
+ });
26
+
27
+ // Delete file metadata
28
+ await this.keyValueStore.delete(`FileManager/File/${file.id}/Metadata`);
29
+ }
30
+ }
31
+ export const DeleteFileFromBucketHandler = FileAfterDeleteHandler.createImplementation({
32
+ implementation: DeleteFileFromBucketHandlerImpl,
33
+ dependencies: [TenantContext, TaskService, GlobalKeyValueStore]
34
+ });
35
+
36
+ //# sourceMappingURL=DeleteFileFromBucketHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FileAfterDeleteHandler","TaskService","GlobalKeyValueStore","TenantContext","DeleteFileFromBucketHandlerImpl","constructor","tenantContext","taskService","keyValueStore","handle","event","file","payload","tenant","getTenant","trigger","definition","input","caller","bucket","String","process","env","S3_BUCKET","folderKey","id","delete","DeleteFileFromBucketHandler","createImplementation","implementation","dependencies"],"sources":["DeleteFileFromBucketHandler.ts"],"sourcesContent":["import { FileAfterDeleteHandler } from \"@webiny/api-file-manager/features/file/DeleteFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport type { DeleteS3FolderInput } from \"~/features/DeleteFileFromBucket/DeleteS3FolderTask.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\n\nclass DeleteFileFromBucketHandlerImpl implements FileAfterDeleteHandler.Interface {\n constructor(\n private tenantContext: TenantContext.Interface,\n private taskService: TaskService.Interface,\n private keyValueStore: GlobalKeyValueStore.Interface\n ) {}\n\n async handle(event: FileAfterDeleteHandler.Event): Promise<void> {\n const { file } = event.payload;\n const tenant = this.tenantContext.getTenant();\n\n // Delete S3 folder recursively\n await this.taskService.trigger<DeleteS3FolderInput>({\n definition: \"fileManagerFolderDelete\",\n input: {\n caller: \"fm-after-delete\",\n bucket: String(process.env.S3_BUCKET),\n folderKey: `tenants/${tenant.id}/files/${file.id}`\n }\n });\n\n // Delete file metadata\n await this.keyValueStore.delete(`FileManager/File/${file.id}/Metadata`);\n }\n}\n\nexport const DeleteFileFromBucketHandler = FileAfterDeleteHandler.createImplementation({\n implementation: DeleteFileFromBucketHandlerImpl,\n dependencies: [TenantContext, TaskService, GlobalKeyValueStore]\n});\n"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,6DAA6D;AACpG,SAASC,WAAW,QAAQ,qDAAqD;AACjF,SAASC,mBAAmB,QAAQ,kDAAkD;AAEtF,SAASC,aAAa,QAAQ,0DAA0D;AAExF,MAAMC,+BAA+B,CAA6C;EAC9EC,WAAWA,CACCC,aAAsC,EACtCC,WAAkC,EAClCC,aAA4C,EACtD;IAAA,KAHUF,aAAsC,GAAtCA,aAAsC;IAAA,KACtCC,WAAkC,GAAlCA,WAAkC;IAAA,KAClCC,aAA4C,GAA5CA,aAA4C;EACrD;EAEH,MAAMC,MAAMA,CAACC,KAAmC,EAAiB;IAC7D,MAAM;MAAEC;IAAK,CAAC,GAAGD,KAAK,CAACE,OAAO;IAC9B,MAAMC,MAAM,GAAG,IAAI,CAACP,aAAa,CAACQ,SAAS,CAAC,CAAC;;IAE7C;IACA,MAAM,IAAI,CAACP,WAAW,CAACQ,OAAO,CAAsB;MAChDC,UAAU,EAAE,yBAAyB;MACrCC,KAAK,EAAE;QACHC,MAAM,EAAE,iBAAiB;QACzBC,MAAM,EAAEC,MAAM,CAACC,OAAO,CAACC,GAAG,CAACC,SAAS,CAAC;QACrCC,SAAS,EAAE,WAAWX,MAAM,CAACY,EAAE,UAAUd,IAAI,CAACc,EAAE;MACpD;IACJ,CAAC,CAAC;;IAEF;IACA,MAAM,IAAI,CAACjB,aAAa,CAACkB,MAAM,CAAC,oBAAoBf,IAAI,CAACc,EAAE,WAAW,CAAC;EAC3E;AACJ;AAEA,OAAO,MAAME,2BAA2B,GAAG3B,sBAAsB,CAAC4B,oBAAoB,CAAC;EACnFC,cAAc,EAAEzB,+BAA+B;EAC/C0B,YAAY,EAAE,CAAC3B,aAAa,EAAEF,WAAW,EAAEC,mBAAmB;AAClE,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
+ export interface DeleteS3FolderInput {
3
+ /**
4
+ * Caller of the task (e.g., `fm-after-delete`).
5
+ */
6
+ caller: string;
7
+ /**
8
+ * Cache paths to invalidate.
9
+ */
10
+ bucket: string;
11
+ /**
12
+ * FM file directory key to delete.
13
+ */
14
+ folderKey: string;
15
+ /**
16
+ * Continuation token for pagination.
17
+ */
18
+ continuationToken?: string;
19
+ }
20
+ declare class DeleteS3FolderTask implements TaskDefinition.Interface<DeleteS3FolderInput> {
21
+ id: string;
22
+ title: string;
23
+ description: string;
24
+ maxIterations: number;
25
+ isPrivate: boolean;
26
+ run({ input, controller }: TaskDefinition.RunParams<DeleteS3FolderInput>): Promise<TaskDefinition.Result<DeleteS3FolderInput>>;
27
+ }
28
+ export declare const DeleteS3FolderTaskDefinition: typeof DeleteS3FolderTask & {
29
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
30
+ };
31
+ export {};
@@ -0,0 +1,60 @@
1
+ import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
3
+ class DeleteS3FolderTask {
4
+ id = "fileManagerFolderDelete";
5
+ title = "Delete folder and all of its contents from the bucket.";
6
+ description = "A task to delete all files from a given folder.";
7
+ maxIterations = 5;
8
+ isPrivate = true;
9
+ async run({
10
+ input,
11
+ controller
12
+ }) {
13
+ if (controller.runtime.isAborted()) {
14
+ return controller.response.aborted();
15
+ }
16
+ if (!input.bucket) {
17
+ return controller.response.error({
18
+ message: `Bucket is not defined.`
19
+ });
20
+ }
21
+ const s3 = new S3();
22
+
23
+ // List objects in the folder with pagination support.
24
+ const filesList = await s3.listObjectsV2({
25
+ Bucket: input.bucket,
26
+ Prefix: `${input.folderKey}/`,
27
+ ContinuationToken: input.continuationToken
28
+ });
29
+
30
+ // Delete all files in the folder using batch delete.
31
+ if (filesList.Contents && filesList.Contents.length > 0) {
32
+ const objectsToDelete = filesList.Contents.filter(file => file.Key).map(file => ({
33
+ Key: file.Key
34
+ }));
35
+ if (objectsToDelete.length > 0) {
36
+ await s3.deleteObjects({
37
+ Bucket: input.bucket,
38
+ Delete: {
39
+ Objects: objectsToDelete
40
+ }
41
+ });
42
+ }
43
+ }
44
+
45
+ // If there are more objects to delete, continue in the next iteration.
46
+ if (filesList.IsTruncated && filesList.NextContinuationToken) {
47
+ return controller.response.continue({
48
+ ...input,
49
+ continuationToken: filesList.NextContinuationToken
50
+ });
51
+ }
52
+ return controller.response.done();
53
+ }
54
+ }
55
+ export const DeleteS3FolderTaskDefinition = TaskDefinition.createImplementation({
56
+ implementation: DeleteS3FolderTask,
57
+ dependencies: []
58
+ });
59
+
60
+ //# sourceMappingURL=DeleteS3FolderTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["S3","TaskDefinition","DeleteS3FolderTask","id","title","description","maxIterations","isPrivate","run","input","controller","runtime","isAborted","response","aborted","bucket","error","message","s3","filesList","listObjectsV2","Bucket","Prefix","folderKey","ContinuationToken","continuationToken","Contents","length","objectsToDelete","filter","file","Key","map","deleteObjects","Delete","Objects","IsTruncated","NextContinuationToken","continue","done","DeleteS3FolderTaskDefinition","createImplementation","implementation","dependencies"],"sources":["DeleteS3FolderTask.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface DeleteS3FolderInput {\n /**\n * Caller of the task (e.g., `fm-after-delete`).\n */\n caller: string;\n /**\n * Cache paths to invalidate.\n */\n bucket: string;\n /**\n * FM file directory key to delete.\n */\n folderKey: string;\n /**\n * Continuation token for pagination.\n */\n continuationToken?: string;\n}\n\nclass DeleteS3FolderTask implements TaskDefinition.Interface<DeleteS3FolderInput> {\n id = \"fileManagerFolderDelete\";\n title = \"Delete folder and all of its contents from the bucket.\";\n description = \"A task to delete all files from a given folder.\";\n maxIterations = 5;\n isPrivate = true;\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<DeleteS3FolderInput>): Promise<\n TaskDefinition.Result<DeleteS3FolderInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n if (!input.bucket) {\n return controller.response.error({ message: `Bucket is not defined.` });\n }\n\n const s3 = new S3();\n\n // List objects in the folder with pagination support.\n const filesList = await s3.listObjectsV2({\n Bucket: input.bucket,\n Prefix: `${input.folderKey}/`,\n ContinuationToken: input.continuationToken\n });\n\n // Delete all files in the folder using batch delete.\n if (filesList.Contents && filesList.Contents.length > 0) {\n const objectsToDelete = filesList.Contents.filter(file => file.Key).map(file => ({\n Key: file.Key!\n }));\n\n if (objectsToDelete.length > 0) {\n await s3.deleteObjects({\n Bucket: input.bucket,\n Delete: {\n Objects: objectsToDelete\n }\n });\n }\n }\n\n // If there are more objects to delete, continue in the next iteration.\n if (filesList.IsTruncated && filesList.NextContinuationToken) {\n return controller.response.continue({\n ...input,\n continuationToken: filesList.NextContinuationToken\n });\n }\n\n return controller.response.done();\n }\n}\n\nexport const DeleteS3FolderTaskDefinition = TaskDefinition.createImplementation({\n implementation: DeleteS3FolderTask,\n dependencies: []\n});\n"],"mappings":"AAAA,SAASA,EAAE,QAAQ,oCAAoC;AACvD,SAASC,cAAc,QAAQ,wDAAwD;AAqBvF,MAAMC,kBAAkB,CAA0D;EAC9EC,EAAE,GAAG,yBAAyB;EAC9BC,KAAK,GAAG,wDAAwD;EAChEC,WAAW,GAAG,iDAAiD;EAC/DC,aAAa,GAAG,CAAC;EACjBC,SAAS,GAAG,IAAI;EAEhB,MAAaC,GAAGA,CAAC;IACbC,KAAK;IACLC;EAC2C,CAAC,EAE9C;IACE,IAAIA,UAAU,CAACC,OAAO,CAACC,SAAS,CAAC,CAAC,EAAE;MAChC,OAAOF,UAAU,CAACG,QAAQ,CAACC,OAAO,CAAC,CAAC;IACxC;IAEA,IAAI,CAACL,KAAK,CAACM,MAAM,EAAE;MACf,OAAOL,UAAU,CAACG,QAAQ,CAACG,KAAK,CAAC;QAAEC,OAAO,EAAE;MAAyB,CAAC,CAAC;IAC3E;IAEA,MAAMC,EAAE,GAAG,IAAIlB,EAAE,CAAC,CAAC;;IAEnB;IACA,MAAMmB,SAAS,GAAG,MAAMD,EAAE,CAACE,aAAa,CAAC;MACrCC,MAAM,EAAEZ,KAAK,CAACM,MAAM;MACpBO,MAAM,EAAE,GAAGb,KAAK,CAACc,SAAS,GAAG;MAC7BC,iBAAiB,EAAEf,KAAK,CAACgB;IAC7B,CAAC,CAAC;;IAEF;IACA,IAAIN,SAAS,CAACO,QAAQ,IAAIP,SAAS,CAACO,QAAQ,CAACC,MAAM,GAAG,CAAC,EAAE;MACrD,MAAMC,eAAe,GAAGT,SAAS,CAACO,QAAQ,CAACG,MAAM,CAACC,IAAI,IAAIA,IAAI,CAACC,GAAG,CAAC,CAACC,GAAG,CAACF,IAAI,KAAK;QAC7EC,GAAG,EAAED,IAAI,CAACC;MACd,CAAC,CAAC,CAAC;MAEH,IAAIH,eAAe,CAACD,MAAM,GAAG,CAAC,EAAE;QAC5B,MAAMT,EAAE,CAACe,aAAa,CAAC;UACnBZ,MAAM,EAAEZ,KAAK,CAACM,MAAM;UACpBmB,MAAM,EAAE;YACJC,OAAO,EAAEP;UACb;QACJ,CAAC,CAAC;MACN;IACJ;;IAEA;IACA,IAAIT,SAAS,CAACiB,WAAW,IAAIjB,SAAS,CAACkB,qBAAqB,EAAE;MAC1D,OAAO3B,UAAU,CAACG,QAAQ,CAACyB,QAAQ,CAAC;QAChC,GAAG7B,KAAK;QACRgB,iBAAiB,EAAEN,SAAS,CAACkB;MACjC,CAAC,CAAC;IACN;IAEA,OAAO3B,UAAU,CAACG,QAAQ,CAAC0B,IAAI,CAAC,CAAC;EACrC;AACJ;AAEA,OAAO,MAAMC,4BAA4B,GAAGvC,cAAc,CAACwC,oBAAoB,CAAC;EAC5EC,cAAc,EAAExC,kBAAkB;EAClCyC,YAAY,EAAE;AAClB,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export declare const DeleteFileFromBucketFeature: import("@webiny/feature/api/createFeature.js").FeatureDefinition<unknown>;
@@ -0,0 +1,12 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { DeleteFileFromBucketHandler } from "./DeleteFileFromBucketHandler.js";
3
+ import { DeleteS3FolderTaskDefinition } from "./DeleteS3FolderTask.js";
4
+ export const DeleteFileFromBucketFeature = createFeature({
5
+ name: "FileManagerS3/DeleteFileFromBucket",
6
+ register(container) {
7
+ container.register(DeleteFileFromBucketHandler);
8
+ container.register(DeleteS3FolderTaskDefinition);
9
+ }
10
+ });
11
+
12
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createFeature","DeleteFileFromBucketHandler","DeleteS3FolderTaskDefinition","DeleteFileFromBucketFeature","name","register","container"],"sources":["feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { DeleteFileFromBucketHandler } from \"./DeleteFileFromBucketHandler.js\";\nimport { DeleteS3FolderTaskDefinition } from \"./DeleteS3FolderTask.js\";\n\nexport const DeleteFileFromBucketFeature = createFeature({\n name: \"FileManagerS3/DeleteFileFromBucket\",\n register(container) {\n container.register(DeleteFileFromBucketHandler);\n container.register(DeleteS3FolderTaskDefinition);\n }\n});\n"],"mappings":"AAAA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,2BAA2B;AACpC,SAASC,4BAA4B;AAErC,OAAO,MAAMC,2BAA2B,GAAGH,aAAa,CAAC;EACrDI,IAAI,EAAE,oCAAoC;EAC1CC,QAAQA,CAACC,SAAS,EAAE;IAChBA,SAAS,CAACD,QAAQ,CAACJ,2BAA2B,CAAC;IAC/CK,SAAS,CAACD,QAAQ,CAACH,4BAA4B,CAAC;EACpD;AACJ,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { FileAfterCreateHandler } from "@webiny/api-file-manager/features/file/CreateFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ declare class ExtractMetadataHandlerImpl implements FileAfterCreateHandler.Interface {
4
+ private taskService;
5
+ constructor(taskService: TaskService.Interface);
6
+ handle(event: FileAfterCreateHandler.Event): Promise<void>;
7
+ }
8
+ export declare const ExtractMetadataHandler: typeof ExtractMetadataHandlerImpl & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/EventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/CreateFile/events.js").FileAfterCreateEvent>>;
10
+ };
11
+ export {};
@@ -0,0 +1,26 @@
1
+ import { FileAfterCreateHandler } from "@webiny/api-file-manager/features/file/CreateFile/events.js";
2
+ import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
3
+ class ExtractMetadataHandlerImpl {
4
+ constructor(taskService) {
5
+ this.taskService = taskService;
6
+ }
7
+ async handle(event) {
8
+ const {
9
+ file
10
+ } = event.payload;
11
+
12
+ // Trigger the metadata extraction task
13
+ await this.taskService.trigger({
14
+ definition: "fileManagerExtractMetadata",
15
+ input: {
16
+ fileId: file.id
17
+ }
18
+ });
19
+ }
20
+ }
21
+ export const ExtractMetadataHandler = FileAfterCreateHandler.createImplementation({
22
+ implementation: ExtractMetadataHandlerImpl,
23
+ dependencies: [TaskService]
24
+ });
25
+
26
+ //# sourceMappingURL=ExtractMetadataHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FileAfterCreateHandler","TaskService","ExtractMetadataHandlerImpl","constructor","taskService","handle","event","file","payload","trigger","definition","input","fileId","id","ExtractMetadataHandler","createImplementation","implementation","dependencies"],"sources":["ExtractMetadataHandler.ts"],"sourcesContent":["import { FileAfterCreateHandler } from \"@webiny/api-file-manager/features/file/CreateFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport type { ExtractMetadataInput } from \"./ExtractMetadataTask.js\";\n\nclass ExtractMetadataHandlerImpl implements FileAfterCreateHandler.Interface {\n constructor(private taskService: TaskService.Interface) {}\n\n async handle(event: FileAfterCreateHandler.Event): Promise<void> {\n const { file } = event.payload;\n\n // Trigger the metadata extraction task\n await this.taskService.trigger<ExtractMetadataInput>({\n definition: \"fileManagerExtractMetadata\",\n input: {\n fileId: file.id\n }\n });\n }\n}\n\nexport const ExtractMetadataHandler = FileAfterCreateHandler.createImplementation({\n implementation: ExtractMetadataHandlerImpl,\n dependencies: [TaskService]\n});\n"],"mappings":"AAAA,SAASA,sBAAsB,QAAQ,6DAA6D;AACpG,SAASC,WAAW,QAAQ,qDAAqD;AAGjF,MAAMC,0BAA0B,CAA6C;EACzEC,WAAWA,CAASC,WAAkC,EAAE;IAAA,KAApCA,WAAkC,GAAlCA,WAAkC;EAAG;EAEzD,MAAMC,MAAMA,CAACC,KAAmC,EAAiB;IAC7D,MAAM;MAAEC;IAAK,CAAC,GAAGD,KAAK,CAACE,OAAO;;IAE9B;IACA,MAAM,IAAI,CAACJ,WAAW,CAACK,OAAO,CAAuB;MACjDC,UAAU,EAAE,4BAA4B;MACxCC,KAAK,EAAE;QACHC,MAAM,EAAEL,IAAI,CAACM;MACjB;IACJ,CAAC,CAAC;EACN;AACJ;AAEA,OAAO,MAAMC,sBAAsB,GAAGd,sBAAsB,CAACe,oBAAoB,CAAC;EAC9EC,cAAc,EAAEd,0BAA0B;EAC1Ce,YAAY,EAAE,CAAChB,WAAW;AAC9B,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,23 @@
1
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
3
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
4
+ export interface ExtractMetadataInput {
5
+ fileId: string;
6
+ }
7
+ declare class ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {
8
+ private keyValueStore;
9
+ private updateFileUseCase;
10
+ id: string;
11
+ title: string;
12
+ description: string;
13
+ maxIterations: number;
14
+ isPrivate: boolean;
15
+ databaseLogs: boolean;
16
+ constructor(keyValueStore: GlobalKeyValueStore.Interface, updateFileUseCase: UpdateFileUseCase.Interface);
17
+ run({ input, controller }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<TaskDefinition.Result<ExtractMetadataInput>>;
18
+ private cleanValues;
19
+ }
20
+ export declare const ExtractMetadataTaskDefinition: typeof ExtractMetadataTask & {
21
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions.js").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions.js").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions.js").ITaskOutput>>;
22
+ };
23
+ export {};
@@ -0,0 +1,128 @@
1
+ import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
5
+ import { MetadataReader } from "../WriteFileMetadata/MetadataReader.js";
6
+ class ExtractMetadataTask {
7
+ id = "fileManagerExtractMetadata";
8
+ title = "Extract image metadata (dimensions, EXIF, IPTC)";
9
+ description = "A task to extract metadata from uploaded image files";
10
+ maxIterations = 1;
11
+ isPrivate = true;
12
+ databaseLogs = false;
13
+ constructor(keyValueStore, updateFileUseCase) {
14
+ this.keyValueStore = keyValueStore;
15
+ this.updateFileUseCase = updateFileUseCase;
16
+ }
17
+ async run({
18
+ input,
19
+ controller
20
+ }) {
21
+ if (controller.runtime.isAborted()) {
22
+ return controller.response.aborted();
23
+ }
24
+
25
+ // Load file metadata
26
+ const metadataReader = new MetadataReader(this.keyValueStore);
27
+ const fileMetadata = await metadataReader.read(input.fileId);
28
+ if (!fileMetadata) {
29
+ return controller.response.error({
30
+ message: `File metadata not found for file ID: ${input.fileId}`
31
+ });
32
+ }
33
+
34
+ // Check if it's an image file
35
+ if (!fileMetadata.contentType.startsWith("image/")) {
36
+ return controller.response.done();
37
+ }
38
+
39
+ // Fetch the image from S3
40
+ const s3 = new S3();
41
+ const bucket = String(process.env.S3_BUCKET);
42
+ try {
43
+ const s3Object = await s3.getObject({
44
+ Bucket: bucket,
45
+ Key: fileMetadata.bucketKey
46
+ });
47
+ if (!s3Object.Body) {
48
+ return controller.response.error({
49
+ message: `S3 object body is empty for file: ${input.fileId}`
50
+ });
51
+ }
52
+ const sharp = await import(/* webpackChunkName: "sharp" */"sharp").then(m => m.default);
53
+ const ExifReader = await import(/* webpackChunkName: "exifreader" */"exifreader").then(m => m.default);
54
+
55
+ // Convert S3 body to buffer
56
+ const buffer = Buffer.from(await s3Object.Body.transformToByteArray());
57
+
58
+ // Extract metadata using Sharp for image dimensions
59
+ const sharpInstance = sharp(buffer);
60
+ const sharpMetadata = await sharpInstance.metadata();
61
+
62
+ // Use ExifReader to extract EXIF and IPTC data
63
+ const tags = ExifReader.load(buffer, {
64
+ expanded: true
65
+ });
66
+
67
+ // Build metadata object
68
+ const metadata = {
69
+ image: {
70
+ width: sharpMetadata.width,
71
+ height: sharpMetadata.height,
72
+ format: sharpMetadata.format,
73
+ orientation: sharpMetadata.orientation ?? 1
74
+ }
75
+ };
76
+
77
+ // Extract EXIF data if available
78
+ if (tags.exif) {
79
+ metadata.exif = this.cleanValues(tags.exif);
80
+ }
81
+
82
+ // Extract IPTC data if available
83
+ if (tags.iptc) {
84
+ metadata.iptc = this.cleanValues(tags.iptc);
85
+ }
86
+
87
+ // Update the file with extracted metadata
88
+ const updateResult = await this.updateFileUseCase.execute({
89
+ id: input.fileId,
90
+ metadata
91
+ });
92
+ if (updateResult.isFail()) {
93
+ return controller.response.error({
94
+ message: `Failed to update file with metadata: ${updateResult.error.message}`
95
+ });
96
+ }
97
+ return controller.response.done();
98
+ } catch (error) {
99
+ return controller.response.error({
100
+ message: `Failed to extract metadata: ${error instanceof Error ? error.message : String(error)}`
101
+ });
102
+ }
103
+ }
104
+ cleanValues(tags) {
105
+ const cleaned = {};
106
+ for (const [key, tag] of Object.entries(tags)) {
107
+ if (!tag || typeof tag !== "object") {
108
+ continue;
109
+ }
110
+
111
+ // Use description if available, otherwise value
112
+ if (tag.description !== undefined && tag.description !== null) {
113
+ cleaned[key] = tag.description;
114
+ } else if (Array.isArray(tag.value) && tag.value.length > 20) {
115
+ // Skip large byte arrays
116
+ } else if (tag.value !== undefined) {
117
+ cleaned[key] = tag.value;
118
+ }
119
+ }
120
+ return cleaned;
121
+ }
122
+ }
123
+ export const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({
124
+ implementation: ExtractMetadataTask,
125
+ dependencies: [GlobalKeyValueStore, UpdateFileUseCase]
126
+ });
127
+
128
+ //# sourceMappingURL=ExtractMetadataTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["S3","TaskDefinition","GlobalKeyValueStore","UpdateFileUseCase","MetadataReader","ExtractMetadataTask","id","title","description","maxIterations","isPrivate","databaseLogs","constructor","keyValueStore","updateFileUseCase","run","input","controller","runtime","isAborted","response","aborted","metadataReader","fileMetadata","read","fileId","error","message","contentType","startsWith","done","s3","bucket","String","process","env","S3_BUCKET","s3Object","getObject","Bucket","Key","bucketKey","Body","sharp","then","m","default","ExifReader","buffer","Buffer","from","transformToByteArray","sharpInstance","sharpMetadata","metadata","tags","load","expanded","image","width","height","format","orientation","exif","cleanValues","iptc","updateResult","execute","isFail","Error","cleaned","key","tag","Object","entries","undefined","Array","isArray","value","length","ExtractMetadataTaskDefinition","createImplementation","implementation","dependencies"],"sources":["ExtractMetadataTask.ts"],"sourcesContent":["import type { ExifTags } from \"exifreader\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"../WriteFileMetadata/MetadataReader.js\";\n\nexport interface ExtractMetadataInput {\n fileId: string;\n}\n\nclass ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {\n id = \"fileManagerExtractMetadata\";\n title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n description = \"A task to extract metadata from uploaded image files\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private updateFileUseCase: UpdateFileUseCase.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<\n TaskDefinition.Result<ExtractMetadataInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Load file metadata\n const metadataReader = new MetadataReader(this.keyValueStore);\n const fileMetadata = await metadataReader.read(input.fileId);\n\n if (!fileMetadata) {\n return controller.response.error({\n message: `File metadata not found for file ID: ${input.fileId}`\n });\n }\n\n // Check if it's an image file\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n // Fetch the image from S3\n const s3 = new S3();\n const bucket = String(process.env.S3_BUCKET);\n\n try {\n const s3Object = await s3.getObject({\n Bucket: bucket,\n Key: fileMetadata.bucketKey\n });\n\n if (!s3Object.Body) {\n return controller.response.error({\n message: `S3 object body is empty for file: ${input.fileId}`\n });\n }\n\n const sharp = await import(/* webpackChunkName: \"sharp\" */ \"sharp\").then(\n m => m.default\n );\n\n const ExifReader = await import(/* webpackChunkName: \"exifreader\" */ \"exifreader\").then(\n m => m.default\n );\n\n // Convert S3 body to buffer\n const buffer = Buffer.from(await s3Object.Body.transformToByteArray());\n\n // Extract metadata using Sharp for image dimensions\n const sharpInstance = sharp(buffer);\n const sharpMetadata = await sharpInstance.metadata();\n\n // Use ExifReader to extract EXIF and IPTC data\n const tags = ExifReader.load(buffer, { expanded: true });\n\n // Build metadata object\n const metadata: Record<string, any> = {\n image: {\n width: sharpMetadata.width,\n height: sharpMetadata.height,\n format: sharpMetadata.format,\n orientation: sharpMetadata.orientation ?? 1\n }\n };\n\n // Extract EXIF data if available\n if (tags.exif) {\n metadata.exif = this.cleanValues(tags.exif);\n }\n\n // Extract IPTC data if available\n if (tags.iptc) {\n metadata.iptc = this.cleanValues(tags.iptc);\n }\n\n // Update the file with extracted metadata\n const updateResult = await this.updateFileUseCase.execute({\n id: input.fileId,\n metadata\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file with metadata: ${updateResult.error.message}`\n });\n }\n\n return controller.response.done();\n } catch (error) {\n return controller.response.error({\n message: `Failed to extract metadata: ${\n error instanceof Error ? error.message : String(error)\n }`\n });\n }\n }\n\n private cleanValues(tags: ExifTags) {\n const cleaned: Record<string, any> = {};\n\n for (const [key, tag] of Object.entries(tags)) {\n if (!tag || typeof tag !== \"object\") {\n continue;\n }\n\n // Use description if available, otherwise value\n if (tag.description !== undefined && tag.description !== null) {\n cleaned[key] = tag.description;\n } else if (Array.isArray(tag.value) && tag.value.length > 20) {\n // Skip large byte arrays\n } else if (tag.value !== undefined) {\n cleaned[key] = tag.value;\n }\n }\n\n return cleaned;\n }\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTask,\n dependencies: [GlobalKeyValueStore, UpdateFileUseCase]\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export declare const ExtractMetadataFeature: import("@webiny/feature/api/createFeature.js").FeatureDefinition<unknown>;
@@ -0,0 +1,12 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { ExtractMetadataHandler } from "./ExtractMetadataHandler.js";
3
+ import { ExtractMetadataTaskDefinition } from "./ExtractMetadataTask.js";
4
+ export const ExtractMetadataFeature = createFeature({
5
+ name: "FileManagerS3/ExtractMetadata",
6
+ register(container) {
7
+ container.register(ExtractMetadataHandler);
8
+ container.register(ExtractMetadataTaskDefinition);
9
+ }
10
+ });
11
+
12
+ //# sourceMappingURL=feature.js.map