@webiny/api-file-manager-s3 6.3.0 → 6.4.0-beta.0
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/assetDelivery/assetDeliveryConfig.js +32 -39
- package/assetDelivery/assetDeliveryConfig.js.map +1 -1
- package/assetDelivery/createAssetDelivery.js +5 -19
- package/assetDelivery/createAssetDelivery.js.map +1 -1
- package/assetDelivery/index.js +0 -2
- package/assetDelivery/s3/S3AssetResolver.js +21 -22
- package/assetDelivery/s3/S3AssetResolver.js.map +1 -1
- package/assetDelivery/s3/S3ContentsReader.js +13 -16
- package/assetDelivery/s3/S3ContentsReader.js.map +1 -1
- package/assetDelivery/s3/S3ErrorAssetReply.js +10 -9
- package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -1
- package/assetDelivery/s3/S3OutputStrategy.js +23 -27
- package/assetDelivery/s3/S3OutputStrategy.js.map +1 -1
- package/assetDelivery/s3/S3RedirectAssetReply.js +12 -11
- package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -1
- package/assetDelivery/s3/S3StreamAssetReply.js +12 -11
- package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -1
- package/assetDelivery/s3/SharpTransform.js +139 -169
- package/assetDelivery/s3/SharpTransform.js.map +1 -1
- package/assetDelivery/s3/transformation/AssetKeyGenerator.js +18 -17
- package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -1
- package/assetDelivery/s3/transformation/CallableContentsReader.js +8 -7
- package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -1
- package/assetDelivery/s3/transformation/WidthCollection.js +15 -16
- package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -1
- package/assetDelivery/s3/transformation/utils.js +24 -30
- package/assetDelivery/s3/transformation/utils.js.map +1 -1
- package/assetDelivery/threatDetection/ObjectKey.js +15 -14
- package/assetDelivery/threatDetection/ObjectKey.js.map +1 -1
- package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js +28 -42
- package/assetDelivery/threatDetection/createThreatDetectionEventHandler.js.map +1 -1
- package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js +2 -3
- package/assetDelivery/threatDetection/createThreatDetectionPluginLoader.js.map +1 -1
- package/assetDelivery/threatDetection/index.js +0 -2
- package/assetDelivery/threatDetection/processThreatScanResult.js +48 -54
- package/assetDelivery/threatDetection/processThreatScanResult.js.map +1 -1
- package/assetDelivery/threatDetection/types.js +0 -3
- package/assetDelivery/types.js +0 -3
- package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js +17 -13
- package/enterprise/ApplyThreatScanning/CreateFileWithThreatScanDecorator.js.map +1 -1
- package/enterprise/ApplyThreatScanning/feature.js +6 -5
- package/enterprise/ApplyThreatScanning/feature.js.map +1 -1
- package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js +26 -27
- package/features/DeleteFileFromBucket/DeleteFileFromBucketHandler.js.map +1 -1
- package/features/DeleteFileFromBucket/DeleteS3FolderTask.js +40 -51
- package/features/DeleteFileFromBucket/DeleteS3FolderTask.js.map +1 -1
- package/features/DeleteFileFromBucket/feature.js +7 -6
- package/features/DeleteFileFromBucket/feature.js.map +1 -1
- package/features/ExtractMetadata/ExtractMetadataHandler.js +18 -19
- package/features/ExtractMetadata/ExtractMetadataHandler.js.map +1 -1
- package/features/ExtractMetadata/ExtractMetadataTask.js +75 -114
- package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -1
- package/features/ExtractMetadata/feature.js +7 -6
- package/features/ExtractMetadata/feature.js.map +1 -1
- package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +20 -19
- package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -1
- package/features/FlushCache/FlushCacheOnFileUpdateHandler.js +22 -26
- package/features/FlushCache/FlushCacheOnFileUpdateHandler.js.map +1 -1
- package/features/FlushCache/InvalidateCacheTask.js +63 -75
- package/features/FlushCache/InvalidateCacheTask.js.map +1 -1
- package/features/FlushCache/feature.js +8 -7
- package/features/FlushCache/feature.js.map +1 -1
- package/features/GetFileContentsById/GetFileContentsByIdUseCase.d.ts +13 -0
- package/features/GetFileContentsById/GetFileContentsByIdUseCase.js +40 -0
- package/features/GetFileContentsById/GetFileContentsByIdUseCase.js.map +1 -0
- package/features/GetFileContentsById/feature.d.ts +4 -0
- package/features/GetFileContentsById/feature.js +11 -0
- package/features/GetFileContentsById/feature.js.map +1 -0
- package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.d.ts +13 -0
- package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js +40 -0
- package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js.map +1 -0
- package/features/GetFileContentsByKey/feature.d.ts +4 -0
- package/features/GetFileContentsByKey/feature.js +11 -0
- package/features/GetFileContentsByKey/feature.js.map +1 -0
- package/features/WriteFileMetadata/MetadataReader.js +9 -10
- package/features/WriteFileMetadata/MetadataReader.js.map +1 -1
- package/features/WriteFileMetadata/MetadataWriter.js +23 -25
- package/features/WriteFileMetadata/MetadataWriter.js.map +1 -1
- package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js +14 -12
- package/features/WriteFileMetadata/WriteMetadataAfterBatchCreateHandler.js.map +1 -1
- package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js +16 -12
- package/features/WriteFileMetadata/WriteMetadataAfterCreateHandler.js.map +1 -1
- package/features/WriteFileMetadata/feature.js +7 -6
- package/features/WriteFileMetadata/feature.js.map +1 -1
- package/graphql/checkPermissions.js +17 -32
- package/graphql/checkPermissions.js.map +1 -1
- package/graphql/schema.js +99 -102
- package/graphql/schema.js.map +1 -1
- package/index.js +19 -13
- package/index.js.map +1 -1
- package/multiPartUpload/CompleteMultiPartUploadUseCase.js +50 -53
- package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -1
- package/multiPartUpload/CreateMultiPartUploadUseCase.js +31 -38
- package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -1
- package/package.json +17 -17
- package/types.js +0 -2
- package/utils/CdnPathsGenerator.js +8 -4
- package/utils/CdnPathsGenerator.js.map +1 -1
- package/utils/FileExtension.js +12 -13
- package/utils/FileExtension.js.map +1 -1
- package/utils/FileKey.js +29 -21
- package/utils/FileKey.js.map +1 -1
- package/utils/FileKey.test.js +49 -49
- package/utils/FileKey.test.js.map +1 -1
- package/utils/FileNormalizer.js +34 -35
- package/utils/FileNormalizer.js.map +1 -1
- package/utils/FileUploadModifier.js +32 -32
- package/utils/FileUploadModifier.js.map +1 -1
- package/utils/createFileNormalizerFromContext.js +5 -4
- package/utils/createFileNormalizerFromContext.js.map +1 -1
- package/utils/getPresignedPostPayload.js +36 -33
- package/utils/getPresignedPostPayload.js.map +1 -1
- package/utils/mimeTypes.js +6 -10
- package/utils/mimeTypes.js.map +1 -1
- package/utils/uploadFileToS3.js +11 -10
- package/utils/uploadFileToS3.js.map +1 -1
- package/assetDelivery/index.js.map +0 -1
- package/assetDelivery/threatDetection/index.js.map +0 -1
- package/assetDelivery/threatDetection/types.js.map +0 -1
- package/assetDelivery/types.js.map +0 -1
- package/types.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/DeleteFileFromBucket/feature.js","sources":["../../../src/features/DeleteFileFromBucket/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { DeleteFileFromBucketHandler } from \"./DeleteFileFromBucketHandler.js\";\nimport { DeleteS3FolderTaskDefinition } from \"./DeleteS3FolderTask.js\";\n\nexport const DeleteFileFromBucketFeature = createFeature({\n name: \"FileManagerS3/DeleteFileFromBucket\",\n register(container) {\n container.register(DeleteFileFromBucketHandler);\n container.register(DeleteS3FolderTaskDefinition);\n }\n});\n"],"names":["DeleteFileFromBucketFeature","createFeature","container","DeleteFileFromBucketHandler","DeleteS3FolderTaskDefinition"],"mappings":";;;AAIO,MAAMA,8BAA8BC,cAAc;IACrD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ"}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { FileAfterCreateEventHandler } from "@webiny/api-file-manager/features/file/CreateFile/events.js";
|
|
2
2
|
import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
|
|
3
3
|
class ExtractMetadataHandlerImpl {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
fileId: file.id
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
4
|
+
constructor(taskService){
|
|
5
|
+
this.taskService = taskService;
|
|
6
|
+
}
|
|
7
|
+
async handle(event) {
|
|
8
|
+
const { file } = event.payload;
|
|
9
|
+
await this.taskService.trigger({
|
|
10
|
+
definition: "fileManagerExtractMetadata",
|
|
11
|
+
input: {
|
|
12
|
+
fileId: file.id
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
20
16
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
const ExtractMetadataHandler = FileAfterCreateEventHandler.createImplementation({
|
|
18
|
+
implementation: ExtractMetadataHandlerImpl,
|
|
19
|
+
dependencies: [
|
|
20
|
+
TaskService
|
|
21
|
+
]
|
|
24
22
|
});
|
|
23
|
+
export { ExtractMetadataHandler };
|
|
25
24
|
|
|
26
25
|
//# sourceMappingURL=ExtractMetadataHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/ExtractMetadata/ExtractMetadataHandler.js","sources":["../../../src/features/ExtractMetadata/ExtractMetadataHandler.ts"],"sourcesContent":["import { FileAfterCreateEventHandler } from \"@webiny/api-file-manager/features/file/CreateFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport type { ExtractMetadataInput } from \"./ExtractMetadataTask.js\";\n\nclass ExtractMetadataHandlerImpl implements FileAfterCreateEventHandler.Interface {\n constructor(private taskService: TaskService.Interface) {}\n\n async handle(event: FileAfterCreateEventHandler.Event): Promise<void> {\n const { file } = event.payload;\n\n // Trigger the metadata extraction task\n await this.taskService.trigger<ExtractMetadataInput>({\n definition: \"fileManagerExtractMetadata\",\n input: {\n fileId: file.id\n }\n });\n }\n}\n\nexport const ExtractMetadataHandler = FileAfterCreateEventHandler.createImplementation({\n implementation: ExtractMetadataHandlerImpl,\n dependencies: [TaskService]\n});\n"],"names":["ExtractMetadataHandlerImpl","taskService","event","file","ExtractMetadataHandler","FileAfterCreateEventHandler","TaskService"],"mappings":";;AAIA,MAAMA;IACF,YAAoBC,WAAkC,CAAE;aAApCA,WAAW,GAAXA;IAAqC;IAEzD,MAAM,OAAOC,KAAwC,EAAiB;QAClE,MAAM,EAAEC,IAAI,EAAE,GAAGD,MAAM,OAAO;QAG9B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAuB;YACjD,YAAY;YACZ,OAAO;gBACH,QAAQC,KAAK,EAAE;YACnB;QACJ;IACJ;AACJ;AAEO,MAAMC,yBAAyBC,4BAA4B,oBAAoB,CAAC;IACnF,gBAAgBL;IAChB,cAAc;QAACM;KAAY;AAC/B"}
|
|
@@ -4,126 +4,87 @@ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/ind
|
|
|
4
4
|
import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
|
|
5
5
|
import { MetadataReader } from "../WriteFileMetadata/MetadataReader.js";
|
|
6
6
|
class ExtractMetadataTask {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
controller
|
|
21
|
-
}) {
|
|
22
|
-
if (controller.runtime.isAborted()) {
|
|
23
|
-
return controller.response.aborted();
|
|
7
|
+
constructor(keyValueStore, updateFileUseCase){
|
|
8
|
+
this.keyValueStore = keyValueStore;
|
|
9
|
+
this.updateFileUseCase = updateFileUseCase;
|
|
10
|
+
this.id = "fileManagerExtractMetadata";
|
|
11
|
+
this.title = "Extract image metadata (dimensions, EXIF, IPTC)";
|
|
12
|
+
this.description = "A task to extract metadata from uploaded image files";
|
|
13
|
+
this.maxIterations = 1;
|
|
14
|
+
this.isPrivate = true;
|
|
15
|
+
this.databaseLogs = false;
|
|
16
|
+
this.selfCleanup = [
|
|
17
|
+
"onSuccess",
|
|
18
|
+
"onAbort"
|
|
19
|
+
];
|
|
24
20
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
message: `File metadata not found for file ID: ${input.fileId}`
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Check if it's an image file
|
|
36
|
-
if (!fileMetadata.contentType.startsWith("image/")) {
|
|
37
|
-
return controller.response.done();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Fetch the image from S3
|
|
41
|
-
const s3 = new S3();
|
|
42
|
-
const bucket = String(process.env.S3_BUCKET);
|
|
43
|
-
try {
|
|
44
|
-
const s3Object = await s3.getObject({
|
|
45
|
-
Bucket: bucket,
|
|
46
|
-
Key: fileMetadata.bucketKey
|
|
47
|
-
});
|
|
48
|
-
if (!s3Object.Body) {
|
|
49
|
-
return controller.response.error({
|
|
50
|
-
message: `S3 object body is empty for file: ${input.fileId}`
|
|
21
|
+
async run({ input, controller }) {
|
|
22
|
+
if (controller.runtime.isAborted()) return controller.response.aborted();
|
|
23
|
+
const metadataReader = new MetadataReader(this.keyValueStore);
|
|
24
|
+
const fileMetadata = await metadataReader.read(input.fileId);
|
|
25
|
+
if (!fileMetadata) return controller.response.error({
|
|
26
|
+
message: `File metadata not found for file ID: ${input.fileId}`
|
|
51
27
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
28
|
+
if (!fileMetadata.contentType.startsWith("image/")) return controller.response.done();
|
|
29
|
+
const s3 = new S3();
|
|
30
|
+
const bucket = String(process.env.S3_BUCKET);
|
|
31
|
+
try {
|
|
32
|
+
const s3Object = await s3.getObject({
|
|
33
|
+
Bucket: bucket,
|
|
34
|
+
Key: fileMetadata.bucketKey
|
|
35
|
+
});
|
|
36
|
+
if (!s3Object.Body) return controller.response.error({
|
|
37
|
+
message: `S3 object body is empty for file: ${input.fileId}`
|
|
38
|
+
});
|
|
39
|
+
const sharp = await import("sharp").then((m)=>m.default);
|
|
40
|
+
const ExifReader = await import("exifreader").then((m)=>m.default);
|
|
41
|
+
const buffer = Buffer.from(await s3Object.Body.transformToByteArray());
|
|
42
|
+
const sharpInstance = sharp(buffer);
|
|
43
|
+
const sharpMetadata = await sharpInstance.metadata();
|
|
44
|
+
const tags = ExifReader.load(buffer, {
|
|
45
|
+
expanded: true
|
|
46
|
+
});
|
|
47
|
+
const metadata = {
|
|
48
|
+
image: {
|
|
49
|
+
width: sharpMetadata.width,
|
|
50
|
+
height: sharpMetadata.height,
|
|
51
|
+
format: sharpMetadata.format,
|
|
52
|
+
orientation: sharpMetadata.orientation ?? 1
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (tags.exif) metadata.exif = this.cleanValues(tags.exif);
|
|
56
|
+
if (tags.iptc) metadata.iptc = this.cleanValues(tags.iptc);
|
|
57
|
+
const updateResult = await this.updateFileUseCase.execute({
|
|
58
|
+
id: input.fileId,
|
|
59
|
+
metadata
|
|
60
|
+
});
|
|
61
|
+
if (updateResult.isFail()) return controller.response.error({
|
|
62
|
+
message: `Failed to update file with metadata: ${updateResult.error.message}`
|
|
63
|
+
});
|
|
64
|
+
return controller.response.done();
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return controller.response.error({
|
|
67
|
+
message: `Failed to extract metadata: ${error instanceof Error ? error.message : String(error)}`
|
|
68
|
+
});
|
|
75
69
|
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// Extract EXIF data if available
|
|
79
|
-
if (tags.exif) {
|
|
80
|
-
metadata.exif = this.cleanValues(tags.exif);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Extract IPTC data if available
|
|
84
|
-
if (tags.iptc) {
|
|
85
|
-
metadata.iptc = this.cleanValues(tags.iptc);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Update the file with extracted metadata
|
|
89
|
-
const updateResult = await this.updateFileUseCase.execute({
|
|
90
|
-
id: input.fileId,
|
|
91
|
-
metadata
|
|
92
|
-
});
|
|
93
|
-
if (updateResult.isFail()) {
|
|
94
|
-
return controller.response.error({
|
|
95
|
-
message: `Failed to update file with metadata: ${updateResult.error.message}`
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
return controller.response.done();
|
|
99
|
-
} catch (error) {
|
|
100
|
-
return controller.response.error({
|
|
101
|
-
message: `Failed to extract metadata: ${error instanceof Error ? error.message : String(error)}`
|
|
102
|
-
});
|
|
103
70
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// Use description if available, otherwise value
|
|
113
|
-
if (tag.description !== undefined && tag.description !== null) {
|
|
114
|
-
cleaned[key] = tag.description;
|
|
115
|
-
} else if (Array.isArray(tag.value) && tag.value.length > 20) {
|
|
116
|
-
// Skip large byte arrays
|
|
117
|
-
} else if (tag.value !== undefined) {
|
|
118
|
-
cleaned[key] = tag.value;
|
|
119
|
-
}
|
|
71
|
+
cleanValues(tags) {
|
|
72
|
+
const cleaned = {};
|
|
73
|
+
for (const [key, tag] of Object.entries(tags))if (tag && "object" == typeof tag) {
|
|
74
|
+
if (void 0 !== tag.description && null !== tag.description) cleaned[key] = tag.description;
|
|
75
|
+
else if (Array.isArray(tag.value) && tag.value.length > 20) ;
|
|
76
|
+
else if (void 0 !== tag.value) cleaned[key] = tag.value;
|
|
77
|
+
}
|
|
78
|
+
return cleaned;
|
|
120
79
|
}
|
|
121
|
-
return cleaned;
|
|
122
|
-
}
|
|
123
80
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
81
|
+
const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({
|
|
82
|
+
implementation: ExtractMetadataTask,
|
|
83
|
+
dependencies: [
|
|
84
|
+
GlobalKeyValueStore,
|
|
85
|
+
UpdateFileUseCase
|
|
86
|
+
]
|
|
127
87
|
});
|
|
88
|
+
export { ExtractMetadataTaskDefinition };
|
|
128
89
|
|
|
129
90
|
//# sourceMappingURL=ExtractMetadataTask.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["S3","TaskDefinition","GlobalKeyValueStore","UpdateFileUseCase","MetadataReader","ExtractMetadataTask","id","title","description","maxIterations","isPrivate","databaseLogs","selfCleanup","constructor","keyValueStore","updateFileUseCase","run","input","controller","runtime","isAborted","response","aborted","metadataReader","fileMetadata","read","fileId","error","message","contentType","startsWith","done","s3","bucket","String","process","env","S3_BUCKET","s3Object","getObject","Bucket","Key","bucketKey","Body","sharp","then","m","default","ExifReader","buffer","Buffer","from","transformToByteArray","sharpInstance","sharpMetadata","metadata","tags","load","expanded","image","width","height","format","orientation","exif","cleanValues","iptc","updateResult","execute","isFail","Error","cleaned","key","tag","Object","entries","undefined","Array","isArray","value","length","ExtractMetadataTaskDefinition","createImplementation","implementation","dependencies"],"sources":["ExtractMetadataTask.ts"],"sourcesContent":["import type { ExifTags } from \"exifreader\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"../WriteFileMetadata/MetadataReader.js\";\n\nexport interface ExtractMetadataInput {\n fileId: string;\n}\n\nclass ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {\n id = \"fileManagerExtractMetadata\";\n title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n description = \"A task to extract metadata from uploaded image files\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private updateFileUseCase: UpdateFileUseCase.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<\n TaskDefinition.Result<ExtractMetadataInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Load file metadata\n const metadataReader = new MetadataReader(this.keyValueStore);\n const fileMetadata = await metadataReader.read(input.fileId);\n\n if (!fileMetadata) {\n return controller.response.error({\n message: `File metadata not found for file ID: ${input.fileId}`\n });\n }\n\n // Check if it's an image file\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n // Fetch the image from S3\n const s3 = new S3();\n const bucket = String(process.env.S3_BUCKET);\n\n try {\n const s3Object = await s3.getObject({\n Bucket: bucket,\n Key: fileMetadata.bucketKey\n });\n\n if (!s3Object.Body) {\n return controller.response.error({\n message: `S3 object body is empty for file: ${input.fileId}`\n });\n }\n\n const sharp = await import(/* webpackChunkName: \"sharp\" */ \"sharp\").then(\n m => m.default\n );\n\n const ExifReader = await import(/* webpackChunkName: \"exifreader\" */ \"exifreader\").then(\n m => m.default\n );\n\n // Convert S3 body to buffer\n const buffer = Buffer.from(await s3Object.Body.transformToByteArray());\n\n // Extract metadata using Sharp for image dimensions\n const sharpInstance = sharp(buffer);\n const sharpMetadata = await sharpInstance.metadata();\n\n // Use ExifReader to extract EXIF and IPTC data\n const tags = ExifReader.load(buffer, { expanded: true });\n\n // Build metadata object\n const metadata: Record<string, any> = {\n image: {\n width: sharpMetadata.width,\n height: sharpMetadata.height,\n format: sharpMetadata.format,\n orientation: sharpMetadata.orientation ?? 1\n }\n };\n\n // Extract EXIF data if available\n if (tags.exif) {\n metadata.exif = this.cleanValues(tags.exif);\n }\n\n // Extract IPTC data if available\n if (tags.iptc) {\n metadata.iptc = this.cleanValues(tags.iptc);\n }\n\n // Update the file with extracted metadata\n const updateResult = await this.updateFileUseCase.execute({\n id: input.fileId,\n metadata\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file with metadata: ${updateResult.error.message}`\n });\n }\n\n return controller.response.done();\n } catch (error) {\n return controller.response.error({\n message: `Failed to extract metadata: ${\n error instanceof Error ? error.message : String(error)\n }`\n });\n }\n }\n\n private cleanValues(tags: ExifTags) {\n const cleaned: Record<string, any> = {};\n\n for (const [key, tag] of Object.entries(tags)) {\n if (!tag || typeof tag !== \"object\") {\n continue;\n }\n\n // Use description if available, otherwise value\n if (tag.description !== undefined && tag.description !== null) {\n cleaned[key] = tag.description;\n } else if (Array.isArray(tag.value) && tag.value.length > 20) {\n // Skip large byte arrays\n } else if (tag.value !== undefined) {\n cleaned[key] = tag.value;\n }\n }\n\n return cleaned;\n }\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTask,\n dependencies: [GlobalKeyValueStore, UpdateFileUseCase]\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"features/ExtractMetadata/ExtractMetadataTask.js","sources":["../../../src/features/ExtractMetadata/ExtractMetadataTask.ts"],"sourcesContent":["import type { ExifTags } from \"exifreader\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"../WriteFileMetadata/MetadataReader.js\";\n\nexport interface ExtractMetadataInput {\n fileId: string;\n}\n\nclass ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {\n id = \"fileManagerExtractMetadata\";\n title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n description = \"A task to extract metadata from uploaded image files\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private updateFileUseCase: UpdateFileUseCase.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<\n TaskDefinition.Result<ExtractMetadataInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Load file metadata\n const metadataReader = new MetadataReader(this.keyValueStore);\n const fileMetadata = await metadataReader.read(input.fileId);\n\n if (!fileMetadata) {\n return controller.response.error({\n message: `File metadata not found for file ID: ${input.fileId}`\n });\n }\n\n // Check if it's an image file\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n // Fetch the image from S3\n const s3 = new S3();\n const bucket = String(process.env.S3_BUCKET);\n\n try {\n const s3Object = await s3.getObject({\n Bucket: bucket,\n Key: fileMetadata.bucketKey\n });\n\n if (!s3Object.Body) {\n return controller.response.error({\n message: `S3 object body is empty for file: ${input.fileId}`\n });\n }\n\n const sharp = await import(/* webpackChunkName: \"sharp\" */ \"sharp\").then(\n m => m.default\n );\n\n const ExifReader = await import(/* webpackChunkName: \"exifreader\" */ \"exifreader\").then(\n m => m.default\n );\n\n // Convert S3 body to buffer\n const buffer = Buffer.from(await s3Object.Body.transformToByteArray());\n\n // Extract metadata using Sharp for image dimensions\n const sharpInstance = sharp(buffer);\n const sharpMetadata = await sharpInstance.metadata();\n\n // Use ExifReader to extract EXIF and IPTC data\n const tags = ExifReader.load(buffer, { expanded: true });\n\n // Build metadata object\n const metadata: Record<string, any> = {\n image: {\n width: sharpMetadata.width,\n height: sharpMetadata.height,\n format: sharpMetadata.format,\n orientation: sharpMetadata.orientation ?? 1\n }\n };\n\n // Extract EXIF data if available\n if (tags.exif) {\n metadata.exif = this.cleanValues(tags.exif);\n }\n\n // Extract IPTC data if available\n if (tags.iptc) {\n metadata.iptc = this.cleanValues(tags.iptc);\n }\n\n // Update the file with extracted metadata\n const updateResult = await this.updateFileUseCase.execute({\n id: input.fileId,\n metadata\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file with metadata: ${updateResult.error.message}`\n });\n }\n\n return controller.response.done();\n } catch (error) {\n return controller.response.error({\n message: `Failed to extract metadata: ${\n error instanceof Error ? error.message : String(error)\n }`\n });\n }\n }\n\n private cleanValues(tags: ExifTags) {\n const cleaned: Record<string, any> = {};\n\n for (const [key, tag] of Object.entries(tags)) {\n if (!tag || typeof tag !== \"object\") {\n continue;\n }\n\n // Use description if available, otherwise value\n if (tag.description !== undefined && tag.description !== null) {\n cleaned[key] = tag.description;\n } else if (Array.isArray(tag.value) && tag.value.length > 20) {\n // Skip large byte arrays\n } else if (tag.value !== undefined) {\n cleaned[key] = tag.value;\n }\n }\n\n return cleaned;\n }\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTask,\n dependencies: [GlobalKeyValueStore, UpdateFileUseCase]\n});\n"],"names":["ExtractMetadataTask","keyValueStore","updateFileUseCase","input","controller","metadataReader","MetadataReader","fileMetadata","s3","S3","bucket","String","process","s3Object","sharp","m","ExifReader","buffer","Buffer","sharpInstance","sharpMetadata","tags","metadata","updateResult","error","Error","cleaned","key","tag","Object","undefined","Array","ExtractMetadataTaskDefinition","TaskDefinition","GlobalKeyValueStore","UpdateFileUseCase"],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createFeature } from "@webiny/feature/api";
|
|
2
2
|
import { ExtractMetadataHandler } from "./ExtractMetadataHandler.js";
|
|
3
3
|
import { ExtractMetadataTaskDefinition } from "./ExtractMetadataTask.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const ExtractMetadataFeature = createFeature({
|
|
5
|
+
name: "FileManagerS3/ExtractMetadata",
|
|
6
|
+
register (container) {
|
|
7
|
+
container.register(ExtractMetadataHandler);
|
|
8
|
+
container.register(ExtractMetadataTaskDefinition);
|
|
9
|
+
}
|
|
10
10
|
});
|
|
11
|
+
export { ExtractMetadataFeature };
|
|
11
12
|
|
|
12
13
|
//# sourceMappingURL=feature.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/ExtractMetadata/feature.js","sources":["../../../src/features/ExtractMetadata/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { ExtractMetadataHandler } from \"./ExtractMetadataHandler.js\";\nimport { ExtractMetadataTaskDefinition } from \"./ExtractMetadataTask.js\";\n\nexport const ExtractMetadataFeature = createFeature({\n name: \"FileManagerS3/ExtractMetadata\",\n register(container) {\n container.register(ExtractMetadataHandler);\n container.register(ExtractMetadataTaskDefinition);\n }\n});\n"],"names":["ExtractMetadataFeature","createFeature","container","ExtractMetadataHandler","ExtractMetadataTaskDefinition"],"mappings":";;;AAIO,MAAMA,yBAAyBC,cAAc;IAChD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ"}
|
|
@@ -2,26 +2,27 @@ import { FileAfterDeleteEventHandler } from "@webiny/api-file-manager/features/f
|
|
|
2
2
|
import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
|
|
3
3
|
import { CdnPathsGenerator } from "../../utils/CdnPathsGenerator.js";
|
|
4
4
|
class FlushCacheOnFileDeleteHandlerImpl {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
20
|
-
}
|
|
5
|
+
constructor(taskService){
|
|
6
|
+
this.taskService = taskService;
|
|
7
|
+
this.pathsGenerator = new CdnPathsGenerator();
|
|
8
|
+
}
|
|
9
|
+
async handle(event) {
|
|
10
|
+
const { file } = event.payload;
|
|
11
|
+
await this.taskService.trigger({
|
|
12
|
+
definition: "cloudfrontInvalidateCache",
|
|
13
|
+
input: {
|
|
14
|
+
caller: "fm-before-delete",
|
|
15
|
+
paths: this.pathsGenerator.generate(file.id)
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
21
19
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const FlushCacheOnFileDeleteHandler = FileAfterDeleteEventHandler.createImplementation({
|
|
21
|
+
implementation: FlushCacheOnFileDeleteHandlerImpl,
|
|
22
|
+
dependencies: [
|
|
23
|
+
TaskService
|
|
24
|
+
]
|
|
25
25
|
});
|
|
26
|
+
export { FlushCacheOnFileDeleteHandler };
|
|
26
27
|
|
|
27
28
|
//# sourceMappingURL=FlushCacheOnFileDeleteHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/FlushCache/FlushCacheOnFileDeleteHandler.js","sources":["../../../src/features/FlushCache/FlushCacheOnFileDeleteHandler.ts"],"sourcesContent":["import { FileAfterDeleteEventHandler } from \"@webiny/api-file-manager/features/file/DeleteFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport { CdnPathsGenerator } from \"~/utils/CdnPathsGenerator.js\";\n\nclass FlushCacheOnFileDeleteHandlerImpl implements FileAfterDeleteEventHandler.Interface {\n private readonly pathsGenerator: CdnPathsGenerator;\n\n constructor(private taskService: TaskService.Interface) {\n this.pathsGenerator = new CdnPathsGenerator();\n }\n\n async handle(event: FileAfterDeleteEventHandler.Event): Promise<void> {\n const { file } = event.payload;\n\n await this.taskService.trigger({\n definition: \"cloudfrontInvalidateCache\",\n input: {\n caller: \"fm-before-delete\",\n paths: this.pathsGenerator.generate(file.id)\n }\n });\n }\n}\n\nexport const FlushCacheOnFileDeleteHandler = FileAfterDeleteEventHandler.createImplementation({\n implementation: FlushCacheOnFileDeleteHandlerImpl,\n dependencies: [TaskService]\n});\n"],"names":["FlushCacheOnFileDeleteHandlerImpl","taskService","CdnPathsGenerator","event","file","FlushCacheOnFileDeleteHandler","FileAfterDeleteEventHandler","TaskService"],"mappings":";;;AAIA,MAAMA;IAGF,YAAoBC,WAAkC,CAAE;aAApCA,WAAW,GAAXA;QAChB,IAAI,CAAC,cAAc,GAAG,IAAIC;IAC9B;IAEA,MAAM,OAAOC,KAAwC,EAAiB;QAClE,MAAM,EAAEC,IAAI,EAAE,GAAGD,MAAM,OAAO;QAE9B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;YAC3B,YAAY;YACZ,OAAO;gBACH,QAAQ;gBACR,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAACC,KAAK,EAAE;YAC/C;QACJ;IACJ;AACJ;AAEO,MAAMC,gCAAgCC,4BAA4B,oBAAoB,CAAC;IAC1F,gBAAgBN;IAChB,cAAc;QAACO;KAAY;AAC/B"}
|
|
@@ -2,34 +2,30 @@ import { FileBeforeUpdateEventHandler } from "@webiny/api-file-manager/features/
|
|
|
2
2
|
import { TaskService } from "@webiny/api-core/features/task/TaskService/index.js";
|
|
3
3
|
import { CdnPathsGenerator } from "../../utils/CdnPathsGenerator.js";
|
|
4
4
|
class FlushCacheOnFileUpdateHandlerImpl {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
constructor(taskService){
|
|
6
|
+
this.taskService = taskService;
|
|
7
|
+
this.pathsGenerator = new CdnPathsGenerator();
|
|
8
|
+
}
|
|
9
|
+
async handle(event) {
|
|
10
|
+
const { file, original } = event.payload;
|
|
11
|
+
const prevAccessControl = original.accessControl;
|
|
12
|
+
const newAccessControl = file.accessControl;
|
|
13
|
+
if (prevAccessControl?.type === newAccessControl?.type) return;
|
|
14
|
+
await this.taskService.trigger({
|
|
15
|
+
definition: "cloudfrontInvalidateCache",
|
|
16
|
+
input: {
|
|
17
|
+
caller: "fm-before-update",
|
|
18
|
+
paths: this.pathsGenerator.generate(file.id)
|
|
19
|
+
}
|
|
20
|
+
});
|
|
20
21
|
}
|
|
21
|
-
await this.taskService.trigger({
|
|
22
|
-
definition: "cloudfrontInvalidateCache",
|
|
23
|
-
input: {
|
|
24
|
-
caller: "fm-before-update",
|
|
25
|
-
paths: this.pathsGenerator.generate(file.id)
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
22
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
const FlushCacheOnFileUpdateHandler = FileBeforeUpdateEventHandler.createImplementation({
|
|
24
|
+
implementation: FlushCacheOnFileUpdateHandlerImpl,
|
|
25
|
+
dependencies: [
|
|
26
|
+
TaskService
|
|
27
|
+
]
|
|
33
28
|
});
|
|
29
|
+
export { FlushCacheOnFileUpdateHandler };
|
|
34
30
|
|
|
35
31
|
//# sourceMappingURL=FlushCacheOnFileUpdateHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/FlushCache/FlushCacheOnFileUpdateHandler.js","sources":["../../../src/features/FlushCache/FlushCacheOnFileUpdateHandler.ts"],"sourcesContent":["import { FileBeforeUpdateEventHandler } from \"@webiny/api-file-manager/features/file/UpdateFile/events.js\";\nimport { TaskService } from \"@webiny/api-core/features/task/TaskService/index.js\";\nimport { CdnPathsGenerator } from \"~/utils/CdnPathsGenerator.js\";\n\nclass FlushCacheOnFileUpdateHandlerImpl implements FileBeforeUpdateEventHandler.Interface {\n private readonly pathsGenerator: CdnPathsGenerator;\n\n constructor(private taskService: TaskService.Interface) {\n this.pathsGenerator = new CdnPathsGenerator();\n }\n\n async handle(event: FileBeforeUpdateEventHandler.Event): Promise<void> {\n const { file, original } = event.payload;\n\n const prevAccessControl = original.accessControl;\n const newAccessControl = file.accessControl;\n\n // Only trigger cache flush if access control type has changed\n if (prevAccessControl?.type === newAccessControl?.type) {\n return;\n }\n\n await this.taskService.trigger({\n definition: \"cloudfrontInvalidateCache\",\n input: {\n caller: \"fm-before-update\",\n paths: this.pathsGenerator.generate(file.id)\n }\n });\n }\n}\n\nexport const FlushCacheOnFileUpdateHandler = FileBeforeUpdateEventHandler.createImplementation({\n implementation: FlushCacheOnFileUpdateHandlerImpl,\n dependencies: [TaskService]\n});\n"],"names":["FlushCacheOnFileUpdateHandlerImpl","taskService","CdnPathsGenerator","event","file","original","prevAccessControl","newAccessControl","FlushCacheOnFileUpdateHandler","FileBeforeUpdateEventHandler","TaskService"],"mappings":";;;AAIA,MAAMA;IAGF,YAAoBC,WAAkC,CAAE;aAApCA,WAAW,GAAXA;QAChB,IAAI,CAAC,cAAc,GAAG,IAAIC;IAC9B;IAEA,MAAM,OAAOC,KAAyC,EAAiB;QACnE,MAAM,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGF,MAAM,OAAO;QAExC,MAAMG,oBAAoBD,SAAS,aAAa;QAChD,MAAME,mBAAmBH,KAAK,aAAa;QAG3C,IAAIE,mBAAmB,SAASC,kBAAkB,MAC9C;QAGJ,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;YAC3B,YAAY;YACZ,OAAO;gBACH,QAAQ;gBACR,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAACH,KAAK,EAAE;YAC/C;QACJ;IACJ;AACJ;AAEO,MAAMI,gCAAgCC,6BAA6B,oBAAoB,CAAC;IAC3F,gBAAgBT;IAChB,cAAc;QAACU;KAAY;AAC/B"}
|