@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,93 @@
1
+ import { promises } from "node:fs";
2
+ import { TaskDefinition, TaskHandler } 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
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
6
+ class ExtractMetadataTaskHandlerImpl {
7
+ constructor(metadataReader, updateFileUseCase, config){
8
+ this.metadataReader = metadataReader;
9
+ this.updateFileUseCase = updateFileUseCase;
10
+ this.config = config;
11
+ }
12
+ async run({ input, controller }) {
13
+ if (controller.runtime.isAborted()) return controller.response.aborted();
14
+ const fileMetadata = await this.metadataReader.read(input.fileId);
15
+ if (!fileMetadata) return controller.response.error({
16
+ message: `File metadata not found for file ID: ${input.fileId}`
17
+ });
18
+ if (!fileMetadata.contentType.startsWith("image/")) return controller.response.done();
19
+ const storagePath = this.config.storagePath;
20
+ const filePath = `${storagePath}/${fileMetadata.bucketKey}`;
21
+ try {
22
+ const buffer = await promises.readFile(filePath);
23
+ const sharp = await import("sharp").then((m)=>m.default);
24
+ const ExifReader = await import("exifreader").then((m)=>m.default);
25
+ const sharpInstance = sharp(buffer);
26
+ const sharpMetadata = await sharpInstance.metadata();
27
+ const tags = ExifReader.load(buffer, {
28
+ expanded: true
29
+ });
30
+ const metadata = {
31
+ image: {
32
+ width: sharpMetadata.width,
33
+ height: sharpMetadata.height,
34
+ format: sharpMetadata.format,
35
+ orientation: sharpMetadata.orientation ?? 1
36
+ }
37
+ };
38
+ if (tags.exif) metadata.exif = this.cleanValues(tags.exif);
39
+ if (tags.iptc) metadata.iptc = this.cleanValues(tags.iptc);
40
+ const updateResult = await this.updateFileUseCase.execute({
41
+ id: input.fileId,
42
+ metadata
43
+ });
44
+ if (updateResult.isFail()) return controller.response.error({
45
+ message: `Failed to update file with metadata: ${updateResult.error.message}`
46
+ });
47
+ return controller.response.done();
48
+ } catch (error) {
49
+ return controller.response.error({
50
+ message: `Failed to extract metadata: ${error instanceof Error ? error.message : String(error)}`
51
+ });
52
+ }
53
+ }
54
+ cleanValues(tags) {
55
+ const cleaned = {};
56
+ for (const [key, tag] of Object.entries(tags))if (tag && "object" == typeof tag) {
57
+ if (void 0 !== tag.description && null !== tag.description) cleaned[key] = tag.description;
58
+ else if (Array.isArray(tag.value) && tag.value.length > 20) ;
59
+ else if (void 0 !== tag.value) cleaned[key] = tag.value;
60
+ }
61
+ return cleaned;
62
+ }
63
+ }
64
+ const ExtractMetadataTaskHandler = TaskHandler.createImplementation({
65
+ implementation: ExtractMetadataTaskHandlerImpl,
66
+ dependencies: [
67
+ MetadataReader,
68
+ UpdateFileUseCase,
69
+ FileManagerStandaloneConfig
70
+ ]
71
+ });
72
+ class ExtractMetadataTaskImpl {
73
+ constructor(){
74
+ this.id = "fileManagerExtractMetadata";
75
+ this.title = "Extract image metadata (dimensions, EXIF, IPTC)";
76
+ this.description = "A task to extract metadata from uploaded image files";
77
+ this.maxIterations = 1;
78
+ this.isPrivate = true;
79
+ this.databaseLogs = false;
80
+ this.selfCleanup = [
81
+ "onSuccess",
82
+ "onAbort"
83
+ ];
84
+ this.handler = ExtractMetadataTaskHandler;
85
+ }
86
+ }
87
+ const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({
88
+ implementation: ExtractMetadataTaskImpl,
89
+ dependencies: []
90
+ });
91
+ export { ExtractMetadataTaskDefinition };
92
+
93
+ //# 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 {\n TaskDefinition,\n TaskHandler\n} 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\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nclass ExtractMetadataTaskHandlerImpl implements TaskHandler.Interface<ExtractMetadataInput> {\n public constructor(\n private readonly metadataReader: MetadataReader.Interface,\n private readonly updateFileUseCase: UpdateFileUseCase.Interface,\n private readonly config: FileManagerStandaloneConfig.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskHandler.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 = this.config.storagePath;\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\nconst ExtractMetadataTaskHandler = TaskHandler.createImplementation({\n implementation: ExtractMetadataTaskHandlerImpl,\n dependencies: [MetadataReader, UpdateFileUseCase, FileManagerStandaloneConfig]\n});\n\nclass ExtractMetadataTaskImpl implements TaskDefinition.Interface {\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 handler = ExtractMetadataTaskHandler;\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTaskImpl,\n dependencies: []\n});\n"],"names":["ExtractMetadataTaskHandlerImpl","metadataReader","updateFileUseCase","config","input","controller","fileMetadata","storagePath","filePath","buffer","fs","sharp","m","ExifReader","sharpInstance","sharpMetadata","tags","metadata","updateResult","error","Error","String","cleaned","key","tag","Object","undefined","Array","ExtractMetadataTaskHandler","TaskHandler","MetadataReader","UpdateFileUseCase","FileManagerStandaloneConfig","ExtractMetadataTaskImpl","ExtractMetadataTaskDefinition","TaskDefinition"],"mappings":"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"}
@@ -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,12 @@
1
+ import { BuildParams } from "@webiny/api-core/features/buildParams/index.js";
2
+ import { FileManagerStandaloneConfig as FileManagerStandaloneConfigAbstraction } from "./abstractions.js";
3
+ declare class FileManagerStandaloneConfigImpl implements FileManagerStandaloneConfigAbstraction.Interface {
4
+ readonly storagePath: string;
5
+ readonly uploadSecret: string;
6
+ readonly apiUrl: string;
7
+ constructor(buildParams: BuildParams.Interface);
8
+ }
9
+ export declare const FileManagerStandaloneConfig: typeof FileManagerStandaloneConfigImpl & {
10
+ __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IFileManagerStandaloneConfig>;
11
+ };
12
+ export {};
@@ -0,0 +1,28 @@
1
+ import { existsSync, mkdirSync } from "node:fs";
2
+ import { BuildParams } from "@webiny/api-core/features/buildParams/index.js";
3
+ import { FileManagerStandaloneConfig } from "./abstractions.js";
4
+ class FileManagerStandaloneConfigImpl {
5
+ constructor(buildParams){
6
+ const storagePath = buildParams.get("WEBINY_LOCAL_STORAGE_PATH");
7
+ if (!storagePath) throw new Error('"WEBINY_LOCAL_STORAGE_PATH" build parameter is not defined. Please set it to a valid local path.');
8
+ const uploadSecret = buildParams.get("WEBINY_UPLOAD_SECRET");
9
+ if (!uploadSecret) throw new Error('"WEBINY_UPLOAD_SECRET" build parameter is not defined. Please set it to a secret string used to sign upload tokens.');
10
+ const apiUrl = buildParams.get("WEBINY_API_URL");
11
+ if (!apiUrl) throw new Error('"WEBINY_API_URL" build parameter is not defined. Configure it via <Infra.ApiUrl url="..." /> in webiny.config.');
12
+ this.storagePath = storagePath;
13
+ this.uploadSecret = uploadSecret;
14
+ this.apiUrl = apiUrl.replace(/\/+$/, "");
15
+ if (!existsSync(this.storagePath)) mkdirSync(this.storagePath, {
16
+ recursive: true
17
+ });
18
+ }
19
+ }
20
+ const FileManagerStandaloneConfig_FileManagerStandaloneConfig = FileManagerStandaloneConfig.createImplementation({
21
+ implementation: FileManagerStandaloneConfigImpl,
22
+ dependencies: [
23
+ BuildParams
24
+ ]
25
+ });
26
+ export { FileManagerStandaloneConfig_FileManagerStandaloneConfig as FileManagerStandaloneConfig };
27
+
28
+ //# sourceMappingURL=FileManagerStandaloneConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/FileManagerStandaloneConfig/FileManagerStandaloneConfig.js","sources":["../../../src/features/FileManagerStandaloneConfig/FileManagerStandaloneConfig.ts"],"sourcesContent":["import { existsSync, mkdirSync } from \"node:fs\";\nimport { BuildParams } from \"@webiny/api-core/features/buildParams/index.js\";\nimport { FileManagerStandaloneConfig as FileManagerStandaloneConfigAbstraction } from \"./abstractions.js\";\n\nclass FileManagerStandaloneConfigImpl implements FileManagerStandaloneConfigAbstraction.Interface {\n public readonly storagePath: string;\n public readonly uploadSecret: string;\n public readonly apiUrl: string;\n\n constructor(buildParams: BuildParams.Interface) {\n const storagePath = buildParams.get<string>(\"WEBINY_LOCAL_STORAGE_PATH\");\n if (!storagePath) {\n throw new Error(\n `\"WEBINY_LOCAL_STORAGE_PATH\" build parameter is not defined. Please set it to a valid local path.`\n );\n }\n\n const uploadSecret = buildParams.get<string>(\"WEBINY_UPLOAD_SECRET\");\n if (!uploadSecret) {\n throw new Error(\n `\"WEBINY_UPLOAD_SECRET\" build parameter is not defined. Please set it to a secret string used to sign upload tokens.`\n );\n }\n\n // The API's own public origin, used to build client-reachable URLs (upload endpoint + file\n // srcPrefix). A build param (baked by Infra.ApiUrl), NOT a process.env read in api runtime code.\n const apiUrl = buildParams.get<string>(\"WEBINY_API_URL\");\n if (!apiUrl) {\n throw new Error(\n `\"WEBINY_API_URL\" build parameter is not defined. Configure it via <Infra.ApiUrl url=\"...\" /> in webiny.config.`\n );\n }\n\n this.storagePath = storagePath;\n this.uploadSecret = uploadSecret;\n this.apiUrl = apiUrl.replace(/\\/+$/, \"\");\n\n // Ensure the storage directory exists. Done here (on first resolve, at request time) rather\n // than in FileManagerStandaloneFeature.register(): build params like WEBINY_LOCAL_STORAGE_PATH are\n // only registered once project extensions are applied, which happens LATER in the request\n // stack than the file-manager transport hook — so resolving this config at register() time\n // would read the param before it exists and throw.\n if (!existsSync(this.storagePath)) {\n mkdirSync(this.storagePath, { recursive: true });\n }\n }\n}\n\nexport const FileManagerStandaloneConfig =\n FileManagerStandaloneConfigAbstraction.createImplementation({\n implementation: FileManagerStandaloneConfigImpl,\n dependencies: [BuildParams]\n });\n"],"names":["FileManagerStandaloneConfigImpl","buildParams","storagePath","Error","uploadSecret","apiUrl","existsSync","mkdirSync","FileManagerStandaloneConfig","FileManagerStandaloneConfigAbstraction","BuildParams"],"mappings":";;;AAIA,MAAMA;IAKF,YAAYC,WAAkC,CAAE;QAC5C,MAAMC,cAAcD,YAAY,GAAG,CAAS;QAC5C,IAAI,CAACC,aACD,MAAM,IAAIC,MACN;QAIR,MAAMC,eAAeH,YAAY,GAAG,CAAS;QAC7C,IAAI,CAACG,cACD,MAAM,IAAID,MACN;QAMR,MAAME,SAASJ,YAAY,GAAG,CAAS;QACvC,IAAI,CAACI,QACD,MAAM,IAAIF,MACN;QAIR,IAAI,CAAC,WAAW,GAAGD;QACnB,IAAI,CAAC,YAAY,GAAGE;QACpB,IAAI,CAAC,MAAM,GAAGC,OAAO,OAAO,CAAC,QAAQ;QAOrC,IAAI,CAACC,WAAW,IAAI,CAAC,WAAW,GAC5BC,UAAU,IAAI,CAAC,WAAW,EAAE;YAAE,WAAW;QAAK;IAEtD;AACJ;AAEO,MAAMC,0DACTC,4BAAAA,oBAA2D,CAAC;IACxD,gBAAgBT;IAChB,cAAc;QAACU;KAAY;AAC/B"}
@@ -0,0 +1,10 @@
1
+ export interface IFileManagerStandaloneConfig {
2
+ readonly storagePath: string;
3
+ readonly uploadSecret: string;
4
+ /** The API's public origin (no trailing slash), e.g. https://api.example.com. */
5
+ readonly apiUrl: string;
6
+ }
7
+ export declare const FileManagerStandaloneConfig: import("@webiny/di").Abstraction<IFileManagerStandaloneConfig>;
8
+ export declare namespace FileManagerStandaloneConfig {
9
+ type Interface = IFileManagerStandaloneConfig;
10
+ }
@@ -0,0 +1,5 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const FileManagerStandaloneConfig = createAbstraction("FileManagerServer/Config");
3
+ export { FileManagerStandaloneConfig };
4
+
5
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/FileManagerStandaloneConfig/abstractions.js","sources":["../../../src/features/FileManagerStandaloneConfig/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\n\nexport interface IFileManagerStandaloneConfig {\n readonly storagePath: string;\n readonly uploadSecret: string;\n /** The API's public origin (no trailing slash), e.g. https://api.example.com. */\n readonly apiUrl: string;\n}\n\nexport const FileManagerStandaloneConfig = createAbstraction<IFileManagerStandaloneConfig>(\n \"FileManagerServer/Config\"\n);\n\nexport namespace FileManagerStandaloneConfig {\n export type Interface = IFileManagerStandaloneConfig;\n}\n"],"names":["FileManagerStandaloneConfig","createAbstraction"],"mappings":";AASO,MAAMA,8BAA8BC,kBACvC"}
@@ -0,0 +1,4 @@
1
+ export declare const FileManagerStandaloneConfigFeature: {
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 { FileManagerStandaloneConfig } from "./FileManagerStandaloneConfig.js";
3
+ const FileManagerStandaloneConfigFeature = createFeature({
4
+ name: "FileManagerServer/Config",
5
+ register (container) {
6
+ container.register(FileManagerStandaloneConfig);
7
+ }
8
+ });
9
+ export { FileManagerStandaloneConfigFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/FileManagerStandaloneConfig/feature.js","sources":["../../../src/features/FileManagerStandaloneConfig/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { FileManagerStandaloneConfig } from \"./FileManagerStandaloneConfig.js\";\n\nexport const FileManagerStandaloneConfigFeature = createFeature({\n name: \"FileManagerServer/Config\",\n register(container) {\n container.register(FileManagerStandaloneConfig);\n }\n});\n"],"names":["FileManagerStandaloneConfigFeature","createFeature","container","FileManagerStandaloneConfig"],"mappings":";;AAGO,MAAMA,qCAAqCC,cAAc;IAC5D,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;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,15 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { GetFileContentsByIdUseCase as GetFileContentsByIdUseCaseAbstraction } 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
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
6
+ declare class GetFileContentsByIdUseCaseImpl implements GetFileContentsByIdUseCaseAbstraction.Interface {
7
+ private readonly metadataReader;
8
+ private readonly config;
9
+ constructor(metadataReader: MetadataReader.Interface, config: FileManagerStandaloneConfig.Interface);
10
+ execute(fileId: string): Promise<Result<FileContents, GetFileContentsByIdUseCaseAbstraction.Error>>;
11
+ }
12
+ export declare const GetFileContentsByIdUseCase: typeof GetFileContentsByIdUseCaseImpl & {
13
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/file/GetFileContentsById/abstractions").IGetFileContentsByIdUseCase>;
14
+ };
15
+ export {};
@@ -0,0 +1,38 @@
1
+ import { promises } from "node:fs";
2
+ import { Result } from "@webiny/feature/api";
3
+ import { GetFileContentsByIdUseCase } from "@webiny/api-file-manager/features/file/GetFileContentsById/index.js";
4
+ import { FileNotFoundError, FilePersistenceError } from "@webiny/api-file-manager/domain/file/errors.js";
5
+ import { MetadataReader } from "@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js";
6
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
7
+ class GetFileContentsByIdUseCaseImpl {
8
+ constructor(metadataReader, config){
9
+ this.metadataReader = metadataReader;
10
+ this.config = config;
11
+ }
12
+ async execute(fileId) {
13
+ const metadata = await this.metadataReader.read(fileId);
14
+ if (!metadata) return Result.fail(new FileNotFoundError(fileId));
15
+ const storagePath = this.config.storagePath;
16
+ try {
17
+ const filePath = `${storagePath}/${metadata.bucketKey}`;
18
+ const buffer = await promises.readFile(filePath);
19
+ return Result.ok({
20
+ buffer,
21
+ contentType: metadata.contentType
22
+ });
23
+ } catch (error) {
24
+ if ("ENOENT" === error.code) return Result.fail(new FileNotFoundError(fileId));
25
+ return Result.fail(new FilePersistenceError(error instanceof Error ? error : new Error(String(error))));
26
+ }
27
+ }
28
+ }
29
+ const GetFileContentsByIdUseCase_GetFileContentsByIdUseCase = GetFileContentsByIdUseCase.createImplementation({
30
+ implementation: GetFileContentsByIdUseCaseImpl,
31
+ dependencies: [
32
+ MetadataReader,
33
+ FileManagerStandaloneConfig
34
+ ]
35
+ });
36
+ export { GetFileContentsByIdUseCase_GetFileContentsByIdUseCase as GetFileContentsByIdUseCase };
37
+
38
+ //# sourceMappingURL=GetFileContentsByIdUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/GetFileContentsById/GetFileContentsByIdUseCase.js","sources":["../../../src/features/GetFileContentsById/GetFileContentsByIdUseCase.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport { Result } from \"@webiny/feature/api\";\nimport { GetFileContentsByIdUseCase as GetFileContentsByIdUseCaseAbstraction } from \"@webiny/api-file-manager/features/file/GetFileContentsById/index.js\";\nimport type { FileContents } from \"@webiny/api-file-manager/features/file/GetFileContentsById/index.js\";\nimport {\n FileNotFoundError,\n FilePersistenceError\n} from \"@webiny/api-file-manager/domain/file/errors.js\";\nimport { MetadataReader } from \"@webiny/api-file-manager/features/upload/ReadFileMetadata/abstractions.js\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nclass GetFileContentsByIdUseCaseImpl implements GetFileContentsByIdUseCaseAbstraction.Interface {\n private readonly metadataReader: MetadataReader.Interface;\n private readonly config: FileManagerStandaloneConfig.Interface;\n\n public constructor(\n metadataReader: MetadataReader.Interface,\n config: FileManagerStandaloneConfig.Interface\n ) {\n this.metadataReader = metadataReader;\n this.config = config;\n }\n\n public async execute(\n fileId: string\n ): Promise<Result<FileContents, GetFileContentsByIdUseCaseAbstraction.Error>> {\n const metadata = await this.metadataReader.read(fileId);\n if (!metadata) {\n return Result.fail(new FileNotFoundError(fileId));\n }\n\n const storagePath = this.config.storagePath;\n\n try {\n const filePath = `${storagePath}/${metadata.bucketKey}`;\n const buffer = await fs.readFile(filePath);\n return Result.ok({ buffer, contentType: metadata.contentType });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return Result.fail(new FileNotFoundError(fileId));\n }\n return Result.fail(\n new FilePersistenceError(error instanceof Error ? error : new Error(String(error)))\n );\n }\n }\n}\n\nexport const GetFileContentsByIdUseCase =\n GetFileContentsByIdUseCaseAbstraction.createImplementation({\n implementation: GetFileContentsByIdUseCaseImpl,\n dependencies: [MetadataReader, FileManagerStandaloneConfig]\n });\n"],"names":["GetFileContentsByIdUseCaseImpl","metadataReader","config","fileId","metadata","Result","FileNotFoundError","storagePath","filePath","buffer","fs","error","FilePersistenceError","Error","String","GetFileContentsByIdUseCase","GetFileContentsByIdUseCaseAbstraction","MetadataReader","FileManagerStandaloneConfig"],"mappings":";;;;;;AAWA,MAAMA;IAIF,YACIC,cAAwC,EACxCC,MAA6C,CAC/C;QACE,IAAI,CAAC,cAAc,GAAGD;QACtB,IAAI,CAAC,MAAM,GAAGC;IAClB;IAEA,MAAa,QACTC,MAAc,EAC4D;QAC1E,MAAMC,WAAW,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAACD;QAChD,IAAI,CAACC,UACD,OAAOC,OAAO,IAAI,CAAC,IAAIC,kBAAkBH;QAG7C,MAAMI,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAE3C,IAAI;YACA,MAAMC,WAAW,GAAGD,YAAY,CAAC,EAAEH,SAAS,SAAS,EAAE;YACvD,MAAMK,SAAS,MAAMC,SAAAA,QAAW,CAACF;YACjC,OAAOH,OAAO,EAAE,CAAC;gBAAEI;gBAAQ,aAAaL,SAAS,WAAW;YAAC;QACjE,EAAE,OAAOO,OAAO;YACZ,IAAKA,AAAyC,aAAzCA,MAAgC,IAAI,EACrC,OAAON,OAAO,IAAI,CAAC,IAAIC,kBAAkBH;YAE7C,OAAOE,OAAO,IAAI,CACd,IAAIO,qBAAqBD,iBAAiBE,QAAQF,QAAQ,IAAIE,MAAMC,OAAOH;QAEnF;IACJ;AACJ;AAEO,MAAMI,wDACTC,2BAAAA,oBAA0D,CAAC;IACvD,gBAAgBhB;IAChB,cAAc;QAACiB;QAAgBC;KAA4B;AAC/D"}
@@ -0,0 +1,4 @@
1
+ export declare const GetFileContentsByIdFeature: {
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 { GetFileContentsByIdUseCase } from "./GetFileContentsByIdUseCase.js";
3
+ const GetFileContentsByIdFeature = createFeature({
4
+ name: "FileManagerServer/GetFileContentsById",
5
+ register (container) {
6
+ container.register(GetFileContentsByIdUseCase);
7
+ }
8
+ });
9
+ export { GetFileContentsByIdFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/GetFileContentsById/feature.js","sources":["../../../src/features/GetFileContentsById/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { GetFileContentsByIdUseCase } from \"./GetFileContentsByIdUseCase.js\";\n\nexport const GetFileContentsByIdFeature = createFeature({\n name: \"FileManagerServer/GetFileContentsById\",\n register(container) {\n container.register(GetFileContentsByIdUseCase);\n }\n});\n"],"names":["GetFileContentsByIdFeature","createFeature","container","GetFileContentsByIdUseCase"],"mappings":";;AAGO,MAAMA,6BAA6BC,cAAc;IACpD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,15 @@
1
+ import { Result } from "@webiny/feature/api";
2
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
3
+ import { GetFileContentsByKeyUseCase as GetFileContentsByKeyUseCaseAbstraction } from "@webiny/api-file-manager/features/file/GetFileContentsByKey/index.js";
4
+ import type { FileContents } from "@webiny/api-file-manager/features/file/GetFileContentsById/index.js";
5
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
6
+ declare class GetFileContentsByKeyUseCaseImpl implements GetFileContentsByKeyUseCaseAbstraction.Interface {
7
+ private readonly tenantContext;
8
+ private readonly config;
9
+ constructor(tenantContext: TenantContext.Interface, config: FileManagerStandaloneConfig.Interface);
10
+ execute(key: string): Promise<Result<FileContents, GetFileContentsByKeyUseCaseAbstraction.Error>>;
11
+ }
12
+ export declare const GetFileContentsByKeyUseCase: typeof GetFileContentsByKeyUseCaseImpl & {
13
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/file/GetFileContentsByKey/abstractions").IGetFileContentsByKeyUseCase>;
14
+ };
15
+ export {};
@@ -0,0 +1,72 @@
1
+ import { promises } from "node:fs";
2
+ import { Result } from "@webiny/feature/api";
3
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
4
+ import { GetFileContentsByKeyUseCase } from "@webiny/api-file-manager/features/file/GetFileContentsByKey/index.js";
5
+ import { FileNotFoundError, FilePersistenceError } from "@webiny/api-file-manager/domain/file/errors.js";
6
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
7
+ const CONTENT_TYPE_MAP = {
8
+ jpg: "image/jpeg",
9
+ jpeg: "image/jpeg",
10
+ png: "image/png",
11
+ gif: "image/gif",
12
+ webp: "image/webp",
13
+ svg: "image/svg+xml",
14
+ ico: "image/x-icon",
15
+ bmp: "image/bmp",
16
+ tiff: "image/tiff",
17
+ tif: "image/tiff",
18
+ pdf: "application/pdf",
19
+ json: "application/json",
20
+ xml: "application/xml",
21
+ zip: "application/zip",
22
+ gz: "application/gzip",
23
+ txt: "text/plain",
24
+ html: "text/html",
25
+ htm: "text/html",
26
+ css: "text/css",
27
+ js: "application/javascript",
28
+ ts: "application/typescript",
29
+ mp4: "video/mp4",
30
+ webm: "video/webm",
31
+ mp3: "audio/mpeg",
32
+ wav: "audio/wav",
33
+ ogg: "audio/ogg"
34
+ };
35
+ function resolveContentType(key) {
36
+ const ext = key.split(".").pop()?.toLowerCase();
37
+ if (!ext) return "application/octet-stream";
38
+ return CONTENT_TYPE_MAP[ext] ?? "application/octet-stream";
39
+ }
40
+ class GetFileContentsByKeyUseCaseImpl {
41
+ constructor(tenantContext, config){
42
+ this.tenantContext = tenantContext;
43
+ this.config = config;
44
+ }
45
+ async execute(key) {
46
+ const tenant = this.tenantContext.getTenant();
47
+ const bucketKey = `tenants/${tenant.id}/files/${key}`;
48
+ const storagePath = this.config.storagePath;
49
+ const filePath = `${storagePath}/${bucketKey}`;
50
+ try {
51
+ const buffer = await promises.readFile(filePath);
52
+ const contentType = resolveContentType(key);
53
+ return Result.ok({
54
+ buffer,
55
+ contentType
56
+ });
57
+ } catch (error) {
58
+ if ("ENOENT" === error.code) return Result.fail(new FileNotFoundError(key));
59
+ return Result.fail(new FilePersistenceError(error instanceof Error ? error : new Error(String(error))));
60
+ }
61
+ }
62
+ }
63
+ const GetFileContentsByKeyUseCase_GetFileContentsByKeyUseCase = GetFileContentsByKeyUseCase.createImplementation({
64
+ implementation: GetFileContentsByKeyUseCaseImpl,
65
+ dependencies: [
66
+ TenantContext,
67
+ FileManagerStandaloneConfig
68
+ ]
69
+ });
70
+ export { GetFileContentsByKeyUseCase_GetFileContentsByKeyUseCase as GetFileContentsByKeyUseCase };
71
+
72
+ //# sourceMappingURL=GetFileContentsByKeyUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/GetFileContentsByKey/GetFileContentsByKeyUseCase.js","sources":["../../../src/features/GetFileContentsByKey/GetFileContentsByKeyUseCase.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport { Result } from \"@webiny/feature/api\";\nimport { TenantContext } from \"@webiny/api-core/features/tenancy/TenantContext/index.js\";\nimport { GetFileContentsByKeyUseCase as GetFileContentsByKeyUseCaseAbstraction } from \"@webiny/api-file-manager/features/file/GetFileContentsByKey/index.js\";\nimport type { FileContents } from \"@webiny/api-file-manager/features/file/GetFileContentsById/index.js\";\nimport {\n FileNotFoundError,\n FilePersistenceError\n} from \"@webiny/api-file-manager/domain/file/errors.js\";\nimport { FileManagerStandaloneConfig } from \"~/features/FileManagerStandaloneConfig/abstractions.js\";\n\nconst CONTENT_TYPE_MAP: Record<string, string> = {\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n ico: \"image/x-icon\",\n bmp: \"image/bmp\",\n tiff: \"image/tiff\",\n tif: \"image/tiff\",\n pdf: \"application/pdf\",\n json: \"application/json\",\n xml: \"application/xml\",\n zip: \"application/zip\",\n gz: \"application/gzip\",\n txt: \"text/plain\",\n html: \"text/html\",\n htm: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n ts: \"application/typescript\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n ogg: \"audio/ogg\"\n};\n\nfunction resolveContentType(key: string): string {\n const ext = key.split(\".\").pop()?.toLowerCase();\n if (!ext) {\n return \"application/octet-stream\";\n }\n return CONTENT_TYPE_MAP[ext] ?? \"application/octet-stream\";\n}\n\nclass GetFileContentsByKeyUseCaseImpl implements GetFileContentsByKeyUseCaseAbstraction.Interface {\n constructor(\n private readonly tenantContext: TenantContext.Interface,\n private readonly config: FileManagerStandaloneConfig.Interface\n ) {}\n\n async execute(\n key: string\n ): Promise<Result<FileContents, GetFileContentsByKeyUseCaseAbstraction.Error>> {\n const tenant = this.tenantContext.getTenant();\n const bucketKey = `tenants/${tenant.id}/files/${key}`;\n const storagePath = this.config.storagePath;\n const filePath = `${storagePath}/${bucketKey}`;\n\n try {\n const buffer = await fs.readFile(filePath);\n const contentType = resolveContentType(key);\n return Result.ok({ buffer, contentType });\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return Result.fail(new FileNotFoundError(key));\n }\n return Result.fail(\n new FilePersistenceError(error instanceof Error ? error : new Error(String(error)))\n );\n }\n }\n}\n\nexport const GetFileContentsByKeyUseCase =\n GetFileContentsByKeyUseCaseAbstraction.createImplementation({\n implementation: GetFileContentsByKeyUseCaseImpl,\n dependencies: [TenantContext, FileManagerStandaloneConfig]\n });\n"],"names":["CONTENT_TYPE_MAP","resolveContentType","key","ext","GetFileContentsByKeyUseCaseImpl","tenantContext","config","tenant","bucketKey","storagePath","filePath","buffer","fs","contentType","Result","error","FileNotFoundError","FilePersistenceError","Error","String","GetFileContentsByKeyUseCase","GetFileContentsByKeyUseCaseAbstraction","TenantContext","FileManagerStandaloneConfig"],"mappings":";;;;;;AAWA,MAAMA,mBAA2C;IAC7C,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,IAAI;IACJ,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;AACT;AAEA,SAASC,mBAAmBC,GAAW;IACnC,MAAMC,MAAMD,IAAI,KAAK,CAAC,KAAK,GAAG,IAAI;IAClC,IAAI,CAACC,KACD,OAAO;IAEX,OAAOH,gBAAgB,CAACG,IAAI,IAAI;AACpC;AAEA,MAAMC;IACF,YACqBC,aAAsC,EACtCC,MAA6C,CAChE;aAFmBD,aAAa,GAAbA;aACAC,MAAM,GAANA;IAClB;IAEH,MAAM,QACFJ,GAAW,EACgE;QAC3E,MAAMK,SAAS,IAAI,CAAC,aAAa,CAAC,SAAS;QAC3C,MAAMC,YAAY,CAAC,QAAQ,EAAED,OAAO,EAAE,CAAC,OAAO,EAAEL,KAAK;QACrD,MAAMO,cAAc,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAMC,WAAW,GAAGD,YAAY,CAAC,EAAED,WAAW;QAE9C,IAAI;YACA,MAAMG,SAAS,MAAMC,SAAAA,QAAW,CAACF;YACjC,MAAMG,cAAcZ,mBAAmBC;YACvC,OAAOY,OAAO,EAAE,CAAC;gBAAEH;gBAAQE;YAAY;QAC3C,EAAE,OAAOE,OAAO;YACZ,IAAKA,AAAyC,aAAzCA,MAAgC,IAAI,EACrC,OAAOD,OAAO,IAAI,CAAC,IAAIE,kBAAkBd;YAE7C,OAAOY,OAAO,IAAI,CACd,IAAIG,qBAAqBF,iBAAiBG,QAAQH,QAAQ,IAAIG,MAAMC,OAAOJ;QAEnF;IACJ;AACJ;AAEO,MAAMK,0DACTC,4BAAAA,oBAA2D,CAAC;IACxD,gBAAgBjB;IAChB,cAAc;QAACkB;QAAeC;KAA4B;AAC9D"}
@@ -0,0 +1,4 @@
1
+ export declare const GetFileContentsByKeyFeature: {
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 { GetFileContentsByKeyUseCase } from "./GetFileContentsByKeyUseCase.js";
3
+ const GetFileContentsByKeyFeature = createFeature({
4
+ name: "FileManagerServer/GetFileContentsByKey",
5
+ register (container) {
6
+ container.register(GetFileContentsByKeyUseCase);
7
+ }
8
+ });
9
+ export { GetFileContentsByKeyFeature };
10
+
11
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features/GetFileContentsByKey/feature.js","sources":["../../../src/features/GetFileContentsByKey/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { GetFileContentsByKeyUseCase } from \"./GetFileContentsByKeyUseCase.js\";\n\nexport const GetFileContentsByKeyFeature = createFeature({\n name: \"FileManagerServer/GetFileContentsByKey\",\n register(container) {\n container.register(GetFileContentsByKeyUseCase);\n }\n});\n"],"names":["GetFileContentsByKeyFeature","createFeature","container","GetFileContentsByKeyUseCase"],"mappings":";;AAGO,MAAMA,8BAA8BC,cAAc;IACrD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
@@ -0,0 +1,16 @@
1
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
2
+ import { GetUploadPayloadUseCase as GetUploadPayloadUseCaseAbstraction } from "@webiny/api-file-manager/features/upload/GetUploadPayload/index.js";
3
+ import type { FileData } from "@webiny/api-file-manager/features/upload/types.js";
4
+ import type { UploadPayloadResponse } from "@webiny/api-file-manager/features/upload/types.js";
5
+ import type { FileManagerSettings } from "@webiny/api-file-manager/domain/settings/types.js";
6
+ import { FileManagerStandaloneConfig } from "../../features/FileManagerStandaloneConfig/abstractions.js";
7
+ declare class GetUploadPayloadUseCaseImpl implements GetUploadPayloadUseCaseAbstraction.Interface {
8
+ private readonly tenantContext;
9
+ private readonly config;
10
+ constructor(tenantContext: TenantContext.Interface, config: FileManagerStandaloneConfig.Interface);
11
+ execute(file: FileData, settings: FileManagerSettings): Promise<UploadPayloadResponse>;
12
+ }
13
+ export declare const GetUploadPayloadUseCase: typeof GetUploadPayloadUseCaseImpl & {
14
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-file-manager/features/upload/GetUploadPayload/abstractions").IGetUploadPayloadUseCase>;
15
+ };
16
+ export {};
@@ -0,0 +1,57 @@
1
+ import { validation } from "@webiny/validation";
2
+ import { TenantContext } from "@webiny/api-core/features/tenancy/TenantContext/index.js";
3
+ import { GetUploadPayloadUseCase } from "@webiny/api-file-manager/features/upload/GetUploadPayload/index.js";
4
+ import { createUploadToken } from "../../utils/uploadToken.js";
5
+ import { FileManagerStandaloneConfig } from "../FileManagerStandaloneConfig/abstractions.js";
6
+ const UPLOAD_MAX_FILE_SIZE_DEFAULT = 1099511627776;
7
+ const sanitizeFileSizeValue = (value, defaultValue)=>{
8
+ try {
9
+ validation.validateSync(value, "required,numeric,gte:0");
10
+ return value;
11
+ } catch {
12
+ return defaultValue;
13
+ }
14
+ };
15
+ class GetUploadPayloadUseCaseImpl {
16
+ constructor(tenantContext, config){
17
+ this.tenantContext = tenantContext;
18
+ this.config = config;
19
+ }
20
+ async execute(file, settings) {
21
+ const uploadMinFileSize = sanitizeFileSizeValue(settings.uploadMinFileSize, 0);
22
+ const uploadMaxFileSize = sanitizeFileSizeValue(settings.uploadMaxFileSize, UPLOAD_MAX_FILE_SIZE_DEFAULT);
23
+ const tenant = this.tenantContext.getTenant();
24
+ const storageKey = `tenants/${tenant.id}/files/${file.key}`;
25
+ const secret = this.config.uploadSecret;
26
+ const expiresAt = Date.now() + 60000;
27
+ const token = createUploadToken({
28
+ key: storageKey,
29
+ tenantId: tenant.id,
30
+ expiresAt,
31
+ uploadMinFileSize,
32
+ uploadMaxFileSize
33
+ }, secret);
34
+ const serverUrl = this.config.apiUrl;
35
+ const data = {
36
+ url: `${serverUrl}/webiny-file-upload`,
37
+ fields: {
38
+ key: storageKey,
39
+ token
40
+ }
41
+ };
42
+ return {
43
+ data: data,
44
+ file
45
+ };
46
+ }
47
+ }
48
+ const GetUploadPayloadUseCase_GetUploadPayloadUseCase = GetUploadPayloadUseCase.createImplementation({
49
+ implementation: GetUploadPayloadUseCaseImpl,
50
+ dependencies: [
51
+ TenantContext,
52
+ FileManagerStandaloneConfig
53
+ ]
54
+ });
55
+ export { GetUploadPayloadUseCase_GetUploadPayloadUseCase as GetUploadPayloadUseCase };
56
+
57
+ //# sourceMappingURL=GetUploadPayloadUseCase.js.map