@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
@@ -1,16 +1,10 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.S3StreamAssetReply = void 0;
7
- var _apiFileManager = require("@webiny/api-file-manager");
8
- var _handler = require("@webiny/handler");
9
- class S3StreamAssetReply extends _apiFileManager.AssetReply {
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ import { ResponseHeaders } from "@webiny/handler";
3
+ export class S3StreamAssetReply extends AssetReply {
10
4
  constructor(asset) {
11
5
  super({
12
6
  code: 200,
13
- headers: _handler.ResponseHeaders.create({
7
+ headers: ResponseHeaders.create({
14
8
  "cache-control": `public, max-age=${86400 * 365}`,
15
9
  "content-type": asset.getContentType()
16
10
  }),
@@ -18,6 +12,5 @@ class S3StreamAssetReply extends _apiFileManager.AssetReply {
18
12
  });
19
13
  }
20
14
  }
21
- exports.S3StreamAssetReply = S3StreamAssetReply;
22
15
 
23
16
  //# sourceMappingURL=S3StreamAssetReply.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_apiFileManager","require","_handler","S3StreamAssetReply","AssetReply","constructor","asset","code","headers","ResponseHeaders","create","getContentType","body","getContents","exports"],"sources":["S3StreamAssetReply.ts"],"sourcesContent":["import { Asset, 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"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEO,MAAME,kBAAkB,SAASC,0BAAU,CAAC;EAC/CC,WAAWA,CAACC,KAAY,EAAE;IACtB,KAAK,CAAC;MACFC,IAAI,EAAE,GAAG;MACTC,OAAO,EAAEC,wBAAe,CAACC,MAAM,CAAC;QAC5B,eAAe,EAAG,mBAAkB,KAAK,GAAG,GAAI,EAAC;QACjD,cAAc,EAAEJ,KAAK,CAACK,cAAc,CAAC;MACzC,CAAC,CAAC;MACFC,IAAI,EAAEA,CAAA,KAAMN,KAAK,CAACO,WAAW,CAAC;IAClC,CAAC,CAAC;EACN;AACJ;AAACC,OAAA,CAAAX,kBAAA,GAAAA,kBAAA","ignoreList":[]}
1
+ {"version":3,"names":["AssetReply","ResponseHeaders","S3StreamAssetReply","constructor","asset","code","headers","create","getContentType","body","getContents"],"sources":["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"],"mappings":"AACA,SAASA,UAAU,QAAQ,0BAA0B;AACrD,SAASC,eAAe,QAAQ,iBAAiB;AAEjD,OAAO,MAAMC,kBAAkB,SAASF,UAAU,CAAC;EAC/CG,WAAWA,CAACC,KAAY,EAAE;IACtB,KAAK,CAAC;MACFC,IAAI,EAAE,GAAG;MACTC,OAAO,EAAEL,eAAe,CAACM,MAAM,CAAC;QAC5B,eAAe,EAAE,mBAAmB,KAAK,GAAG,GAAG,EAAE;QACjD,cAAc,EAAEH,KAAK,CAACI,cAAc,CAAC;MACzC,CAAC,CAAC;MACFC,IAAI,EAAEA,CAAA,KAAML,KAAK,CAACM,WAAW,CAAC;IAClC,CAAC,CAAC;EACN;AACJ","ignoreList":[]}
@@ -1,5 +1,5 @@
1
- import { S3 } from "@webiny/aws-sdk/client-s3";
2
- import { Asset, AssetRequest, AssetTransformationStrategy } from "@webiny/api-file-manager";
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ import type { Asset, AssetRequest, AssetTransformationStrategy } from "@webiny/api-file-manager";
3
3
  interface SharpTransformationParams {
4
4
  s3: S3;
5
5
  bucket: string;
@@ -1,22 +1,15 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.SharpTransform = void 0;
9
- var _sharp = _interopRequireDefault(require("sharp"));
10
- var _WidthCollection = require("./transformation/WidthCollection");
11
- var utils = _interopRequireWildcard(require("./transformation/utils"));
12
- var _CallableContentsReader = require("./transformation/CallableContentsReader");
13
- var _AssetKeyGenerator = require("./transformation/AssetKeyGenerator");
14
- class SharpTransform {
1
+ import sharp from "sharp";
2
+ import { WidthCollection } from "./transformation/WidthCollection.js";
3
+ import * as utils from "./transformation/utils.js";
4
+ import { CallableContentsReader } from "./transformation/CallableContentsReader.js";
5
+ import { AssetKeyGenerator } from "./transformation/AssetKeyGenerator.js";
6
+ export class SharpTransform {
15
7
  constructor(params) {
16
8
  this.params = params;
17
9
  }
18
10
  async transform(assetRequest, asset) {
19
11
  if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {
12
+ console.log(`Transformations/optimizations of ${asset.getContentType()} assets are not supported. Skipping.`);
20
13
  return asset;
21
14
  }
22
15
 
@@ -41,7 +34,7 @@ class SharpTransform {
41
34
  s3,
42
35
  bucket
43
36
  } = this.params;
44
- const assetKey = new _AssetKeyGenerator.AssetKeyGenerator(asset);
37
+ const assetKey = new AssetKeyGenerator(asset);
45
38
  const transformedAssetKey = assetKey.getTransformedImageKey(options);
46
39
  try {
47
40
  const {
@@ -54,32 +47,50 @@ class SharpTransform {
54
47
  throw new Error(`Missing image body!`);
55
48
  }
56
49
  const buffer = Buffer.from(await Body.transformToByteArray());
57
- asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => buffer));
58
- } catch (e) {
50
+ const newAsset = asset.withProps({
51
+ size: buffer.length
52
+ });
53
+ newAsset.setContentsReader(new CallableContentsReader(() => buffer));
54
+ console.log(`Return a previously transformed asset`, {
55
+ key: transformedAssetKey,
56
+ size: newAsset.getSize()
57
+ });
58
+ return newAsset;
59
+ } catch {
59
60
  const optimizedImage = await this.optimizeAsset(asset);
60
- const widths = new _WidthCollection.WidthCollection(this.params.imageResizeWidths);
61
+ const widths = new WidthCollection(this.params.imageResizeWidths);
61
62
  const width = widths.getClosestOrMax(options.width);
62
63
 
63
64
  /**
64
65
  * `width` is the only transformation we currently support.
65
66
  */
67
+ console.log(`Resize the asset (width: ${width})`);
66
68
  const buffer = await optimizedImage.getContents();
67
- const transformedBuffer = (0, _sharp.default)(buffer, {
69
+ const transformedBuffer = await sharp(buffer, {
68
70
  animated: this.isAssetAnimated(asset)
69
- }).resize({
70
- width
71
+ }).withMetadata().resize({
72
+ width,
73
+ withoutEnlargement: true
71
74
  }).toBuffer();
72
75
 
73
76
  /**
74
77
  * Transformations are applied to the optimized image.
75
78
  */
76
- asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => transformedBuffer));
79
+ const newAsset = asset.withProps({
80
+ size: transformedBuffer.length
81
+ });
82
+ newAsset.setContentsReader(new CallableContentsReader(() => transformedBuffer));
77
83
  await s3.putObject({
78
84
  Bucket: bucket,
79
85
  Key: transformedAssetKey,
80
- ContentType: asset.getContentType(),
81
- Body: await asset.getContents()
86
+ ContentType: newAsset.getContentType(),
87
+ Body: await newAsset.getContents()
88
+ });
89
+ console.log(`Return the resized asset`, {
90
+ key: transformedAssetKey,
91
+ size: newAsset.getSize()
82
92
  });
93
+ return newAsset;
83
94
  }
84
95
  }
85
96
  return asset;
@@ -89,7 +100,13 @@ class SharpTransform {
89
100
  s3,
90
101
  bucket
91
102
  } = this.params;
92
- const assetKey = new _AssetKeyGenerator.AssetKeyGenerator(asset);
103
+ console.log("Optimize asset", {
104
+ id: asset.getId(),
105
+ key: asset.getKey(),
106
+ size: asset.getSize(),
107
+ type: asset.getContentType()
108
+ });
109
+ const assetKey = new AssetKeyGenerator(asset);
93
110
  const optimizedAssetKey = assetKey.getOptimizedImageKey();
94
111
  try {
95
112
  const {
@@ -101,9 +118,15 @@ class SharpTransform {
101
118
  if (!Body) {
102
119
  throw new Error(`Missing image body!`);
103
120
  }
121
+ console.log("Return a previously optimized asset", optimizedAssetKey);
104
122
  const buffer = Buffer.from(await Body.transformToByteArray());
105
- asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => buffer));
106
- } catch (e) {
123
+ const newAsset = asset.withProps({
124
+ size: buffer.length
125
+ });
126
+ newAsset.setContentsReader(new CallableContentsReader(() => buffer));
127
+ return newAsset;
128
+ } catch {
129
+ console.log("Create an optimized version of the original asset", asset.getKey());
107
130
  // If not found, create an optimized version of the original asset.
108
131
  const buffer = await asset.getContents();
109
132
  const optimizationMap = {
@@ -113,25 +136,29 @@ class SharpTransform {
113
136
  };
114
137
  const optimization = optimizationMap[asset.getContentType()];
115
138
  if (!optimization) {
116
- console.log(`no optimizations defined for ${asset.getContentType()}`);
139
+ console.log(`No optimizations defined for ${asset.getContentType()}`);
117
140
  return asset;
118
141
  }
119
- const optimizedBuffer = optimization(buffer).toBuffer();
120
- asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => optimizedBuffer));
142
+ const optimizedBuffer = await optimization(buffer).toBuffer();
143
+ console.log("Optimized asset size", optimizedBuffer.length);
144
+ const newAsset = asset.withProps({
145
+ size: optimizedBuffer.length
146
+ });
147
+ newAsset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));
121
148
  await s3.putObject({
122
149
  Bucket: bucket,
123
150
  Key: optimizedAssetKey,
124
- ContentType: asset.getContentType(),
125
- Body: await asset.getContents()
151
+ ContentType: newAsset.getContentType(),
152
+ Body: await newAsset.getContents()
126
153
  });
154
+ return newAsset;
127
155
  }
128
- return asset;
129
156
  }
130
157
  isAssetAnimated(asset) {
131
158
  return ["gif", "webp"].includes(asset.getExtension());
132
159
  }
133
160
  optimizePng(buffer) {
134
- return (0, _sharp.default)(buffer).resize({
161
+ return sharp(buffer).resize({
135
162
  width: 2560,
136
163
  withoutEnlargement: true,
137
164
  fit: "inside"
@@ -142,15 +169,14 @@ class SharpTransform {
142
169
  }).withMetadata();
143
170
  }
144
171
  optimizeJpeg(buffer) {
145
- return (0, _sharp.default)(buffer).resize({
172
+ return sharp(buffer).resize({
146
173
  width: 2560,
147
174
  withoutEnlargement: true,
148
175
  fit: "inside"
149
- }).toFormat("jpeg", {
176
+ }).withMetadata().toFormat("jpeg", {
150
177
  quality: 90
151
178
  });
152
179
  }
153
180
  }
154
- exports.SharpTransform = SharpTransform;
155
181
 
156
182
  //# sourceMappingURL=SharpTransform.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_sharp","_interopRequireDefault","require","_WidthCollection","utils","_interopRequireWildcard","_CallableContentsReader","_AssetKeyGenerator","SharpTransform","constructor","params","transform","assetRequest","asset","SUPPORTED_TRANSFORMABLE_IMAGES","includes","getExtension","original","options","getOptions","transformedAsset","clone","Object","keys","length","transformAsset","optimizeAsset","width","s3","bucket","assetKey","AssetKeyGenerator","transformedAssetKey","getTransformedImageKey","Body","getObject","Bucket","Key","Error","buffer","Buffer","from","transformToByteArray","setContentsReader","CallableContentsReader","e","optimizedImage","widths","WidthCollection","imageResizeWidths","getClosestOrMax","getContents","transformedBuffer","sharp","animated","isAssetAnimated","resize","toBuffer","putObject","ContentType","getContentType","optimizedAssetKey","getOptimizedImageKey","optimizationMap","optimizePng","optimizeJpeg","optimization","console","log","optimizedBuffer","withoutEnlargement","fit","png","compressionLevel","adaptiveFiltering","force","withMetadata","toFormat","quality","exports"],"sources":["SharpTransform.ts"],"sourcesContent":["import sharp from \"sharp\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport {\n Asset,\n AssetRequest,\n AssetRequestOptions,\n AssetTransformationStrategy\n} from \"@webiny/api-file-manager\";\nimport { WidthCollection } from \"./transformation/WidthCollection\";\nimport * as utils from \"./transformation/utils\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator\";\n\ninterface SharpTransformationParams {\n s3: S3;\n bucket: string;\n imageResizeWidths: number[];\n}\n\nexport class SharpTransform implements AssetTransformationStrategy {\n private readonly params: SharpTransformationParams;\n\n constructor(params: SharpTransformationParams) {\n this.params = params;\n }\n\n async transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset> {\n if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {\n return asset;\n }\n\n // `original` is part of the request, but it won't even get to this point in the execution.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { original, ...options } = assetRequest.getOptions();\n\n const transformedAsset = asset.clone();\n\n if (Object.keys(options).length > 0) {\n // Transformations were requested.\n return this.transformAsset(transformedAsset, options);\n }\n\n // Return an optimized asset.\n return this.optimizeAsset(transformedAsset);\n }\n\n private async transformAsset(asset: Asset, options: Omit<AssetRequestOptions, \"original\">) {\n if (options.width) {\n const { s3, bucket } = this.params;\n\n const assetKey = new AssetKeyGenerator(asset);\n const transformedAssetKey = assetKey.getTransformedImageKey(options);\n\n try {\n const { Body } = await s3.getObject({\n Bucket: 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 asset.setContentsReader(new CallableContentsReader(() => buffer));\n } catch (e) {\n const optimizedImage = await this.optimizeAsset(asset);\n\n const widths = new WidthCollection(this.params.imageResizeWidths);\n const width = widths.getClosestOrMax(options.width);\n\n /**\n * `width` is the only transformation we currently support.\n */\n const buffer = await optimizedImage.getContents();\n const transformedBuffer = sharp(buffer, { animated: this.isAssetAnimated(asset) })\n .resize({ width })\n .toBuffer();\n\n /**\n * Transformations are applied to the optimized image.\n */\n asset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: transformedAssetKey,\n ContentType: asset.getContentType(),\n Body: await asset.getContents()\n });\n }\n }\n\n return asset;\n }\n\n private async optimizeAsset(asset: Asset) {\n const { s3, bucket } = this.params;\n\n const assetKey = new AssetKeyGenerator(asset);\n const optimizedAssetKey = assetKey.getOptimizedImageKey();\n\n try {\n const { Body } = await s3.getObject({\n Bucket: bucket,\n Key: optimizedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n asset.setContentsReader(new CallableContentsReader(() => buffer));\n } catch (e) {\n // If not found, create an optimized version of the original asset.\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 = optimization(buffer).toBuffer();\n\n asset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: optimizedAssetKey,\n ContentType: asset.getContentType(),\n Body: await asset.getContents()\n });\n }\n\n return asset;\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 .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["sharp","WidthCollection","utils","CallableContentsReader","AssetKeyGenerator","SharpTransform","constructor","params","transform","assetRequest","asset","SUPPORTED_TRANSFORMABLE_IMAGES","includes","getExtension","console","log","getContentType","original","options","getOptions","transformedAsset","clone","Object","keys","length","transformAsset","optimizeAsset","width","s3","bucket","assetKey","transformedAssetKey","getTransformedImageKey","Body","getObject","Bucket","Key","Error","buffer","Buffer","from","transformToByteArray","newAsset","withProps","size","setContentsReader","key","getSize","optimizedImage","widths","imageResizeWidths","getClosestOrMax","getContents","transformedBuffer","animated","isAssetAnimated","withMetadata","resize","withoutEnlargement","toBuffer","putObject","ContentType","id","getId","getKey","type","optimizedAssetKey","getOptimizedImageKey","optimizationMap","optimizePng","optimizeJpeg","optimization","optimizedBuffer","fit","png","compressionLevel","adaptiveFiltering","force","toFormat","quality"],"sources":["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 { WidthCollection } from \"./transformation/WidthCollection.js\";\nimport * as utils from \"./transformation/utils.js\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader.js\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator.js\";\n\ninterface SharpTransformationParams {\n s3: S3;\n bucket: string;\n imageResizeWidths: number[];\n}\n\nexport class SharpTransform implements AssetTransformationStrategy {\n private readonly params: SharpTransformationParams;\n\n constructor(params: SharpTransformationParams) {\n this.params = params;\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 // `original` is part of the request, but it won't even get to this point in the execution.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { original, ...options } = assetRequest.getOptions();\n\n const transformedAsset = asset.clone();\n\n if (Object.keys(options).length > 0) {\n // Transformations were requested.\n return this.transformAsset(transformedAsset, options);\n }\n\n // Return an optimized asset.\n return this.optimizeAsset(transformedAsset);\n }\n\n private async transformAsset(asset: Asset, options: Omit<AssetRequestOptions, \"original\">) {\n if (options.width) {\n const { s3, bucket } = this.params;\n\n const assetKey = new AssetKeyGenerator(asset);\n const transformedAssetKey = assetKey.getTransformedImageKey(options);\n\n try {\n const { Body } = await s3.getObject({\n Bucket: 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.params.imageResizeWidths);\n const width = widths.getClosestOrMax(options.width);\n\n /**\n * `width` is the only transformation we currently support.\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 /**\n * Transformations are applied to the optimized image.\n */\n const newAsset = asset.withProps({ size: transformedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await s3.putObject({\n Bucket: 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 const { s3, bucket } = this.params;\n\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 s3.getObject({\n Bucket: 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 // If not found, create an optimized version of the original asset.\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 s3.putObject({\n Bucket: 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"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAQzB,SAASC,eAAe;AACxB,OAAO,KAAKC,KAAK;AACjB,SAASC,sBAAsB;AAC/B,SAASC,iBAAiB;AAQ1B,OAAO,MAAMC,cAAc,CAAwC;EAG/DC,WAAWA,CAACC,MAAiC,EAAE;IAC3C,IAAI,CAACA,MAAM,GAAGA,MAAM;EACxB;EAEA,MAAMC,SAASA,CAACC,YAA0B,EAAEC,KAAY,EAAkB;IACtE,IAAI,CAACR,KAAK,CAACS,8BAA8B,CAACC,QAAQ,CAACF,KAAK,CAACG,YAAY,CAAC,CAAC,CAAC,EAAE;MACtEC,OAAO,CAACC,GAAG,CACP,oCAAoCL,KAAK,CAACM,cAAc,CAAC,CAAC,sCAC9D,CAAC;MACD,OAAON,KAAK;IAChB;;IAEA;IACA;IACA,MAAM;MAAEO,QAAQ;MAAE,GAAGC;IAAQ,CAAC,GAAGT,YAAY,CAACU,UAAU,CAAC,CAAC;IAE1D,MAAMC,gBAAgB,GAAGV,KAAK,CAACW,KAAK,CAAC,CAAC;IAEtC,IAAIC,MAAM,CAACC,IAAI,CAACL,OAAO,CAAC,CAACM,MAAM,GAAG,CAAC,EAAE;MACjC;MACA,OAAO,IAAI,CAACC,cAAc,CAACL,gBAAgB,EAAEF,OAAO,CAAC;IACzD;;IAEA;IACA,OAAO,IAAI,CAACQ,aAAa,CAACN,gBAAgB,CAAC;EAC/C;EAEA,MAAcK,cAAcA,CAACf,KAAY,EAAEQ,OAA8C,EAAE;IACvF,IAAIA,OAAO,CAACS,KAAK,EAAE;MACf,MAAM;QAAEC,EAAE;QAAEC;MAAO,CAAC,GAAG,IAAI,CAACtB,MAAM;MAElC,MAAMuB,QAAQ,GAAG,IAAI1B,iBAAiB,CAACM,KAAK,CAAC;MAC7C,MAAMqB,mBAAmB,GAAGD,QAAQ,CAACE,sBAAsB,CAACd,OAAO,CAAC;MAEpE,IAAI;QACA,MAAM;UAAEe;QAAK,CAAC,GAAG,MAAML,EAAE,CAACM,SAAS,CAAC;UAChCC,MAAM,EAAEN,MAAM;UACdO,GAAG,EAAEL;QACT,CAAC,CAAC;QAEF,IAAI,CAACE,IAAI,EAAE;UACP,MAAM,IAAII,KAAK,CAAC,qBAAqB,CAAC;QAC1C;QAEA,MAAMC,MAAM,GAAGC,MAAM,CAACC,IAAI,CAAC,MAAMP,IAAI,CAACQ,oBAAoB,CAAC,CAAC,CAAC;QAE7D,MAAMC,QAAQ,GAAGhC,KAAK,CAACiC,SAAS,CAAC;UAAEC,IAAI,EAAEN,MAAM,CAACd;QAAO,CAAC,CAAC;QACzDkB,QAAQ,CAACG,iBAAiB,CAAC,IAAI1C,sBAAsB,CAAC,MAAMmC,MAAM,CAAC,CAAC;QAEpExB,OAAO,CAACC,GAAG,CAAC,uCAAuC,EAAE;UACjD+B,GAAG,EAAEf,mBAAmB;UACxBa,IAAI,EAAEF,QAAQ,CAACK,OAAO,CAAC;QAC3B,CAAC,CAAC;QAEF,OAAOL,QAAQ;MACnB,CAAC,CAAC,MAAM;QACJ,MAAMM,cAAc,GAAG,MAAM,IAAI,CAACtB,aAAa,CAAChB,KAAK,CAAC;QAEtD,MAAMuC,MAAM,GAAG,IAAIhD,eAAe,CAAC,IAAI,CAACM,MAAM,CAAC2C,iBAAiB,CAAC;QACjE,MAAMvB,KAAK,GAAGsB,MAAM,CAACE,eAAe,CAACjC,OAAO,CAACS,KAAK,CAAC;;QAEnD;AAChB;AACA;QACgBb,OAAO,CAACC,GAAG,CAAC,4BAA4BY,KAAK,GAAG,CAAC;QACjD,MAAMW,MAAM,GAAG,MAAMU,cAAc,CAACI,WAAW,CAAC,CAAC;QACjD,MAAMC,iBAAiB,GAAG,MAAMrD,KAAK,CAACsC,MAAM,EAAE;UAC1CgB,QAAQ,EAAE,IAAI,CAACC,eAAe,CAAC7C,KAAK;QACxC,CAAC,CAAC,CACG8C,YAAY,CAAC,CAAC,CACdC,MAAM,CAAC;UAAE9B,KAAK;UAAE+B,kBAAkB,EAAE;QAAK,CAAC,CAAC,CAC3CC,QAAQ,CAAC,CAAC;;QAEf;AAChB;AACA;QACgB,MAAMjB,QAAQ,GAAGhC,KAAK,CAACiC,SAAS,CAAC;UAAEC,IAAI,EAAES,iBAAiB,CAAC7B;QAAO,CAAC,CAAC;QACpEkB,QAAQ,CAACG,iBAAiB,CAAC,IAAI1C,sBAAsB,CAAC,MAAMkD,iBAAiB,CAAC,CAAC;QAE/E,MAAMzB,EAAE,CAACgC,SAAS,CAAC;UACfzB,MAAM,EAAEN,MAAM;UACdO,GAAG,EAAEL,mBAAmB;UACxB8B,WAAW,EAAEnB,QAAQ,CAAC1B,cAAc,CAAC,CAAC;UACtCiB,IAAI,EAAE,MAAMS,QAAQ,CAACU,WAAW,CAAC;QACrC,CAAC,CAAC;QAEFtC,OAAO,CAACC,GAAG,CAAC,0BAA0B,EAAE;UACpC+B,GAAG,EAAEf,mBAAmB;UACxBa,IAAI,EAAEF,QAAQ,CAACK,OAAO,CAAC;QAC3B,CAAC,CAAC;QAEF,OAAOL,QAAQ;MACnB;IACJ;IAEA,OAAOhC,KAAK;EAChB;EAEA,MAAcgB,aAAaA,CAAChB,KAAY,EAAE;IACtC,MAAM;MAAEkB,EAAE;MAAEC;IAAO,CAAC,GAAG,IAAI,CAACtB,MAAM;IAElCO,OAAO,CAACC,GAAG,CAAC,gBAAgB,EAAE;MAC1B+C,EAAE,EAAEpD,KAAK,CAACqD,KAAK,CAAC,CAAC;MACjBjB,GAAG,EAAEpC,KAAK,CAACsD,MAAM,CAAC,CAAC;MACnBpB,IAAI,EAAElC,KAAK,CAACqC,OAAO,CAAC,CAAC;MACrBkB,IAAI,EAAEvD,KAAK,CAACM,cAAc,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAMc,QAAQ,GAAG,IAAI1B,iBAAiB,CAACM,KAAK,CAAC;IAC7C,MAAMwD,iBAAiB,GAAGpC,QAAQ,CAACqC,oBAAoB,CAAC,CAAC;IAEzD,IAAI;MACA,MAAM;QAAElC;MAAK,CAAC,GAAG,MAAML,EAAE,CAACM,SAAS,CAAC;QAChCC,MAAM,EAAEN,MAAM;QACdO,GAAG,EAAE8B;MACT,CAAC,CAAC;MAEF,IAAI,CAACjC,IAAI,EAAE;QACP,MAAM,IAAII,KAAK,CAAC,qBAAqB,CAAC;MAC1C;MAEAvB,OAAO,CAACC,GAAG,CAAC,qCAAqC,EAAEmD,iBAAiB,CAAC;MAErE,MAAM5B,MAAM,GAAGC,MAAM,CAACC,IAAI,CAAC,MAAMP,IAAI,CAACQ,oBAAoB,CAAC,CAAC,CAAC;MAE7D,MAAMC,QAAQ,GAAGhC,KAAK,CAACiC,SAAS,CAAC;QAAEC,IAAI,EAAEN,MAAM,CAACd;MAAO,CAAC,CAAC;MACzDkB,QAAQ,CAACG,iBAAiB,CAAC,IAAI1C,sBAAsB,CAAC,MAAMmC,MAAM,CAAC,CAAC;MAEpE,OAAOI,QAAQ;IACnB,CAAC,CAAC,MAAM;MACJ5B,OAAO,CAACC,GAAG,CAAC,mDAAmD,EAAEL,KAAK,CAACsD,MAAM,CAAC,CAAC,CAAC;MAChF;MACA,MAAM1B,MAAM,GAAG,MAAM5B,KAAK,CAAC0C,WAAW,CAAC,CAAC;MAExC,MAAMgB,eAA8E,GAAG;QACnF,WAAW,EAAG9B,MAAc,IAAK,IAAI,CAAC+B,WAAW,CAAC/B,MAAM,CAAC;QACzD,YAAY,EAAGA,MAAc,IAAK,IAAI,CAACgC,YAAY,CAAChC,MAAM,CAAC;QAC3D,WAAW,EAAGA,MAAc,IAAK,IAAI,CAACgC,YAAY,CAAChC,MAAM;MAC7D,CAAC;MAED,MAAMiC,YAAY,GAAGH,eAAe,CAAC1D,KAAK,CAACM,cAAc,CAAC,CAAC,CAAC;MAE5D,IAAI,CAACuD,YAAY,EAAE;QACfzD,OAAO,CAACC,GAAG,CAAC,gCAAgCL,KAAK,CAACM,cAAc,CAAC,CAAC,EAAE,CAAC;QACrE,OAAON,KAAK;MAChB;MAEA,MAAM8D,eAAe,GAAG,MAAMD,YAAY,CAACjC,MAAM,CAAC,CAACqB,QAAQ,CAAC,CAAC;MAE7D7C,OAAO,CAACC,GAAG,CAAC,sBAAsB,EAAEyD,eAAe,CAAChD,MAAM,CAAC;MAE3D,MAAMkB,QAAQ,GAAGhC,KAAK,CAACiC,SAAS,CAAC;QAAEC,IAAI,EAAE4B,eAAe,CAAChD;MAAO,CAAC,CAAC;MAClEkB,QAAQ,CAACG,iBAAiB,CAAC,IAAI1C,sBAAsB,CAAC,MAAMqE,eAAe,CAAC,CAAC;MAE7E,MAAM5C,EAAE,CAACgC,SAAS,CAAC;QACfzB,MAAM,EAAEN,MAAM;QACdO,GAAG,EAAE8B,iBAAiB;QACtBL,WAAW,EAAEnB,QAAQ,CAAC1B,cAAc,CAAC,CAAC;QACtCiB,IAAI,EAAE,MAAMS,QAAQ,CAACU,WAAW,CAAC;MACrC,CAAC,CAAC;MAEF,OAAOV,QAAQ;IACnB;EACJ;EAEQa,eAAeA,CAAC7C,KAAY,EAAE;IAClC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAACE,QAAQ,CAACF,KAAK,CAACG,YAAY,CAAC,CAAC,CAAC;EACzD;EAEQwD,WAAWA,CAAC/B,MAAc,EAAE;IAChC,OAAOtC,KAAK,CAACsC,MAAM,CAAC,CACfmB,MAAM,CAAC;MAAE9B,KAAK,EAAE,IAAI;MAAE+B,kBAAkB,EAAE,IAAI;MAAEe,GAAG,EAAE;IAAS,CAAC,CAAC,CAChEC,GAAG,CAAC;MAAEC,gBAAgB,EAAE,CAAC;MAAEC,iBAAiB,EAAE,IAAI;MAAEC,KAAK,EAAE;IAAK,CAAC,CAAC,CAClErB,YAAY,CAAC,CAAC;EACvB;EAEQc,YAAYA,CAAChC,MAAc,EAAE;IACjC,OAAOtC,KAAK,CAACsC,MAAM,CAAC,CACfmB,MAAM,CAAC;MAAE9B,KAAK,EAAE,IAAI;MAAE+B,kBAAkB,EAAE,IAAI;MAAEe,GAAG,EAAE;IAAS,CAAC,CAAC,CAChEjB,YAAY,CAAC,CAAC,CACdsB,QAAQ,CAAC,MAAM,EAAE;MAAEC,OAAO,EAAE;IAAG,CAAC,CAAC;EAC1C;AACJ","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import { Asset } from "@webiny/api-file-manager";
1
+ import type { Asset } from "@webiny/api-file-manager";
2
2
  export declare class AssetKeyGenerator {
3
3
  private utils;
4
4
  private asset;
@@ -1,16 +1,8 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.AssetKeyGenerator = void 0;
8
- var newUtils = _interopRequireWildcard(require("./utils"));
9
- var legacyUtils = _interopRequireWildcard(require("./legacyUtils"));
10
- class AssetKeyGenerator {
1
+ import * as newUtils from "./utils.js";
2
+ export class AssetKeyGenerator {
11
3
  constructor(asset) {
12
4
  this.asset = asset;
13
- this.utils = asset.getKey().includes("/") ? newUtils : legacyUtils;
5
+ this.utils = newUtils;
14
6
  }
15
7
  getOptimizedImageKey() {
16
8
  return this.utils.getImageKey({
@@ -24,6 +16,5 @@ class AssetKeyGenerator {
24
16
  });
25
17
  }
26
18
  }
27
- exports.AssetKeyGenerator = AssetKeyGenerator;
28
19
 
29
20
  //# sourceMappingURL=AssetKeyGenerator.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["newUtils","_interopRequireWildcard","require","legacyUtils","AssetKeyGenerator","constructor","asset","utils","getKey","includes","getOptimizedImageKey","getImageKey","key","getTransformedImageKey","transformations","exports"],"sources":["AssetKeyGenerator.ts"],"sourcesContent":["import { Asset } from \"@webiny/api-file-manager\";\nimport * as newUtils from \"./utils\";\nimport * as legacyUtils from \"./legacyUtils\";\n\nexport class AssetKeyGenerator {\n private utils: typeof newUtils;\n private asset: Asset;\n\n constructor(asset: Asset) {\n this.asset = asset;\n this.utils = asset.getKey().includes(\"/\") ? newUtils : legacyUtils;\n }\n\n getOptimizedImageKey() {\n return this.utils.getImageKey({ key: this.asset.getKey() });\n }\n getTransformedImageKey(transformations: Record<string, any>) {\n return this.utils.getImageKey({ key: this.asset.getKey(), transformations });\n }\n}\n"],"mappings":";;;;;;;AACA,IAAAA,QAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,WAAA,GAAAF,uBAAA,CAAAC,OAAA;AAEO,MAAME,iBAAiB,CAAC;EAI3BC,WAAWA,CAACC,KAAY,EAAE;IACtB,IAAI,CAACA,KAAK,GAAGA,KAAK;IAClB,IAAI,CAACC,KAAK,GAAGD,KAAK,CAACE,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,GAAG,CAAC,GAAGT,QAAQ,GAAGG,WAAW;EACtE;EAEAO,oBAAoBA,CAAA,EAAG;IACnB,OAAO,IAAI,CAACH,KAAK,CAACI,WAAW,CAAC;MAAEC,GAAG,EAAE,IAAI,CAACN,KAAK,CAACE,MAAM,CAAC;IAAE,CAAC,CAAC;EAC/D;EACAK,sBAAsBA,CAACC,eAAoC,EAAE;IACzD,OAAO,IAAI,CAACP,KAAK,CAACI,WAAW,CAAC;MAAEC,GAAG,EAAE,IAAI,CAACN,KAAK,CAACE,MAAM,CAAC,CAAC;MAAEM;IAAgB,CAAC,CAAC;EAChF;AACJ;AAACC,OAAA,CAAAX,iBAAA,GAAAA,iBAAA","ignoreList":[]}
1
+ {"version":3,"names":["newUtils","AssetKeyGenerator","constructor","asset","utils","getOptimizedImageKey","getImageKey","key","getKey","getTransformedImageKey","transformations"],"sources":["AssetKeyGenerator.ts"],"sourcesContent":["import type { Asset } from \"@webiny/api-file-manager\";\nimport * as newUtils from \"./utils.js\";\n\nexport class AssetKeyGenerator {\n private utils: typeof newUtils;\n private asset: Asset;\n\n constructor(asset: Asset) {\n this.asset = asset;\n this.utils = newUtils;\n }\n\n getOptimizedImageKey() {\n return this.utils.getImageKey({ key: this.asset.getKey() });\n }\n getTransformedImageKey(transformations: Record<string, any>) {\n return this.utils.getImageKey({ key: this.asset.getKey(), transformations });\n }\n}\n"],"mappings":"AACA,OAAO,KAAKA,QAAQ;AAEpB,OAAO,MAAMC,iBAAiB,CAAC;EAI3BC,WAAWA,CAACC,KAAY,EAAE;IACtB,IAAI,CAACA,KAAK,GAAGA,KAAK;IAClB,IAAI,CAACC,KAAK,GAAGJ,QAAQ;EACzB;EAEAK,oBAAoBA,CAAA,EAAG;IACnB,OAAO,IAAI,CAACD,KAAK,CAACE,WAAW,CAAC;MAAEC,GAAG,EAAE,IAAI,CAACJ,KAAK,CAACK,MAAM,CAAC;IAAE,CAAC,CAAC;EAC/D;EACAC,sBAAsBA,CAACC,eAAoC,EAAE;IACzD,OAAO,IAAI,CAACN,KAAK,CAACE,WAAW,CAAC;MAAEC,GAAG,EAAE,IAAI,CAACJ,KAAK,CAACK,MAAM,CAAC,CAAC;MAAEE;IAAgB,CAAC,CAAC;EAChF;AACJ","ignoreList":[]}
@@ -1,5 +1,4 @@
1
- /// <reference types="node" />
2
- import { AssetContentsReader } from "@webiny/api-file-manager";
1
+ import type { AssetContentsReader } from "@webiny/api-file-manager";
3
2
  interface ContentsCallable {
4
3
  (): Promise<Buffer> | Buffer;
5
4
  }
@@ -1,10 +1,4 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.CallableContentsReader = void 0;
7
- class CallableContentsReader {
1
+ export class CallableContentsReader {
8
2
  constructor(callable) {
9
3
  this.callable = callable;
10
4
  }
@@ -12,6 +6,5 @@ class CallableContentsReader {
12
6
  return this.callable();
13
7
  }
14
8
  }
15
- exports.CallableContentsReader = CallableContentsReader;
16
9
 
17
10
  //# sourceMappingURL=CallableContentsReader.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["CallableContentsReader","constructor","callable","read","exports"],"sources":["CallableContentsReader.ts"],"sourcesContent":["import { AssetContentsReader } from \"@webiny/api-file-manager\";\n\ninterface ContentsCallable {\n (): Promise<Buffer> | Buffer;\n}\n\nexport class CallableContentsReader implements AssetContentsReader {\n private readonly callable: ContentsCallable;\n\n constructor(callable: ContentsCallable) {\n this.callable = callable;\n }\n\n async read(): Promise<Buffer> {\n return this.callable();\n }\n}\n"],"mappings":";;;;;;AAMO,MAAMA,sBAAsB,CAAgC;EAG/DC,WAAWA,CAACC,QAA0B,EAAE;IACpC,IAAI,CAACA,QAAQ,GAAGA,QAAQ;EAC5B;EAEA,MAAMC,IAAIA,CAAA,EAAoB;IAC1B,OAAO,IAAI,CAACD,QAAQ,CAAC,CAAC;EAC1B;AACJ;AAACE,OAAA,CAAAJ,sBAAA,GAAAA,sBAAA","ignoreList":[]}
1
+ {"version":3,"names":["CallableContentsReader","constructor","callable","read"],"sources":["CallableContentsReader.ts"],"sourcesContent":["import type { AssetContentsReader } from \"@webiny/api-file-manager\";\n\ninterface ContentsCallable {\n (): Promise<Buffer> | Buffer;\n}\n\nexport class CallableContentsReader implements AssetContentsReader {\n private readonly callable: ContentsCallable;\n\n constructor(callable: ContentsCallable) {\n this.callable = callable;\n }\n\n async read(): Promise<Buffer> {\n return this.callable();\n }\n}\n"],"mappings":"AAMA,OAAO,MAAMA,sBAAsB,CAAgC;EAG/DC,WAAWA,CAACC,QAA0B,EAAE;IACpC,IAAI,CAACA,QAAQ,GAAGA,QAAQ;EAC5B;EAEA,MAAMC,IAAIA,CAAA,EAAoB;IAC1B,OAAO,IAAI,CAACD,QAAQ,CAAC,CAAC;EAC1B;AACJ","ignoreList":[]}
@@ -1,10 +1,4 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.WidthCollection = void 0;
7
- class WidthCollection {
1
+ export class WidthCollection {
8
2
  constructor(values) {
9
3
  this.values = values.sort((a, b) => a - b);
10
4
  }
@@ -22,6 +16,5 @@ class WidthCollection {
22
16
  return gteGivenValue.length > 0 ? gteGivenValue[0] : this.max();
23
17
  }
24
18
  }
25
- exports.WidthCollection = WidthCollection;
26
19
 
27
20
  //# sourceMappingURL=WidthCollection.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["WidthCollection","constructor","values","sort","a","b","max","Math","min","getClosestOrMax","value","gteGivenValue","filter","w","length","exports"],"sources":["WidthCollection.ts"],"sourcesContent":["export class WidthCollection {\n private readonly values: number[];\n\n constructor(values: number[]) {\n this.values = values.sort((a, b) => a - b);\n }\n\n max() {\n return Math.max(...this.values);\n }\n\n min() {\n return Math.min(...this.values);\n }\n\n getClosestOrMax(value: number | undefined): number {\n if (!value) {\n return this.max();\n }\n const gteGivenValue = this.values.filter(w => w >= value);\n return gteGivenValue.length > 0 ? gteGivenValue[0] : this.max();\n }\n}\n"],"mappings":";;;;;;AAAO,MAAMA,eAAe,CAAC;EAGzBC,WAAWA,CAACC,MAAgB,EAAE;IAC1B,IAAI,CAACA,MAAM,GAAGA,MAAM,CAACC,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,GAAGC,CAAC,CAAC;EAC9C;EAEAC,GAAGA,CAAA,EAAG;IACF,OAAOC,IAAI,CAACD,GAAG,CAAC,GAAG,IAAI,CAACJ,MAAM,CAAC;EACnC;EAEAM,GAAGA,CAAA,EAAG;IACF,OAAOD,IAAI,CAACC,GAAG,CAAC,GAAG,IAAI,CAACN,MAAM,CAAC;EACnC;EAEAO,eAAeA,CAACC,KAAyB,EAAU;IAC/C,IAAI,CAACA,KAAK,EAAE;MACR,OAAO,IAAI,CAACJ,GAAG,CAAC,CAAC;IACrB;IACA,MAAMK,aAAa,GAAG,IAAI,CAACT,MAAM,CAACU,MAAM,CAACC,CAAC,IAAIA,CAAC,IAAIH,KAAK,CAAC;IACzD,OAAOC,aAAa,CAACG,MAAM,GAAG,CAAC,GAAGH,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAACL,GAAG,CAAC,CAAC;EACnE;AACJ;AAACS,OAAA,CAAAf,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"names":["WidthCollection","constructor","values","sort","a","b","max","Math","min","getClosestOrMax","value","gteGivenValue","filter","w","length"],"sources":["WidthCollection.ts"],"sourcesContent":["export class WidthCollection {\n private readonly values: number[];\n\n constructor(values: number[]) {\n this.values = values.sort((a, b) => a - b);\n }\n\n max() {\n return Math.max(...this.values);\n }\n\n min() {\n return Math.min(...this.values);\n }\n\n getClosestOrMax(value: number | undefined): number {\n if (!value) {\n return this.max();\n }\n const gteGivenValue = this.values.filter(w => w >= value);\n return gteGivenValue.length > 0 ? gteGivenValue[0] : this.max();\n }\n}\n"],"mappings":"AAAA,OAAO,MAAMA,eAAe,CAAC;EAGzBC,WAAWA,CAACC,MAAgB,EAAE;IAC1B,IAAI,CAACA,MAAM,GAAGA,MAAM,CAACC,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,GAAGC,CAAC,CAAC;EAC9C;EAEAC,GAAGA,CAAA,EAAG;IACF,OAAOC,IAAI,CAACD,GAAG,CAAC,GAAG,IAAI,CAACJ,MAAM,CAAC;EACnC;EAEAM,GAAGA,CAAA,EAAG;IACF,OAAOD,IAAI,CAACC,GAAG,CAAC,GAAG,IAAI,CAACN,MAAM,CAAC;EACnC;EAEAO,eAAeA,CAACC,KAAyB,EAAU;IAC/C,IAAI,CAACA,KAAK,EAAE;MACR,OAAO,IAAI,CAACJ,GAAG,CAAC,CAAC;IACrB;IACA,MAAMK,aAAa,GAAG,IAAI,CAACT,MAAM,CAACU,MAAM,CAACC,CAAC,IAAIA,CAAC,IAAIH,KAAK,CAAC;IACzD,OAAOC,aAAa,CAACG,MAAM,GAAG,CAAC,GAAGH,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAACL,GAAG,CAAC,CAAC;EACnE;AACJ","ignoreList":[]}
@@ -1,6 +1,4 @@
1
1
  declare const SUPPORTED_TRANSFORMABLE_IMAGES: string[];
2
- declare const OPTIMIZED_TRANSFORMED_IMAGE_PREFIX = "img-o-t-";
3
- declare const OPTIMIZED_IMAGE_PREFIX = "img-o-";
4
2
  declare const getOptimizedImageKeyPrefix: (key: string) => string;
5
3
  declare const getOptimizedTransformedImageKeyPrefix: (key: string, transformationsHash: string) => string;
6
4
  interface GetImageKeyParams {
@@ -8,4 +6,4 @@ interface GetImageKeyParams {
8
6
  transformations?: any;
9
7
  }
10
8
  declare const getImageKey: ({ key, transformations }: GetImageKeyParams) => string;
11
- export { SUPPORTED_TRANSFORMABLE_IMAGES, OPTIMIZED_TRANSFORMED_IMAGE_PREFIX, OPTIMIZED_IMAGE_PREFIX, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
9
+ export { SUPPORTED_TRANSFORMABLE_IMAGES, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
@@ -1,24 +1,28 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.getOptimizedTransformedImageKeyPrefix = exports.getOptimizedImageKeyPrefix = exports.getImageKey = exports.SUPPORTED_TRANSFORMABLE_IMAGES = exports.OPTIMIZED_TRANSFORMED_IMAGE_PREFIX = exports.OPTIMIZED_IMAGE_PREFIX = void 0;
8
- var _objectHash = _interopRequireDefault(require("object-hash"));
9
- const SUPPORTED_TRANSFORMABLE_IMAGES = exports.SUPPORTED_TRANSFORMABLE_IMAGES = ["jpg", "jpeg", "png", "webp"];
10
- const OPTIMIZED_TRANSFORMED_IMAGE_PREFIX = exports.OPTIMIZED_TRANSFORMED_IMAGE_PREFIX = "img-o-t-";
11
- const OPTIMIZED_IMAGE_PREFIX = exports.OPTIMIZED_IMAGE_PREFIX = "img-o-";
1
+ import objectHash from "object-hash";
2
+ import path from "node:path";
3
+ const SUPPORTED_TRANSFORMABLE_IMAGES = ["jpg", "jpeg", "png", "webp"];
4
+ const parseKey = key => {
5
+ const filename = path.basename(key);
6
+ const dirname = path.dirname(key);
7
+ return {
8
+ filename,
9
+ dirname
10
+ };
11
+ };
12
12
  const getOptimizedImageKeyPrefix = key => {
13
- const [id, name] = key.split("/");
14
- return `${id}/${OPTIMIZED_IMAGE_PREFIX}${name}`;
13
+ const {
14
+ filename,
15
+ dirname
16
+ } = parseKey(key);
17
+ return `${dirname}/optimized/${filename}`;
15
18
  };
16
- exports.getOptimizedImageKeyPrefix = getOptimizedImageKeyPrefix;
17
19
  const getOptimizedTransformedImageKeyPrefix = (key, transformationsHash) => {
18
- const [id, name] = key.split("/");
19
- return `${id}/${OPTIMIZED_TRANSFORMED_IMAGE_PREFIX}${transformationsHash}-${name}`;
20
+ const {
21
+ filename,
22
+ dirname
23
+ } = parseKey(key);
24
+ return `${dirname}/optimized/${transformationsHash}-${filename}`;
20
25
  };
21
- exports.getOptimizedTransformedImageKeyPrefix = getOptimizedTransformedImageKeyPrefix;
22
26
  const getImageKey = ({
23
27
  key,
24
28
  transformations
@@ -26,8 +30,8 @@ const getImageKey = ({
26
30
  if (!transformations) {
27
31
  return getOptimizedImageKeyPrefix(key);
28
32
  }
29
- return getOptimizedTransformedImageKeyPrefix(key, (0, _objectHash.default)(transformations));
33
+ return getOptimizedTransformedImageKeyPrefix(key, objectHash(transformations));
30
34
  };
31
- exports.getImageKey = getImageKey;
35
+ export { SUPPORTED_TRANSFORMABLE_IMAGES, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
32
36
 
33
37
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_objectHash","_interopRequireDefault","require","SUPPORTED_TRANSFORMABLE_IMAGES","exports","OPTIMIZED_TRANSFORMED_IMAGE_PREFIX","OPTIMIZED_IMAGE_PREFIX","getOptimizedImageKeyPrefix","key","id","name","split","getOptimizedTransformedImageKeyPrefix","transformationsHash","getImageKey","transformations","objectHash"],"sources":["utils.ts"],"sourcesContent":["import objectHash from \"object-hash\";\n\nconst SUPPORTED_TRANSFORMABLE_IMAGES = [\"jpg\", \"jpeg\", \"png\", \"webp\"];\nconst OPTIMIZED_TRANSFORMED_IMAGE_PREFIX = \"img-o-t-\";\nconst OPTIMIZED_IMAGE_PREFIX = \"img-o-\";\n\nconst getOptimizedImageKeyPrefix = (key: string): string => {\n const [id, name] = key.split(\"/\");\n return `${id}/${OPTIMIZED_IMAGE_PREFIX}${name}`;\n};\n\nconst getOptimizedTransformedImageKeyPrefix = (\n key: string,\n transformationsHash: string\n): string => {\n const [id, name] = key.split(\"/\");\n return `${id}/${OPTIMIZED_TRANSFORMED_IMAGE_PREFIX}${transformationsHash}-${name}`;\n};\n\ninterface GetImageKeyParams {\n key: string;\n transformations?: any;\n}\n\nconst getImageKey = ({ key, transformations }: GetImageKeyParams): string => {\n if (!transformations) {\n return getOptimizedImageKeyPrefix(key);\n }\n\n return getOptimizedTransformedImageKeyPrefix(key, objectHash(transformations));\n};\n\nexport {\n SUPPORTED_TRANSFORMABLE_IMAGES,\n OPTIMIZED_TRANSFORMED_IMAGE_PREFIX,\n OPTIMIZED_IMAGE_PREFIX,\n getImageKey,\n getOptimizedImageKeyPrefix,\n getOptimizedTransformedImageKeyPrefix\n};\n"],"mappings":";;;;;;;AAAA,IAAAA,WAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,MAAMC,8BAA8B,GAAAC,OAAA,CAAAD,8BAAA,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;AACrE,MAAME,kCAAkC,GAAAD,OAAA,CAAAC,kCAAA,GAAG,UAAU;AACrD,MAAMC,sBAAsB,GAAAF,OAAA,CAAAE,sBAAA,GAAG,QAAQ;AAEvC,MAAMC,0BAA0B,GAAIC,GAAW,IAAa;EACxD,MAAM,CAACC,EAAE,EAAEC,IAAI,CAAC,GAAGF,GAAG,CAACG,KAAK,CAAC,GAAG,CAAC;EACjC,OAAQ,GAAEF,EAAG,IAAGH,sBAAuB,GAAEI,IAAK,EAAC;AACnD,CAAC;AAACN,OAAA,CAAAG,0BAAA,GAAAA,0BAAA;AAEF,MAAMK,qCAAqC,GAAGA,CAC1CJ,GAAW,EACXK,mBAA2B,KAClB;EACT,MAAM,CAACJ,EAAE,EAAEC,IAAI,CAAC,GAAGF,GAAG,CAACG,KAAK,CAAC,GAAG,CAAC;EACjC,OAAQ,GAAEF,EAAG,IAAGJ,kCAAmC,GAAEQ,mBAAoB,IAAGH,IAAK,EAAC;AACtF,CAAC;AAACN,OAAA,CAAAQ,qCAAA,GAAAA,qCAAA;AAOF,MAAME,WAAW,GAAGA,CAAC;EAAEN,GAAG;EAAEO;AAAmC,CAAC,KAAa;EACzE,IAAI,CAACA,eAAe,EAAE;IAClB,OAAOR,0BAA0B,CAACC,GAAG,CAAC;EAC1C;EAEA,OAAOI,qCAAqC,CAACJ,GAAG,EAAE,IAAAQ,mBAAU,EAACD,eAAe,CAAC,CAAC;AAClF,CAAC;AAACX,OAAA,CAAAU,WAAA,GAAAA,WAAA","ignoreList":[]}
1
+ {"version":3,"names":["objectHash","path","SUPPORTED_TRANSFORMABLE_IMAGES","parseKey","key","filename","basename","dirname","getOptimizedImageKeyPrefix","getOptimizedTransformedImageKeyPrefix","transformationsHash","getImageKey","transformations"],"sources":["utils.ts"],"sourcesContent":["import objectHash from \"object-hash\";\nimport path from \"node:path\";\n\nconst SUPPORTED_TRANSFORMABLE_IMAGES = [\"jpg\", \"jpeg\", \"png\", \"webp\"];\n\nconst parseKey = (key: string) => {\n const filename = path.basename(key);\n const dirname = path.dirname(key);\n\n return { filename, dirname };\n};\n\nconst getOptimizedImageKeyPrefix = (key: string): string => {\n const { filename, dirname } = parseKey(key);\n\n return `${dirname}/optimized/${filename}`;\n};\n\nconst getOptimizedTransformedImageKeyPrefix = (\n key: string,\n transformationsHash: string\n): string => {\n const { filename, dirname } = parseKey(key);\n\n return `${dirname}/optimized/${transformationsHash}-${filename}`;\n};\n\ninterface GetImageKeyParams {\n key: string;\n transformations?: any;\n}\n\nconst getImageKey = ({ key, transformations }: GetImageKeyParams): string => {\n if (!transformations) {\n return getOptimizedImageKeyPrefix(key);\n }\n\n return getOptimizedTransformedImageKeyPrefix(key, objectHash(transformations));\n};\n\nexport {\n SUPPORTED_TRANSFORMABLE_IMAGES,\n getImageKey,\n getOptimizedImageKeyPrefix,\n getOptimizedTransformedImageKeyPrefix\n};\n"],"mappings":"AAAA,OAAOA,UAAU,MAAM,aAAa;AACpC,OAAOC,IAAI,MAAM,WAAW;AAE5B,MAAMC,8BAA8B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;AAErE,MAAMC,QAAQ,GAAIC,GAAW,IAAK;EAC9B,MAAMC,QAAQ,GAAGJ,IAAI,CAACK,QAAQ,CAACF,GAAG,CAAC;EACnC,MAAMG,OAAO,GAAGN,IAAI,CAACM,OAAO,CAACH,GAAG,CAAC;EAEjC,OAAO;IAAEC,QAAQ;IAAEE;EAAQ,CAAC;AAChC,CAAC;AAED,MAAMC,0BAA0B,GAAIJ,GAAW,IAAa;EACxD,MAAM;IAAEC,QAAQ;IAAEE;EAAQ,CAAC,GAAGJ,QAAQ,CAACC,GAAG,CAAC;EAE3C,OAAO,GAAGG,OAAO,cAAcF,QAAQ,EAAE;AAC7C,CAAC;AAED,MAAMI,qCAAqC,GAAGA,CAC1CL,GAAW,EACXM,mBAA2B,KAClB;EACT,MAAM;IAAEL,QAAQ;IAAEE;EAAQ,CAAC,GAAGJ,QAAQ,CAACC,GAAG,CAAC;EAE3C,OAAO,GAAGG,OAAO,cAAcG,mBAAmB,IAAIL,QAAQ,EAAE;AACpE,CAAC;AAOD,MAAMM,WAAW,GAAGA,CAAC;EAAEP,GAAG;EAAEQ;AAAmC,CAAC,KAAa;EACzE,IAAI,CAACA,eAAe,EAAE;IAClB,OAAOJ,0BAA0B,CAACJ,GAAG,CAAC;EAC1C;EAEA,OAAOK,qCAAqC,CAACL,GAAG,EAAEJ,UAAU,CAACY,eAAe,CAAC,CAAC;AAClF,CAAC;AAED,SACIV,8BAA8B,EAC9BS,WAAW,EACXH,0BAA0B,EAC1BC,qCAAqC","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ export declare class ObjectKey {
2
+ private bucketKey;
3
+ static from(key: string): ObjectKey;
4
+ private constructor();
5
+ id(): string;
6
+ relativeKey(): string;
7
+ }
@@ -0,0 +1,17 @@
1
+ export class ObjectKey {
2
+ static from(key) {
3
+ return new ObjectKey(key);
4
+ }
5
+ constructor(key) {
6
+ this.bucketKey = key;
7
+ }
8
+ id() {
9
+ const [id] = this.relativeKey().split("/");
10
+ return id;
11
+ }
12
+ relativeKey() {
13
+ return this.bucketKey.replace(/^tenants\/[^/]+\/files\//, "");
14
+ }
15
+ }
16
+
17
+ //# sourceMappingURL=ObjectKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ObjectKey","from","key","constructor","bucketKey","id","relativeKey","split","replace"],"sources":["ObjectKey.ts"],"sourcesContent":["export class ObjectKey {\n private bucketKey: string;\n\n static from(key: string) {\n return new ObjectKey(key);\n }\n\n private constructor(key: string) {\n this.bucketKey = key;\n }\n\n id() {\n const [id] = this.relativeKey().split(\"/\");\n return id;\n }\n\n relativeKey() {\n return this.bucketKey.replace(/^tenants\\/[^/]+\\/files\\//, \"\");\n }\n}\n"],"mappings":"AAAA,OAAO,MAAMA,SAAS,CAAC;EAGnB,OAAOC,IAAIA,CAACC,GAAW,EAAE;IACrB,OAAO,IAAIF,SAAS,CAACE,GAAG,CAAC;EAC7B;EAEQC,WAAWA,CAACD,GAAW,EAAE;IAC7B,IAAI,CAACE,SAAS,GAAGF,GAAG;EACxB;EAEAG,EAAEA,CAAA,EAAG;IACD,MAAM,CAACA,EAAE,CAAC,GAAG,IAAI,CAACC,WAAW,CAAC,CAAC,CAACC,KAAK,CAAC,GAAG,CAAC;IAC1C,OAAOF,EAAE;EACb;EAEAC,WAAWA,CAAA,EAAG;IACV,OAAO,IAAI,CAACF,SAAS,CAACI,OAAO,CAAC,0BAA0B,EAAE,EAAE,CAAC;EACjE;AACJ","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import type { GuardDutyEvent } from "./types.js";
2
+ export declare const createThreatDetectionEventHandler: () => (import("@webiny/handler").HandlerOnRequestPlugin<import("@webiny/handler/types.js").Context> | import("@webiny/handler-aws").EventBridgeEventHandler<"GuardDuty Malware Protection Object Scan Result", GuardDutyEvent, any>)[];
@@ -0,0 +1,51 @@
1
+ import { createEventBridgeEventHandler } from "@webiny/handler-aws";
2
+ import { createHandlerOnRequest } from "@webiny/handler";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { processThreatScanResult } from "./processThreatScanResult.js";
5
+ import { ObjectKey } from "./ObjectKey.js";
6
+ const detailType = "GuardDuty Malware Protection Object Scan Result";
7
+ export const createThreatDetectionEventHandler = () => {
8
+ const handlerOnRequest = createHandlerOnRequest(async (request, _, context) => {
9
+ const payload = request.body;
10
+ if (payload["detail-type"] !== detailType) {
11
+ return;
12
+ }
13
+ const objectKey = payload.detail.s3ObjectDetails.objectKey;
14
+ const keyValueStore = context.container.resolve(GlobalKeyValueStore);
15
+ try {
16
+ // Extract file id from the absolute S3 object key
17
+ const fileId = ObjectKey.from(objectKey).id();
18
+ const result = await keyValueStore.get(`FileManager/File/${fileId}/Metadata`);
19
+ if (result.isFail()) {
20
+ return;
21
+ }
22
+ request.headers = {
23
+ ...request.headers,
24
+ "x-tenant": result.value.tenant
25
+ };
26
+ } catch {
27
+ // If metadata can't be loaded, we ignore the file.
28
+ // Most likely it's because the file is a rendition of the original file,
29
+ // so we don't need to do anything with it.
30
+ }
31
+ });
32
+ // Guard Duty event handler.
33
+ const threatScanEventHandler = createEventBridgeEventHandler(async ({
34
+ payload,
35
+ next,
36
+ ...rest
37
+ }) => {
38
+ const context = rest.context;
39
+ const threatDetectionEnabled = context.wcp.canUseFileManagerThreatDetection();
40
+ if (!threatDetectionEnabled || payload["detail-type"] !== detailType) {
41
+ return next();
42
+ }
43
+ await processThreatScanResult(context, payload.detail);
44
+ });
45
+
46
+ // Assign a human-readable name for easier debugging.
47
+ threatScanEventHandler.name = threatScanEventHandler.type + ".threatDetectionEventHandler";
48
+ return [handlerOnRequest, threatScanEventHandler];
49
+ };
50
+
51
+ //# sourceMappingURL=createThreatDetectionEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createEventBridgeEventHandler","createHandlerOnRequest","GlobalKeyValueStore","processThreatScanResult","ObjectKey","detailType","createThreatDetectionEventHandler","handlerOnRequest","request","_","context","payload","body","objectKey","detail","s3ObjectDetails","keyValueStore","container","resolve","fileId","from","id","result","get","isFail","headers","value","tenant","threatScanEventHandler","next","rest","threatDetectionEnabled","wcp","canUseFileManagerThreatDetection","name","type"],"sources":["createThreatDetectionEventHandler.ts"],"sourcesContent":["import { createEventBridgeEventHandler } from \"@webiny/handler-aws\";\nimport { createHandlerOnRequest } from \"@webiny/handler\";\nimport type { EventBridgeEvent } from \"@webiny/aws-sdk/types/index.js\";\nimport type { ApiCoreContext } from \"@webiny/api-core/types/core.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport type { GuardDutyEvent } from \"./types.js\";\nimport { processThreatScanResult } from \"./processThreatScanResult.js\";\nimport { ObjectKey } from \"./ObjectKey.js\";\n\nconst detailType = \"GuardDuty Malware Protection Object Scan Result\";\n\nexport const createThreatDetectionEventHandler = () => {\n const handlerOnRequest = createHandlerOnRequest(async (request, _, context) => {\n const payload = request.body as EventBridgeEvent<string, GuardDutyEvent>;\n\n if (payload[\"detail-type\"] !== detailType) {\n return;\n }\n\n const objectKey = payload.detail.s3ObjectDetails.objectKey;\n const keyValueStore = context.container.resolve(GlobalKeyValueStore);\n\n try {\n // Extract file id from the absolute S3 object key\n const fileId = ObjectKey.from(objectKey).id();\n const result = await keyValueStore.get<{ tenant: string }>(\n `FileManager/File/${fileId}/Metadata`\n );\n\n if (result.isFail()) {\n return;\n }\n\n request.headers = {\n ...request.headers,\n \"x-tenant\": result.value.tenant\n };\n } catch {\n // If metadata can't be loaded, we ignore the file.\n // Most likely it's because the file is a rendition of the original file,\n // so we don't need to do anything with it.\n }\n });\n // Guard Duty event handler.\n const threatScanEventHandler = createEventBridgeEventHandler<typeof detailType, GuardDutyEvent>(\n async ({ payload, next, ...rest }) => {\n const context = rest.context as ApiCoreContext;\n\n const threatDetectionEnabled = context.wcp.canUseFileManagerThreatDetection();\n\n if (!threatDetectionEnabled || payload[\"detail-type\"] !== detailType) {\n return next();\n }\n\n await processThreatScanResult(context, payload.detail);\n }\n );\n\n // Assign a human-readable name for easier debugging.\n threatScanEventHandler.name = threatScanEventHandler.type + \".threatDetectionEventHandler\";\n\n return [handlerOnRequest, threatScanEventHandler];\n};\n"],"mappings":"AAAA,SAASA,6BAA6B,QAAQ,qBAAqB;AACnE,SAASC,sBAAsB,QAAQ,iBAAiB;AAGxD,SAASC,mBAAmB,QAAQ,kDAAkD;AAEtF,SAASC,uBAAuB;AAChC,SAASC,SAAS;AAElB,MAAMC,UAAU,GAAG,iDAAiD;AAEpE,OAAO,MAAMC,iCAAiC,GAAGA,CAAA,KAAM;EACnD,MAAMC,gBAAgB,GAAGN,sBAAsB,CAAC,OAAOO,OAAO,EAAEC,CAAC,EAAEC,OAAO,KAAK;IAC3E,MAAMC,OAAO,GAAGH,OAAO,CAACI,IAAgD;IAExE,IAAID,OAAO,CAAC,aAAa,CAAC,KAAKN,UAAU,EAAE;MACvC;IACJ;IAEA,MAAMQ,SAAS,GAAGF,OAAO,CAACG,MAAM,CAACC,eAAe,CAACF,SAAS;IAC1D,MAAMG,aAAa,GAAGN,OAAO,CAACO,SAAS,CAACC,OAAO,CAAChB,mBAAmB,CAAC;IAEpE,IAAI;MACA;MACA,MAAMiB,MAAM,GAAGf,SAAS,CAACgB,IAAI,CAACP,SAAS,CAAC,CAACQ,EAAE,CAAC,CAAC;MAC7C,MAAMC,MAAM,GAAG,MAAMN,aAAa,CAACO,GAAG,CAClC,oBAAoBJ,MAAM,WAC9B,CAAC;MAED,IAAIG,MAAM,CAACE,MAAM,CAAC,CAAC,EAAE;QACjB;MACJ;MAEAhB,OAAO,CAACiB,OAAO,GAAG;QACd,GAAGjB,OAAO,CAACiB,OAAO;QAClB,UAAU,EAAEH,MAAM,CAACI,KAAK,CAACC;MAC7B,CAAC;IACL,CAAC,CAAC,MAAM;MACJ;MACA;MACA;IAAA;EAER,CAAC,CAAC;EACF;EACA,MAAMC,sBAAsB,GAAG5B,6BAA6B,CACxD,OAAO;IAAEW,OAAO;IAAEkB,IAAI;IAAE,GAAGC;EAAK,CAAC,KAAK;IAClC,MAAMpB,OAAO,GAAGoB,IAAI,CAACpB,OAAyB;IAE9C,MAAMqB,sBAAsB,GAAGrB,OAAO,CAACsB,GAAG,CAACC,gCAAgC,CAAC,CAAC;IAE7E,IAAI,CAACF,sBAAsB,IAAIpB,OAAO,CAAC,aAAa,CAAC,KAAKN,UAAU,EAAE;MAClE,OAAOwB,IAAI,CAAC,CAAC;IACjB;IAEA,MAAM1B,uBAAuB,CAACO,OAAO,EAAEC,OAAO,CAACG,MAAM,CAAC;EAC1D,CACJ,CAAC;;EAED;EACAc,sBAAsB,CAACM,IAAI,GAAGN,sBAAsB,CAACO,IAAI,GAAG,8BAA8B;EAE1F,OAAO,CAAC5B,gBAAgB,EAAEqB,sBAAsB,CAAC;AACrD,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import type { PluginFactory } from "@webiny/plugins/types.js";
2
+ export declare const createThreatDetectionPluginLoader: (cb: PluginFactory) => PluginFactory;
@@ -0,0 +1,6 @@
1
+ import { createConditionalPluginFactory } from "@webiny/api";
2
+ export const createThreatDetectionPluginLoader = cb => {
3
+ return createConditionalPluginFactory(() => process.env.WEBINY_FUNCTION_TYPE === "threat-detection-event-handler", cb);
4
+ };
5
+
6
+ //# sourceMappingURL=createThreatDetectionPluginLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createConditionalPluginFactory","createThreatDetectionPluginLoader","cb","process","env","WEBINY_FUNCTION_TYPE"],"sources":["createThreatDetectionPluginLoader.ts"],"sourcesContent":["import type { PluginFactory } from \"@webiny/plugins/types.js\";\nimport { createConditionalPluginFactory } from \"@webiny/api\";\n\nexport const createThreatDetectionPluginLoader = (cb: PluginFactory) => {\n return createConditionalPluginFactory(\n () => process.env.WEBINY_FUNCTION_TYPE === \"threat-detection-event-handler\",\n cb\n );\n};\n"],"mappings":"AACA,SAASA,8BAA8B,QAAQ,aAAa;AAE5D,OAAO,MAAMC,iCAAiC,GAAIC,EAAiB,IAAK;EACpE,OAAOF,8BAA8B,CACjC,MAAMG,OAAO,CAACC,GAAG,CAACC,oBAAoB,KAAK,gCAAgC,EAC3EH,EACJ,CAAC;AACL,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from "./createThreatDetectionEventHandler.js";
2
+ export * from "./createThreatDetectionPluginLoader.js";