@webiny/api-file-manager-server 0.0.0-unstable.9f53ea597d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/assetDelivery/LocalAssetResolver.d.ts +13 -0
  4. package/assetDelivery/LocalAssetResolver.js +40 -0
  5. package/assetDelivery/LocalAssetResolver.js.map +1 -0
  6. package/assetDelivery/LocalContentsReader.d.ts +7 -0
  7. package/assetDelivery/LocalContentsReader.js +18 -0
  8. package/assetDelivery/LocalContentsReader.js.map +1 -0
  9. package/assetDelivery/LocalOutputStrategy.d.ts +11 -0
  10. package/assetDelivery/LocalOutputStrategy.js +21 -0
  11. package/assetDelivery/LocalOutputStrategy.js.map +1 -0
  12. package/assetDelivery/LocalSharpTransform.d.ts +24 -0
  13. package/assetDelivery/LocalSharpTransform.js +174 -0
  14. package/assetDelivery/LocalSharpTransform.js.map +1 -0
  15. package/assetDelivery/abstractions.d.ts +8 -0
  16. package/assetDelivery/abstractions.js +6 -0
  17. package/assetDelivery/abstractions.js.map +1 -0
  18. package/assetDelivery/assetDeliveryConfig.d.ts +2 -0
  19. package/assetDelivery/assetDeliveryConfig.js +15 -0
  20. package/assetDelivery/assetDeliveryConfig.js.map +1 -0
  21. package/assetDelivery/createAssetDelivery.d.ts +3 -0
  22. package/assetDelivery/createAssetDelivery.js +7 -0
  23. package/assetDelivery/createAssetDelivery.js.map +1 -0
  24. package/assetDelivery/feature.d.ts +5 -0
  25. package/assetDelivery/feature.js +33 -0
  26. package/assetDelivery/feature.js.map +1 -0
  27. package/assetDelivery/types.d.ts +8 -0
  28. package/assetDelivery/types.js +0 -0
  29. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.d.ts +18 -0
  30. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.js +58 -0
  31. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.js.map +1 -0
  32. package/features/CleanupStaleMultipartUploads/feature.d.ts +4 -0
  33. package/features/CleanupStaleMultipartUploads/feature.js +11 -0
  34. package/features/CleanupStaleMultipartUploads/feature.js.map +1 -0
  35. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.d.ts +11 -0
  36. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.js +59 -0
  37. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -0
  38. package/features/CompleteMultiPartUpload/feature.d.ts +4 -0
  39. package/features/CompleteMultiPartUpload/feature.js +11 -0
  40. package/features/CompleteMultiPartUpload/feature.js.map +1 -0
  41. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.d.ts +14 -0
  42. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.js +59 -0
  43. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -0
  44. package/features/CreateMultiPartUpload/feature.d.ts +4 -0
  45. package/features/CreateMultiPartUpload/feature.js +11 -0
  46. package/features/CreateMultiPartUpload/feature.js.map +1 -0
  47. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.d.ts +13 -0
  48. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.js +31 -0
  49. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.js.map +1 -0
  50. package/features/DeleteFileFromDisk/feature.d.ts +4 -0
  51. package/features/DeleteFileFromDisk/feature.js +11 -0
  52. package/features/DeleteFileFromDisk/feature.js.map +1 -0
  53. package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +1 -0
  54. package/features/ExtractMetadata/ExtractMetadataHandler.js +1 -0
  55. package/features/ExtractMetadata/ExtractMetadataTask.d.ts +22 -0
  56. package/features/ExtractMetadata/ExtractMetadataTask.js +81 -0
  57. package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
  58. package/features/ExtractMetadata/feature.d.ts +4 -0
  59. package/features/ExtractMetadata/feature.js +13 -0
  60. package/features/ExtractMetadata/feature.js.map +1 -0
  61. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.d.ts +8 -0
  62. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.js +11 -0
  63. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.js.map +1 -0
  64. package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +8 -0
  65. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +11 -0
  66. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
  67. package/features/FlushCache/feature.d.ts +4 -0
  68. package/features/FlushCache/feature.js +13 -0
  69. package/features/FlushCache/feature.js.map +1 -0
  70. package/features/GetFileContentsById/GetFileContentsByIdUseCase.d.ts +13 -0
  71. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js +35 -0
  72. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js.map +1 -0
  73. package/features/GetFileContentsById/feature.d.ts +4 -0
  74. package/features/GetFileContentsById/feature.js +11 -0
  75. package/features/GetFileContentsById/feature.js.map +1 -0
  76. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.d.ts +13 -0
  77. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js +69 -0
  78. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js.map +1 -0
  79. package/features/GetFileContentsByKey/feature.d.ts +4 -0
  80. package/features/GetFileContentsByKey/feature.js +11 -0
  81. package/features/GetFileContentsByKey/feature.js.map +1 -0
  82. package/features/GetUploadPayload/GetUploadPayloadUseCase.d.ts +16 -0
  83. package/features/GetUploadPayload/GetUploadPayloadUseCase.js +58 -0
  84. package/features/GetUploadPayload/GetUploadPayloadUseCase.js.map +1 -0
  85. package/features/GetUploadPayload/feature.d.ts +4 -0
  86. package/features/GetUploadPayload/feature.js +11 -0
  87. package/features/GetUploadPayload/feature.js.map +1 -0
  88. package/index.d.ts +4 -0
  89. package/index.js +42 -0
  90. package/index.js.map +1 -0
  91. package/package.json +44 -0
  92. package/routes/uploadRoutes.d.ts +4 -0
  93. package/routes/uploadRoutes.js +130 -0
  94. package/routes/uploadRoutes.js.map +1 -0
  95. package/types.d.ts +10 -0
  96. package/types.js +1 -0
  97. package/utils/resolveServerUrl.d.ts +2 -0
  98. package/utils/resolveServerUrl.js +10 -0
  99. package/utils/resolveServerUrl.js.map +1 -0
  100. package/utils/uploadToken.d.ts +3 -0
  101. package/utils/uploadToken.js +22 -0
  102. package/utils/uploadToken.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.js","sources":["../../../src/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface CleanupStaleMultipartUploadsInput {\n /* Reserved for future use. */\n noop?: boolean;\n}\n\nconst STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;\n\n/* Returns directory entries or an empty array if the path does not exist. */\nasync function readdirSafe(dirPath: string): Promise<string[]> {\n try {\n return await fs.readdir(dirPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return [];\n }\n throw err;\n }\n}\n\nclass CleanupStaleMultipartUploadsTaskImpl implements TaskDefinition.Interface<CleanupStaleMultipartUploadsInput> {\n public readonly id = \"fileManagerCleanupStaleMultipartUploads\";\n public readonly title = \"Clean up stale multipart upload directories\";\n public readonly description =\n \"Removes multipart upload directories that are older than 24 hours.\";\n public readonly maxIterations = 1;\n public readonly isPrivate = true;\n public readonly databaseLogs = false;\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n public async run({\n controller\n }: TaskDefinition.RunParams<CleanupStaleMultipartUploadsInput>): Promise<\n TaskDefinition.Result<CleanupStaleMultipartUploadsInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);\n const tenantsDir = path.join(storagePath, \"tenants\");\n const now = Date.now();\n\n const tenantDirs = await readdirSafe(tenantsDir);\n\n for (const tenantId of tenantDirs) {\n const multipartDir = path.join(tenantsDir, tenantId, \"multipart\");\n const uploadDirs = await readdirSafe(multipartDir);\n\n for (const uploadId of uploadDirs) {\n const uploadPath = path.join(multipartDir, uploadId);\n\n try {\n const stat = await fs.stat(uploadPath);\n const ageMs = now - stat.mtimeMs;\n\n if (ageMs > STALE_THRESHOLD_MS) {\n await fs.rm(uploadPath, { recursive: true, force: true });\n }\n } catch (err) {\n /* Skip entries that have already been removed or cannot be accessed. */\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw err;\n }\n }\n }\n }\n\n return controller.response.done();\n }\n}\n\nexport const CleanupStaleMultipartUploadsTaskDefinition = TaskDefinition.createImplementation({\n implementation: CleanupStaleMultipartUploadsTaskImpl,\n dependencies: []\n});\n"],"names":["STALE_THRESHOLD_MS","readdirSafe","dirPath","fs","err","CleanupStaleMultipartUploadsTaskImpl","controller","storagePath","String","process","tenantsDir","path","now","Date","tenantDirs","tenantId","multipartDir","uploadDirs","uploadId","uploadPath","stat","ageMs","CleanupStaleMultipartUploadsTaskDefinition","TaskDefinition"],"mappings":";;;AASA,MAAMA,qBAAqB;AAG3B,eAAeC,YAAYC,OAAe;IACtC,IAAI;QACA,OAAO,MAAMC,SAAAA,OAAU,CAACD;IAC5B,EAAE,OAAOE,KAAK;QACV,IAAKA,AAAuC,aAAvCA,IAA8B,IAAI,EACnC,OAAO,EAAE;QAEb,MAAMA;IACV;AACJ;AAEA,MAAMC;IAUF,MAAa,IAAI,EACbC,UAAU,EACgD,EAE5D;QACE,IAAIA,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAGtC,MAAMC,cAAcC,OAAOC,QAAQ,GAAG,CAAC,yBAAyB;QAChE,MAAMC,aAAaC,UAAAA,IAAS,CAACJ,aAAa;QAC1C,MAAMK,MAAMC,KAAK,GAAG;QAEpB,MAAMC,aAAa,MAAMb,YAAYS;QAErC,KAAK,MAAMK,YAAYD,WAAY;YAC/B,MAAME,eAAeL,UAAAA,IAAS,CAACD,YAAYK,UAAU;YACrD,MAAME,aAAa,MAAMhB,YAAYe;YAErC,KAAK,MAAME,YAAYD,WAAY;gBAC/B,MAAME,aAAaR,UAAAA,IAAS,CAACK,cAAcE;gBAE3C,IAAI;oBACA,MAAME,OAAO,MAAMjB,SAAAA,IAAO,CAACgB;oBAC3B,MAAME,QAAQT,MAAMQ,KAAK,OAAO;oBAEhC,IAAIC,QAAQrB,oBACR,MAAMG,SAAAA,EAAK,CAACgB,YAAY;wBAAE,WAAW;wBAAM,OAAO;oBAAK;gBAE/D,EAAE,OAAOf,KAAK;oBAEV,IAAKA,AAAuC,aAAvCA,IAA8B,IAAI,EACnC,MAAMA;gBAEd;YACJ;QACJ;QAEA,OAAOE,WAAW,QAAQ,CAAC,IAAI;IACnC;;aAhDgB,EAAE,GAAG;aACL,KAAK,GAAG;aACR,WAAW,GACvB;aACY,aAAa,GAAG;aAChB,SAAS,GAAG;aACZ,YAAY,GAAG;aACf,WAAW,GAAG;YAAC;YAAsB;SAAmB;;AA0C5E;AAEO,MAAMgB,6CAA6CC,eAAe,oBAAoB,CAAC;IAC1F,gBAAgBlB;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,4 @@
1
+ export declare const CleanupStaleMultipartUploadsFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { CleanupStaleMultipartUploadsTaskDefinition } from "./CleanupStaleMultipartUploadsTask.js";
3
+ const CleanupStaleMultipartUploadsFeature = createFeature({
4
+ name: "FileManagerServer/CleanupStaleMultipartUploads",
5
+ register (container) {
6
+ container.register(CleanupStaleMultipartUploadsTaskDefinition);
7
+ }
8
+ });
9
+ export { CleanupStaleMultipartUploadsFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CleanupStaleMultipartUploads/feature.js","sources":["../../../src/features/CleanupStaleMultipartUploads/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CleanupStaleMultipartUploadsTaskDefinition } from \"./CleanupStaleMultipartUploadsTask.js\";\n\nexport const CleanupStaleMultipartUploadsFeature = createFeature({\n name: \"FileManagerServer/CleanupStaleMultipartUploads\",\n register(container) {\n container.register(CleanupStaleMultipartUploadsTaskDefinition);\n }\n});\n"],"names":["CleanupStaleMultipartUploadsFeature","createFeature","container","CleanupStaleMultipartUploadsTaskDefinition"],"mappings":";;AAGO,MAAMA,sCAAsCC,cAAc;IAC7D,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,11 @@
1
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
2
+ import { CompleteMultiPartUploadUseCase } from "@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/index.js";
3
+ declare class CompleteMultiPartUploadUseCaseImpl implements CompleteMultiPartUploadUseCase.Interface {
4
+ private readonly tenantContext;
5
+ constructor(tenantContext: TenantContext.Interface);
6
+ execute(params: CompleteMultiPartUploadUseCase.Params): Promise<void>;
7
+ }
8
+ export declare const CompleteMultiPartUploadUseCaseImplementation: typeof CompleteMultiPartUploadUseCaseImpl & {
9
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/abstractions").ICompleteMultiPartUploadUseCase>;
10
+ };
11
+ export {};
@@ -0,0 +1,59 @@
1
+ import node_path from "node:path";
2
+ import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
3
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
4
+ import { CompleteMultiPartUploadUseCase } from "@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/index.js";
5
+ class CompleteMultiPartUploadUseCaseImpl {
6
+ constructor(tenantContext){
7
+ this.tenantContext = tenantContext;
8
+ }
9
+ async execute(params) {
10
+ const { fileKey, uploadId } = params;
11
+ const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);
12
+ const tenant = this.tenantContext.getTenant();
13
+ assertNoTraversal(uploadId);
14
+ for (const seg of fileKey.split(/[\\/]/))assertNoTraversal(seg);
15
+ const tenantRoot = node_path.resolve(node_path.join(storagePath, "tenants", tenant.id, "files"));
16
+ const destPath = node_path.resolve(node_path.join(tenantRoot, fileKey));
17
+ assertPathContained(destPath, tenantRoot);
18
+ const multipartDir = node_path.join(storagePath, "tenants", tenant.id, "multipart", uploadId);
19
+ const entries = await readdir(multipartDir);
20
+ const sorted = entries.filter((name)=>name.startsWith("part-")).sort((a, b)=>{
21
+ const numA = parseInt(a.replace("part-", ""), 10);
22
+ const numB = parseInt(b.replace("part-", ""), 10);
23
+ return numA - numB;
24
+ });
25
+ const destDir = node_path.dirname(destPath);
26
+ await mkdir(destDir, {
27
+ recursive: true
28
+ });
29
+ const buffers = [];
30
+ for (const partName of sorted){
31
+ const partPath = node_path.join(multipartDir, partName);
32
+ const partData = await readFile(partPath);
33
+ buffers.push(partData);
34
+ }
35
+ const finalBuffer = Buffer.concat(buffers);
36
+ await writeFile(destPath, finalBuffer);
37
+ await rm(multipartDir, {
38
+ recursive: true,
39
+ force: true
40
+ });
41
+ }
42
+ }
43
+ function assertNoTraversal(segment) {
44
+ if (segment.includes("..") || segment.includes("/") || segment.includes("\\")) throw new Error("Invalid path segment.");
45
+ }
46
+ function assertPathContained(resolved, root) {
47
+ const normalized = node_path.resolve(resolved);
48
+ const normalizedRoot = node_path.resolve(root);
49
+ if (!normalized.startsWith(normalizedRoot + node_path.sep) && normalized !== normalizedRoot) throw new Error("Path escapes tenant root.");
50
+ }
51
+ const CompleteMultiPartUploadUseCaseImplementation = CompleteMultiPartUploadUseCase.createImplementation({
52
+ implementation: CompleteMultiPartUploadUseCaseImpl,
53
+ dependencies: [
54
+ TenantContext
55
+ ]
56
+ });
57
+ export { CompleteMultiPartUploadUseCaseImplementation };
58
+
59
+ //# sourceMappingURL=CompleteMultiPartUploadUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.js","sources":["../../../src/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\nimport { readdir } from \"node:fs/promises\";\nimport { readFile } from \"node:fs/promises\";\nimport { writeFile } from \"node:fs/promises\";\nimport { rm } from \"node:fs/promises\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { CompleteMultiPartUploadUseCase } from \"@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/index.js\";\n\nclass CompleteMultiPartUploadUseCaseImpl implements CompleteMultiPartUploadUseCase.Interface {\n public constructor(private readonly tenantContext: TenantContext.Interface) {}\n\n public async execute(params: CompleteMultiPartUploadUseCase.Params): Promise<void> {\n const { fileKey, uploadId } = params;\n const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);\n const tenant = this.tenantContext.getTenant();\n\n assertNoTraversal(uploadId);\n for (const seg of fileKey.split(/[\\\\/]/)) {\n assertNoTraversal(seg);\n }\n\n const tenantRoot = path.resolve(path.join(storagePath, \"tenants\", tenant.id, \"files\"));\n const destPath = path.resolve(path.join(tenantRoot, fileKey));\n assertPathContained(destPath, tenantRoot);\n\n const multipartDir = path.join(storagePath, \"tenants\", tenant.id, \"multipart\", uploadId);\n\n const entries = await readdir(multipartDir);\n const sorted = entries\n .filter(name => name.startsWith(\"part-\"))\n .sort((a, b) => {\n const numA = parseInt(a.replace(\"part-\", \"\"), 10);\n const numB = parseInt(b.replace(\"part-\", \"\"), 10);\n return numA - numB;\n });\n\n const destDir = path.dirname(destPath);\n await mkdir(destDir, { recursive: true });\n\n const buffers: Buffer[] = [];\n for (const partName of sorted) {\n const partPath = path.join(multipartDir, partName);\n const partData = await readFile(partPath);\n buffers.push(partData);\n }\n\n const finalBuffer = Buffer.concat(buffers);\n await writeFile(destPath, finalBuffer);\n\n await rm(multipartDir, { recursive: true, force: true });\n }\n}\n\nfunction assertNoTraversal(segment: string): void {\n if (segment.includes(\"..\") || segment.includes(\"/\") || segment.includes(\"\\\\\")) {\n throw new Error(\"Invalid path segment.\");\n }\n}\n\nfunction assertPathContained(resolved: string, root: string): void {\n const normalized = path.resolve(resolved);\n const normalizedRoot = path.resolve(root);\n if (!normalized.startsWith(normalizedRoot + path.sep) && normalized !== normalizedRoot) {\n throw new Error(\"Path escapes tenant root.\");\n }\n}\n\nexport const CompleteMultiPartUploadUseCaseImplementation =\n CompleteMultiPartUploadUseCase.createImplementation({\n implementation: CompleteMultiPartUploadUseCaseImpl,\n dependencies: [TenantContext]\n });\n"],"names":["CompleteMultiPartUploadUseCaseImpl","tenantContext","params","fileKey","uploadId","storagePath","String","process","tenant","assertNoTraversal","seg","tenantRoot","path","destPath","assertPathContained","multipartDir","entries","readdir","sorted","name","a","b","numA","parseInt","numB","destDir","mkdir","buffers","partName","partPath","partData","readFile","finalBuffer","Buffer","writeFile","rm","segment","Error","resolved","root","normalized","normalizedRoot","CompleteMultiPartUploadUseCaseImplementation","CompleteMultiPartUploadUseCase","TenantContext"],"mappings":";;;;AASA,MAAMA;IACF,YAAoCC,aAAsC,CAAE;aAAxCA,aAAa,GAAbA;IAAyC;IAE7E,MAAa,QAAQC,MAA6C,EAAiB;QAC/E,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGF;QAC9B,MAAMG,cAAcC,OAAOC,QAAQ,GAAG,CAAC,yBAAyB;QAChE,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3CC,kBAAkBL;QAClB,KAAK,MAAMM,OAAOP,QAAQ,KAAK,CAAC,SAC5BM,kBAAkBC;QAGtB,MAAMC,aAAaC,UAAAA,OAAY,CAACA,UAAAA,IAAS,CAACP,aAAa,WAAWG,OAAO,EAAE,EAAE;QAC7E,MAAMK,WAAWD,UAAAA,OAAY,CAACA,UAAAA,IAAS,CAACD,YAAYR;QACpDW,oBAAoBD,UAAUF;QAE9B,MAAMI,eAAeH,UAAAA,IAAS,CAACP,aAAa,WAAWG,OAAO,EAAE,EAAE,aAAaJ;QAE/E,MAAMY,UAAU,MAAMC,QAAQF;QAC9B,MAAMG,SAASF,QACV,MAAM,CAACG,CAAAA,OAAQA,KAAK,UAAU,CAAC,UAC/B,IAAI,CAAC,CAACC,GAAGC;YACN,MAAMC,OAAOC,SAASH,EAAE,OAAO,CAAC,SAAS,KAAK;YAC9C,MAAMI,OAAOD,SAASF,EAAE,OAAO,CAAC,SAAS,KAAK;YAC9C,OAAOC,OAAOE;QAClB;QAEJ,MAAMC,UAAUb,UAAAA,OAAY,CAACC;QAC7B,MAAMa,MAAMD,SAAS;YAAE,WAAW;QAAK;QAEvC,MAAME,UAAoB,EAAE;QAC5B,KAAK,MAAMC,YAAYV,OAAQ;YAC3B,MAAMW,WAAWjB,UAAAA,IAAS,CAACG,cAAca;YACzC,MAAME,WAAW,MAAMC,SAASF;YAChCF,QAAQ,IAAI,CAACG;QACjB;QAEA,MAAME,cAAcC,OAAO,MAAM,CAACN;QAClC,MAAMO,UAAUrB,UAAUmB;QAE1B,MAAMG,GAAGpB,cAAc;YAAE,WAAW;YAAM,OAAO;QAAK;IAC1D;AACJ;AAEA,SAASN,kBAAkB2B,OAAe;IACtC,IAAIA,QAAQ,QAAQ,CAAC,SAASA,QAAQ,QAAQ,CAAC,QAAQA,QAAQ,QAAQ,CAAC,OACpE,MAAM,IAAIC,MAAM;AAExB;AAEA,SAASvB,oBAAoBwB,QAAgB,EAAEC,IAAY;IACvD,MAAMC,aAAa5B,UAAAA,OAAY,CAAC0B;IAChC,MAAMG,iBAAiB7B,UAAAA,OAAY,CAAC2B;IACpC,IAAI,CAACC,WAAW,UAAU,CAACC,iBAAiB7B,UAAAA,GAAQ,KAAK4B,eAAeC,gBACpE,MAAM,IAAIJ,MAAM;AAExB;AAEO,MAAMK,+CACTC,+BAA+B,oBAAoB,CAAC;IAChD,gBAAgB3C;IAChB,cAAc;QAAC4C;KAAc;AACjC"}
@@ -0,0 +1,4 @@
1
+ export declare const CompleteMultiPartUploadFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { CompleteMultiPartUploadUseCaseImplementation } from "./CompleteMultiPartUploadUseCase.js";
3
+ const CompleteMultiPartUploadFeature = createFeature({
4
+ name: "FileManagerServer/CompleteMultiPartUpload",
5
+ register (container) {
6
+ container.register(CompleteMultiPartUploadUseCaseImplementation);
7
+ }
8
+ });
9
+ export { CompleteMultiPartUploadFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CompleteMultiPartUpload/feature.js","sources":["../../../src/features/CompleteMultiPartUpload/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CompleteMultiPartUploadUseCaseImplementation } from \"./CompleteMultiPartUploadUseCase.js\";\n\nexport const CompleteMultiPartUploadFeature = createFeature({\n name: \"FileManagerServer/CompleteMultiPartUpload\",\n register(container) {\n container.register(CompleteMultiPartUploadUseCaseImplementation);\n }\n});\n"],"names":["CompleteMultiPartUploadFeature","createFeature","container","CompleteMultiPartUploadUseCaseImplementation"],"mappings":";;AAGO,MAAMA,iCAAiCC,cAAc;IACxD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,14 @@
1
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
2
+ import { Request } from "@webiny/handler/abstractions/Request.js";
3
+ import { CreateMultiPartUploadUseCase } from "@webiny/api-file-manager/features/upload/CreateMultiPartUpload/index.js";
4
+ import type { CreateMultiPartUploadResult } from "@webiny/api-file-manager/features/upload/types.js";
5
+ declare class CreateMultiPartUploadUseCaseImpl implements CreateMultiPartUploadUseCase.Interface {
6
+ private readonly tenantContext;
7
+ private readonly request;
8
+ constructor(tenantContext: TenantContext.Interface, request: Request.Interface);
9
+ execute(params: CreateMultiPartUploadUseCase.Params): Promise<CreateMultiPartUploadResult>;
10
+ }
11
+ export declare const CreateMultiPartUploadUseCaseImplementation: typeof CreateMultiPartUploadUseCaseImpl & {
12
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/upload/CreateMultiPartUpload/abstractions").ICreateMultiPartUploadUseCase>;
13
+ };
14
+ export {};
@@ -0,0 +1,59 @@
1
+ import node_path from "node:path";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { mdbid } from "@webiny/utils";
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ import { Request } from "@webiny/handler/abstractions/Request.js";
6
+ import { CreateMultiPartUploadUseCase } from "@webiny/api-file-manager/features/upload/CreateMultiPartUpload/index.js";
7
+ import { createUploadToken } from "../../utils/uploadToken.js";
8
+ import { resolveServerUrl } from "../../utils/resolveServerUrl.js";
9
+ class CreateMultiPartUploadUseCaseImpl {
10
+ constructor(tenantContext, request){
11
+ this.tenantContext = tenantContext;
12
+ this.request = request;
13
+ }
14
+ async execute(params) {
15
+ const { file, numberOfParts } = params;
16
+ const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);
17
+ const tenant = this.tenantContext.getTenant();
18
+ const serverUrl = await resolveServerUrl(this.request);
19
+ const uploadId = mdbid();
20
+ const multipartDir = node_path.join(storagePath, "tenants", tenant.id, "multipart", uploadId);
21
+ await mkdir(multipartDir, {
22
+ recursive: true
23
+ });
24
+ const secret = process.env.WEBINY_UPLOAD_SECRET;
25
+ const expiresAt = Date.now() + 86400000;
26
+ const parts = Array.from({
27
+ length: numberOfParts
28
+ }, (_, index)=>{
29
+ const partNumber = index + 1;
30
+ const token = createUploadToken({
31
+ key: `tenants/${tenant.id}/multipart/${uploadId}/part-${partNumber}`,
32
+ tenantId: tenant.id,
33
+ expiresAt,
34
+ uploadMinFileSize: 0,
35
+ uploadMaxFileSize: 1099511627776
36
+ }, secret);
37
+ const url = `${serverUrl}/webiny-file-upload/parts?uploadId=${uploadId}&partNumber=${partNumber}&token=${token}`;
38
+ return {
39
+ partNumber,
40
+ url
41
+ };
42
+ });
43
+ return {
44
+ file,
45
+ uploadId,
46
+ parts
47
+ };
48
+ }
49
+ }
50
+ const CreateMultiPartUploadUseCaseImplementation = CreateMultiPartUploadUseCase.createImplementation({
51
+ implementation: CreateMultiPartUploadUseCaseImpl,
52
+ dependencies: [
53
+ TenantContext,
54
+ Request
55
+ ]
56
+ });
57
+ export { CreateMultiPartUploadUseCaseImplementation };
58
+
59
+ //# sourceMappingURL=CreateMultiPartUploadUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.js","sources":["../../../src/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\nimport { mdbid } from \"@webiny/utils\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { Request } from \"@webiny/handler/abstractions/Request.js\";\nimport { CreateMultiPartUploadUseCase } from \"@webiny/api-file-manager/features/upload/CreateMultiPartUpload/index.js\";\nimport type { CreateMultiPartUploadResult } from \"@webiny/api-file-manager/features/upload/types.js\";\nimport { createUploadToken } from \"~/utils/uploadToken.js\";\nimport { resolveServerUrl } from \"~/utils/resolveServerUrl.js\";\n\nclass CreateMultiPartUploadUseCaseImpl implements CreateMultiPartUploadUseCase.Interface {\n public constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly request: Request.Interface\n ) {}\n\n public async execute(\n params: CreateMultiPartUploadUseCase.Params\n ): Promise<CreateMultiPartUploadResult> {\n const { file, numberOfParts } = params;\n const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);\n const tenant = this.tenantContext.getTenant();\n const serverUrl = await resolveServerUrl(this.request);\n\n const uploadId = mdbid();\n\n const multipartDir = path.join(storagePath, \"tenants\", tenant.id, \"multipart\", uploadId);\n await mkdir(multipartDir, { recursive: true });\n\n const secret = process.env.WEBINY_UPLOAD_SECRET as string;\n const expiresAt = Date.now() + 86_400_000; /* 24h */\n\n const parts = Array.from({ length: numberOfParts }, (_, index) => {\n const partNumber = index + 1;\n\n const token = createUploadToken(\n {\n key: `tenants/${tenant.id}/multipart/${uploadId}/part-${partNumber}`,\n tenantId: tenant.id,\n expiresAt,\n uploadMinFileSize: 0,\n uploadMaxFileSize: 1_099_511_627_776\n },\n secret\n );\n\n const url = `${serverUrl}/webiny-file-upload/parts?uploadId=${uploadId}&partNumber=${partNumber}&token=${token}`;\n\n return { partNumber, url };\n });\n\n return { file, uploadId, parts };\n }\n}\n\nexport const CreateMultiPartUploadUseCaseImplementation =\n CreateMultiPartUploadUseCase.createImplementation({\n implementation: CreateMultiPartUploadUseCaseImpl,\n dependencies: [TenantContext, Request]\n });\n"],"names":["CreateMultiPartUploadUseCaseImpl","tenantContext","request","params","file","numberOfParts","storagePath","String","process","tenant","serverUrl","resolveServerUrl","uploadId","mdbid","multipartDir","path","mkdir","secret","expiresAt","Date","parts","Array","_","index","partNumber","token","createUploadToken","url","CreateMultiPartUploadUseCaseImplementation","CreateMultiPartUploadUseCase","TenantContext","Request"],"mappings":";;;;;;;;AAUA,MAAMA;IACF,YACqBC,aAAsC,EACtCC,OAA0B,CAC7C;aAFmBD,aAAa,GAAbA;aACAC,OAAO,GAAPA;IAClB;IAEH,MAAa,QACTC,MAA2C,EACP;QACpC,MAAM,EAAEC,IAAI,EAAEC,aAAa,EAAE,GAAGF;QAChC,MAAMG,cAAcC,OAAOC,QAAQ,GAAG,CAAC,yBAAyB;QAChE,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAC3C,MAAMC,YAAY,MAAMC,iBAAiB,IAAI,CAAC,OAAO;QAErD,MAAMC,WAAWC;QAEjB,MAAMC,eAAeC,UAAAA,IAAS,CAACT,aAAa,WAAWG,OAAO,EAAE,EAAE,aAAaG;QAC/E,MAAMI,MAAMF,cAAc;YAAE,WAAW;QAAK;QAE5C,MAAMG,SAAST,QAAQ,GAAG,CAAC,oBAAoB;QAC/C,MAAMU,YAAYC,KAAK,GAAG,KAAK;QAE/B,MAAMC,QAAQC,MAAM,IAAI,CAAC;YAAE,QAAQhB;QAAc,GAAG,CAACiB,GAAGC;YACpD,MAAMC,aAAaD,QAAQ;YAE3B,MAAME,QAAQC,kBACV;gBACI,KAAK,CAAC,QAAQ,EAAEjB,OAAO,EAAE,CAAC,WAAW,EAAEG,SAAS,MAAM,EAAEY,YAAY;gBACpE,UAAUf,OAAO,EAAE;gBACnBS;gBACA,mBAAmB;gBACnB,mBAAmB;YACvB,GACAD;YAGJ,MAAMU,MAAM,GAAGjB,UAAU,mCAAmC,EAAEE,SAAS,YAAY,EAAEY,WAAW,OAAO,EAAEC,OAAO;YAEhH,OAAO;gBAAED;gBAAYG;YAAI;QAC7B;QAEA,OAAO;YAAEvB;YAAMQ;YAAUQ;QAAM;IACnC;AACJ;AAEO,MAAMQ,6CACTC,6BAA6B,oBAAoB,CAAC;IAC9C,gBAAgB7B;IAChB,cAAc;QAAC8B;QAAeC;KAAQ;AAC1C"}
@@ -0,0 +1,4 @@
1
+ export declare const CreateMultiPartUploadFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { CreateMultiPartUploadUseCaseImplementation } from "./CreateMultiPartUploadUseCase.js";
3
+ const CreateMultiPartUploadFeature = createFeature({
4
+ name: "FileManagerServer/CreateMultiPartUpload",
5
+ register (container) {
6
+ container.register(CreateMultiPartUploadUseCaseImplementation);
7
+ }
8
+ });
9
+ export { CreateMultiPartUploadFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/CreateMultiPartUpload/feature.js","sources":["../../../src/features/CreateMultiPartUpload/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { CreateMultiPartUploadUseCaseImplementation } from \"./CreateMultiPartUploadUseCase.js\";\n\nexport const CreateMultiPartUploadFeature = createFeature({\n name: \"FileManagerServer/CreateMultiPartUpload\",\n register(container) {\n container.register(CreateMultiPartUploadUseCaseImplementation);\n }\n});\n"],"names":["CreateMultiPartUploadFeature","createFeature","container","CreateMultiPartUploadUseCaseImplementation"],"mappings":";;AAGO,MAAMA,+BAA+BC,cAAc;IACtD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,13 @@
1
+ import { FileAfterDeleteEventHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
2
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
3
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
4
+ declare class DeleteFileFromDiskHandlerImpl implements FileAfterDeleteEventHandler.Interface {
5
+ private readonly tenantContext;
6
+ private readonly keyValueStore;
7
+ constructor(tenantContext: TenantContext.Interface, keyValueStore: GlobalKeyValueStore.Interface);
8
+ handle(event: FileAfterDeleteEventHandler.Event): Promise<void>;
9
+ }
10
+ export declare const DeleteFileFromDiskHandler: typeof DeleteFileFromDiskHandlerImpl & {
11
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/eventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/DeleteFile/events.js").FileAfterDeleteEvent>>;
12
+ };
13
+ export {};
@@ -0,0 +1,31 @@
1
+ import { promises } from "node:fs";
2
+ import { FileAfterDeleteEventHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
4
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
5
+ class DeleteFileFromDiskHandlerImpl {
6
+ constructor(tenantContext, keyValueStore){
7
+ this.tenantContext = tenantContext;
8
+ this.keyValueStore = keyValueStore;
9
+ }
10
+ async handle(event) {
11
+ const { file } = event.payload;
12
+ const tenant = this.tenantContext.getTenant();
13
+ const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);
14
+ const folderPath = `${storagePath}/tenants/${tenant.id}/files/${file.id}`;
15
+ await promises.rm(folderPath, {
16
+ recursive: true,
17
+ force: true
18
+ });
19
+ await this.keyValueStore.delete(`FileManager/File/${file.id}/Metadata`);
20
+ }
21
+ }
22
+ const DeleteFileFromDiskHandler = FileAfterDeleteEventHandler.createImplementation({
23
+ implementation: DeleteFileFromDiskHandlerImpl,
24
+ dependencies: [
25
+ TenantContext,
26
+ GlobalKeyValueStore
27
+ ]
28
+ });
29
+ export { DeleteFileFromDiskHandler };
30
+
31
+ //# sourceMappingURL=DeleteFileFromDiskHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/DeleteFileFromDisk/DeleteFileFromDiskHandler.js","sources":["../../../src/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport { FileAfterDeleteEventHandler } from \"@webiny/api-file-manager/features/file/DeleteFile/events.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\n\nclass DeleteFileFromDiskHandlerImpl implements FileAfterDeleteEventHandler.Interface {\n constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly keyValueStore: GlobalKeyValueStore.Interface\n ) {}\n\n async handle(event: FileAfterDeleteEventHandler.Event): Promise<void> {\n const { file } = event.payload;\n const tenant = this.tenantContext.getTenant();\n const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);\n const folderPath = `${storagePath}/tenants/${tenant.id}/files/${file.id}`;\n\n /* Delete the file folder from local disk. */\n await fs.rm(folderPath, { recursive: true, force: true });\n\n /* Delete file metadata from the key-value store. */\n await this.keyValueStore.delete(`FileManager/File/${file.id}/Metadata`);\n }\n}\n\nexport const DeleteFileFromDiskHandler = FileAfterDeleteEventHandler.createImplementation({\n implementation: DeleteFileFromDiskHandlerImpl,\n dependencies: [TenantContext, GlobalKeyValueStore]\n});\n"],"names":["DeleteFileFromDiskHandlerImpl","tenantContext","keyValueStore","event","file","tenant","storagePath","String","process","folderPath","fs","DeleteFileFromDiskHandler","FileAfterDeleteEventHandler","TenantContext","GlobalKeyValueStore"],"mappings":";;;;AAKA,MAAMA;IACF,YACqBC,aAAsC,EACtCC,aAA4C,CAC/D;aAFmBD,aAAa,GAAbA;aACAC,aAAa,GAAbA;IAClB;IAEH,MAAM,OAAOC,KAAwC,EAAiB;QAClE,MAAM,EAAEC,IAAI,EAAE,GAAGD,MAAM,OAAO;QAC9B,MAAME,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAC3C,MAAMC,cAAcC,OAAOC,QAAQ,GAAG,CAAC,yBAAyB;QAChE,MAAMC,aAAa,GAAGH,YAAY,SAAS,EAAED,OAAO,EAAE,CAAC,OAAO,EAAED,KAAK,EAAE,EAAE;QAGzE,MAAMM,SAAAA,EAAK,CAACD,YAAY;YAAE,WAAW;YAAM,OAAO;QAAK;QAGvD,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAEL,KAAK,EAAE,CAAC,SAAS,CAAC;IAC1E;AACJ;AAEO,MAAMO,4BAA4BC,4BAA4B,oBAAoB,CAAC;IACtF,gBAAgBZ;IAChB,cAAc;QAACa;QAAeC;KAAoB;AACtD"}
@@ -0,0 +1,4 @@
1
+ export declare const DeleteFileFromDiskFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,11 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { DeleteFileFromDiskHandler } from "./DeleteFileFromDiskHandler.js";
3
+ const DeleteFileFromDiskFeature = createFeature({
4
+ name: "FileManagerServer/DeleteFileFromDisk",
5
+ register (container) {
6
+ container.register(DeleteFileFromDiskHandler);
7
+ }
8
+ });
9
+ export { DeleteFileFromDiskFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/DeleteFileFromDisk/feature.js","sources":["../../../src/features/DeleteFileFromDisk/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { DeleteFileFromDiskHandler } from \"./DeleteFileFromDiskHandler.js\";\n\nexport const DeleteFileFromDiskFeature = createFeature({\n name: \"FileManagerServer/DeleteFileFromDisk\",\n register(container) {\n container.register(DeleteFileFromDiskHandler);\n }\n});\n"],"names":["DeleteFileFromDiskFeature","createFeature","container","DeleteFileFromDiskHandler"],"mappings":";;AAGO,MAAMA,4BAA4BC,cAAc;IACnD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1 @@
1
+ export { ExtractMetadataHandler } from "@webiny/api-file-manager/features/extractMetadata/ExtractMetadataHandler.js";
@@ -0,0 +1 @@
1
+ export { ExtractMetadataHandler } from "@webiny/api-file-manager/features/extractMetadata/ExtractMetadataHandler.js";
@@ -0,0 +1,22 @@
1
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
3
+ import { MetadataReader } from "@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js";
4
+ import type { ExtractMetadataInput } from "@webiny/api-file-manager/features/extractMetadata/ExtractMetadataInput.js";
5
+ declare class ExtractMetadataTaskImpl implements TaskDefinition.Interface<ExtractMetadataInput> {
6
+ private readonly metadataReader;
7
+ private readonly updateFileUseCase;
8
+ readonly id = "fileManagerExtractMetadata";
9
+ readonly title = "Extract image metadata (dimensions, EXIF, IPTC)";
10
+ readonly description = "A task to extract metadata from uploaded image files";
11
+ readonly maxIterations = 1;
12
+ readonly isPrivate = true;
13
+ readonly databaseLogs = false;
14
+ readonly selfCleanup: ("onAbort" | "onSuccess")[];
15
+ constructor(metadataReader: MetadataReader.Interface, updateFileUseCase: UpdateFileUseCase.Interface);
16
+ run({ input, controller }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<TaskDefinition.Result<ExtractMetadataInput>>;
17
+ private cleanValues;
18
+ }
19
+ export declare const ExtractMetadataTaskDefinition: typeof ExtractMetadataTaskImpl & {
20
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskDefinition<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
21
+ };
22
+ export {};
@@ -0,0 +1,81 @@
1
+ import { promises } from "node:fs";
2
+ import { TaskDefinition } from "@webiny/api-core/features/task/TaskDefinition/index.js";
3
+ import { UpdateFileUseCase } from "@webiny/api-file-manager/features/file/UpdateFile/index.js";
4
+ import { MetadataReader } from "@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js";
5
+ class ExtractMetadataTaskImpl {
6
+ constructor(metadataReader, updateFileUseCase){
7
+ this.metadataReader = metadataReader;
8
+ this.updateFileUseCase = updateFileUseCase;
9
+ this.id = "fileManagerExtractMetadata";
10
+ this.title = "Extract image metadata (dimensions, EXIF, IPTC)";
11
+ this.description = "A task to extract metadata from uploaded image files";
12
+ this.maxIterations = 1;
13
+ this.isPrivate = true;
14
+ this.databaseLogs = false;
15
+ this.selfCleanup = [
16
+ "onSuccess",
17
+ "onAbort"
18
+ ];
19
+ }
20
+ async run({ input, controller }) {
21
+ if (controller.runtime.isAborted()) return controller.response.aborted();
22
+ const fileMetadata = await this.metadataReader.read(input.fileId);
23
+ if (!fileMetadata) return controller.response.error({
24
+ message: `File metadata not found for file ID: ${input.fileId}`
25
+ });
26
+ if (!fileMetadata.contentType.startsWith("image/")) return controller.response.done();
27
+ const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);
28
+ const filePath = `${storagePath}/${fileMetadata.bucketKey}`;
29
+ try {
30
+ const buffer = await promises.readFile(filePath);
31
+ const sharp = await import("sharp").then((m)=>m.default);
32
+ const ExifReader = await import("exifreader").then((m)=>m.default);
33
+ const sharpInstance = sharp(buffer);
34
+ const sharpMetadata = await sharpInstance.metadata();
35
+ const tags = ExifReader.load(buffer, {
36
+ expanded: true
37
+ });
38
+ const metadata = {
39
+ image: {
40
+ width: sharpMetadata.width,
41
+ height: sharpMetadata.height,
42
+ format: sharpMetadata.format,
43
+ orientation: sharpMetadata.orientation ?? 1
44
+ }
45
+ };
46
+ if (tags.exif) metadata.exif = this.cleanValues(tags.exif);
47
+ if (tags.iptc) metadata.iptc = this.cleanValues(tags.iptc);
48
+ const updateResult = await this.updateFileUseCase.execute({
49
+ id: input.fileId,
50
+ metadata
51
+ });
52
+ if (updateResult.isFail()) return controller.response.error({
53
+ message: `Failed to update file with metadata: ${updateResult.error.message}`
54
+ });
55
+ return controller.response.done();
56
+ } catch (error) {
57
+ return controller.response.error({
58
+ message: `Failed to extract metadata: ${error instanceof Error ? error.message : String(error)}`
59
+ });
60
+ }
61
+ }
62
+ cleanValues(tags) {
63
+ const cleaned = {};
64
+ for (const [key, tag] of Object.entries(tags))if (tag && "object" == typeof tag) {
65
+ if (void 0 !== tag.description && null !== tag.description) cleaned[key] = tag.description;
66
+ else if (Array.isArray(tag.value) && tag.value.length > 20) ;
67
+ else if (void 0 !== tag.value) cleaned[key] = tag.value;
68
+ }
69
+ return cleaned;
70
+ }
71
+ }
72
+ const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({
73
+ implementation: ExtractMetadataTaskImpl,
74
+ dependencies: [
75
+ MetadataReader,
76
+ UpdateFileUseCase
77
+ ]
78
+ });
79
+ export { ExtractMetadataTaskDefinition };
80
+
81
+ //# sourceMappingURL=ExtractMetadataTask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/ExtractMetadata/ExtractMetadataTask.js","sources":["../../../src/features/ExtractMetadata/ExtractMetadataTask.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport type { ExifTags } from \"exifreader\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js\";\nimport type { ExtractMetadataInput } from \"@webiny/api-file-manager/features/extractMetadata/ExtractMetadataInput.js\";\n\nclass ExtractMetadataTaskImpl implements TaskDefinition.Interface<ExtractMetadataInput> {\n public readonly id = \"fileManagerExtractMetadata\";\n public readonly title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n public readonly description = \"A task to extract metadata from uploaded image files\";\n public readonly maxIterations = 1;\n public readonly isPrivate = true;\n public readonly databaseLogs = false;\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n public constructor(\n private readonly metadataReader: MetadataReader.Interface,\n private readonly 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 from the key-value store. */\n const fileMetadata = await this.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 /* Only process image files. */\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n const storagePath = String(process.env.WEBINY_LOCAL_STORAGE_PATH);\n const filePath = `${storagePath}/${fileMetadata.bucketKey}`;\n\n try {\n /* Read the image file from local disk. */\n const buffer = await fs.readFile(filePath);\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 /* Extract image dimensions using Sharp. */\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, unknown> = {\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, unknown> = {};\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: ExtractMetadataTaskImpl,\n dependencies: [MetadataReader, UpdateFileUseCase]\n});\n"],"names":["ExtractMetadataTaskImpl","metadataReader","updateFileUseCase","input","controller","fileMetadata","storagePath","String","process","filePath","buffer","fs","sharp","m","ExifReader","sharpInstance","sharpMetadata","tags","metadata","updateResult","error","Error","cleaned","key","tag","Object","undefined","Array","ExtractMetadataTaskDefinition","TaskDefinition","MetadataReader","UpdateFileUseCase"],"mappings":";;;;AAOA,MAAMA;IASF,YACqBC,cAAwC,EACxCC,iBAA8C,CACjE;aAFmBD,cAAc,GAAdA;aACAC,iBAAiB,GAAjBA;aAVL,EAAE,GAAG;aACL,KAAK,GAAG;aACR,WAAW,GAAG;aACd,aAAa,GAAG;aAChB,SAAS,GAAG;aACZ,YAAY,GAAG;aACf,WAAW,GAAG;YAAC;YAAsB;SAAmB;IAKrE;IAEH,MAAa,IAAI,EACbC,KAAK,EACLC,UAAU,EACmC,EAE/C;QACE,IAAIA,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAItC,MAAMC,eAAe,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAACF,MAAM,MAAM;QAEhE,IAAI,CAACE,cACD,OAAOD,WAAW,QAAQ,CAAC,KAAK,CAAC;YAC7B,SAAS,CAAC,qCAAqC,EAAED,MAAM,MAAM,EAAE;QACnE;QAIJ,IAAI,CAACE,aAAa,WAAW,CAAC,UAAU,CAAC,WACrC,OAAOD,WAAW,QAAQ,CAAC,IAAI;QAGnC,MAAME,cAAcC,OAAOC,QAAQ,GAAG,CAAC,yBAAyB;QAChE,MAAMC,WAAW,GAAGH,YAAY,CAAC,EAAED,aAAa,SAAS,EAAE;QAE3D,IAAI;YAEA,MAAMK,SAAS,MAAMC,SAAAA,QAAW,CAACF;YAEjC,MAAMG,QAAQ,MAAM,MAAM,CAAiC,SAAS,IAAI,CACpEC,CAAAA,IAAKA,EAAE,OAAO;YAGlB,MAAMC,aAAa,MAAM,MAAM,CAAsC,cAAc,IAAI,CACnFD,CAAAA,IAAKA,EAAE,OAAO;YAIlB,MAAME,gBAAgBH,MAAMF;YAC5B,MAAMM,gBAAgB,MAAMD,cAAc,QAAQ;YAGlD,MAAME,OAAOH,WAAW,IAAI,CAACJ,QAAQ;gBAAE,UAAU;YAAK;YAGtD,MAAMQ,WAAoC;gBACtC,OAAO;oBACH,OAAOF,cAAc,KAAK;oBAC1B,QAAQA,cAAc,MAAM;oBAC5B,QAAQA,cAAc,MAAM;oBAC5B,aAAaA,cAAc,WAAW,IAAI;gBAC9C;YACJ;YAGA,IAAIC,KAAK,IAAI,EACTC,SAAS,IAAI,GAAG,IAAI,CAAC,WAAW,CAACD,KAAK,IAAI;YAI9C,IAAIA,KAAK,IAAI,EACTC,SAAS,IAAI,GAAG,IAAI,CAAC,WAAW,CAACD,KAAK,IAAI;YAI9C,MAAME,eAAe,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;gBACtD,IAAIhB,MAAM,MAAM;gBAChBe;YACJ;YAEA,IAAIC,aAAa,MAAM,IACnB,OAAOf,WAAW,QAAQ,CAAC,KAAK,CAAC;gBAC7B,SAAS,CAAC,qCAAqC,EAAEe,aAAa,KAAK,CAAC,OAAO,EAAE;YACjF;YAGJ,OAAOf,WAAW,QAAQ,CAAC,IAAI;QACnC,EAAE,OAAOgB,OAAO;YACZ,OAAOhB,WAAW,QAAQ,CAAC,KAAK,CAAC;gBAC7B,SAAS,CAAC,4BAA4B,EAClCgB,iBAAiBC,QAAQD,MAAM,OAAO,GAAGb,OAAOa,QAClD;YACN;QACJ;IACJ;IAEQ,YAAYH,IAAc,EAAE;QAChC,MAAMK,UAAmC,CAAC;QAE1C,KAAK,MAAM,CAACC,KAAKC,IAAI,IAAIC,OAAO,OAAO,CAACR,MACpC,IAAI,AAACO,OAAO,AAAe,YAAf,OAAOA,KAKnB;YAAA,IAAIA,AAAoBE,WAApBF,IAAI,WAAW,IAAkBA,AAAoB,SAApBA,IAAI,WAAW,EAChDF,OAAO,CAACC,IAAI,GAAGC,IAAI,WAAW;iBAC3B,IAAIG,MAAM,OAAO,CAACH,IAAI,KAAK,KAAKA,IAAI,KAAK,CAAC,MAAM,GAAG;iBAEnD,IAAIA,AAAcE,WAAdF,IAAI,KAAK,EAChBF,OAAO,CAACC,IAAI,GAAGC,IAAI,KAAK;QAC5B;QAGJ,OAAOF;IACX;AACJ;AAEO,MAAMM,gCAAgCC,eAAe,oBAAoB,CAAC;IAC7E,gBAAgB7B;IAChB,cAAc;QAAC8B;QAAgBC;KAAkB;AACrD"}
@@ -0,0 +1,4 @@
1
+ export declare const ExtractMetadataFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,13 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { ExtractMetadataHandler } from "./ExtractMetadataHandler.js";
3
+ import { ExtractMetadataTaskDefinition } from "./ExtractMetadataTask.js";
4
+ const ExtractMetadataFeature = createFeature({
5
+ name: "FileManagerServer/ExtractMetadata",
6
+ register (container) {
7
+ container.register(ExtractMetadataHandler);
8
+ container.register(ExtractMetadataTaskDefinition);
9
+ }
10
+ });
11
+ export { ExtractMetadataFeature };
12
+
13
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
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: \"FileManagerServer/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"}
@@ -0,0 +1,8 @@
1
+ import { FileBeforeUpdateEventHandler } from "@webiny/api-file-manager/features/file/UpdateFile/events.js";
2
+ declare class FlushCacheOnFileBeforeUpdateHandlerImpl implements FileBeforeUpdateEventHandler.Interface {
3
+ handle(_event: FileBeforeUpdateEventHandler.Event): Promise<void>;
4
+ }
5
+ export declare const FlushCacheOnFileBeforeUpdateHandler: typeof FlushCacheOnFileBeforeUpdateHandlerImpl & {
6
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/eventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/UpdateFile/events.js").FileBeforeUpdateEvent>>;
7
+ };
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import { FileBeforeUpdateEventHandler } from "@webiny/api-file-manager/features/file/UpdateFile/events.js";
2
+ class FlushCacheOnFileBeforeUpdateHandlerImpl {
3
+ async handle(_event) {}
4
+ }
5
+ const FlushCacheOnFileBeforeUpdateHandler = FileBeforeUpdateEventHandler.createImplementation({
6
+ implementation: FlushCacheOnFileBeforeUpdateHandlerImpl,
7
+ dependencies: []
8
+ });
9
+ export { FlushCacheOnFileBeforeUpdateHandler };
10
+
11
+ //# sourceMappingURL=FlushCacheOnFileBeforeUpdateHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.js","sources":["../../../src/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.ts"],"sourcesContent":["import { FileBeforeUpdateEventHandler } from \"@webiny/api-file-manager/features/file/UpdateFile/events.js\";\n\nclass FlushCacheOnFileBeforeUpdateHandlerImpl implements FileBeforeUpdateEventHandler.Interface {\n /* No-op: local disk does not use a CDN cache. */\n async handle(_event: FileBeforeUpdateEventHandler.Event): Promise<void> {\n /* Nothing to do. */\n }\n}\n\nexport const FlushCacheOnFileBeforeUpdateHandler =\n FileBeforeUpdateEventHandler.createImplementation({\n implementation: FlushCacheOnFileBeforeUpdateHandlerImpl,\n dependencies: []\n });\n"],"names":["FlushCacheOnFileBeforeUpdateHandlerImpl","_event","FlushCacheOnFileBeforeUpdateHandler","FileBeforeUpdateEventHandler"],"mappings":";AAEA,MAAMA;IAEF,MAAM,OAAOC,MAA0C,EAAiB,CAExE;AACJ;AAEO,MAAMC,sCACTC,6BAA6B,oBAAoB,CAAC;IAC9C,gBAAgBH;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,8 @@
1
+ import { FileAfterDeleteEventHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
2
+ declare class FlushCacheOnFileDeleteHandlerImpl implements FileAfterDeleteEventHandler.Interface {
3
+ handle(_event: FileAfterDeleteEventHandler.Event): Promise<void>;
4
+ }
5
+ export declare const FlushCacheOnFileDeleteHandler: typeof FlushCacheOnFileDeleteHandlerImpl & {
6
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/eventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/DeleteFile/events.js").FileAfterDeleteEvent>>;
7
+ };
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import { FileAfterDeleteEventHandler } from "@webiny/api-file-manager/features/file/DeleteFile/events.js";
2
+ class FlushCacheOnFileDeleteHandlerImpl {
3
+ async handle(_event) {}
4
+ }
5
+ const FlushCacheOnFileDeleteHandler = FileAfterDeleteEventHandler.createImplementation({
6
+ implementation: FlushCacheOnFileDeleteHandlerImpl,
7
+ dependencies: []
8
+ });
9
+ export { FlushCacheOnFileDeleteHandler };
10
+
11
+ //# sourceMappingURL=FlushCacheOnFileDeleteHandler.js.map
@@ -0,0 +1 @@
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\";\n\nclass FlushCacheOnFileDeleteHandlerImpl implements FileAfterDeleteEventHandler.Interface {\n /* No-op: local disk does not use a CDN cache. */\n async handle(_event: FileAfterDeleteEventHandler.Event): Promise<void> {\n /* Nothing to do. */\n }\n}\n\nexport const FlushCacheOnFileDeleteHandler = FileAfterDeleteEventHandler.createImplementation({\n implementation: FlushCacheOnFileDeleteHandlerImpl,\n dependencies: []\n});\n"],"names":["FlushCacheOnFileDeleteHandlerImpl","_event","FlushCacheOnFileDeleteHandler","FileAfterDeleteEventHandler"],"mappings":";AAEA,MAAMA;IAEF,MAAM,OAAOC,MAAyC,EAAiB,CAEvE;AACJ;AAEO,MAAMC,gCAAgCC,4BAA4B,oBAAoB,CAAC;IAC1F,gBAAgBH;IAChB,cAAc,EAAE;AACpB"}
@@ -0,0 +1,4 @@
1
+ export declare const FlushCacheFeature: {
2
+ name: string;
3
+ register(container: import("@webiny/di").Container): void;
4
+ };
@@ -0,0 +1,13 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { FlushCacheOnFileDeleteHandler } from "./FlushCacheOnFileDeleteHandler.js";
3
+ import { FlushCacheOnFileBeforeUpdateHandler } from "./FlushCacheOnFileBeforeUpdateHandler.js";
4
+ const FlushCacheFeature = createFeature({
5
+ name: "FileManagerServer/FlushCache",
6
+ register (container) {
7
+ container.register(FlushCacheOnFileDeleteHandler);
8
+ container.register(FlushCacheOnFileBeforeUpdateHandler);
9
+ }
10
+ });
11
+ export { FlushCacheFeature };
12
+
13
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/FlushCache/feature.js","sources":["../../../src/features/FlushCache/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { FlushCacheOnFileDeleteHandler } from \"./FlushCacheOnFileDeleteHandler.js\";\nimport { FlushCacheOnFileBeforeUpdateHandler } from \"./FlushCacheOnFileBeforeUpdateHandler.js\";\n\nexport const FlushCacheFeature = createFeature({\n name: \"FileManagerServer/FlushCache\",\n register(container) {\n container.register(FlushCacheOnFileDeleteHandler);\n container.register(FlushCacheOnFileBeforeUpdateHandler);\n }\n});\n"],"names":["FlushCacheFeature","createFeature","container","FlushCacheOnFileDeleteHandler","FlushCacheOnFileBeforeUpdateHandler"],"mappings":";;;AAIO,MAAMA,oBAAoBC,cAAc;IAC3C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;QACnBD,UAAU,QAAQ,CAACE;IACvB;AACJ"}
@@ -0,0 +1,13 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { GetFileContentsByIdUseCase } from "@webiny/api-file-manager/features/file/GetFileContentsById/index.js";
3
+ import type { FileContents } from "@webiny/api-file-manager/features/file/GetFileContentsById/index.js";
4
+ import { MetadataReader } from "@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js";
5
+ declare class GetFileContentsByIdUseCaseImpl implements GetFileContentsByIdUseCase.Interface {
6
+ private readonly metadataReader;
7
+ constructor(metadataReader: MetadataReader.Interface);
8
+ execute(fileId: string): Promise<Result<FileContents, GetFileContentsByIdUseCase.Error>>;
9
+ }
10
+ export declare const GetFileContentsByIdUseCaseImplementation: typeof GetFileContentsByIdUseCaseImpl & {
11
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/file/GetFileContentsById/abstractions").IGetFileContentsByIdUseCase>;
12
+ };
13
+ export {};