@webiny/api-file-manager-standalone 6.6.0-alpha.4

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 (128) hide show
  1. package/FileManagerStandaloneFeature.d.ts +5 -0
  2. package/FileManagerStandaloneFeature.js +41 -0
  3. package/FileManagerStandaloneFeature.js.map +1 -0
  4. package/LICENSE +21 -0
  5. package/README.md +11 -0
  6. package/assetDelivery/LazyLocalSharpTransform.d.ts +33 -0
  7. package/assetDelivery/LazyLocalSharpTransform.js +32 -0
  8. package/assetDelivery/LazyLocalSharpTransform.js.map +1 -0
  9. package/assetDelivery/LocalAssetResolver.d.ts +15 -0
  10. package/assetDelivery/LocalAssetResolver.js +40 -0
  11. package/assetDelivery/LocalAssetResolver.js.map +1 -0
  12. package/assetDelivery/LocalContentsReader.d.ts +7 -0
  13. package/assetDelivery/LocalContentsReader.js +18 -0
  14. package/assetDelivery/LocalContentsReader.js.map +1 -0
  15. package/assetDelivery/LocalOutputStrategy.d.ts +12 -0
  16. package/assetDelivery/LocalOutputStrategy.js +21 -0
  17. package/assetDelivery/LocalOutputStrategy.js.map +1 -0
  18. package/assetDelivery/LocalSharpTransform.d.ts +24 -0
  19. package/assetDelivery/LocalSharpTransform.js +161 -0
  20. package/assetDelivery/LocalSharpTransform.js.map +1 -0
  21. package/assetDelivery/abstractions.d.ts +8 -0
  22. package/assetDelivery/abstractions.js +6 -0
  23. package/assetDelivery/abstractions.js.map +1 -0
  24. package/assetDelivery/assetDeliveryConfig.d.ts +2 -0
  25. package/assetDelivery/assetDeliveryConfig.js +15 -0
  26. package/assetDelivery/assetDeliveryConfig.js.map +1 -0
  27. package/assetDelivery/createAssetDelivery.d.ts +3 -0
  28. package/assetDelivery/createAssetDelivery.js +7 -0
  29. package/assetDelivery/createAssetDelivery.js.map +1 -0
  30. package/assetDelivery/feature.d.ts +5 -0
  31. package/assetDelivery/feature.js +33 -0
  32. package/assetDelivery/feature.js.map +1 -0
  33. package/assetDelivery/types.d.ts +8 -0
  34. package/assetDelivery/types.js +0 -0
  35. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.d.ts +26 -0
  36. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.js +71 -0
  37. package/features/CleanupStaleMultipartUploads/CleanupStaleMultipartUploadsTask.js.map +1 -0
  38. package/features/CleanupStaleMultipartUploads/feature.d.ts +4 -0
  39. package/features/CleanupStaleMultipartUploads/feature.js +11 -0
  40. package/features/CleanupStaleMultipartUploads/feature.js.map +1 -0
  41. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.d.ts +13 -0
  42. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.js +62 -0
  43. package/features/CompleteMultiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -0
  44. package/features/CompleteMultiPartUpload/feature.d.ts +4 -0
  45. package/features/CompleteMultiPartUpload/feature.js +11 -0
  46. package/features/CompleteMultiPartUpload/feature.js.map +1 -0
  47. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.d.ts +14 -0
  48. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.js +58 -0
  49. package/features/CreateMultiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -0
  50. package/features/CreateMultiPartUpload/feature.d.ts +4 -0
  51. package/features/CreateMultiPartUpload/feature.js +11 -0
  52. package/features/CreateMultiPartUpload/feature.js.map +1 -0
  53. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.d.ts +15 -0
  54. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.js +34 -0
  55. package/features/DeleteFileFromDisk/DeleteFileFromDiskHandler.js.map +1 -0
  56. package/features/DeleteFileFromDisk/feature.d.ts +4 -0
  57. package/features/DeleteFileFromDisk/feature.js +11 -0
  58. package/features/DeleteFileFromDisk/feature.js.map +1 -0
  59. package/features/ExtractMetadata/ExtractMetadataHandler.d.ts +1 -0
  60. package/features/ExtractMetadata/ExtractMetadataHandler.js +1 -0
  61. package/features/ExtractMetadata/ExtractMetadataTask.d.ts +29 -0
  62. package/features/ExtractMetadata/ExtractMetadataTask.js +93 -0
  63. package/features/ExtractMetadata/ExtractMetadataTask.js.map +1 -0
  64. package/features/ExtractMetadata/feature.d.ts +4 -0
  65. package/features/ExtractMetadata/feature.js +13 -0
  66. package/features/ExtractMetadata/feature.js.map +1 -0
  67. package/features/FileManagerStandaloneConfig/FileManagerStandaloneConfig.d.ts +12 -0
  68. package/features/FileManagerStandaloneConfig/FileManagerStandaloneConfig.js +28 -0
  69. package/features/FileManagerStandaloneConfig/FileManagerStandaloneConfig.js.map +1 -0
  70. package/features/FileManagerStandaloneConfig/abstractions.d.ts +10 -0
  71. package/features/FileManagerStandaloneConfig/abstractions.js +5 -0
  72. package/features/FileManagerStandaloneConfig/abstractions.js.map +1 -0
  73. package/features/FileManagerStandaloneConfig/feature.d.ts +4 -0
  74. package/features/FileManagerStandaloneConfig/feature.js +11 -0
  75. package/features/FileManagerStandaloneConfig/feature.js.map +1 -0
  76. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.d.ts +8 -0
  77. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.js +11 -0
  78. package/features/FlushCache/FlushCacheOnFileBeforeUpdateHandler.js.map +1 -0
  79. package/features/FlushCache/FlushCacheOnFileDeleteHandler.d.ts +8 -0
  80. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js +11 -0
  81. package/features/FlushCache/FlushCacheOnFileDeleteHandler.js.map +1 -0
  82. package/features/FlushCache/feature.d.ts +4 -0
  83. package/features/FlushCache/feature.js +13 -0
  84. package/features/FlushCache/feature.js.map +1 -0
  85. package/features/GetFileContentsById/GetFileContentsByIdUseCase.d.ts +15 -0
  86. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js +38 -0
  87. package/features/GetFileContentsById/GetFileContentsByIdUseCase.js.map +1 -0
  88. package/features/GetFileContentsById/feature.d.ts +4 -0
  89. package/features/GetFileContentsById/feature.js +11 -0
  90. package/features/GetFileContentsById/feature.js.map +1 -0
  91. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.d.ts +15 -0
  92. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js +72 -0
  93. package/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js.map +1 -0
  94. package/features/GetFileContentsByKey/feature.d.ts +4 -0
  95. package/features/GetFileContentsByKey/feature.js +11 -0
  96. package/features/GetFileContentsByKey/feature.js.map +1 -0
  97. package/features/GetUploadPayload/GetUploadPayloadUseCase.d.ts +16 -0
  98. package/features/GetUploadPayload/GetUploadPayloadUseCase.js +57 -0
  99. package/features/GetUploadPayload/GetUploadPayloadUseCase.js.map +1 -0
  100. package/features/GetUploadPayload/feature.d.ts +4 -0
  101. package/features/GetUploadPayload/feature.js +11 -0
  102. package/features/GetUploadPayload/feature.js.map +1 -0
  103. package/graphql/StandaloneGraphQLSchema.d.ts +15 -0
  104. package/graphql/StandaloneGraphQLSchema.js +221 -0
  105. package/graphql/StandaloneGraphQLSchema.js.map +1 -0
  106. package/index.d.ts +3 -0
  107. package/index.js +3 -0
  108. package/package.json +44 -0
  109. package/routes/UploadPartRoute/UploadPartRoute.d.ts +23 -0
  110. package/routes/UploadPartRoute/UploadPartRoute.js +71 -0
  111. package/routes/UploadPartRoute/UploadPartRoute.js.map +1 -0
  112. package/routes/UploadPartRoute/feature.d.ts +4 -0
  113. package/routes/UploadPartRoute/feature.js +11 -0
  114. package/routes/UploadPartRoute/feature.js.map +1 -0
  115. package/routes/UploadSingleFileRoute/UploadSingleFileRoute.d.ts +23 -0
  116. package/routes/UploadSingleFileRoute/UploadSingleFileRoute.js +78 -0
  117. package/routes/UploadSingleFileRoute/UploadSingleFileRoute.js.map +1 -0
  118. package/routes/UploadSingleFileRoute/feature.d.ts +4 -0
  119. package/routes/UploadSingleFileRoute/feature.js +11 -0
  120. package/routes/UploadSingleFileRoute/feature.js.map +1 -0
  121. package/routes/utils.d.ts +18 -0
  122. package/routes/utils.js +55 -0
  123. package/routes/utils.js.map +1 -0
  124. package/types.d.ts +10 -0
  125. package/types.js +1 -0
  126. package/utils/uploadToken.d.ts +3 -0
  127. package/utils/uploadToken.js +22 -0
  128. package/utils/uploadToken.js.map +1 -0
@@ -0,0 +1,5 @@
1
+ import type { AssetDeliveryParams } from "./types.js";
2
+ export declare const createLocalAssetDeliveryFeature: (params?: AssetDeliveryParams) => {
3
+ name: string;
4
+ register(container: import("@webiny/di").Container): void;
5
+ };
@@ -0,0 +1,33 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { LocalAssetDeliveryConfig, LocalStoragePath } from "./abstractions.js";
3
+ import { LocalAssetResolver } from "./LocalAssetResolver.js";
4
+ import { LocalOutputStrategy } from "./LocalOutputStrategy.js";
5
+ import { LazyLocalSharpTransformImpl } from "./LazyLocalSharpTransform.js";
6
+ const createLocalAssetDeliveryFeature = (params = {})=>createFeature({
7
+ name: "AssetDelivery/Local",
8
+ register (container) {
9
+ container.registerInstance(LocalStoragePath, process.env.WEBINY_LOCAL_STORAGE_PATH);
10
+ container.registerInstance(LocalAssetDeliveryConfig, {
11
+ imageResizeWidths: params.imageResizeWidths ?? [
12
+ 128,
13
+ 384,
14
+ 640,
15
+ 750,
16
+ 828,
17
+ 1080,
18
+ 1200,
19
+ 1920,
20
+ 2048,
21
+ 3840
22
+ ],
23
+ imageQuality: params.imageQuality ?? {},
24
+ assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592
25
+ });
26
+ container.register(LocalAssetResolver);
27
+ container.register(LocalOutputStrategy);
28
+ if ("asset-delivery" === process.env.WEBINY_FUNCTION_TYPE) container.register(LazyLocalSharpTransformImpl).inSingletonScope();
29
+ }
30
+ });
31
+ export { createLocalAssetDeliveryFeature };
32
+
33
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/feature.js","sources":["../../src/assetDelivery/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { LocalStoragePath } from \"./abstractions.js\";\nimport { LocalAssetDeliveryConfig } from \"./abstractions.js\";\nimport type { AssetDeliveryParams } from \"./types.js\";\nimport { LocalAssetResolver } from \"./LocalAssetResolver.js\";\nimport { LocalOutputStrategy } from \"./LocalOutputStrategy.js\";\nimport { LazyLocalSharpTransformImpl } from \"./LazyLocalSharpTransform.js\";\n\nexport const createLocalAssetDeliveryFeature = (params: AssetDeliveryParams = {}) => {\n return createFeature({\n name: \"AssetDelivery/Local\",\n register(container) {\n container.registerInstance(\n LocalStoragePath,\n process.env.WEBINY_LOCAL_STORAGE_PATH as string\n );\n container.registerInstance(LocalAssetDeliveryConfig, {\n imageResizeWidths: params.imageResizeWidths ?? [\n 128, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840\n ],\n imageQuality: params.imageQuality ?? {},\n assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592\n });\n\n container.register(LocalAssetResolver);\n container.register(LocalOutputStrategy);\n\n if (process.env.WEBINY_FUNCTION_TYPE === \"asset-delivery\") {\n // Registered eagerly; `sharp` is still loaded lazily, inside the handler.\n container.register(LazyLocalSharpTransformImpl).inSingletonScope();\n }\n }\n });\n};\n"],"names":["createLocalAssetDeliveryFeature","params","createFeature","container","LocalStoragePath","process","LocalAssetDeliveryConfig","LocalAssetResolver","LocalOutputStrategy","LazyLocalSharpTransformImpl"],"mappings":";;;;;AAQO,MAAMA,kCAAkC,CAACC,SAA8B,CAAC,CAAC,GACrEC,cAAc;QACjB,MAAM;QACN,UAASC,SAAS;YACdA,UAAU,gBAAgB,CACtBC,kBACAC,QAAQ,GAAG,CAAC,yBAAyB;YAEzCF,UAAU,gBAAgB,CAACG,0BAA0B;gBACjD,mBAAmBL,OAAO,iBAAiB,IAAI;oBAC3C;oBAAK;oBAAK;oBAAK;oBAAK;oBAAK;oBAAM;oBAAM;oBAAM;oBAAM;iBACpD;gBACD,cAAcA,OAAO,YAAY,IAAI,CAAC;gBACtC,uBAAuBA,OAAO,qBAAqB,IAAI;YAC3D;YAEAE,UAAU,QAAQ,CAACI;YACnBJ,UAAU,QAAQ,CAACK;YAEnB,IAAIH,AAAqC,qBAArCA,QAAQ,GAAG,CAAC,oBAAoB,EAEhCF,UAAU,QAAQ,CAACM,6BAA6B,gBAAgB;QAExE;IACJ"}
@@ -0,0 +1,8 @@
1
+ import type { ImageFormat } from "@webiny/api-file-manager/features/assetDelivery/transformation/index.js";
2
+ export type AssetDeliveryParams = {
3
+ imageResizeWidths?: number[];
4
+ /** Per-format encoder quality (1-100). Merged over the built-in defaults. */
5
+ imageQuality?: Partial<Record<ImageFormat, number>>;
6
+ presignedUrlTtl?: number;
7
+ assetStreamingMaxSize?: number;
8
+ };
File without changes
@@ -0,0 +1,26 @@
1
+ import { TaskDefinition, TaskHandler } from "@webiny/api-core/features/task/TaskDefinition/index.js";
2
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
3
+ export interface CleanupStaleMultipartUploadsInput {
4
+ noop?: boolean;
5
+ }
6
+ declare class CleanupStaleMultipartUploadsTaskHandlerImpl implements TaskHandler.Interface<CleanupStaleMultipartUploadsInput> {
7
+ private readonly config;
8
+ constructor(config: FileManagerStandaloneConfig.Interface);
9
+ run({ controller }: TaskHandler.RunParams<CleanupStaleMultipartUploadsInput>): Promise<TaskDefinition.Result<CleanupStaleMultipartUploadsInput>>;
10
+ }
11
+ declare class CleanupStaleMultipartUploadsTaskImpl implements TaskDefinition.Interface {
12
+ readonly id = "fileManagerCleanupStaleMultipartUploads";
13
+ readonly title = "Clean up stale multipart upload directories";
14
+ readonly description = "Removes multipart upload directories that are older than 24 hours.";
15
+ readonly maxIterations = 1;
16
+ readonly isPrivate = true;
17
+ readonly databaseLogs = false;
18
+ readonly selfCleanup: ("onAbort" | "onSuccess")[];
19
+ handler: typeof CleanupStaleMultipartUploadsTaskHandlerImpl & {
20
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskHandler<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
21
+ };
22
+ }
23
+ export declare const CleanupStaleMultipartUploadsTaskDefinition: typeof CleanupStaleMultipartUploadsTaskImpl & {
24
+ __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>>;
25
+ };
26
+ export {};
@@ -0,0 +1,71 @@
1
+ import { promises } from "node:fs";
2
+ import node_path from "node:path";
3
+ import { TaskDefinition, TaskHandler } from "@webiny/api-core/features/task/TaskDefinition/index.js";
4
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
5
+ const STALE_THRESHOLD_MS = 86400000;
6
+ async function readdirSafe(dirPath) {
7
+ try {
8
+ return await promises.readdir(dirPath);
9
+ } catch (err) {
10
+ if ("ENOENT" === err.code) return [];
11
+ throw err;
12
+ }
13
+ }
14
+ class CleanupStaleMultipartUploadsTaskHandlerImpl {
15
+ constructor(config){
16
+ this.config = config;
17
+ }
18
+ async run({ controller }) {
19
+ if (controller.runtime.isAborted()) return controller.response.aborted();
20
+ const storagePath = this.config.storagePath;
21
+ const tenantsDir = node_path.join(storagePath, "tenants");
22
+ const now = Date.now();
23
+ const tenantDirs = await readdirSafe(tenantsDir);
24
+ for (const tenantId of tenantDirs){
25
+ const multipartDir = node_path.join(tenantsDir, tenantId, "multipart");
26
+ const uploadDirs = await readdirSafe(multipartDir);
27
+ for (const uploadId of uploadDirs){
28
+ const uploadPath = node_path.join(multipartDir, uploadId);
29
+ try {
30
+ const stat = await promises.stat(uploadPath);
31
+ const ageMs = now - stat.mtimeMs;
32
+ if (ageMs > STALE_THRESHOLD_MS) await promises.rm(uploadPath, {
33
+ recursive: true,
34
+ force: true
35
+ });
36
+ } catch (err) {
37
+ if ("ENOENT" !== err.code) throw err;
38
+ }
39
+ }
40
+ }
41
+ return controller.response.done();
42
+ }
43
+ }
44
+ const CleanupStaleMultipartUploadsTaskHandler = TaskHandler.createImplementation({
45
+ implementation: CleanupStaleMultipartUploadsTaskHandlerImpl,
46
+ dependencies: [
47
+ FileManagerStandaloneConfig
48
+ ]
49
+ });
50
+ class CleanupStaleMultipartUploadsTaskImpl {
51
+ constructor(){
52
+ this.id = "fileManagerCleanupStaleMultipartUploads";
53
+ this.title = "Clean up stale multipart upload directories";
54
+ this.description = "Removes multipart upload directories that are older than 24 hours.";
55
+ this.maxIterations = 1;
56
+ this.isPrivate = true;
57
+ this.databaseLogs = false;
58
+ this.selfCleanup = [
59
+ "onSuccess",
60
+ "onAbort"
61
+ ];
62
+ this.handler = CleanupStaleMultipartUploadsTaskHandler;
63
+ }
64
+ }
65
+ const CleanupStaleMultipartUploadsTaskDefinition = TaskDefinition.createImplementation({
66
+ implementation: CleanupStaleMultipartUploadsTaskImpl,
67
+ dependencies: []
68
+ });
69
+ export { CleanupStaleMultipartUploadsTaskDefinition };
70
+
71
+ //# sourceMappingURL=CleanupStaleMultipartUploadsTask.js.map
@@ -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 {\n TaskDefinition,\n TaskHandler\n} from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.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 CleanupStaleMultipartUploadsTaskHandlerImpl implements TaskHandler.Interface<CleanupStaleMultipartUploadsInput> {\n public constructor(private readonly config: FileManagerStandaloneConfig.Interface) {}\n\n public async run({\n controller\n }: TaskHandler.RunParams<CleanupStaleMultipartUploadsInput>): Promise<\n TaskDefinition.Result<CleanupStaleMultipartUploadsInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const storagePath = this.config.storagePath;\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\nconst CleanupStaleMultipartUploadsTaskHandler = TaskHandler.createImplementation({\n implementation: CleanupStaleMultipartUploadsTaskHandlerImpl,\n dependencies: [FileManagerStandaloneConfig]\n});\n\nclass CleanupStaleMultipartUploadsTaskImpl implements TaskDefinition.Interface {\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 handler = CleanupStaleMultipartUploadsTaskHandler;\n}\n\nexport const CleanupStaleMultipartUploadsTaskDefinition = TaskDefinition.createImplementation({\n implementation: CleanupStaleMultipartUploadsTaskImpl,\n dependencies: []\n});\n"],"names":["STALE_THRESHOLD_MS","readdirSafe","dirPath","fs","err","CleanupStaleMultipartUploadsTaskHandlerImpl","config","controller","storagePath","tenantsDir","path","now","Date","tenantDirs","tenantId","multipartDir","uploadDirs","uploadId","uploadPath","stat","ageMs","CleanupStaleMultipartUploadsTaskHandler","TaskHandler","FileManagerStandaloneConfig","CleanupStaleMultipartUploadsTaskImpl","CleanupStaleMultipartUploadsTaskDefinition","TaskDefinition"],"mappings":";;;;AAaA,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;IACF,YAAoCC,MAA6C,CAAE;aAA/CA,MAAM,GAANA;IAAgD;IAEpF,MAAa,IAAI,EACbC,UAAU,EAC6C,EAEzD;QACE,IAAIA,WAAW,OAAO,CAAC,SAAS,IAC5B,OAAOA,WAAW,QAAQ,CAAC,OAAO;QAGtC,MAAMC,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAMC,aAAaC,UAAAA,IAAS,CAACF,aAAa;QAC1C,MAAMG,MAAMC,KAAK,GAAG;QAEpB,MAAMC,aAAa,MAAMZ,YAAYQ;QAErC,KAAK,MAAMK,YAAYD,WAAY;YAC/B,MAAME,eAAeL,UAAAA,IAAS,CAACD,YAAYK,UAAU;YACrD,MAAME,aAAa,MAAMf,YAAYc;YAErC,KAAK,MAAME,YAAYD,WAAY;gBAC/B,MAAME,aAAaR,UAAAA,IAAS,CAACK,cAAcE;gBAE3C,IAAI;oBACA,MAAME,OAAO,MAAMhB,SAAAA,IAAO,CAACe;oBAC3B,MAAME,QAAQT,MAAMQ,KAAK,OAAO;oBAEhC,IAAIC,QAAQpB,oBACR,MAAMG,SAAAA,EAAK,CAACe,YAAY;wBAAE,WAAW;wBAAM,OAAO;oBAAK;gBAE/D,EAAE,OAAOd,KAAK;oBAEV,IAAKA,AAAuC,aAAvCA,IAA8B,IAAI,EACnC,MAAMA;gBAEd;YACJ;QACJ;QAEA,OAAOG,WAAW,QAAQ,CAAC,IAAI;IACnC;AACJ;AAEA,MAAMc,0CAA0CC,YAAY,oBAAoB,CAAC;IAC7E,gBAAgBjB;IAChB,cAAc;QAACkB;KAA4B;AAC/C;AAEA,MAAMC;;aACc,EAAE,GAAG;aACL,KAAK,GAAG;aACR,WAAW,GACvB;aACY,aAAa,GAAG;aAChB,SAAS,GAAG;aACZ,YAAY,GAAG;aACf,WAAW,GAAG;YAAC;YAAsB;SAAmB;aAExE,OAAO,GAAGH;;AACd;AAEO,MAAMI,6CAA6CC,eAAe,oBAAoB,CAAC;IAC1F,gBAAgBF;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,13 @@
1
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
2
+ import { CompleteMultiPartUploadUseCase as CompleteMultiPartUploadUseCaseAbstraction } from "@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/index.js";
3
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
4
+ declare class CompleteMultiPartUploadUseCaseImpl implements CompleteMultiPartUploadUseCaseAbstraction.Interface {
5
+ private readonly tenantContext;
6
+ private readonly config;
7
+ constructor(tenantContext: TenantContext.Interface, config: FileManagerStandaloneConfig.Interface);
8
+ execute(params: CompleteMultiPartUploadUseCaseAbstraction.Params): Promise<void>;
9
+ }
10
+ export declare const CompleteMultiPartUploadUseCase: typeof CompleteMultiPartUploadUseCaseImpl & {
11
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/abstractions").ICompleteMultiPartUploadUseCase>;
12
+ };
13
+ export {};
@@ -0,0 +1,62 @@
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
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
6
+ class CompleteMultiPartUploadUseCaseImpl {
7
+ constructor(tenantContext, config){
8
+ this.tenantContext = tenantContext;
9
+ this.config = config;
10
+ }
11
+ async execute(params) {
12
+ const { fileKey, uploadId } = params;
13
+ const storagePath = this.config.storagePath;
14
+ const tenant = this.tenantContext.getTenant();
15
+ assertNoTraversal(uploadId);
16
+ for (const seg of fileKey.split(/[\\/]/))assertNoTraversal(seg);
17
+ const tenantRoot = node_path.resolve(node_path.join(storagePath, "tenants", tenant.id, "files"));
18
+ const destPath = node_path.resolve(node_path.join(tenantRoot, fileKey));
19
+ assertPathContained(destPath, tenantRoot);
20
+ const multipartDir = node_path.join(storagePath, "tenants", tenant.id, "multipart", uploadId);
21
+ const entries = await readdir(multipartDir);
22
+ const sorted = entries.filter((name)=>name.startsWith("part-")).sort((a, b)=>{
23
+ const numA = parseInt(a.replace("part-", ""), 10);
24
+ const numB = parseInt(b.replace("part-", ""), 10);
25
+ return numA - numB;
26
+ });
27
+ const destDir = node_path.dirname(destPath);
28
+ await mkdir(destDir, {
29
+ recursive: true
30
+ });
31
+ const buffers = [];
32
+ for (const partName of sorted){
33
+ const partPath = node_path.join(multipartDir, partName);
34
+ const partData = await readFile(partPath);
35
+ buffers.push(partData);
36
+ }
37
+ const finalBuffer = Buffer.concat(buffers);
38
+ await writeFile(destPath, finalBuffer);
39
+ await rm(multipartDir, {
40
+ recursive: true,
41
+ force: true
42
+ });
43
+ }
44
+ }
45
+ function assertNoTraversal(segment) {
46
+ if (segment.includes("..") || segment.includes("/") || segment.includes("\\")) throw new Error("Invalid path segment.");
47
+ }
48
+ function assertPathContained(resolved, root) {
49
+ const normalized = node_path.resolve(resolved);
50
+ const normalizedRoot = node_path.resolve(root);
51
+ if (!normalized.startsWith(normalizedRoot + node_path.sep) && normalized !== normalizedRoot) throw new Error("Path escapes tenant root.");
52
+ }
53
+ const CompleteMultiPartUploadUseCase_CompleteMultiPartUploadUseCase = CompleteMultiPartUploadUseCase.createImplementation({
54
+ implementation: CompleteMultiPartUploadUseCaseImpl,
55
+ dependencies: [
56
+ TenantContext,
57
+ FileManagerStandaloneConfig
58
+ ]
59
+ });
60
+ export { CompleteMultiPartUploadUseCase_CompleteMultiPartUploadUseCase as CompleteMultiPartUploadUseCase };
61
+
62
+ //# 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 as CompleteMultiPartUploadUseCaseAbstraction } from \"@webiny/api-file-manager/features/upload/CompleteMultiPartUpload/index.js\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nclass CompleteMultiPartUploadUseCaseImpl\n implements CompleteMultiPartUploadUseCaseAbstraction.Interface\n{\n public constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly config: FileManagerStandaloneConfig.Interface\n ) {}\n\n public async execute(params: CompleteMultiPartUploadUseCaseAbstraction.Params): Promise<void> {\n const { fileKey, uploadId } = params;\n const storagePath = this.config.storagePath;\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 CompleteMultiPartUploadUseCase =\n CompleteMultiPartUploadUseCaseAbstraction.createImplementation({\n implementation: CompleteMultiPartUploadUseCaseImpl,\n dependencies: [TenantContext, FileManagerStandaloneConfig]\n });\n"],"names":["CompleteMultiPartUploadUseCaseImpl","tenantContext","config","params","fileKey","uploadId","storagePath","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","CompleteMultiPartUploadUseCase","CompleteMultiPartUploadUseCaseAbstraction","TenantContext","FileManagerStandaloneConfig"],"mappings":";;;;;AAUA,MAAMA;IAGF,YACqBC,aAAsC,EACtCC,MAA6C,CAChE;aAFmBD,aAAa,GAAbA;aACAC,MAAM,GAANA;IAClB;IAEH,MAAa,QAAQC,MAAwD,EAAiB;QAC1F,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGF;QAC9B,MAAMG,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAE3CC,kBAAkBH;QAClB,KAAK,MAAMI,OAAOL,QAAQ,KAAK,CAAC,SAC5BI,kBAAkBC;QAGtB,MAAMC,aAAaC,UAAAA,OAAY,CAACA,UAAAA,IAAS,CAACL,aAAa,WAAWC,OAAO,EAAE,EAAE;QAC7E,MAAMK,WAAWD,UAAAA,OAAY,CAACA,UAAAA,IAAS,CAACD,YAAYN;QACpDS,oBAAoBD,UAAUF;QAE9B,MAAMI,eAAeH,UAAAA,IAAS,CAACL,aAAa,WAAWC,OAAO,EAAE,EAAE,aAAaF;QAE/E,MAAMU,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,gEACTC,+BAAAA,oBAA8D,CAAC;IAC3D,gBAAgB1C;IAChB,cAAc;QAAC2C;QAAeC;KAA4B;AAC9D"}
@@ -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 { CompleteMultiPartUploadUseCase } from "./CompleteMultiPartUploadUseCase.js";
3
+ const CompleteMultiPartUploadFeature = createFeature({
4
+ name: "FileManagerServer/CompleteMultiPartUpload",
5
+ register (container) {
6
+ container.register(CompleteMultiPartUploadUseCase);
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 { CompleteMultiPartUploadUseCase } from \"./CompleteMultiPartUploadUseCase.js\";\n\nexport const CompleteMultiPartUploadFeature = createFeature({\n name: \"FileManagerServer/CompleteMultiPartUpload\",\n register(container) {\n container.register(CompleteMultiPartUploadUseCase);\n }\n});\n"],"names":["CompleteMultiPartUploadFeature","createFeature","container","CompleteMultiPartUploadUseCase"],"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 { CreateMultiPartUploadUseCase as CreateMultiPartUploadUseCaseAbstraction } from "@webiny/api-file-manager/features/upload/CreateMultiPartUpload/index.js";
3
+ import type { CreateMultiPartUploadResult } from "@webiny/api-file-manager/features/upload/types.js";
4
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
5
+ declare class CreateMultiPartUploadUseCaseImpl implements CreateMultiPartUploadUseCaseAbstraction.Interface {
6
+ private readonly tenantContext;
7
+ private readonly config;
8
+ constructor(tenantContext: TenantContext.Interface, config: FileManagerStandaloneConfig.Interface);
9
+ execute(params: CreateMultiPartUploadUseCaseAbstraction.Params): Promise<CreateMultiPartUploadResult>;
10
+ }
11
+ export declare const CreateMultiPartUploadUseCase: typeof CreateMultiPartUploadUseCaseImpl & {
12
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/upload/CreateMultiPartUpload/abstractions").ICreateMultiPartUploadUseCase>;
13
+ };
14
+ export {};
@@ -0,0 +1,58 @@
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 { CreateMultiPartUploadUseCase } from "@webiny/api-file-manager/features/upload/CreateMultiPartUpload/index.js";
6
+ import { createUploadToken } from "../../utils/uploadToken.js";
7
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
8
+ class CreateMultiPartUploadUseCaseImpl {
9
+ constructor(tenantContext, config){
10
+ this.tenantContext = tenantContext;
11
+ this.config = config;
12
+ }
13
+ async execute(params) {
14
+ const { file, numberOfParts } = params;
15
+ const storagePath = this.config.storagePath;
16
+ const tenant = this.tenantContext.getTenant();
17
+ const serverUrl = this.config.apiUrl;
18
+ const uploadId = mdbid();
19
+ const multipartDir = node_path.join(storagePath, "tenants", tenant.id, "multipart", uploadId);
20
+ await mkdir(multipartDir, {
21
+ recursive: true
22
+ });
23
+ const secret = this.config.uploadSecret;
24
+ const expiresAt = Date.now() + 86400000;
25
+ const parts = Array.from({
26
+ length: numberOfParts
27
+ }, (_, index)=>{
28
+ const partNumber = index + 1;
29
+ const token = createUploadToken({
30
+ key: `tenants/${tenant.id}/multipart/${uploadId}/part-${partNumber}`,
31
+ tenantId: tenant.id,
32
+ expiresAt,
33
+ uploadMinFileSize: 0,
34
+ uploadMaxFileSize: 1099511627776
35
+ }, secret);
36
+ const url = `${serverUrl}/webiny-file-upload/parts?uploadId=${uploadId}&partNumber=${partNumber}&token=${token}`;
37
+ return {
38
+ partNumber,
39
+ url
40
+ };
41
+ });
42
+ return {
43
+ file,
44
+ uploadId,
45
+ parts
46
+ };
47
+ }
48
+ }
49
+ const CreateMultiPartUploadUseCase_CreateMultiPartUploadUseCase = CreateMultiPartUploadUseCase.createImplementation({
50
+ implementation: CreateMultiPartUploadUseCaseImpl,
51
+ dependencies: [
52
+ TenantContext,
53
+ FileManagerStandaloneConfig
54
+ ]
55
+ });
56
+ export { CreateMultiPartUploadUseCase_CreateMultiPartUploadUseCase as CreateMultiPartUploadUseCase };
57
+
58
+ //# 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 { CreateMultiPartUploadUseCase as CreateMultiPartUploadUseCaseAbstraction } 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 { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nclass CreateMultiPartUploadUseCaseImpl\n implements CreateMultiPartUploadUseCaseAbstraction.Interface\n{\n public constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly config: FileManagerStandaloneConfig.Interface\n ) {}\n\n public async execute(\n params: CreateMultiPartUploadUseCaseAbstraction.Params\n ): Promise<CreateMultiPartUploadResult> {\n const { file, numberOfParts } = params;\n const storagePath = this.config.storagePath;\n const tenant = this.tenantContext.getTenant();\n const serverUrl = this.config.apiUrl;\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 = this.config.uploadSecret;\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 CreateMultiPartUploadUseCase =\n CreateMultiPartUploadUseCaseAbstraction.createImplementation({\n implementation: CreateMultiPartUploadUseCaseImpl,\n dependencies: [TenantContext, FileManagerStandaloneConfig]\n });\n"],"names":["CreateMultiPartUploadUseCaseImpl","tenantContext","config","params","file","numberOfParts","storagePath","tenant","serverUrl","uploadId","mdbid","multipartDir","path","mkdir","secret","expiresAt","Date","parts","Array","_","index","partNumber","token","createUploadToken","url","CreateMultiPartUploadUseCase","CreateMultiPartUploadUseCaseAbstraction","TenantContext","FileManagerStandaloneConfig"],"mappings":";;;;;;;AASA,MAAMA;IAGF,YACqBC,aAAsC,EACtCC,MAA6C,CAChE;aAFmBD,aAAa,GAAbA;aACAC,MAAM,GAANA;IAClB;IAEH,MAAa,QACTC,MAAsD,EAClB;QACpC,MAAM,EAAEC,IAAI,EAAEC,aAAa,EAAE,GAAGF;QAChC,MAAMG,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAMC,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAC3C,MAAMC,YAAY,IAAI,CAAC,MAAM,CAAC,MAAM;QAEpC,MAAMC,WAAWC;QAEjB,MAAMC,eAAeC,UAAAA,IAAS,CAACN,aAAa,WAAWC,OAAO,EAAE,EAAE,aAAaE;QAC/E,MAAMI,MAAMF,cAAc;YAAE,WAAW;QAAK;QAE5C,MAAMG,SAAS,IAAI,CAAC,MAAM,CAAC,YAAY;QACvC,MAAMC,YAAYC,KAAK,GAAG,KAAK;QAE/B,MAAMC,QAAQC,MAAM,IAAI,CAAC;YAAE,QAAQb;QAAc,GAAG,CAACc,GAAGC;YACpD,MAAMC,aAAaD,QAAQ;YAE3B,MAAME,QAAQC,kBACV;gBACI,KAAK,CAAC,QAAQ,EAAEhB,OAAO,EAAE,CAAC,WAAW,EAAEE,SAAS,MAAM,EAAEY,YAAY;gBACpE,UAAUd,OAAO,EAAE;gBACnBQ;gBACA,mBAAmB;gBACnB,mBAAmB;YACvB,GACAD;YAGJ,MAAMU,MAAM,GAAGhB,UAAU,mCAAmC,EAAEC,SAAS,YAAY,EAAEY,WAAW,OAAO,EAAEC,OAAO;YAEhH,OAAO;gBAAED;gBAAYG;YAAI;QAC7B;QAEA,OAAO;YAAEpB;YAAMK;YAAUQ;QAAM;IACnC;AACJ;AAEO,MAAMQ,4DACTC,6BAAAA,oBAA4D,CAAC;IACzD,gBAAgB1B;IAChB,cAAc;QAAC2B;QAAeC;KAA4B;AAC9D"}
@@ -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 { CreateMultiPartUploadUseCase } from "./CreateMultiPartUploadUseCase.js";
3
+ const CreateMultiPartUploadFeature = createFeature({
4
+ name: "FileManagerServer/CreateMultiPartUpload",
5
+ register (container) {
6
+ container.register(CreateMultiPartUploadUseCase);
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 { CreateMultiPartUploadUseCase } from \"./CreateMultiPartUploadUseCase.js\";\n\nexport const CreateMultiPartUploadFeature = createFeature({\n name: \"FileManagerServer/CreateMultiPartUpload\",\n register(container) {\n container.register(CreateMultiPartUploadUseCase);\n }\n});\n"],"names":["CreateMultiPartUploadFeature","createFeature","container","CreateMultiPartUploadUseCase"],"mappings":";;AAGO,MAAMA,+BAA+BC,cAAc;IACtD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,15 @@
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
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
5
+ declare class DeleteFileFromDiskHandlerImpl implements FileAfterDeleteEventHandler.Interface {
6
+ private readonly tenantContext;
7
+ private readonly keyValueStore;
8
+ private readonly config;
9
+ constructor(tenantContext: TenantContext.Interface, keyValueStore: GlobalKeyValueStore.Interface, config: FileManagerStandaloneConfig.Interface);
10
+ handle(event: FileAfterDeleteEventHandler.Event): Promise<void>;
11
+ }
12
+ export declare const DeleteFileFromDiskHandler: typeof DeleteFileFromDiskHandlerImpl & {
13
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/eventPublisher").IEventHandler<import("@webiny/api-file-manager/features/file/DeleteFile/events.js").FileAfterDeleteEvent>>;
14
+ };
15
+ export {};
@@ -0,0 +1,34 @@
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
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
6
+ class DeleteFileFromDiskHandlerImpl {
7
+ constructor(tenantContext, keyValueStore, config){
8
+ this.tenantContext = tenantContext;
9
+ this.keyValueStore = keyValueStore;
10
+ this.config = config;
11
+ }
12
+ async handle(event) {
13
+ const { file } = event.payload;
14
+ const tenant = this.tenantContext.getTenant();
15
+ const storagePath = this.config.storagePath;
16
+ const folderPath = `${storagePath}/tenants/${tenant.id}/files/${file.id}`;
17
+ await promises.rm(folderPath, {
18
+ recursive: true,
19
+ force: true
20
+ });
21
+ await this.keyValueStore.delete(`FileManager/File/${file.id}/Metadata`);
22
+ }
23
+ }
24
+ const DeleteFileFromDiskHandler = FileAfterDeleteEventHandler.createImplementation({
25
+ implementation: DeleteFileFromDiskHandlerImpl,
26
+ dependencies: [
27
+ TenantContext,
28
+ GlobalKeyValueStore,
29
+ FileManagerStandaloneConfig
30
+ ]
31
+ });
32
+ export { DeleteFileFromDiskHandler };
33
+
34
+ //# 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\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nclass DeleteFileFromDiskHandlerImpl implements FileAfterDeleteEventHandler.Interface {\n constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly keyValueStore: GlobalKeyValueStore.Interface,\n private readonly config: FileManagerStandaloneConfig.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 = this.config.storagePath;\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, FileManagerStandaloneConfig]\n});\n"],"names":["DeleteFileFromDiskHandlerImpl","tenantContext","keyValueStore","config","event","file","tenant","storagePath","folderPath","fs","DeleteFileFromDiskHandler","FileAfterDeleteEventHandler","TenantContext","GlobalKeyValueStore","FileManagerStandaloneConfig"],"mappings":";;;;;AAMA,MAAMA;IACF,YACqBC,aAAsC,EACtCC,aAA4C,EAC5CC,MAA6C,CAChE;aAHmBF,aAAa,GAAbA;aACAC,aAAa,GAAbA;aACAC,MAAM,GAANA;IAClB;IAEH,MAAM,OAAOC,KAAwC,EAAiB;QAClE,MAAM,EAAEC,IAAI,EAAE,GAAGD,MAAM,OAAO;QAC9B,MAAME,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAC3C,MAAMC,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAMC,aAAa,GAAGD,YAAY,SAAS,EAAED,OAAO,EAAE,CAAC,OAAO,EAAED,KAAK,EAAE,EAAE;QAGzE,MAAMI,SAAAA,EAAK,CAACD,YAAY;YAAE,WAAW;YAAM,OAAO;QAAK;QAGvD,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAEH,KAAK,EAAE,CAAC,SAAS,CAAC;IAC1E;AACJ;AAEO,MAAMK,4BAA4BC,4BAA4B,oBAAoB,CAAC;IACtF,gBAAgBX;IAChB,cAAc;QAACY;QAAeC;QAAqBC;KAA4B;AACnF"}
@@ -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,29 @@
1
+ import { TaskDefinition, TaskHandler } 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
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
6
+ declare class ExtractMetadataTaskHandlerImpl implements TaskHandler.Interface<ExtractMetadataInput> {
7
+ private readonly metadataReader;
8
+ private readonly updateFileUseCase;
9
+ private readonly config;
10
+ constructor(metadataReader: MetadataReader.Interface, updateFileUseCase: UpdateFileUseCase.Interface, config: FileManagerStandaloneConfig.Interface);
11
+ run({ input, controller }: TaskHandler.RunParams<ExtractMetadataInput>): Promise<TaskDefinition.Result<ExtractMetadataInput>>;
12
+ private cleanValues;
13
+ }
14
+ declare class ExtractMetadataTaskImpl implements TaskDefinition.Interface {
15
+ readonly id = "fileManagerExtractMetadata";
16
+ readonly title = "Extract image metadata (dimensions, EXIF, IPTC)";
17
+ readonly description = "A task to extract metadata from uploaded image files";
18
+ readonly maxIterations = 1;
19
+ readonly isPrivate = true;
20
+ readonly databaseLogs = false;
21
+ readonly selfCleanup: ("onAbort" | "onSuccess")[];
22
+ handler: typeof ExtractMetadataTaskHandlerImpl & {
23
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskHandler<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskInput, import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput>>;
24
+ };
25
+ }
26
+ export declare const ExtractMetadataTaskDefinition: typeof ExtractMetadataTaskImpl & {
27
+ __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>>;
28
+ };
29
+ export {};