@webiny/api-file-manager-s3 0.0.0-unstable.78f581c1d2 → 0.0.0-unstable.7be00a75a9

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 (184) hide show
  1. package/README.md +11 -1
  2. package/assetDelivery/abstractions.d.ts +9 -0
  3. package/assetDelivery/abstractions.js +7 -0
  4. package/assetDelivery/abstractions.js.map +1 -0
  5. package/assetDelivery/assetDeliveryConfig.d.ts +2 -0
  6. package/assetDelivery/assetDeliveryConfig.js +15 -0
  7. package/assetDelivery/assetDeliveryConfig.js.map +1 -0
  8. package/assetDelivery/createAssetDelivery.d.ts +3 -0
  9. package/assetDelivery/createAssetDelivery.js +9 -0
  10. package/assetDelivery/createAssetDelivery.js.map +1 -0
  11. package/assetDelivery/feature.d.ts +5 -0
  12. package/assetDelivery/feature.js +37 -0
  13. package/assetDelivery/feature.js.map +1 -0
  14. package/assetDelivery/index.d.ts +8 -0
  15. package/assetDelivery/index.js +8 -0
  16. package/assetDelivery/s3/S3AssetResolver.d.ts +14 -0
  17. package/assetDelivery/s3/S3AssetResolver.js +39 -0
  18. package/assetDelivery/s3/S3AssetResolver.js.map +1 -0
  19. package/assetDelivery/s3/S3ContentsReader.d.ts +8 -0
  20. package/assetDelivery/s3/S3ContentsReader.js +17 -0
  21. package/assetDelivery/s3/S3ContentsReader.js.map +1 -0
  22. package/assetDelivery/s3/S3ErrorAssetReply.d.ts +4 -0
  23. package/assetDelivery/s3/S3ErrorAssetReply.js +14 -0
  24. package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -0
  25. package/assetDelivery/s3/S3OutputStrategy.d.ts +15 -0
  26. package/assetDelivery/s3/S3OutputStrategy.js +40 -0
  27. package/assetDelivery/s3/S3OutputStrategy.js.map +1 -0
  28. package/assetDelivery/s3/S3RedirectAssetReply.d.ts +4 -0
  29. package/assetDelivery/s3/S3RedirectAssetReply.js +17 -0
  30. package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -0
  31. package/assetDelivery/s3/S3StreamAssetReply.d.ts +5 -0
  32. package/assetDelivery/s3/S3StreamAssetReply.js +17 -0
  33. package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -0
  34. package/assetDelivery/s3/SharpTransform.d.ts +18 -0
  35. package/assetDelivery/s3/SharpTransform.js +162 -0
  36. package/assetDelivery/s3/SharpTransform.js.map +1 -0
  37. package/assetDelivery/s3/transformation/AssetKeyGenerator.d.ts +8 -0
  38. package/assetDelivery/s3/transformation/AssetKeyGenerator.js +21 -0
  39. package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -0
  40. package/assetDelivery/s3/transformation/CallableContentsReader.d.ts +10 -0
  41. package/assetDelivery/s3/transformation/CallableContentsReader.js +11 -0
  42. package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -0
  43. package/assetDelivery/s3/transformation/WidthCollection.d.ts +7 -0
  44. package/assetDelivery/s3/transformation/WidthCollection.js +19 -0
  45. package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -0
  46. package/assetDelivery/s3/transformation/utils.d.ts +9 -0
  47. package/assetDelivery/s3/transformation/utils.js +31 -0
  48. package/assetDelivery/s3/transformation/utils.js.map +1 -0
  49. package/assetDelivery/threatDetection/ObjectKey.d.ts +7 -0
  50. package/assetDelivery/threatDetection/ObjectKey.js +18 -0
  51. package/assetDelivery/threatDetection/ObjectKey.js.map +1 -0
  52. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.d.ts +2 -0
  53. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js +37 -0
  54. package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js.map +1 -0
  55. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.d.ts +2 -0
  56. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js +5 -0
  57. package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js.map +1 -0
  58. package/assetDelivery/threatDetection/index.d.ts +2 -0
  59. package/assetDelivery/threatDetection/index.js +2 -0
  60. package/assetDelivery/threatDetection/processThreatScanResult.d.ts +3 -0
  61. package/assetDelivery/threatDetection/processThreatScanResult.js +59 -0
  62. package/assetDelivery/threatDetection/processThreatScanResult.js.map +1 -0
  63. package/assetDelivery/threatDetection/types.d.ts +9 -0
  64. package/assetDelivery/threatDetection/types.js +0 -0
  65. package/assetDelivery/types.d.ts +10 -0
  66. package/assetDelivery/types.js +0 -0
  67. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.d.ts +11 -0
  68. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js +23 -0
  69. package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js.map +1 -0
  70. package/enterprise/ApplyThreatScanning/feature.d.ts +4 -0
  71. package/enterprise/ApplyThreatScanning/feature.js +11 -0
  72. package/enterprise/ApplyThreatScanning/feature.js.map +1 -0
  73. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.d.ts +15 -0
  74. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js +35 -0
  75. package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js.map +1 -0
  76. package/features/DeleteFileFromBucket/DeleteS3FolderTask.d.ts +32 -0
  77. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js +50 -0
  78. package/features/DeleteFileFromBucket/DeleteS3FolderTask.js.map +1 -0
  79. package/features/DeleteFileFromBucket/feature.d.ts +4 -0
  80. package/features/DeleteFileFromBucket/feature.js +13 -0
  81. package/features/DeleteFileFromBucket/feature.js.map +1 -0
  82. package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +11 -0
  83. package/features/ExtractMetadata/ExtractMetadataHandler.js +25 -0
  84. package/features/ExtractMetadata/ExtractMetadataHandler.js.map +1 -0
  85. package/features/ExtractMetadata/ExtractMetadataTask.d.ts +24 -0
  86. package/features/ExtractMetadata/ExtractMetadataTask.js +90 -0
  87. package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
  88. package/features/ExtractMetadata/feature.d.ts +4 -0
  89. package/features/ExtractMetadata/feature.js +13 -0
  90. package/features/ExtractMetadata/feature.js.map +1 -0
  91. package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +12 -0
  92. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +28 -0
  93. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
  94. package/features/FlushCache/FlushCacheOnFileUpdateHandler.d.ts +12 -0
  95. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js +31 -0
  96. package/features/FlushCache/FlushCacheOnFileUpdateHandler.js.map +1 -0
  97. package/features/FlushCache/InvalidateCacheTask.d.ts +26 -0
  98. package/features/FlushCache/InvalidateCacheTask.js +75 -0
  99. package/features/FlushCache/InvalidateCacheTask.js.map +1 -0
  100. package/features/FlushCache/feature.d.ts +4 -0
  101. package/features/FlushCache/feature.js +15 -0
  102. package/features/FlushCache/feature.js.map +1 -0
  103. package/features/GetFileContentsById/GetFileContentsByIdUseCase.d.ts +13 -0
  104. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js +40 -0
  105. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js.map +1 -0
  106. package/features/GetFileContentsById/feature.d.ts +4 -0
  107. package/features/GetFileContentsById/feature.js +11 -0
  108. package/features/GetFileContentsById/feature.js.map +1 -0
  109. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.d.ts +13 -0
  110. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js +40 -0
  111. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js.map +1 -0
  112. package/features/GetFileContentsByKey/feature.d.ts +4 -0
  113. package/features/GetFileContentsByKey/feature.js +11 -0
  114. package/features/GetFileContentsByKey/feature.js.map +1 -0
  115. package/features/WriteFileMetadata/MetadataReader.d.ts +14 -0
  116. package/features/WriteFileMetadata/MetadataReader.js +13 -0
  117. package/features/WriteFileMetadata/MetadataReader.js.map +1 -0
  118. package/features/WriteFileMetadata/MetadataWriter.d.ts +10 -0
  119. package/features/WriteFileMetadata/MetadataWriter.js +26 -0
  120. package/features/WriteFileMetadata/MetadataWriter.js.map +1 -0
  121. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.d.ts +12 -0
  122. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +23 -0
  123. package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -0
  124. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.d.ts +12 -0
  125. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +25 -0
  126. package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -0
  127. package/features/WriteFileMetadata/feature.d.ts +4 -0
  128. package/features/WriteFileMetadata/feature.js +13 -0
  129. package/features/WriteFileMetadata/feature.js.map +1 -0
  130. package/graphql/checkPermissions.d.ts +5 -0
  131. package/graphql/checkPermissions.js +22 -0
  132. package/graphql/checkPermissions.js.map +1 -0
  133. package/graphql/schema.d.ts +1 -0
  134. package/graphql/schema.js +201 -0
  135. package/graphql/schema.js.map +1 -0
  136. package/index.d.ts +4 -2
  137. package/index.js +29 -14
  138. package/index.js.map +1 -1
  139. package/multiPartUpload/CompleteMultiPartUploadUseCase.d.ts +15 -0
  140. package/multiPartUpload/CompleteMultiPartUploadUseCase.js +55 -0
  141. package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -0
  142. package/multiPartUpload/CreateMultiPartUploadUseCase.d.ts +20 -0
  143. package/multiPartUpload/CreateMultiPartUploadUseCase.js +34 -0
  144. package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -0
  145. package/package.json +35 -24
  146. package/types.d.ts +14 -9
  147. package/types.js +1 -5
  148. package/utils/CdnPathsGenerator.d.ts +3 -0
  149. package/utils/CdnPathsGenerator.js +11 -0
  150. package/utils/CdnPathsGenerator.js.map +1 -0
  151. package/utils/FileExtension.d.ts +6 -0
  152. package/utils/FileExtension.js +16 -0
  153. package/utils/FileExtension.js.map +1 -0
  154. package/utils/FileKey.d.ts +11 -0
  155. package/utils/FileKey.js +33 -0
  156. package/utils/FileKey.js.map +1 -0
  157. package/utils/FileKey.test.d.ts +1 -0
  158. package/utils/FileKey.test.js +59 -0
  159. package/utils/FileKey.test.js.map +1 -0
  160. package/utils/FileNormalizer.d.ts +18 -0
  161. package/utils/FileNormalizer.js +41 -0
  162. package/utils/FileNormalizer.js.map +1 -0
  163. package/utils/FileUploadModifier.d.ts +30 -0
  164. package/utils/FileUploadModifier.js +39 -0
  165. package/utils/FileUploadModifier.js.map +1 -0
  166. package/utils/createFileNormalizerFromContext.d.ts +3 -0
  167. package/utils/createFileNormalizerFromContext.js +9 -0
  168. package/utils/createFileNormalizerFromContext.js.map +1 -0
  169. package/utils/getPresignedPostPayload.d.ts +4 -4
  170. package/utils/getPresignedPostPayload.js +39 -83
  171. package/utils/getPresignedPostPayload.js.map +1 -1
  172. package/utils/mimeTypes.d.ts +5 -0
  173. package/utils/mimeTypes.js +9 -0
  174. package/utils/mimeTypes.js.map +1 -0
  175. package/utils/uploadFileToS3.d.ts +2 -4
  176. package/utils/uploadFileToS3.js +12 -27
  177. package/utils/uploadFileToS3.js.map +1 -1
  178. package/plugins/fileStorageS3.d.ts +0 -6
  179. package/plugins/fileStorageS3.js +0 -68
  180. package/plugins/fileStorageS3.js.map +0 -1
  181. package/plugins/graphqlFileStorageS3.d.ts +0 -4
  182. package/plugins/graphqlFileStorageS3.js +0 -150
  183. package/plugins/graphqlFileStorageS3.js.map +0 -1
  184. package/types.js.map +0 -1
package/README.md CHANGED
@@ -1 +1,11 @@
1
- # @webiny/api-file-manager-s3
1
+ # @webiny/api-file-manager-s3
2
+
3
+ > [!NOTE]
4
+ > This package is part of the [Webiny](https://www.webiny.com) monorepo.
5
+ > It’s **included in every Webiny project by default** and is not meant to be used as a standalone package.
6
+
7
+ 📘 **Documentation:** [https://www.webiny.com/docs](https://www.webiny.com/docs)
8
+
9
+ ---
10
+
11
+ _This README file is automatically generated during the publish process._
@@ -0,0 +1,9 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ export interface IS3AssetDeliveryConfig {
3
+ presignedUrlTtl: number;
4
+ imageResizeWidths: number[];
5
+ assetStreamingMaxSize: number;
6
+ }
7
+ export declare const S3AssetDeliveryConfig: import("@webiny/di").Abstraction<IS3AssetDeliveryConfig>;
8
+ export declare const S3Client: import("@webiny/di").Abstraction<S3>;
9
+ export declare const S3Bucket: import("@webiny/di").Abstraction<string>;
@@ -0,0 +1,7 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const S3AssetDeliveryConfig = createAbstraction("AssetDelivery/S3Config");
3
+ const S3Client = createAbstraction("AssetDelivery/S3Client");
4
+ const S3Bucket = createAbstraction("AssetDelivery/S3Bucket");
5
+ export { S3AssetDeliveryConfig, S3Bucket, S3Client };
6
+
7
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/abstractions.js","sources":["../../src/assetDelivery/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\n\nexport interface IS3AssetDeliveryConfig {\n presignedUrlTtl: number;\n imageResizeWidths: number[];\n assetStreamingMaxSize: number;\n}\n\nexport const S3AssetDeliveryConfig =\n createAbstraction<IS3AssetDeliveryConfig>(\"AssetDelivery/S3Config\");\n\nexport const S3Client = createAbstraction<S3>(\"AssetDelivery/S3Client\");\n\nexport const S3Bucket = createAbstraction<string>(\"AssetDelivery/S3Bucket\");\n"],"names":["S3AssetDeliveryConfig","createAbstraction","S3Client","S3Bucket"],"mappings":";AASO,MAAMA,wBACTC,kBAA0C;AAEvC,MAAMC,WAAWD,kBAAsB;AAEvC,MAAME,WAAWF,kBAA0B"}
@@ -0,0 +1,2 @@
1
+ import type { AssetDeliveryParams } from "../assetDelivery/types.js";
2
+ export declare const assetDeliveryConfig: (params: AssetDeliveryParams) => (import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types").Context> | (import("@webiny/handler").ModifyFastifyPlugin | import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types").Context>)[])[];
@@ -0,0 +1,15 @@
1
+ import { createAssetDelivery } from "@webiny/api-file-manager";
2
+ import { createRegisterExtensionPlugin } from "@webiny/handler";
3
+ import { createS3AssetDeliveryFeature } from "./feature.js";
4
+ const assetDeliveryConfig = (params)=>{
5
+ const feature = createS3AssetDeliveryFeature(params);
6
+ return [
7
+ createAssetDelivery(),
8
+ createRegisterExtensionPlugin((context)=>{
9
+ feature.register(context.container);
10
+ })
11
+ ];
12
+ };
13
+ export { assetDeliveryConfig };
14
+
15
+ //# sourceMappingURL=assetDeliveryConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/assetDeliveryConfig.js","sources":["../../src/assetDelivery/assetDeliveryConfig.ts"],"sourcesContent":["import { createAssetDelivery as createBaseAssetDelivery } from \"@webiny/api-file-manager\";\nimport { createRegisterExtensionPlugin } from \"@webiny/handler\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types.js\";\nimport { createS3AssetDeliveryFeature } from \"~/assetDelivery/feature.js\";\n\nexport const assetDeliveryConfig = (params: AssetDeliveryParams) => {\n const feature = createS3AssetDeliveryFeature(params);\n\n return [\n createBaseAssetDelivery(),\n createRegisterExtensionPlugin(context => {\n feature.register(context.container);\n })\n ];\n};\n"],"names":["assetDeliveryConfig","params","feature","createS3AssetDeliveryFeature","createBaseAssetDelivery","createRegisterExtensionPlugin","context"],"mappings":";;;AAKO,MAAMA,sBAAsB,CAACC;IAChC,MAAMC,UAAUC,6BAA6BF;IAE7C,OAAO;QACHG;QACAC,8BAA8BC,CAAAA;YAC1BJ,QAAQ,QAAQ,CAACI,QAAQ,SAAS;QACtC;KACH;AACL"}
@@ -0,0 +1,3 @@
1
+ import type { PluginFactory } from "@webiny/plugins/types.js";
2
+ import type { AssetDeliveryParams } from "../assetDelivery/types.js";
3
+ export declare const createAssetDelivery: (params?: AssetDeliveryParams) => PluginFactory[];
@@ -0,0 +1,9 @@
1
+ import { createAssetDeliveryPluginLoader } from "@webiny/api-file-manager";
2
+ import { createThreatDetectionPluginLoader } from "./threatDetection/index.js";
3
+ const createAssetDelivery = (params = {})=>[
4
+ createAssetDeliveryPluginLoader(()=>import("./assetDeliveryConfig.js").then(({ assetDeliveryConfig })=>assetDeliveryConfig(params))),
5
+ createThreatDetectionPluginLoader(()=>import("./threatDetection/createThreatDetectionEventHandler.js").then(({ createThreatDetectionEventHandler })=>createThreatDetectionEventHandler()))
6
+ ];
7
+ export { createAssetDelivery };
8
+
9
+ //# sourceMappingURL=createAssetDelivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/createAssetDelivery.js","sources":["../../src/assetDelivery/createAssetDelivery.ts"],"sourcesContent":["import { createAssetDeliveryPluginLoader } from \"@webiny/api-file-manager\";\nimport type { PluginFactory } from \"@webiny/plugins/types.js\";\nimport { createThreatDetectionPluginLoader } from \"~/assetDelivery/threatDetection/index.js\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types.js\";\n\nexport const createAssetDelivery = (params: AssetDeliveryParams = {}): PluginFactory[] => {\n return [\n /**\n * We only want to load this plugin in the context of the Asset Delivery Lambda function.\n */\n createAssetDeliveryPluginLoader(() => {\n return import(\n /* webpackChunkName: \"s3AssetDelivery\" */ \"./assetDeliveryConfig.js\"\n ).then(({ assetDeliveryConfig }) => assetDeliveryConfig(params));\n }),\n /**\n * We only want to load this plugin in the context of the Threat Detection Lambda function.\n */\n createThreatDetectionPluginLoader(() => {\n return import(\n /* webpackChunkName: \"threatDetectionEventHandler\" */ \"./threatDetection/createThreatDetectionEventHandler.js\"\n ).then(({ createThreatDetectionEventHandler }) => createThreatDetectionEventHandler());\n })\n ];\n};\n"],"names":["createAssetDelivery","params","createAssetDeliveryPluginLoader","assetDeliveryConfig","createThreatDetectionPluginLoader","createThreatDetectionEventHandler"],"mappings":";;AAKO,MAAMA,sBAAsB,CAACC,SAA8B,CAAC,CAAC,GACzD;QAIHC,gCAAgC,IACrB,MAAM,CAAN,4BAEL,IAAI,CAAC,CAAC,EAAEC,mBAAmB,EAAE,GAAKA,oBAAoBF;QAK5DG,kCAAkC,IACvB,MAAM,CAAN,0DAEL,IAAI,CAAC,CAAC,EAAEC,iCAAiC,EAAE,GAAKA;KAEzD"}
@@ -0,0 +1,5 @@
1
+ import type { AssetDeliveryParams } from "./types.js";
2
+ export declare const createS3AssetDeliveryFeature: (params?: AssetDeliveryParams) => {
3
+ name: string;
4
+ register(container: import("@webiny/di").Container): void;
5
+ };
@@ -0,0 +1,37 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
3
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "./abstractions.js";
4
+ import { S3AssetResolverImpl } from "./s3/S3AssetResolver.js";
5
+ import { S3OutputStrategyImpl } from "./s3/S3OutputStrategy.js";
6
+ import { SharpTransformImpl } from "./s3/SharpTransform.js";
7
+ const createS3AssetDeliveryFeature = (params = {})=>createFeature({
8
+ name: "AssetDelivery/S3",
9
+ register (container) {
10
+ container.registerInstance(S3Client, new S3({
11
+ region: process.env.AWS_REGION
12
+ }));
13
+ container.registerInstance(S3Bucket, process.env.S3_BUCKET);
14
+ container.registerInstance(S3AssetDeliveryConfig, {
15
+ presignedUrlTtl: params.presignedUrlTtl ?? 3600,
16
+ imageResizeWidths: params.imageResizeWidths ?? [
17
+ 128,
18
+ 384,
19
+ 640,
20
+ 750,
21
+ 828,
22
+ 1080,
23
+ 1200,
24
+ 1920,
25
+ 2048,
26
+ 3840
27
+ ],
28
+ assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592
29
+ });
30
+ container.register(S3AssetResolverImpl);
31
+ container.register(S3OutputStrategyImpl);
32
+ container.register(SharpTransformImpl);
33
+ }
34
+ });
35
+ export { createS3AssetDeliveryFeature };
36
+
37
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/feature.js","sources":["../../src/assetDelivery/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"./abstractions.js\";\nimport type { AssetDeliveryParams } from \"./types.js\";\nimport { S3AssetResolverImpl } from \"./s3/S3AssetResolver.js\";\nimport { S3OutputStrategyImpl } from \"./s3/S3OutputStrategy.js\";\nimport { SharpTransformImpl } from \"./s3/SharpTransform.js\";\n\nexport const createS3AssetDeliveryFeature = (params: AssetDeliveryParams = {}) => {\n return createFeature({\n name: \"AssetDelivery/S3\",\n register(container) {\n container.registerInstance(\n S3Client,\n new S3({ region: process.env.AWS_REGION as string })\n );\n container.registerInstance(S3Bucket, process.env.S3_BUCKET as string);\n container.registerInstance(S3AssetDeliveryConfig, {\n presignedUrlTtl: params.presignedUrlTtl ?? 3600,\n imageResizeWidths: params.imageResizeWidths ?? [\n 128, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840\n ],\n assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592\n });\n\n container.register(S3AssetResolverImpl);\n container.register(S3OutputStrategyImpl);\n container.register(SharpTransformImpl);\n }\n });\n};\n"],"names":["createS3AssetDeliveryFeature","params","createFeature","container","S3Client","S3","process","S3Bucket","S3AssetDeliveryConfig","S3AssetResolverImpl","S3OutputStrategyImpl","SharpTransformImpl"],"mappings":";;;;;;AAQO,MAAMA,+BAA+B,CAACC,SAA8B,CAAC,CAAC,GAClEC,cAAc;QACjB,MAAM;QACN,UAASC,SAAS;YACdA,UAAU,gBAAgB,CACtBC,UACA,IAAIC,GAAG;gBAAE,QAAQC,QAAQ,GAAG,CAAC,UAAU;YAAW;YAEtDH,UAAU,gBAAgB,CAACI,UAAUD,QAAQ,GAAG,CAAC,SAAS;YAC1DH,UAAU,gBAAgB,CAACK,uBAAuB;gBAC9C,iBAAiBP,OAAO,eAAe,IAAI;gBAC3C,mBAAmBA,OAAO,iBAAiB,IAAI;oBAC3C;oBAAK;oBAAK;oBAAK;oBAAK;oBAAK;oBAAM;oBAAM;oBAAM;oBAAM;iBACpD;gBACD,uBAAuBA,OAAO,qBAAqB,IAAI;YAC3D;YAEAE,UAAU,QAAQ,CAACM;YACnBN,UAAU,QAAQ,CAACO;YACnBP,UAAU,QAAQ,CAACQ;QACvB;IACJ"}
@@ -0,0 +1,8 @@
1
+ export { S3AssetResolver } from "./s3/S3AssetResolver.js";
2
+ export { S3OutputStrategy } from "./s3/S3OutputStrategy.js";
3
+ export { S3ContentsReader } from "./s3/S3ContentsReader.js";
4
+ export { S3ErrorAssetReply } from "./s3/S3ErrorAssetReply.js";
5
+ export { S3RedirectAssetReply } from "./s3/S3RedirectAssetReply.js";
6
+ export { S3StreamAssetReply } from "./s3/S3StreamAssetReply.js";
7
+ export { SharpTransform } from "./s3/SharpTransform.js";
8
+ export { CallableContentsReader } from "./s3/transformation/CallableContentsReader.js";
@@ -0,0 +1,8 @@
1
+ export { S3AssetResolver } from "./s3/S3AssetResolver.js";
2
+ export { S3OutputStrategy } from "./s3/S3OutputStrategy.js";
3
+ export { S3ContentsReader } from "./s3/S3ContentsReader.js";
4
+ export { S3ErrorAssetReply } from "./s3/S3ErrorAssetReply.js";
5
+ export { S3RedirectAssetReply } from "./s3/S3RedirectAssetReply.js";
6
+ export { S3StreamAssetReply } from "./s3/S3StreamAssetReply.js";
7
+ export { SharpTransform } from "./s3/SharpTransform.js";
8
+ export { CallableContentsReader } from "./s3/transformation/CallableContentsReader.js";
@@ -0,0 +1,14 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import type { AssetRequest, AssetResolver } from "@webiny/api-file-manager";
3
+ import { Asset } from "@webiny/api-file-manager";
4
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
5
+ export declare class S3AssetResolver implements AssetResolver {
6
+ private keyValueStore;
7
+ private s3;
8
+ private bucket;
9
+ constructor(keyValueStore: GlobalKeyValueStore.Interface, s3: S3, bucket: string);
10
+ resolve(request: AssetRequest): Promise<Asset | undefined>;
11
+ }
12
+ export declare const S3AssetResolverImpl: typeof S3AssetResolver & {
13
+ __abstraction: import("@webiny/di").Abstraction<AssetResolver>;
14
+ };
@@ -0,0 +1,39 @@
1
+ import { Asset } from "@webiny/api-file-manager";
2
+ import { AssetResolver } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { S3ContentsReader } from "../index.js";
5
+ import { ObjectKey } from "../threatDetection/ObjectKey.js";
6
+ import { S3Bucket, S3Client } from "../abstractions.js";
7
+ class S3AssetResolver {
8
+ constructor(keyValueStore, s3, bucket){
9
+ this.keyValueStore = keyValueStore;
10
+ this.s3 = s3;
11
+ this.bucket = bucket;
12
+ }
13
+ async resolve(request) {
14
+ const fileId = ObjectKey.from(request.getKey()).id();
15
+ const result = await this.keyValueStore.get(`FileManager/File/${fileId}/Metadata`);
16
+ if (result.isFail()) return;
17
+ const metadata = result.value;
18
+ const asset = new Asset({
19
+ id: metadata.id,
20
+ tenant: metadata.tenant,
21
+ size: metadata.size,
22
+ contentType: metadata.contentType,
23
+ key: metadata.bucketKey
24
+ });
25
+ asset.setContentsReader(new S3ContentsReader(this.s3, this.bucket));
26
+ return asset;
27
+ }
28
+ }
29
+ const S3AssetResolverImpl = AssetResolver.createImplementation({
30
+ implementation: S3AssetResolver,
31
+ dependencies: [
32
+ GlobalKeyValueStore,
33
+ S3Client,
34
+ S3Bucket
35
+ ]
36
+ });
37
+ export { S3AssetResolver, S3AssetResolverImpl };
38
+
39
+ //# sourceMappingURL=S3AssetResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3AssetResolver.js","sources":["../../../src/assetDelivery/s3/S3AssetResolver.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type { AssetRequest, AssetResolver } from \"@webiny/api-file-manager\";\nimport { Asset } from \"@webiny/api-file-manager\";\nimport { AssetResolver as AssetResolverAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { S3ContentsReader } from \"~/assetDelivery/index.js\";\nimport { ObjectKey } from \"~/assetDelivery/threatDetection/ObjectKey.js\";\nimport { S3Client, S3Bucket } from \"~/assetDelivery/abstractions.js\";\n\ninterface AssetMetadata {\n id: string;\n tenant: string;\n size: number;\n contentType: string;\n bucketKey: string;\n}\n\nexport class S3AssetResolver implements AssetResolver {\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private s3: S3,\n private bucket: string\n ) {}\n\n async resolve(request: AssetRequest): Promise<Asset | undefined> {\n const fileId = ObjectKey.from(request.getKey()).id();\n const result = await this.keyValueStore.get<AssetMetadata>(\n `FileManager/File/${fileId}/Metadata`\n );\n\n if (result.isFail()) {\n return undefined;\n }\n\n const metadata = result.value;\n\n const asset = new Asset({\n id: metadata.id,\n tenant: metadata.tenant,\n size: metadata.size,\n contentType: metadata.contentType,\n key: metadata.bucketKey\n });\n\n asset.setContentsReader(new S3ContentsReader(this.s3, this.bucket));\n\n return asset;\n }\n}\n\nexport const S3AssetResolverImpl = AssetResolverAbstraction.createImplementation({\n implementation: S3AssetResolver,\n dependencies: [GlobalKeyValueStore, S3Client, S3Bucket]\n});\n"],"names":["S3AssetResolver","keyValueStore","s3","bucket","request","fileId","ObjectKey","result","metadata","asset","Asset","S3ContentsReader","S3AssetResolverImpl","AssetResolverAbstraction","GlobalKeyValueStore","S3Client","S3Bucket"],"mappings":";;;;;;AAiBO,MAAMA;IACT,YACYC,aAA4C,EAC5CC,EAAM,EACNC,MAAc,CACxB;aAHUF,aAAa,GAAbA;aACAC,EAAE,GAAFA;aACAC,MAAM,GAANA;IACT;IAEH,MAAM,QAAQC,OAAqB,EAA8B;QAC7D,MAAMC,SAASC,UAAU,IAAI,CAACF,QAAQ,MAAM,IAAI,EAAE;QAClD,MAAMG,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CACvC,CAAC,iBAAiB,EAAEF,OAAO,SAAS,CAAC;QAGzC,IAAIE,OAAO,MAAM,IACb;QAGJ,MAAMC,WAAWD,OAAO,KAAK;QAE7B,MAAME,QAAQ,IAAIC,MAAM;YACpB,IAAIF,SAAS,EAAE;YACf,QAAQA,SAAS,MAAM;YACvB,MAAMA,SAAS,IAAI;YACnB,aAAaA,SAAS,WAAW;YACjC,KAAKA,SAAS,SAAS;QAC3B;QAEAC,MAAM,iBAAiB,CAAC,IAAIE,iBAAiB,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM;QAEjE,OAAOF;IACX;AACJ;AAEO,MAAMG,sBAAsBC,cAAAA,oBAA6C,CAAC;IAC7E,gBAAgBb;IAChB,cAAc;QAACc;QAAqBC;QAAUC;KAAS;AAC3D"}
@@ -0,0 +1,8 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import type { Asset, AssetContentsReader } from "@webiny/api-file-manager";
3
+ export declare class S3ContentsReader implements AssetContentsReader {
4
+ private s3;
5
+ private readonly bucket;
6
+ constructor(s3: S3, bucket: string);
7
+ read(asset: Asset): Promise<Buffer>;
8
+ }
@@ -0,0 +1,17 @@
1
+ class S3ContentsReader {
2
+ constructor(s3, bucket){
3
+ this.s3 = s3;
4
+ this.bucket = bucket;
5
+ }
6
+ async read(asset) {
7
+ const { Body } = await this.s3.getObject({
8
+ Bucket: this.bucket,
9
+ Key: asset.getKey()
10
+ });
11
+ if (!Body) throw Error(`Unable to read ${asset.getKey()}!`);
12
+ return Buffer.from(await Body.transformToByteArray());
13
+ }
14
+ }
15
+ export { S3ContentsReader };
16
+
17
+ //# sourceMappingURL=S3ContentsReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3ContentsReader.js","sources":["../../../src/assetDelivery/s3/S3ContentsReader.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type { Asset, AssetContentsReader } from \"@webiny/api-file-manager\";\n\nexport class S3ContentsReader implements AssetContentsReader {\n private s3: S3;\n private readonly bucket: string;\n\n constructor(s3: S3, bucket: string) {\n this.s3 = s3;\n this.bucket = bucket;\n }\n\n async read(asset: Asset): Promise<Buffer> {\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: asset.getKey()\n });\n\n if (!Body) {\n throw Error(`Unable to read ${asset.getKey()}!`);\n }\n\n return Buffer.from(await Body.transformToByteArray());\n }\n}\n"],"names":["S3ContentsReader","s3","bucket","asset","Body","Error","Buffer"],"mappings":"AAGO,MAAMA;IAIT,YAAYC,EAAM,EAAEC,MAAc,CAAE;QAChC,IAAI,CAAC,EAAE,GAAGD;QACV,IAAI,CAAC,MAAM,GAAGC;IAClB;IAEA,MAAM,KAAKC,KAAY,EAAmB;QACtC,MAAM,EAAEC,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;YACrC,QAAQ,IAAI,CAAC,MAAM;YACnB,KAAKD,MAAM,MAAM;QACrB;QAEA,IAAI,CAACC,MACD,MAAMC,MAAM,CAAC,eAAe,EAAEF,MAAM,MAAM,GAAG,CAAC,CAAC;QAGnD,OAAOG,OAAO,IAAI,CAAC,MAAMF,KAAK,oBAAoB;IACtD;AACJ"}
@@ -0,0 +1,4 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ export declare class S3ErrorAssetReply extends AssetReply {
3
+ constructor(message: string);
4
+ }
@@ -0,0 +1,14 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ class S3ErrorAssetReply extends AssetReply {
3
+ constructor(message){
4
+ super({
5
+ code: 400,
6
+ body: ()=>({
7
+ error: message
8
+ })
9
+ });
10
+ }
11
+ }
12
+ export { S3ErrorAssetReply };
13
+
14
+ //# sourceMappingURL=S3ErrorAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3ErrorAssetReply.js","sources":["../../../src/assetDelivery/s3/S3ErrorAssetReply.ts"],"sourcesContent":["import { AssetReply } from \"@webiny/api-file-manager\";\n\nexport class S3ErrorAssetReply extends AssetReply {\n constructor(message: string) {\n super({\n code: 400,\n body: () => ({ error: message })\n });\n }\n}\n"],"names":["S3ErrorAssetReply","AssetReply","message"],"mappings":";AAEO,MAAMA,0BAA0BC;IACnC,YAAYC,OAAe,CAAE;QACzB,KAAK,CAAC;YACF,MAAM;YACN,MAAM,IAAO;oBAAE,OAAOA;gBAAQ;QAClC;IACJ;AACJ"}
@@ -0,0 +1,15 @@
1
+ import type { Asset, AssetOutputStrategy, AssetReply } from "@webiny/api-file-manager";
2
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
3
+ import type { IS3AssetDeliveryConfig } from "../../assetDelivery/abstractions.js";
4
+ export declare class S3OutputStrategy implements AssetOutputStrategy {
5
+ private readonly s3;
6
+ private readonly bucket;
7
+ private readonly presignedUrlTtl;
8
+ private readonly assetStreamingMaxSize;
9
+ constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig);
10
+ output(asset: Asset): Promise<AssetReply>;
11
+ protected getPresignedUrl(asset: Asset): Promise<string>;
12
+ }
13
+ export declare const S3OutputStrategyImpl: typeof S3OutputStrategy & {
14
+ __abstraction: import("@webiny/di").Abstraction<AssetOutputStrategy>;
15
+ };
@@ -0,0 +1,40 @@
1
+ import { AssetOutputStrategy } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
2
+ import { GetObjectCommand, getSignedUrl } from "@webiny/aws-sdk/client-s3/index.js";
3
+ import { S3RedirectAssetReply } from "./S3RedirectAssetReply.js";
4
+ import { S3StreamAssetReply } from "./S3StreamAssetReply.js";
5
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "../abstractions.js";
6
+ class S3OutputStrategy {
7
+ constructor(s3, bucket, config){
8
+ this.s3 = s3;
9
+ this.bucket = bucket;
10
+ this.presignedUrlTtl = config.presignedUrlTtl;
11
+ this.assetStreamingMaxSize = config.assetStreamingMaxSize;
12
+ }
13
+ async output(asset) {
14
+ if (asset.getSize() > this.assetStreamingMaxSize) {
15
+ console.log(`Asset size is greater than ${this.assetStreamingMaxSize}; redirecting to a presigned S3 URL.`);
16
+ return new S3RedirectAssetReply(await this.getPresignedUrl(asset), this.presignedUrlTtl);
17
+ }
18
+ console.log(`Asset size is smaller than ${this.assetStreamingMaxSize}; streaming directly from Lambda function.`);
19
+ return new S3StreamAssetReply(asset);
20
+ }
21
+ getPresignedUrl(asset) {
22
+ return getSignedUrl(this.s3, new GetObjectCommand({
23
+ Bucket: this.bucket,
24
+ Key: asset.getKey()
25
+ }), {
26
+ expiresIn: this.presignedUrlTtl
27
+ });
28
+ }
29
+ }
30
+ const S3OutputStrategyImpl = AssetOutputStrategy.createImplementation({
31
+ implementation: S3OutputStrategy,
32
+ dependencies: [
33
+ S3Client,
34
+ S3Bucket,
35
+ S3AssetDeliveryConfig
36
+ ]
37
+ });
38
+ export { S3OutputStrategy, S3OutputStrategyImpl };
39
+
40
+ //# sourceMappingURL=S3OutputStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3OutputStrategy.js","sources":["../../../src/assetDelivery/s3/S3OutputStrategy.ts"],"sourcesContent":["import type { Asset, AssetOutputStrategy, AssetReply } from \"@webiny/api-file-manager\";\nimport { AssetOutputStrategy as AssetOutputStrategyAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { GetObjectCommand, getSignedUrl } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3RedirectAssetReply } from \"~/assetDelivery/s3/S3RedirectAssetReply.js\";\nimport { S3StreamAssetReply } from \"~/assetDelivery/s3/S3StreamAssetReply.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\nimport type { IS3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\n\nexport class S3OutputStrategy implements AssetOutputStrategy {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly presignedUrlTtl: number;\n private readonly assetStreamingMaxSize: number;\n\n constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig) {\n this.s3 = s3;\n this.bucket = bucket;\n this.presignedUrlTtl = config.presignedUrlTtl;\n this.assetStreamingMaxSize = config.assetStreamingMaxSize;\n }\n\n async output(asset: Asset): Promise<AssetReply> {\n if (asset.getSize() > this.assetStreamingMaxSize) {\n console.log(\n `Asset size is greater than ${this.assetStreamingMaxSize}; redirecting to a presigned S3 URL.`\n );\n\n return new S3RedirectAssetReply(\n await this.getPresignedUrl(asset),\n this.presignedUrlTtl\n );\n }\n\n console.log(\n `Asset size is smaller than ${this.assetStreamingMaxSize}; streaming directly from Lambda function.`\n );\n return new S3StreamAssetReply(asset);\n }\n\n protected getPresignedUrl(asset: Asset) {\n return getSignedUrl(\n this.s3,\n new GetObjectCommand({\n Bucket: this.bucket,\n Key: asset.getKey()\n }),\n { expiresIn: this.presignedUrlTtl }\n );\n }\n}\n\nexport const S3OutputStrategyImpl = AssetOutputStrategyAbstraction.createImplementation({\n implementation: S3OutputStrategy,\n dependencies: [S3Client, S3Bucket, S3AssetDeliveryConfig]\n});\n"],"names":["S3OutputStrategy","s3","bucket","config","asset","console","S3RedirectAssetReply","S3StreamAssetReply","getSignedUrl","GetObjectCommand","S3OutputStrategyImpl","AssetOutputStrategyAbstraction","S3Client","S3Bucket","S3AssetDeliveryConfig"],"mappings":";;;;;AASO,MAAMA;IAMT,YAAYC,EAAM,EAAEC,MAAc,EAAEC,MAA8B,CAAE;QAChE,IAAI,CAAC,EAAE,GAAGF;QACV,IAAI,CAAC,MAAM,GAAGC;QACd,IAAI,CAAC,eAAe,GAAGC,OAAO,eAAe;QAC7C,IAAI,CAAC,qBAAqB,GAAGA,OAAO,qBAAqB;IAC7D;IAEA,MAAM,OAAOC,KAAY,EAAuB;QAC5C,IAAIA,MAAM,OAAO,KAAK,IAAI,CAAC,qBAAqB,EAAE;YAC9CC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,oCAAoC,CAAC;YAGlG,OAAO,IAAIC,qBACP,MAAM,IAAI,CAAC,eAAe,CAACF,QAC3B,IAAI,CAAC,eAAe;QAE5B;QAEAC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,0CAA0C,CAAC;QAExG,OAAO,IAAIE,mBAAmBH;IAClC;IAEU,gBAAgBA,KAAY,EAAE;QACpC,OAAOI,aACH,IAAI,CAAC,EAAE,EACP,IAAIC,iBAAiB;YACjB,QAAQ,IAAI,CAAC,MAAM;YACnB,KAAKL,MAAM,MAAM;QACrB,IACA;YAAE,WAAW,IAAI,CAAC,eAAe;QAAC;IAE1C;AACJ;AAEO,MAAMM,uBAAuBC,oBAAAA,oBAAmD,CAAC;IACpF,gBAAgBX;IAChB,cAAc;QAACY;QAAUC;QAAUC;KAAsB;AAC7D"}
@@ -0,0 +1,4 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ export declare class S3RedirectAssetReply extends AssetReply {
3
+ constructor(url: string, cacheDuration: number);
4
+ }
@@ -0,0 +1,17 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ import { ResponseHeaders } from "@webiny/handler";
3
+ class S3RedirectAssetReply extends AssetReply {
4
+ constructor(url, cacheDuration){
5
+ super({
6
+ code: 301,
7
+ headers: ResponseHeaders.create({
8
+ location: url,
9
+ "cache-control": "public, max-age=" + cacheDuration
10
+ }),
11
+ body: ()=>""
12
+ });
13
+ }
14
+ }
15
+ export { S3RedirectAssetReply };
16
+
17
+ //# sourceMappingURL=S3RedirectAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3RedirectAssetReply.js","sources":["../../../src/assetDelivery/s3/S3RedirectAssetReply.ts"],"sourcesContent":["import { AssetReply } from \"@webiny/api-file-manager\";\nimport { ResponseHeaders } from \"@webiny/handler\";\n\nexport class S3RedirectAssetReply extends AssetReply {\n constructor(url: string, cacheDuration: number) {\n super({\n code: 301,\n headers: ResponseHeaders.create({\n location: url,\n \"cache-control\": \"public, max-age=\" + cacheDuration\n }),\n body: () => \"\"\n });\n }\n}\n"],"names":["S3RedirectAssetReply","AssetReply","url","cacheDuration","ResponseHeaders"],"mappings":";;AAGO,MAAMA,6BAA6BC;IACtC,YAAYC,GAAW,EAAEC,aAAqB,CAAE;QAC5C,KAAK,CAAC;YACF,MAAM;YACN,SAASC,gBAAgB,MAAM,CAAC;gBAC5B,UAAUF;gBACV,iBAAiB,qBAAqBC;YAC1C;YACA,MAAM,IAAM;QAChB;IACJ;AACJ"}
@@ -0,0 +1,5 @@
1
+ import type { Asset } from "@webiny/api-file-manager";
2
+ import { AssetReply } from "@webiny/api-file-manager";
3
+ export declare class S3StreamAssetReply extends AssetReply {
4
+ constructor(asset: Asset);
5
+ }
@@ -0,0 +1,17 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ import { ResponseHeaders } from "@webiny/handler";
3
+ class S3StreamAssetReply extends AssetReply {
4
+ constructor(asset){
5
+ super({
6
+ code: 200,
7
+ headers: ResponseHeaders.create({
8
+ "cache-control": "public, max-age=31536000",
9
+ "content-type": asset.getContentType()
10
+ }),
11
+ body: ()=>asset.getContents()
12
+ });
13
+ }
14
+ }
15
+ export { S3StreamAssetReply };
16
+
17
+ //# sourceMappingURL=S3StreamAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/S3StreamAssetReply.js","sources":["../../../src/assetDelivery/s3/S3StreamAssetReply.ts"],"sourcesContent":["import type { Asset } from \"@webiny/api-file-manager\";\nimport { AssetReply } from \"@webiny/api-file-manager\";\nimport { ResponseHeaders } from \"@webiny/handler\";\n\nexport class S3StreamAssetReply extends AssetReply {\n constructor(asset: Asset) {\n super({\n code: 200,\n headers: ResponseHeaders.create({\n \"cache-control\": `public, max-age=${86400 * 365}`,\n \"content-type\": asset.getContentType()\n }),\n body: () => asset.getContents()\n });\n }\n}\n"],"names":["S3StreamAssetReply","AssetReply","asset","ResponseHeaders"],"mappings":";;AAIO,MAAMA,2BAA2BC;IACpC,YAAYC,KAAY,CAAE;QACtB,KAAK,CAAC;YACF,MAAM;YACN,SAASC,gBAAgB,MAAM,CAAC;gBAC5B,iBAAiB;gBACjB,gBAAgBD,MAAM,cAAc;YACxC;YACA,MAAM,IAAMA,MAAM,WAAW;QACjC;IACJ;AACJ"}
@@ -0,0 +1,18 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import type { Asset, AssetRequest, AssetTransformationStrategy } from "@webiny/api-file-manager";
3
+ import type { IS3AssetDeliveryConfig } from "../../assetDelivery/abstractions.js";
4
+ export declare class SharpTransform implements AssetTransformationStrategy {
5
+ private readonly s3;
6
+ private readonly bucket;
7
+ private readonly imageResizeWidths;
8
+ constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig);
9
+ transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset>;
10
+ private transformAsset;
11
+ private optimizeAsset;
12
+ private isAssetAnimated;
13
+ private optimizePng;
14
+ private optimizeJpeg;
15
+ }
16
+ export declare const SharpTransformImpl: typeof SharpTransform & {
17
+ __abstraction: import("@webiny/di").Abstraction<AssetTransformationStrategy>;
18
+ };
@@ -0,0 +1,162 @@
1
+ import sharp from "sharp";
2
+ import { AssetTransformationStrategy } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
3
+ import { WidthCollection } from "./transformation/WidthCollection.js";
4
+ import { CallableContentsReader } from "./transformation/CallableContentsReader.js";
5
+ import { AssetKeyGenerator } from "./transformation/AssetKeyGenerator.js";
6
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "../abstractions.js";
7
+ import * as __rspack_external__transformation_utils_js_d3dc8821 from "./transformation/utils.js";
8
+ class SharpTransform {
9
+ constructor(s3, bucket, config){
10
+ this.s3 = s3;
11
+ this.bucket = bucket;
12
+ this.imageResizeWidths = config.imageResizeWidths;
13
+ }
14
+ async transform(assetRequest, asset) {
15
+ if (!__rspack_external__transformation_utils_js_d3dc8821.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {
16
+ console.log(`Transformations/optimizations of ${asset.getContentType()} assets are not supported. Skipping.`);
17
+ return asset;
18
+ }
19
+ const { original, ...options } = assetRequest.getOptions();
20
+ const transformedAsset = asset.clone();
21
+ if (Object.keys(options).length > 0) return this.transformAsset(transformedAsset, options);
22
+ return this.optimizeAsset(transformedAsset);
23
+ }
24
+ async transformAsset(asset, options) {
25
+ if (options.width) {
26
+ const assetKey = new AssetKeyGenerator(asset);
27
+ const transformedAssetKey = assetKey.getTransformedImageKey(options);
28
+ try {
29
+ const { Body } = await this.s3.getObject({
30
+ Bucket: this.bucket,
31
+ Key: transformedAssetKey
32
+ });
33
+ if (!Body) throw new Error("Missing image body!");
34
+ const buffer = Buffer.from(await Body.transformToByteArray());
35
+ const newAsset = asset.withProps({
36
+ size: buffer.length
37
+ });
38
+ newAsset.setContentsReader(new CallableContentsReader(()=>buffer));
39
+ console.log("Return a previously transformed asset", {
40
+ key: transformedAssetKey,
41
+ size: newAsset.getSize()
42
+ });
43
+ return newAsset;
44
+ } catch {
45
+ const optimizedImage = await this.optimizeAsset(asset);
46
+ const widths = new WidthCollection(this.imageResizeWidths);
47
+ const width = widths.getClosestOrMax(options.width);
48
+ console.log(`Resize the asset (width: ${width})`);
49
+ const buffer = await optimizedImage.getContents();
50
+ const transformedBuffer = await sharp(buffer, {
51
+ animated: this.isAssetAnimated(asset)
52
+ }).withMetadata().resize({
53
+ width,
54
+ withoutEnlargement: true
55
+ }).toBuffer();
56
+ const newAsset = asset.withProps({
57
+ size: transformedBuffer.length
58
+ });
59
+ newAsset.setContentsReader(new CallableContentsReader(()=>transformedBuffer));
60
+ await this.s3.putObject({
61
+ Bucket: this.bucket,
62
+ Key: transformedAssetKey,
63
+ ContentType: newAsset.getContentType(),
64
+ Body: await newAsset.getContents()
65
+ });
66
+ console.log("Return the resized asset", {
67
+ key: transformedAssetKey,
68
+ size: newAsset.getSize()
69
+ });
70
+ return newAsset;
71
+ }
72
+ }
73
+ return asset;
74
+ }
75
+ async optimizeAsset(asset) {
76
+ console.log("Optimize asset", {
77
+ id: asset.getId(),
78
+ key: asset.getKey(),
79
+ size: asset.getSize(),
80
+ type: asset.getContentType()
81
+ });
82
+ const assetKey = new AssetKeyGenerator(asset);
83
+ const optimizedAssetKey = assetKey.getOptimizedImageKey();
84
+ try {
85
+ const { Body } = await this.s3.getObject({
86
+ Bucket: this.bucket,
87
+ Key: optimizedAssetKey
88
+ });
89
+ if (!Body) throw new Error("Missing image body!");
90
+ console.log("Return a previously optimized asset", optimizedAssetKey);
91
+ const buffer = Buffer.from(await Body.transformToByteArray());
92
+ const newAsset = asset.withProps({
93
+ size: buffer.length
94
+ });
95
+ newAsset.setContentsReader(new CallableContentsReader(()=>buffer));
96
+ return newAsset;
97
+ } catch {
98
+ console.log("Create an optimized version of the original asset", asset.getKey());
99
+ const buffer = await asset.getContents();
100
+ const optimizationMap = {
101
+ "image/png": (buffer)=>this.optimizePng(buffer),
102
+ "image/jpeg": (buffer)=>this.optimizeJpeg(buffer),
103
+ "image/jpg": (buffer)=>this.optimizeJpeg(buffer)
104
+ };
105
+ const optimization = optimizationMap[asset.getContentType()];
106
+ if (!optimization) {
107
+ console.log(`No optimizations defined for ${asset.getContentType()}`);
108
+ return asset;
109
+ }
110
+ const optimizedBuffer = await optimization(buffer).toBuffer();
111
+ console.log("Optimized asset size", optimizedBuffer.length);
112
+ const newAsset = asset.withProps({
113
+ size: optimizedBuffer.length
114
+ });
115
+ newAsset.setContentsReader(new CallableContentsReader(()=>optimizedBuffer));
116
+ await this.s3.putObject({
117
+ Bucket: this.bucket,
118
+ Key: optimizedAssetKey,
119
+ ContentType: newAsset.getContentType(),
120
+ Body: await newAsset.getContents()
121
+ });
122
+ return newAsset;
123
+ }
124
+ }
125
+ isAssetAnimated(asset) {
126
+ return [
127
+ "gif",
128
+ "webp"
129
+ ].includes(asset.getExtension());
130
+ }
131
+ optimizePng(buffer) {
132
+ return sharp(buffer).resize({
133
+ width: 2560,
134
+ withoutEnlargement: true,
135
+ fit: "inside"
136
+ }).png({
137
+ compressionLevel: 9,
138
+ adaptiveFiltering: true,
139
+ force: true
140
+ }).withMetadata();
141
+ }
142
+ optimizeJpeg(buffer) {
143
+ return sharp(buffer).resize({
144
+ width: 2560,
145
+ withoutEnlargement: true,
146
+ fit: "inside"
147
+ }).withMetadata().toFormat("jpeg", {
148
+ quality: 90
149
+ });
150
+ }
151
+ }
152
+ const SharpTransformImpl = AssetTransformationStrategy.createImplementation({
153
+ implementation: SharpTransform,
154
+ dependencies: [
155
+ S3Client,
156
+ S3Bucket,
157
+ S3AssetDeliveryConfig
158
+ ]
159
+ });
160
+ export { SharpTransform, SharpTransformImpl };
161
+
162
+ //# sourceMappingURL=SharpTransform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/s3/SharpTransform.js","sources":["../../../src/assetDelivery/s3/SharpTransform.ts"],"sourcesContent":["import sharp from \"sharp\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type {\n Asset,\n AssetRequest,\n AssetRequestOptions,\n AssetTransformationStrategy\n} from \"@webiny/api-file-manager\";\nimport { AssetTransformationStrategy as AssetTransformationStrategyAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport { WidthCollection } from \"./transformation/WidthCollection.js\";\nimport * as utils from \"./transformation/utils.js\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader.js\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\nimport type { IS3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\n\nexport class SharpTransform implements AssetTransformationStrategy {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly imageResizeWidths: number[];\n\n constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig) {\n this.s3 = s3;\n this.bucket = bucket;\n this.imageResizeWidths = config.imageResizeWidths;\n }\n\n async transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset> {\n if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {\n console.log(\n `Transformations/optimizations of ${asset.getContentType()} assets are not supported. Skipping.`\n );\n return asset;\n }\n\n // oxlint-disable-next-line typescript/no-unused-vars\n const { original, ...options } = assetRequest.getOptions();\n\n const transformedAsset = asset.clone();\n\n if (Object.keys(options).length > 0) {\n return this.transformAsset(transformedAsset, options);\n }\n\n return this.optimizeAsset(transformedAsset);\n }\n\n private async transformAsset(asset: Asset, options: Omit<AssetRequestOptions, \"original\">) {\n if (options.width) {\n const assetKey = new AssetKeyGenerator(asset);\n const transformedAssetKey = assetKey.getTransformedImageKey(options);\n\n try {\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: transformedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n console.log(`Return a previously transformed asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n } catch {\n const optimizedImage = await this.optimizeAsset(asset);\n\n const widths = new WidthCollection(this.imageResizeWidths);\n const width = widths.getClosestOrMax(options.width);\n\n console.log(`Resize the asset (width: ${width})`);\n const buffer = await optimizedImage.getContents();\n const transformedBuffer = await sharp(buffer, {\n animated: this.isAssetAnimated(asset)\n })\n .withMetadata()\n .resize({ width, withoutEnlargement: true })\n .toBuffer();\n\n const newAsset = asset.withProps({ size: transformedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await this.s3.putObject({\n Bucket: this.bucket,\n Key: transformedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n console.log(`Return the resized asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n }\n }\n\n return asset;\n }\n\n private async optimizeAsset(asset: Asset) {\n console.log(\"Optimize asset\", {\n id: asset.getId(),\n key: asset.getKey(),\n size: asset.getSize(),\n type: asset.getContentType()\n });\n\n const assetKey = new AssetKeyGenerator(asset);\n const optimizedAssetKey = assetKey.getOptimizedImageKey();\n\n try {\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: optimizedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n console.log(\"Return a previously optimized asset\", optimizedAssetKey);\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n return newAsset;\n } catch {\n console.log(\"Create an optimized version of the original asset\", asset.getKey());\n const buffer = await asset.getContents();\n\n const optimizationMap: Record<string, ((buffer: Buffer) => sharp.Sharp) | undefined> = {\n \"image/png\": (buffer: Buffer) => this.optimizePng(buffer),\n \"image/jpeg\": (buffer: Buffer) => this.optimizeJpeg(buffer),\n \"image/jpg\": (buffer: Buffer) => this.optimizeJpeg(buffer)\n };\n\n const optimization = optimizationMap[asset.getContentType()];\n\n if (!optimization) {\n console.log(`No optimizations defined for ${asset.getContentType()}`);\n return asset;\n }\n\n const optimizedBuffer = await optimization(buffer).toBuffer();\n\n console.log(\"Optimized asset size\", optimizedBuffer.length);\n\n const newAsset = asset.withProps({ size: optimizedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));\n\n await this.s3.putObject({\n Bucket: this.bucket,\n Key: optimizedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n return newAsset;\n }\n }\n\n private isAssetAnimated(asset: Asset) {\n return [\"gif\", \"webp\"].includes(asset.getExtension());\n }\n\n private optimizePng(buffer: Buffer) {\n return sharp(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .png({ compressionLevel: 9, adaptiveFiltering: true, force: true })\n .withMetadata();\n }\n\n private optimizeJpeg(buffer: Buffer) {\n return sharp(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .withMetadata()\n .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n\nexport const SharpTransformImpl = AssetTransformationStrategyAbstraction.createImplementation({\n implementation: SharpTransform,\n dependencies: [S3Client, S3Bucket, S3AssetDeliveryConfig]\n});\n"],"names":["SharpTransform","s3","bucket","config","assetRequest","asset","utils","console","original","options","transformedAsset","Object","assetKey","AssetKeyGenerator","transformedAssetKey","Body","Error","buffer","Buffer","newAsset","CallableContentsReader","optimizedImage","widths","WidthCollection","width","transformedBuffer","sharp","optimizedAssetKey","optimizationMap","optimization","optimizedBuffer","SharpTransformImpl","AssetTransformationStrategyAbstraction","S3Client","S3Bucket","S3AssetDeliveryConfig"],"mappings":"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"}