@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.
- package/README.md +11 -1
- package/assetDelivery/assetDeliveryConfig.d.ts +2 -6
- package/assetDelivery/assetDeliveryConfig.js +24 -23
- package/assetDelivery/assetDeliveryConfig.js.map +1 -1
- package/assetDelivery/createAssetDelivery.d.ts +3 -3
- package/assetDelivery/createAssetDelivery.js +15 -12
- package/assetDelivery/createAssetDelivery.js.map +1 -1
- package/assetDelivery/index.d.ts +8 -9
- package/assetDelivery/index.js +8 -68
- package/assetDelivery/index.js.map +1 -1
- package/assetDelivery/s3/S3AssetResolver.d.ts +8 -5
- package/assetDelivery/s3/S3AssetResolver.js +19 -27
- package/assetDelivery/s3/S3AssetResolver.js.map +1 -1
- package/assetDelivery/s3/S3ContentsReader.d.ts +2 -3
- package/assetDelivery/s3/S3ContentsReader.js +1 -8
- package/assetDelivery/s3/S3ContentsReader.js.map +1 -1
- package/assetDelivery/s3/S3ErrorAssetReply.js +2 -9
- package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -1
- package/assetDelivery/s3/S3OutputStrategy.d.ts +4 -3
- package/assetDelivery/s3/S3OutputStrategy.js +12 -17
- package/assetDelivery/s3/S3OutputStrategy.js.map +1 -1
- package/assetDelivery/s3/S3RedirectAssetReply.js +4 -11
- package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -1
- package/assetDelivery/s3/S3StreamAssetReply.d.ts +2 -1
- package/assetDelivery/s3/S3StreamAssetReply.js +4 -11
- package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -1
- package/assetDelivery/s3/SharpTransform.d.ts +2 -2
- package/assetDelivery/s3/SharpTransform.js +63 -37
- package/assetDelivery/s3/SharpTransform.js.map +1 -1
- package/assetDelivery/s3/transformation/AssetKeyGenerator.d.ts +1 -1
- package/assetDelivery/s3/transformation/AssetKeyGenerator.js +3 -12
- package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -1
- package/assetDelivery/s3/transformation/CallableContentsReader.d.ts +1 -2
- package/assetDelivery/s3/transformation/CallableContentsReader.js +1 -8
- package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -1
- package/assetDelivery/s3/transformation/WidthCollection.js +1 -8
- package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -1
- package/assetDelivery/s3/transformation/utils.d.ts +1 -3
- package/assetDelivery/s3/transformation/utils.js +23 -19
- package/assetDelivery/s3/transformation/utils.js.map +1 -1
- package/assetDelivery/threatDetection/ObjectKey.d.ts +7 -0
- package/assetDelivery/threatDetection/ObjectKey.js +17 -0
- package/assetDelivery/threatDetection/ObjectKey.js.map +1 -0
- package/assetDelivery/threatDetection/createThreatDetectionEventHandler.d.ts +2 -0
- package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js +51 -0
- package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js.map +1 -0
- package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.d.ts +2 -0
- package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js +6 -0
- package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js.map +1 -0
- package/assetDelivery/threatDetection/index.d.ts +2 -0
- package/assetDelivery/threatDetection/index.js +4 -0
- package/assetDelivery/threatDetection/index.js.map +1 -0
- package/assetDelivery/threatDetection/processThreatScanResult.d.ts +3 -0
- package/assetDelivery/threatDetection/processThreatScanResult.js +65 -0
- package/assetDelivery/threatDetection/processThreatScanResult.js.map +1 -0
- package/assetDelivery/threatDetection/types.d.ts +9 -0
- package/assetDelivery/threatDetection/types.js +3 -0
- package/assetDelivery/threatDetection/types.js.map +1 -0
- package/assetDelivery/types.d.ts +10 -0
- package/assetDelivery/types.js +3 -0
- package/assetDelivery/types.js.map +1 -0
- package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.d.ts +11 -0
- package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js +19 -0
- package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js.map +1 -0
- package/enterprise/ApplyThreatScanning/feature.d.ts +1 -0
- package/enterprise/ApplyThreatScanning/feature.js +10 -0
- package/enterprise/ApplyThreatScanning/feature.js.map +1 -0
- package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.d.ts +15 -0
- package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js +36 -0
- package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js.map +1 -0
- package/features/DeleteFileFromBucket/DeleteS3FolderTask.d.ts +31 -0
- package/features/DeleteFileFromBucket/DeleteS3FolderTask.js +60 -0
- package/features/DeleteFileFromBucket/DeleteS3FolderTask.js.map +1 -0
- package/features/DeleteFileFromBucket/feature.d.ts +1 -0
- package/features/DeleteFileFromBucket/feature.js +12 -0
- package/features/DeleteFileFromBucket/feature.js.map +1 -0
- package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +11 -0
- package/features/ExtractMetadata/ExtractMetadataHandler.js +26 -0
- package/features/ExtractMetadata/ExtractMetadataHandler.js.map +1 -0
- package/features/ExtractMetadata/ExtractMetadataTask.d.ts +23 -0
- package/features/ExtractMetadata/ExtractMetadataTask.js +128 -0
- package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
- package/features/ExtractMetadata/feature.d.ts +1 -0
- package/features/ExtractMetadata/feature.js +12 -0
- package/features/ExtractMetadata/feature.js.map +1 -0
- package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +12 -0
- package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +27 -0
- package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
- package/features/FlushCache/FlushCacheOnFileUpdateHandler.d.ts +12 -0
- package/features/FlushCache/FlushCacheOnFileUpdateHandler.js +35 -0
- package/features/FlushCache/FlushCacheOnFileUpdateHandler.js.map +1 -0
- package/features/FlushCache/InvalidateCacheTask.d.ts +25 -0
- package/features/FlushCache/InvalidateCacheTask.js +86 -0
- package/features/FlushCache/InvalidateCacheTask.js.map +1 -0
- package/features/FlushCache/feature.d.ts +1 -0
- package/features/FlushCache/feature.js +14 -0
- package/features/FlushCache/feature.js.map +1 -0
- package/features/WriteFileMetadata/MetadataReader.d.ts +14 -0
- package/features/WriteFileMetadata/MetadataReader.js +14 -0
- package/features/WriteFileMetadata/MetadataReader.js.map +1 -0
- package/features/WriteFileMetadata/MetadataWriter.d.ts +10 -0
- package/features/WriteFileMetadata/MetadataWriter.js +28 -0
- package/features/WriteFileMetadata/MetadataWriter.js.map +1 -0
- package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.d.ts +12 -0
- package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +21 -0
- package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -0
- package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.d.ts +12 -0
- package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +21 -0
- package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -0
- package/features/WriteFileMetadata/feature.d.ts +1 -0
- package/features/WriteFileMetadata/feature.js +12 -0
- package/features/WriteFileMetadata/feature.js.map +1 -0
- package/graphql/checkPermissions.d.ts +5 -0
- package/{plugins → graphql}/checkPermissions.js +4 -11
- package/graphql/checkPermissions.js.map +1 -0
- package/graphql/schema.d.ts +1 -0
- package/{plugins/graphqlFileStorageS3.js → graphql/schema.js} +49 -57
- package/graphql/schema.js.map +1 -0
- package/index.d.ts +4 -5
- package/index.js +21 -32
- package/index.js.map +1 -1
- package/multiPartUpload/CompleteMultiPartUploadUseCase.d.ts +1 -1
- package/multiPartUpload/CompleteMultiPartUploadUseCase.js +4 -11
- package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -1
- package/multiPartUpload/CreateMultiPartUploadUseCase.d.ts +2 -2
- package/multiPartUpload/CreateMultiPartUploadUseCase.js +3 -10
- package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -1
- package/package.json +23 -29
- package/types.d.ts +1 -1
- package/types.js +1 -5
- package/types.js.map +1 -1
- package/utils/CdnPathsGenerator.d.ts +3 -0
- package/utils/CdnPathsGenerator.js +7 -0
- package/utils/CdnPathsGenerator.js.map +1 -0
- package/utils/FileExtension.d.ts +1 -1
- package/utils/FileExtension.js +3 -10
- package/utils/FileExtension.js.map +1 -1
- package/utils/FileKey.d.ts +1 -1
- package/utils/FileKey.js +5 -13
- package/utils/FileKey.js.map +1 -1
- package/utils/FileKey.test.js +8 -9
- package/utils/FileKey.test.js.map +1 -1
- package/utils/FileNormalizer.d.ts +2 -2
- package/utils/FileNormalizer.js +5 -12
- package/utils/FileNormalizer.js.map +1 -1
- package/utils/FileUploadModifier.d.ts +1 -1
- package/utils/FileUploadModifier.js +6 -16
- package/utils/FileUploadModifier.js.map +1 -1
- package/utils/createFileNormalizerFromContext.d.ts +2 -2
- package/utils/createFileNormalizerFromContext.js +5 -12
- package/utils/createFileNormalizerFromContext.js.map +1 -1
- package/utils/getPresignedPostPayload.d.ts +4 -3
- package/utils/getPresignedPostPayload.js +10 -15
- package/utils/getPresignedPostPayload.js.map +1 -1
- package/utils/mimeTypes.js +5 -13
- package/utils/mimeTypes.js.map +1 -1
- package/utils/uploadFileToS3.d.ts +1 -3
- package/utils/uploadFileToS3.js +7 -20
- package/utils/uploadFileToS3.js.map +1 -1
- package/assetDelivery/createCustomAssetDelivery.d.ts +0 -12
- package/assetDelivery/createCustomAssetDelivery.js +0 -28
- package/assetDelivery/createCustomAssetDelivery.js.map +0 -1
- package/assetDelivery/customAssets/CustomAsset.d.ts +0 -6
- package/assetDelivery/customAssets/CustomAsset.js +0 -14
- package/assetDelivery/customAssets/CustomAsset.js.map +0 -1
- package/assetDelivery/customAssets/CustomAssetProcessor.d.ts +0 -10
- package/assetDelivery/customAssets/CustomAssetProcessor.js +0 -25
- package/assetDelivery/customAssets/CustomAssetProcessor.js.map +0 -1
- package/assetDelivery/customAssets/S3CustomAssetResolver.d.ts +0 -15
- package/assetDelivery/customAssets/S3CustomAssetResolver.js +0 -90
- package/assetDelivery/customAssets/S3CustomAssetResolver.js.map +0 -1
- package/assetDelivery/customAssets/customAssetDeliveryConfig.d.ts +0 -1
- package/assetDelivery/customAssets/customAssetDeliveryConfig.js +0 -30
- package/assetDelivery/customAssets/customAssetDeliveryConfig.js.map +0 -1
- package/assetDelivery/s3/S3AssetMetadataReader.d.ts +0 -15
- package/assetDelivery/s3/S3AssetMetadataReader.js +0 -36
- package/assetDelivery/s3/S3AssetMetadataReader.js.map +0 -1
- package/assetDelivery/s3/transformation/legacyUtils.d.ts +0 -12
- package/assetDelivery/s3/transformation/legacyUtils.js +0 -34
- package/assetDelivery/s3/transformation/legacyUtils.js.map +0 -1
- package/flushCdnCache/CdnPathsGenerator.d.ts +0 -4
- package/flushCdnCache/CdnPathsGenerator.js +0 -14
- package/flushCdnCache/CdnPathsGenerator.js.map +0 -1
- package/flushCdnCache/InvalidateCacheTask.d.ts +0 -18
- package/flushCdnCache/InvalidateCacheTask.js +0 -78
- package/flushCdnCache/InvalidateCacheTask.js.map +0 -1
- package/flushCdnCache/flushCacheOnFileDelete.d.ts +0 -3
- package/flushCdnCache/flushCacheOnFileDelete.js +0 -34
- package/flushCdnCache/flushCacheOnFileDelete.js.map +0 -1
- package/flushCdnCache/flushCacheOnFileUpdate.d.ts +0 -3
- package/flushCdnCache/flushCacheOnFileUpdate.js +0 -40
- package/flushCdnCache/flushCacheOnFileUpdate.js.map +0 -1
- package/flushCdnCache/index.d.ts +0 -1
- package/flushCdnCache/index.js +0 -15
- package/flushCdnCache/index.js.map +0 -1
- package/flushCdnCache/invalidateCacheTaskDefinition.d.ts +0 -2
- package/flushCdnCache/invalidateCacheTaskDefinition.js +0 -22
- package/flushCdnCache/invalidateCacheTaskDefinition.js.map +0 -1
- package/plugins/addFileMetadata.d.ts +0 -10
- package/plugins/addFileMetadata.js +0 -67
- package/plugins/addFileMetadata.js.map +0 -1
- package/plugins/checkPermissions.d.ts +0 -4
- package/plugins/checkPermissions.js.map +0 -1
- package/plugins/fileStorageS3.d.ts +0 -3
- package/plugins/fileStorageS3.js +0 -60
- package/plugins/fileStorageS3.js.map +0 -1
- package/plugins/graphqlFileStorageS3.d.ts +0 -4
- package/plugins/graphqlFileStorageS3.js.map +0 -1
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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:
|
|
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":["
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
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.
|
|
58
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
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:
|
|
81
|
-
Body: await
|
|
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
|
-
|
|
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.
|
|
106
|
-
|
|
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(`
|
|
139
|
+
console.log(`No optimizations defined for ${asset.getContentType()}`);
|
|
117
140
|
return asset;
|
|
118
141
|
}
|
|
119
|
-
const optimizedBuffer = optimization(buffer).toBuffer();
|
|
120
|
-
|
|
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:
|
|
125
|
-
Body: await
|
|
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 (
|
|
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 (
|
|
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":"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","ignoreList":[]}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
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 =
|
|
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","
|
|
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,10 +1,4 @@
|
|
|
1
|
-
|
|
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"
|
|
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
|
-
|
|
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"
|
|
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,
|
|
9
|
+
export { SUPPORTED_TRANSFORMABLE_IMAGES, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
14
|
-
|
|
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
|
|
19
|
-
|
|
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, (
|
|
33
|
+
return getOptimizedTransformedImageKeyPrefix(key, objectHash(transformations));
|
|
30
34
|
};
|
|
31
|
-
|
|
35
|
+
export { SUPPORTED_TRANSFORMABLE_IMAGES, getImageKey, getOptimizedImageKeyPrefix, getOptimizedTransformedImageKeyPrefix };
|
|
32
36
|
|
|
33
37
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
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,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,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":[]}
|